diff options
author | Henry Conklin <henrywconklin@gmail.com> | 2021-02-11 09:33:55 -0600 |
---|---|---|
committer | Henry Conklin <henrywconklin@gmail.com> | 2021-02-14 11:00:25 -0600 |
commit | c6a911f0379b429691aa0dca6615523892bbfb06 (patch) | |
tree | 40b85fbb5f85cca9d99bfc91123a600a6aa62a4a /tests | |
parent | e5bb89cdd5e92fa6fdeff78aad08bf0cbfbcc692 (diff) |
Add support for numeric XML entities to XMLParser
* Add support for decimal numeric entities to String::xml_unescape
* Add more error checks to String::xml_unescape
* Refactor XMLParser to use String::xml_unescape instead of an internal
implementation
Diffstat (limited to 'tests')
-rw-r--r-- | tests/test_main.cpp | 1 | ||||
-rw-r--r-- | tests/test_string.h | 46 | ||||
-rw-r--r-- | tests/test_xml_parser.h | 74 |
3 files changed, 121 insertions, 0 deletions
diff --git a/tests/test_main.cpp b/tests/test_main.cpp index 2697eb6399..ad099604c1 100644 --- a/tests/test_main.cpp +++ b/tests/test_main.cpp @@ -70,6 +70,7 @@ #include "test_text_server.h" #include "test_validate_testing.h" #include "test_variant.h" +#include "test_xml_parser.h" #include "modules/modules_tests.gen.h" diff --git a/tests/test_string.h b/tests/test_string.h index cc3152203e..17f24fb0d8 100644 --- a/tests/test_string.h +++ b/tests/test_string.h @@ -1166,6 +1166,52 @@ TEST_CASE("[String] xml_escape/unescape") { CHECK(s.xml_escape(false).xml_unescape() == s); } +TEST_CASE("[String] xml_unescape") { + // Named entities + String input = ""&'<>"; + CHECK(input.xml_unescape() == "\"&\'<>"); + + // Numeric entities + input = "AB"; + CHECK(input.xml_unescape() == "AB"); + + input = "�&x#0;More text"; + String result = input.xml_unescape(); + // Didn't put in a leading NUL and terminate the string + CHECK(input.length() > 0); + CHECK(input[0] != '\0'); + // Entity should be left as-is if invalid + CHECK(input.xml_unescape() == input); + + // Check near char32_t range + input = "�"; + result = input.xml_unescape(); + CHECK(result.length() == 1); + CHECK(result[0] == 0xFFFFFFFF); + input = "�"; + result = input.xml_unescape(); + CHECK(result.length() == 1); + CHECK(result[0] == 0xFFFFFFFF); + + // Check out of range of char32_t + input = "�"; + CHECK(input.xml_unescape() == input); + input = "�"; + CHECK(input.xml_unescape() == input); + + // Shouldn't consume without ending in a ';' + input = "B"; + CHECK(input.xml_unescape() == input); + input = "A"; + CHECK(input.xml_unescape() == input); + + // Invalid characters should make the entity ignored + input = "ASomeIrrelevantText;"; + CHECK(input.xml_unescape() == input); + input = "BSomeIrrelevantText;"; + CHECK(input.xml_unescape() == input); +} + TEST_CASE("[String] Strip escapes") { String s = "\t\tTest Test\r\n Test"; CHECK(s.strip_escapes() == "Test Test Test"); diff --git a/tests/test_xml_parser.h b/tests/test_xml_parser.h new file mode 100644 index 0000000000..55de048d6a --- /dev/null +++ b/tests/test_xml_parser.h @@ -0,0 +1,74 @@ +/*************************************************************************/ +/* test_xml_parser.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef TEST_XML_PARSER_H +#define TEST_XML_PARSER_H + +#include <inttypes.h> + +#include "core/io/xml_parser.h" +#include "core/string/ustring.h" + +#include "tests/test_macros.h" + +namespace TestXMLParser { +TEST_CASE("[XMLParser] End-to-end") { + String source = "<?xml version = \"1.0\" encoding=\"UTF-8\" ?>\ +<top attr=\"attr value\">\ + Text<AB>\ +</top>"; + Vector<uint8_t> buff = source.to_utf8_buffer(); + + XMLParser parser; + parser.open_buffer(buff); + + // <?xml ...?> gets parsed as NODE_UNKNOWN + CHECK(parser.read() == OK); + CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_UNKNOWN); + + CHECK(parser.read() == OK); + CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_ELEMENT); + CHECK(parser.get_node_name() == "top"); + CHECK(parser.has_attribute("attr")); + CHECK(parser.get_attribute_value("attr") == "attr value"); + + CHECK(parser.read() == OK); + CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_TEXT); + CHECK(parser.get_node_data().lstrip(" \t") == "Text<AB>"); + + CHECK(parser.read() == OK); + CHECK(parser.get_node_type() == XMLParser::NodeType::NODE_ELEMENT_END); + CHECK(parser.get_node_name() == "top"); + + parser.close(); +} +} // namespace TestXMLParser + +#endif // TEST_XML_PARSER_H |