From 0a585dc3bba21ba2191cc1b71acede5275c7db0f Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Thu, 29 Jan 2026 17:17:28 +0100 Subject: [PATCH] Base: Add tests for escapeXml --- tests/src/Base/CMakeLists.txt | 1 + tests/src/Base/XMLTools.cpp | 79 +++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 tests/src/Base/XMLTools.cpp diff --git a/tests/src/Base/CMakeLists.txt b/tests/src/Base/CMakeLists.txt index b3f31b71ab..3bcce0c585 100644 --- a/tests/src/Base/CMakeLists.txt +++ b/tests/src/Base/CMakeLists.txt @@ -29,6 +29,7 @@ add_executable(Base_tests_run Vector3D.cpp ViewProj.cpp Writer.cpp + XMLTools.cpp ) setup_qt_test(InventorBuilder) diff --git a/tests/src/Base/XMLTools.cpp b/tests/src/Base/XMLTools.cpp new file mode 100644 index 0000000000..38b4efb5a6 --- /dev/null +++ b/tests/src/Base/XMLTools.cpp @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +#include +#include + +class TestXMLTools: public testing::Test +{ +}; + + +TEST_F(TestXMLTools, EscapeXmlEmptyString) +{ + EXPECT_EQ(XMLTools::escapeXml(""), ""); +} + +TEST_F(TestXMLTools, EscapeXmlNoChangesForSafeText) +{ + EXPECT_EQ(XMLTools::escapeXml("abcXYZ_123"), "abcXYZ_123"); + EXPECT_EQ(XMLTools::escapeXml("hello world"), "hello world"); + EXPECT_EQ(XMLTools::escapeXml("line1\nline2\tend"), "line1\nline2\tend"); +} + +TEST_F(TestXMLTools, EscapeXmlEscapesAmpersand) +{ + EXPECT_EQ(XMLTools::escapeXml("&"), "&"); + EXPECT_EQ(XMLTools::escapeXml("a&b"), "a&b"); +} + +TEST_F(TestXMLTools, EscapeXmlEscapesLessThanAndGreaterThan) +{ + EXPECT_EQ(XMLTools::escapeXml("<"), "<"); + EXPECT_EQ(XMLTools::escapeXml(">"), ">"); + EXPECT_EQ(XMLTools::escapeXml("ab"), "a>b"); + EXPECT_EQ(XMLTools::escapeXml("ac"), "a<b>c"); +} + +TEST_F(TestXMLTools, EscapeXmlEscapesQuotes) +{ + EXPECT_EQ(XMLTools::escapeXml("\""), """); + EXPECT_EQ(XMLTools::escapeXml("'"), "'"); + EXPECT_EQ(XMLTools::escapeXml("a\"b"), "a"b"); + EXPECT_EQ(XMLTools::escapeXml("a'b"), "a'b"); +} + +TEST_F(TestXMLTools, EscapeXmlEscapesAllFiveInOneString) +{ + // input: & < > " ' + EXPECT_EQ(XMLTools::escapeXml("&<>\"'"), "&<>"'"); +} + +TEST_F(TestXMLTools, EscapeXmlDoesNotDoubleEscapeNewlyInsertedEntities) +{ + // This test specifically catches the classic bug where you replace + // '<' with "<" and then later replace '&' with "&" and end up with "&lt;". + EXPECT_EQ(XMLTools::escapeXml("<"), "<"); + EXPECT_EQ(XMLTools::escapeXml(">"), ">"); + EXPECT_EQ(XMLTools::escapeXml("\""), """); + EXPECT_EQ(XMLTools::escapeXml("'"), "'"); +} + +TEST_F(TestXMLTools, EscapeXmlComplexMixedContent) +{ + const std::string in = "Tom & Jerry <\"fun\"> 'n' games"; + const std::string out = "Tom & Jerry <"fun"> 'n' games"; + EXPECT_EQ(XMLTools::escapeXml(in), out); +} + +TEST_F(TestXMLTools, EscapeXmlMultipleAdjacentCharacters) +{ + EXPECT_EQ(XMLTools::escapeXml("&&&&"), "&&&&"); + EXPECT_EQ(XMLTools::escapeXml("<<<<"), "<<<<"); + EXPECT_EQ(XMLTools::escapeXml("\"\"''"), """''"); +} + +TEST_F(TestXMLTools, EscapeXmlPreservesWhitespaceAndControlCommonInText) +{ + EXPECT_EQ(XMLTools::escapeXml(" a \r\n b \t c "), " a \r\n b \t c "); +}