From 359422c97cce93bbb27051f9df3efb45bd0b9052 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Sat, 23 Aug 2025 11:18:44 +0200 Subject: settings file writing --- libs/xml.c/test/CMakeLists.txt | 128 +++++++++++++++++ libs/xml.c/test/example.c | 96 +++++++++++++ libs/xml.c/test/test-attributes.xml | 1 + libs/xml.c/test/test-huitre39.c | 181 ++++++++++++++++++++++++ libs/xml.c/test/test-xml-c.c | 265 ++++++++++++++++++++++++++++++++++++ libs/xml.c/test/test-xml-cpp.cpp | 222 ++++++++++++++++++++++++++++++ libs/xml.c/test/test.xml | 7 + 7 files changed, 900 insertions(+) create mode 100644 libs/xml.c/test/CMakeLists.txt create mode 100644 libs/xml.c/test/example.c create mode 100644 libs/xml.c/test/test-attributes.xml create mode 100644 libs/xml.c/test/test-huitre39.c create mode 100644 libs/xml.c/test/test-xml-c.c create mode 100644 libs/xml.c/test/test-xml-cpp.cpp create mode 100644 libs/xml.c/test/test.xml (limited to 'libs/xml.c/test') diff --git a/libs/xml.c/test/CMakeLists.txt b/libs/xml.c/test/CMakeLists.txt new file mode 100644 index 0000000..09097d0 --- /dev/null +++ b/libs/xml.c/test/CMakeLists.txt @@ -0,0 +1,128 @@ +# xml.c / test +cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) + + + +# Example +add_executable( + "${PROJECT_NAME}-example" + "${CMAKE_CURRENT_LIST_DIR}/example.c" +) + +target_compile_options( + "${PROJECT_NAME}-example" + PRIVATE + -std=c11 +) + +target_link_libraries( + "${PROJECT_NAME}-example" + PRIVATE + xml +) + +add_test( + NAME "${PROJECT_NAME}-example" + COMMAND "${PROJECT_NAME}-example" +) + + + +# Test cases +FILE( COPY "${CMAKE_CURRENT_LIST_DIR}/test.xml" + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" +) + +FILE( COPY "${CMAKE_CURRENT_LIST_DIR}/test-attributes.xml" + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" +) + + + +# Test (C) +add_executable( + "${PROJECT_NAME}-test-c" + "${CMAKE_CURRENT_LIST_DIR}/test-xml-c.c" +) + +target_compile_options( + "${PROJECT_NAME}-test-c" + PRIVATE + -std=c11 +) + +target_link_libraries( + "${PROJECT_NAME}-test-c" + PRIVATE + xml +) + + +add_test( + NAME "${PROJECT_NAME}-test-c" + COMMAND "${PROJECT_NAME}-test-c" +) + +add_test( + NAME "${PROJECT_NAME}-test-c-valgrind" + COMMAND valgrind --tool=memcheck --leak-check=full --track-origins=yes -v "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-test-c" +) + + + +# Test (C++) +add_executable( + "${PROJECT_NAME}-test-cpp" + "${CMAKE_CURRENT_LIST_DIR}/test-xml-cpp.cpp" +) + +target_compile_options( + "${PROJECT_NAME}-test-cpp" + PRIVATE + -std=c++11 +) + +target_link_libraries( + "${PROJECT_NAME}-test-cpp" + PRIVATE + xml +) + + +add_test( + NAME "${PROJECT_NAME}-test-cpp" + COMMAND "${PROJECT_NAME}-test-cpp" +) + + +add_test( + NAME "${PROJECT_NAME}-test-cpp-valgrind" + COMMAND valgrind --tool=memcheck --leak-check=full --track-origins=yes -v "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-test-cpp" +) + + + +# Test huitre39 +add_executable( + "${PROJECT_NAME}-test-huitre39" + "${CMAKE_CURRENT_LIST_DIR}/test-huitre39.c" +) + +target_compile_options( + "${PROJECT_NAME}-test-huitre39" + PRIVATE + -std=c11 +) + +target_link_libraries( + "${PROJECT_NAME}-test-huitre39" + PRIVATE + xml +) + + +add_test( + NAME "${PROJECT_NAME}-test-huitre39" + COMMAND "${PROJECT_NAME}-test-huitre39" +) + diff --git a/libs/xml.c/test/example.c b/libs/xml.c/test/example.c new file mode 100644 index 0000000..ebf605c --- /dev/null +++ b/libs/xml.c/test/example.c @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2012 ooxi/xml.c + * https://github.com/ooxi/xml.c + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from the + * use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +#include +#include +#include +#include + + + +int main(int argc, char** argv) { + + /* XML source, could be read from disk + */ + uint8_t* source = "" + "" + "World" + "" + ":-)" + ":-O" + ":-D" + "" + "" + ; + + + /* Parse the document + * + * Watch out: Remember not to free the source until you have freed the + * document itself. If you have to free the source before, supply a + * copy to xml_parse_document which can be freed together with the + * document (`free_buffer' argument to `xml_document_free') + */ + struct xml_document* document = xml_parse_document(source, strlen(source)); + + /* You _have_ to check the result of `xml_parse_document', if it's 0 + * then the source could not be parsed. If you think this is a bug in + * xml.c, than use a debug build (cmake -DCMAKE_BUILD_TYPE=Debug) which + * will verbosely tell you about the parsing process + */ + if (!document) { + printf("Could parse document\n"); + exit(EXIT_FAILURE); + } + struct xml_node* root = xml_document_root(document); + + + /* Say Hello World :-) + */ + struct xml_node* root_hello = xml_node_child(root, 0); + struct xml_string* hello = xml_node_name(root_hello); + struct xml_string* world = xml_node_content(root_hello); + + /* Watch out: `xml_string_copy' will not 0-terminate your buffers! (but + * `calloc' will :-) + */ + uint8_t* hello_0 = calloc(xml_string_length(hello) + 1, sizeof(uint8_t)); + uint8_t* world_0 = calloc(xml_string_length(world) + 1, sizeof(uint8_t)); + xml_string_copy(hello, hello_0, xml_string_length(hello)); + xml_string_copy(world, world_0, xml_string_length(world)); + + printf("%s %s\n", hello_0, world_0); + free(hello_0); + free(world_0); + + + /* Extract amount of Root/This children + */ + struct xml_node* root_this = xml_node_child(root, 1); + printf("Root/This has %lu children\n", (unsigned long)xml_node_children(root_this)); + + + /* Remember to free the document or you'll risk a memory leak + */ + xml_document_free(document, false); +} + diff --git a/libs/xml.c/test/test-attributes.xml b/libs/xml.c/test/test-attributes.xml new file mode 100644 index 0000000..7832c02 --- /dev/null +++ b/libs/xml.c/test/test-attributes.xml @@ -0,0 +1 @@ + diff --git a/libs/xml.c/test/test-huitre39.c b/libs/xml.c/test/test-huitre39.c new file mode 100644 index 0000000..43b9ae7 --- /dev/null +++ b/libs/xml.c/test/test-huitre39.c @@ -0,0 +1,181 @@ +#include +#include +#include +#include +#include "./xml.h" + + + + + +/** + * Will halt the program iff assertion fails + */ +static void _assert_that(_Bool condition, char const* message, char const* func, char const* file, int line) { + if (!condition) { + fprintf(stderr, "Assertion failed: %s, in %s (%s:%i)\n", message, func, file, line); + exit(EXIT_FAILURE); + } +} + +#define assert_that(condition, message) \ + _assert_that(condition, message, __func__, __FILE__, __LINE__) + + + + + +/** + * Behaves similar to `getElementsByTagName`, however returns just the first and + * not all elements with a given tag name + * + * @param base Node in tree which should be the start of te recursive search + * @param 0-terminated tag name, case sensitive + * + * @return First node below `base` iff found, otherwise 0 + * @warning Depth-First search! + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName + */ +static struct xml_node* get_node_by_name(struct xml_node* base, uint8_t* name) { + + + /* Check whether `base` already has the tag name we are searching for + */ + size_t const name_length = strlen(name); + + uint8_t* base_name = xml_easy_name(base); + size_t const base_name_length = strlen(base_name); + + + /* Length of `name` and `base_name` do match, we should now do a real + * comparison + */ + if (name_length == base_name_length) { + int const rs = memcmp(name, base_name, name_length); + + /* Names match! We have found an element which fullfills our + * search criteria + */ + if (!rs) { + free(base_name); + return base; + } + } + + + /* Unfortunately, `base` is not the element we are looking for :-( + */ + free(base_name); + + + /* Let's take a look at the children of `base` + */ + size_t const number_of_children = xml_node_children(base); + + + /* No children → No luck with base + */ + if (!number_of_children) { + return 0; + } + + + /* Recursivly look through all children + */ + size_t child = 0; for (; child < number_of_children; ++child) { + struct xml_node* child_node = xml_node_child(base, child); + + /* Maybe this child does contain the element we are looking for? + */ + struct xml_node* search_result = get_node_by_name( + child_node, name + ); + + /* We are lucky! + */ + if (search_result) { + return search_result; + } + } + + + /* No luck :-( + */ + return 0; +} + + + + + +int main(int argc, char** argv) { + + /* XML source, could be read from disk + */ + uint8_t* source = "" + "" + "World" + + "" + "" + "testas one" + "testos" + "" + + "" + "testis" + "testus" + "testls" + "" + + "" + "testmn" + "testas two" + "" + "" + "" + ; + + struct xml_document* document = xml_parse_document(source, strlen(source)); + + if (!document) { + printf("Could parse document\n"); + exit(EXIT_FAILURE); + } + struct xml_node* root = xml_document_root(document); + + + + /* We expect to find Root / Functions / Function#1 / us + */ + struct xml_node* us = get_node_by_name(root, "us"); + assert_that(us, "Did not find element by tag name `us'"); + + uint8_t* us_content = xml_easy_content(us); + assert_that(us_content, "`us' should have content"); + assert_that(!strcmp(us_content, "testus"), "Unexpected content for node `us'"); + free(us_content); + + + /* We expect to find Root / Functions / Function#0 / as + */ + struct xml_node* as = get_node_by_name(root, "as"); + assert_that(as, "Did not find element by tag name `as'"); + + uint8_t* as_content = xml_easy_content(as); + assert_that(as_content, "`as' should have content"); + assert_that(!strcmp(as_content, "testas one"), "Unexpected content for first `as' node"); + free(as_content); + + + /* We do not expect do find a node with tag name `does_not_exist' + */ + struct xml_node* does_not_exist = get_node_by_name(root, "does_not_exist"); + assert_that(!does_not_exist, "Found node that should not exist"); + + + + xml_document_free(document, false); +} + diff --git a/libs/xml.c/test/test-xml-c.c b/libs/xml.c/test/test-xml-c.c new file mode 100644 index 0000000..ee54bac --- /dev/null +++ b/libs/xml.c/test/test-xml-c.c @@ -0,0 +1,265 @@ +/** + * Copyright (c) 2012 ooxi/xml.c + * https://github.com/ooxi/xml.c + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from the + * use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ +#include +#include +#include +#include +#include + + + + + +/** + * Will halt the program iff assertion fails + */ +static void _assert_that(_Bool condition, char const* message, char const* func, char const* file, int line) { + if (!condition) { + fprintf(stderr, "Assertion failed: %s, in %s (%s:%i)\n", message, func, file, line); + exit(EXIT_FAILURE); + } +} + +#define assert_that(condition, message) \ + _assert_that(condition, message, __func__, __FILE__, __LINE__) + + + +/** + * @return true iff xml string equals the c string + */ +static _Bool string_equals(struct xml_string* a, char const* b) { + size_t a_length = xml_string_length(a); + size_t b_length = strlen(b); + + uint8_t* a_buffer = alloca((a_length + 1) * sizeof(uint8_t)); + xml_string_copy(a, a_buffer, a_length); + a_buffer[a_length] = 0; + + if (a_length != b_length) { + fprintf(stderr, "string_equals: %s#%i <> %s#%i\n", a_buffer, (int)a_length, b, (int)b_length); + return false; + } + + size_t i = 0; for (; i < a_length; ++i) { + if (a_buffer[i] != b[i]) { + fprintf(stderr, "string_equals: %s <> %s\n", a_buffer, b); + return false; + } + } + + return true; +} + + + +/** + * Converts a static character array to an uint8_t data source + */ +#define SOURCE(source, content) \ + uint8_t* source = calloc(strlen(content) + 1, sizeof(uint8_t)); \ + { char const* content_string = content; \ + memcpy(source, content_string, strlen(content) + 1); \ + } + + + +/** + * Tries to parse a simple document containing only one tag + */ +static void test_xml_parse_document_0() { + SOURCE(source, "World"); +// uint8_t* source = malloc((1 + strlen("World")) * sizeof(uint8_t)); +// { char const* content_string = "World"; +// memcpy(source, content_string, strlen("World") + 1); +// } + + struct xml_document* document = xml_parse_document(source, strlen(source)); + assert_that(document, "Could not parse document"); + + struct xml_node* root = xml_document_root(document); + assert_that(string_equals(xml_node_name(root), "Hello"), "root node name must be `Hello'"); + assert_that(string_equals(xml_node_content(root), "World"), "root node content must be `World'"); + + xml_document_free(document, true); +} + +/** + * Tries to parse a document containing multiple tags + */ +static void test_xml_parse_document_1() { + SOURCE(source, "" + "\n" + "\t\n" + "\t\tFirst content\n" + "\t\n" + "\t\n" + "\t\tSecond content\n" + "\t\n" + "\n" + ); + struct xml_document* document = xml_parse_document(source, strlen(source)); + assert_that(document, "Could not parse document"); + + struct xml_node* root = xml_document_root(document); + assert_that(string_equals(xml_node_name(root), "Parent"), "root node name must be `Parent'"); + assert_that(2 == xml_node_children(root), "root must have two children"); + + struct xml_node* first_child = xml_node_child(root, 0); + struct xml_node* second_child = xml_node_child(root, 1); + assert_that(first_child && second_child, "Failed retrieving the children of root"); + + struct xml_node* third_child = xml_node_child(root, 2); + assert_that(!third_child, "root has a third child where non should be"); + + assert_that(string_equals(xml_node_name(first_child), "Child"), "first_child node name must be `Child'"); + assert_that(string_equals(xml_node_content(first_child), "First content"), "first_child node content must be `First content'"); + assert_that(string_equals(xml_node_name(second_child), "Child"), "second_child node name must be `Child'"); + assert_that(string_equals(xml_node_content(second_child), "Second content"), "second_child node content must be `tSecond content'"); + + xml_document_free(document, true); +} + + + +/** + * Tests the eas functionality + */ +static void test_xml_parse_document_2() { + SOURCE(source, "" + "\n" + "\t\n" + "\t\tFirst content\n" + "\t\n" + "\t\n" + "Content A\n" + "Content B\n" + "\t\n" + "\t\n" + "\t\tSecond content\n" + "\t\n" + "\n" + ); + struct xml_document* document = xml_parse_document(source, strlen(source)); + assert_that(document, "Could not parse document"); + + struct xml_node* root = xml_document_root(document); + assert_that(string_equals(xml_node_name(root), "Parent"), "root node name must be `Parent'"); + assert_that(3 == xml_node_children(root), "root must have two children"); + + struct xml_node* test_a = xml_easy_child(root, "This", "Is", "A", "Test", 0); + assert_that(test_a, "Cannot find Parent/This/Is/A/Test"); + assert_that(string_equals(xml_node_content(test_a), "Content A"), "Content of Parent/This/Is/A/Test must be `Content A'"); + + struct xml_node* test_b = xml_easy_child(root, "This", "Is", "B", "Test", 0); + assert_that(test_b, "Cannot find Parent/This/Is/B/Test"); + assert_that(string_equals(xml_node_content(test_b), "Content B"), "Content of Parent/This/Is/B/Test must be `Content B'"); + + struct xml_node* test_c = xml_easy_child(root, "This", "Is", "C", "Test", 0); + assert_that(!test_c, "Must not find Parent/This/Is/C/Test because no such path exists"); + + struct xml_node* must_be_null = xml_easy_child(root, "Child"); + assert_that(!must_be_null, "Parent/Child cannot be a valid expression, because there are two children named `Child' in `Parent'"); + + uint8_t* name_is = xml_easy_name(xml_easy_child(root, "This", "Is", 0)); + assert_that(!strcmp(name_is, "Is"), "Name of Parent/This/Is must be `Is'"); + free(name_is); + + uint8_t* content_a = xml_easy_content(test_a); + assert_that(!strcmp(content_a, "Content A"), "Content of Parent/This/Is/A/Test must be `Content A'"); + free(content_a); + + xml_document_free(document, true); +} + + + +/** + * Tests the xml_open_document functionality + */ +static void test_xml_parse_document_3() { + #define FILE_NAME "test.xml" + FILE* handle = fopen(FILE_NAME, "rb"); + assert_that(handle, "Cannot open " FILE_NAME); + + struct xml_document* document = xml_open_document(handle); + assert_that(document, "Cannot parse " FILE_NAME); + + struct xml_node* element = xml_easy_child( + xml_document_root(document), "Element", "With", 0 + ); + assert_that(element, "Cannot find Document/Element/With"); + assert_that(string_equals(xml_node_content(element), "Child"), "Content of Document/Element/With must be `Child'"); + + xml_document_free(document, true); + #undef FILE_NAME +} + + + +/** + * Test parsing of attributes + * + * @author Isty001 + * @see https://github.com/Isty001/ + */ +static void test_xml_parse_attributes() { + #define FILE_NAME "test-attributes.xml" + FILE* handle = fopen(FILE_NAME, "rb"); + assert_that(handle, "Cannot open " FILE_NAME); + + struct xml_document* document = xml_open_document(handle); + assert_that(document, "Cannot parse " FILE_NAME); + + struct xml_node* element = xml_easy_child( + xml_document_root(document), 0 + ); + + assert_that(element, "Cannot find Document/Element/With"); + assert_that(2 == xml_node_attributes(element), "Should have 2 attributes"); + + assert_that(string_equals(xml_node_attribute_name(element, 0), "value"), "Content of Document/Element/With must be `Child'"); + assert_that(string_equals(xml_node_attribute_content(element, 0), "2"), "First attribute's content should be \"2\""); + + assert_that(string_equals(xml_node_attribute_name(element, 1), "value_2"), "Content of Document/Element/With must be `Child'"); + assert_that(string_equals(xml_node_attribute_content(element, 1), "Hello"), "Second attribute's content should be Hello"); + + xml_document_free(document, true); + #undef FILE_NAME +} + + + +/** + * Console interface + */ +int main(int argc, char** argv) { + test_xml_parse_document_0(); + test_xml_parse_document_1(); + test_xml_parse_document_2(); + test_xml_parse_document_3(); + test_xml_parse_attributes(); + + fprintf(stdout, "All tests passed :-)\n"); + exit(EXIT_SUCCESS); +} diff --git a/libs/xml.c/test/test-xml-cpp.cpp b/libs/xml.c/test/test-xml-cpp.cpp new file mode 100644 index 0000000..513d14b --- /dev/null +++ b/libs/xml.c/test/test-xml-cpp.cpp @@ -0,0 +1,222 @@ +/** + * Copyright (c) 2012 ooxi/xml.c + * https://github.com/ooxi/xml.c + * + * This software is provided 'as-is', without any express or implied warranty. + * In no event will the authors be held liable for any damages arising from the + * use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software in a + * product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source distribution. + */ + +#include +#include +#include +#include + +/** + * Will halt the program iff assertion fails + */ +static void _assert_that(bool condition, const char* message, + const char* func, const char* file, int line) { + if (!condition) { + std::cerr << "Assertion failed: " << message << ", in " << func << " (" + << file << ":" << line << ")\n"; + exit(EXIT_FAILURE); + } +} + +#define assert_that(condition, message) \ + _assert_that(condition, message, __func__, __FILE__, __LINE__) + +/** + * @return true iff xml string equals the c string + */ +static bool string_equals(struct xml_string* a, const char* b) { + size_t a_length = xml_string_length(a); + size_t b_length = strlen(b); + uint8_t* a_buffer = new uint8_t[((a_length + 1) * sizeof(uint8_t))]; + xml_string_copy(a, a_buffer, a_length); + a_buffer[a_length] = 0; + if (a_length != b_length) { + std::cerr << "string_equals: " << a_buffer << "#" << a_length << " <> " + << b << "#" << b_length << "\n"; + delete[] a_buffer; + return false; + } + size_t i = 0; for (; i < a_length; ++i) { + if (a_buffer[i] != b[i]) { + std::cerr << "string_equals: " << a_buffer << " <> " << b << "\n"; + delete[] a_buffer; + return false; + } + } + delete[] a_buffer; + return true; +} + + +/** + * Converts a static character array to an uint8_t data source which can be + * freed + */ +#define SOURCE(source, content) \ + uint8_t* source = (uint8_t*)calloc(strlen(content) + 1, sizeof(uint8_t)); \ + memcpy(source, (content), strlen(content) + 1); \ + + +/** + * Tries to parse a simple document containing only one tag + */ +static void test_xml_parse_document_0() { + SOURCE(source, "World"); + // uint8_t* source = malloc((1 + strlen("World")) * + // sizeof(uint8_t)); + // { + // const char* content_string = "World"; + // memcpy(source, content_string, strlen("World") + 1); + // } + struct xml_document* document = xml_parse_document(source, + strlen((const char *)source)); + assert_that(document, "Could not parse document"); + struct xml_node* root = xml_document_root(document); + assert_that(string_equals(xml_node_name(root), "Hello"), + "root node name must be `Hello'"); + assert_that(string_equals(xml_node_content(root), "World"), + "root node content must be `World'"); + xml_document_free(document, true); +} + +/** + * Tries to parse a document containing multiple tags + */ +static void test_xml_parse_document_1() { + SOURCE(source, "" + "\n" + "\t\n" + "\t\tFirst content\n" + "\t\n" + "\t\n" + "\t\tSecond content\n" + "\t\n" + "\n" + ); + struct xml_document* document = xml_parse_document(source, + strlen((const char *)source)); + assert_that(document, "Could not parse document"); + struct xml_node* root = xml_document_root(document); + assert_that(string_equals(xml_node_name(root), "Parent"), + "root node name must be `Parent'"); + assert_that(2 == xml_node_children(root), "root must have two children"); + struct xml_node* first_child = xml_node_child(root, 0); + struct xml_node* second_child = xml_node_child(root, 1); + assert_that(first_child && second_child, + "Failed retrieving the children of root"); + struct xml_node* third_child = xml_node_child(root, 2); + assert_that(!third_child, "root has a third child where non should be"); + assert_that(string_equals(xml_node_name(first_child), "Child"), + "first_child node name must be `Child'"); + assert_that(string_equals(xml_node_content(first_child), "First content"), + "first_child node content must be `First content'"); + assert_that(string_equals(xml_node_name(second_child), "Child"), + "second_child node name must be `Child'"); + assert_that(string_equals(xml_node_content(second_child), "Second content"), + "second_child node content must be `tSecond content'"); + xml_document_free(document, true); +} + +/** + * Tests the eas functionality + */ +static void test_xml_parse_document_2() { + SOURCE(source, "" + "\n" + "\t\n" + "\t\tFirst content\n" + "\t\n" + "\t\n" + "Content A\n" + "Content B\n" + "\t\n" + "\t\n" + "\t\tSecond content\n" + "\t\n" + "\n" + ); + struct xml_document* document = xml_parse_document(source, + strlen((const char *)source)); + assert_that(document, "Could not parse document"); + struct xml_node* root = xml_document_root(document); + assert_that(string_equals(xml_node_name(root), "Parent"), + "root node name must be `Parent'"); + assert_that(3 == xml_node_children(root), + "root must have two children"); + struct xml_node* test_a = xml_easy_child(root, (uint8_t *)"This", + (uint8_t *)"Is", (uint8_t *)"A", (uint8_t *)"Test", 0); + assert_that(test_a, "Cannot find Parent/This/Is/A/Test"); + assert_that(string_equals(xml_node_content(test_a), "Content A"), + "Content of Parent/This/Is/A/Test must be `Content A'"); + struct xml_node* test_b = xml_easy_child(root, (uint8_t *)"This", + (uint8_t *)"Is", (uint8_t *)"B", (uint8_t *)"Test", 0); + assert_that(test_b, "Cannot find Parent/This/Is/B/Test"); + assert_that(string_equals(xml_node_content(test_b), "Content B"), + "Content of Parent/This/Is/B/Test must be `Content B'"); + struct xml_node* test_c = xml_easy_child(root, (uint8_t *)"This", + (uint8_t *)"Is", (uint8_t *)"C", (uint8_t *)"Test", 0); + assert_that(!test_c, + "Must not find Parent/This/Is/C/Test because no such path exists"); + struct xml_node* must_be_null = xml_easy_child(root, (uint8_t *)"Child"); + assert_that(!must_be_null, + "Parent/Child cannot be a valid expression, because there are two children " + "named `Child' in `Parent'"); + uint8_t* name_is = xml_easy_name(xml_easy_child(root, (uint8_t *)"This", + (uint8_t *)"Is", 0)); + assert_that(!strcmp((const char*)name_is, "Is"), + "Name of Parent/This/Is must be `Is'"); + free(name_is); + uint8_t* content_a = xml_easy_content(test_a); + assert_that(!strcmp((const char*)content_a, "Content A"), + "Content of Parent/This/Is/A/Test must be `Content A'"); + free(content_a); + xml_document_free(document, true); +} + +/** + * Tests the xml_open_document functionality + */ +static void test_xml_parse_document_3() { + #define FILE_NAME "test.xml" + FILE* handle = fopen(FILE_NAME, "rb"); + assert_that(handle, "Cannot open " FILE_NAME); + struct xml_document* document = xml_open_document(handle); + assert_that(document, "Cannot parse " FILE_NAME); + struct xml_node* element = xml_easy_child(xml_document_root(document), + (uint8_t *)"Element", (uint8_t *)"With", 0); + assert_that(element, "Cannot find Document/Element/With"); + assert_that(string_equals(xml_node_content(element), "Child"), + "Content of Document/Element/With must be `Child'"); + xml_document_free(document, true); + #undef FILE_NAME +} + +int main(int argc, char **argv) { + test_xml_parse_document_0(); + test_xml_parse_document_1(); + test_xml_parse_document_2(); + test_xml_parse_document_3(); + std::cout << "All tests passed :-)\n"; + exit(EXIT_SUCCESS); +} + diff --git a/libs/xml.c/test/test.xml b/libs/xml.c/test/test.xml new file mode 100644 index 0000000..a0e1ab8 --- /dev/null +++ b/libs/xml.c/test/test.xml @@ -0,0 +1,7 @@ + + + + Child + + + -- cgit v1.2.3-70-g09d2