From 13670f535fad8ab5db06049366a38f7a364d37d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Ho=C5=99e=C5=88ovsk=C3=BD?= Date: Fri, 1 Oct 2021 12:02:17 +0200 Subject: [PATCH] Add more tests for XmlWrite::write* members --- src/catch2/internal/catch_xmlwriter.cpp | 5 ++- src/catch2/internal/catch_xmlwriter.hpp | 2 + .../SelfTest/IntrospectiveTests/Xml.tests.cpp | 44 +++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/catch2/internal/catch_xmlwriter.cpp b/src/catch2/internal/catch_xmlwriter.cpp index b8635f7f..1be19bfc 100644 --- a/src/catch2/internal/catch_xmlwriter.cpp +++ b/src/catch2/internal/catch_xmlwriter.cpp @@ -295,13 +295,14 @@ namespace { } XmlWriter& XmlWriter::writeText( StringRef text, XmlFormatting fmt ) { + CATCH_ENFORCE(!m_tags.empty(), "Cannot write text as top level element"); if( !text.empty() ){ bool tagWasOpen = m_tagIsOpen; ensureTagClosed(); if (tagWasOpen && shouldIndent(fmt)) { m_os << m_indent; } - m_os << XmlEncode( text ); + m_os << XmlEncode( text, XmlEncode::ForTextNodes ); applyFormatting(fmt); } return *this; @@ -312,7 +313,7 @@ namespace { if (shouldIndent(fmt)) { m_os << m_indent; } - m_os << ""; + m_os << ""; applyFormatting(fmt); return *this; } diff --git a/src/catch2/internal/catch_xmlwriter.hpp b/src/catch2/internal/catch_xmlwriter.hpp index 3ba8c08e..a939a6f3 100644 --- a/src/catch2/internal/catch_xmlwriter.hpp +++ b/src/catch2/internal/catch_xmlwriter.hpp @@ -117,10 +117,12 @@ namespace Catch { return writeAttribute( name, rss.str() ); } + //! Writes escaped `text` in a element XmlWriter& writeText( StringRef text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent ); + //! Writes XML comment as "" XmlWriter& writeComment( StringRef text, XmlFormatting fmt = XmlFormatting::Newline | XmlFormatting::Indent ); diff --git a/tests/SelfTest/IntrospectiveTests/Xml.tests.cpp b/tests/SelfTest/IntrospectiveTests/Xml.tests.cpp index 0459c579..4659dc52 100644 --- a/tests/SelfTest/IntrospectiveTests/Xml.tests.cpp +++ b/tests/SelfTest/IntrospectiveTests/Xml.tests.cpp @@ -131,3 +131,47 @@ TEST_CASE("XmlWriter writes boolean attributes as true/false", "[XML][XmlWriter] ContainsSubstring(R"(attr1="true")") && ContainsSubstring(R"(attr2="false")") ); } + +TEST_CASE("XmlWriter does not escape comments", "[XML][XmlWriter][approvals]") { + using Catch::Matchers::ContainsSubstring; + std::stringstream stream; + { + Catch::XmlWriter xml(stream); + + xml.writeComment(R"(unescaped special chars: < > ' " &)"); + } + REQUIRE_THAT( stream.str(), + ContainsSubstring(R"()")); +} + +TEST_CASE("XmlWriter errors out when writing text without enclosing element", "[XmlWriter][approvals]") { + std::stringstream stream; + Catch::XmlWriter xml(stream); + REQUIRE_THROWS(xml.writeText("some text")); +} + +TEST_CASE("XmlWriter escapes text properly", "[XML][XmlWriter][approvals]") { + using Catch::Matchers::ContainsSubstring; + std::stringstream stream; + { + Catch::XmlWriter xml(stream); + xml.scopedElement("root") + .writeText(R"(Special chars need escaping: < > ' " &)"); + } + + REQUIRE_THAT( stream.str(), + ContainsSubstring(R"(Special chars need escaping: < > ' " &)")); +} + +TEST_CASE("XmlWriter escapes attributes properly", "[XML][XmlWriter][approvals]") { + using Catch::Matchers::ContainsSubstring; + std::stringstream stream; + { + Catch::XmlWriter xml(stream); + xml.scopedElement("root") + .writeAttribute("some-attribute", R"(Special chars need escaping: < > ' " &)"); + } + + REQUIRE_THAT(stream.str(), + ContainsSubstring(R"(some-attribute="Special chars need escaping: < > ' " &")")); +}