Browse Source

XML attributes unit test

* `strtok_r` is not a standard function, and not available wiht std=c11 so I used a public domain implementation of it.
* Added an attribute unit test
master
Farkasvölgyi 4 years ago
committed by ooxi
parent
commit
070d0ec22b
4 changed files with 104 additions and 10 deletions
  1. +66
    -8
      src/xml.c
  2. +5
    -1
      test/CMakeLists.txt
  3. +1
    -0
      test/test-attributes.xml
  4. +32
    -1
      test/test-xml-c.c

+ 66
- 8
src/xml.c View File

@@ -36,6 +36,47 @@



/*
* public domain strtok_r() by Charlie Gordon
*
* from comp.lang.c 9/14/2007
*
* http://groups.google.com/group/comp.lang.c/msg/2ab1ecbb86646684
*
* (Declaration that it's public domain):
* http://groups.google.com/group/comp.lang.c/msg/7c7b39328fefab9c
*/
static char* xml_strtok_r(char *str, const char *delim, char **nextp) {
char *ret;

if (str == NULL) {
str = *nextp;
}

str += strspn(str, delim);

if (*str == '\0') {
return NULL;
}

ret = str;

str += strcspn(str, delim);

if (*str) {
*str++ = '\0';
}

*nextp = str;

return ret;
}






/**
* [OPAQUE API]
*
@@ -116,9 +157,26 @@ enum xml_parser_offset {
/**
* [PRIVATE]
*
* @return Number of elements in 0-terminated array
* @return Number of attributes in 0-terminated array
*/
static size_t get_zero_terminated_array_attributes(struct xml_attribute** attributes) {
size_t elements = 0;

while (attributes[elements]) {
++elements;
}

return elements;
}



/**
* [PRIVATE]
*
* @return Number of nodes in 0-terminated array
*/
static size_t get_zero_terminated_array_elements(struct xml_node** nodes) {
static size_t get_zero_terminated_array_nodes(struct xml_node** nodes) {
size_t elements = 0;

while (nodes[elements]) {
@@ -398,13 +456,13 @@ static struct xml_attribute** xml_find_attributes(struct xml_parser* parser, str

tmp = (char*) xml_string_clone(tag_open);

token = strtok_r(tmp, " ", &rest); // skip the first value
token = xml_strtok_r(tmp, " ", &rest); // skip the first value
if(token == NULL) {
goto cleanup;
}
tag_open->length = strlen(token);

for(token=strtok_r(NULL," ", &rest); token!=NULL; token=strtok_r(NULL," ", &rest)) {
for(token=xml_strtok_r(NULL," ", &rest); token!=NULL; token=xml_strtok_r(NULL," ", &rest)) {
str_name = malloc(strlen(token)+1);
str_content = malloc(strlen(token)+1);
// %s=\"%s\" wasn't working for some reason, ugly hack to make it work
@@ -427,7 +485,7 @@ static struct xml_attribute** xml_find_attributes(struct xml_parser* parser, str
new_attribute->content->buffer = (unsigned char*)start_content;
new_attribute->content->length = strlen(str_content);

old_elements = get_zero_terminated_array_elements(attributes);
old_elements = get_zero_terminated_array_attributes(attributes);
new_elements = old_elements + 1;
attributes = realloc(attributes, (new_elements+1)*sizeof(struct xml_attributes*));

@@ -690,7 +748,7 @@ static struct xml_node* xml_parse_node(struct xml_parser* parser) {

/* Grow child array :)
*/
size_t old_elements = get_zero_terminated_array_elements(children);
size_t old_elements = get_zero_terminated_array_nodes(children);
size_t new_elements = old_elements + 1;
children = realloc(children, (new_elements + 1) * sizeof(struct xml_node*));

@@ -892,7 +950,7 @@ struct xml_string* xml_node_content(struct xml_node* node) {
* @warning O(n)
*/
size_t xml_node_children(struct xml_node* node) {
return get_zero_terminated_array_elements(node->children);
return get_zero_terminated_array_nodes(node->children);
}


@@ -914,7 +972,7 @@ struct xml_node* xml_node_child(struct xml_node* node, size_t child) {
* [PUBLIC API]
*/
size_t xml_node_attributes(struct xml_node* node) {
return get_zero_terminated_array_elements(node->attributes);
return get_zero_terminated_array_attributes(node->attributes);
}




+ 5
- 1
test/CMakeLists.txt View File

@@ -28,11 +28,15 @@ add_test(



# Test case
# 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)


+ 1
- 0
test/test-attributes.xml View File

@@ -0,0 +1 @@
<Test value="2" value_2="Hello"></Test>

+ 32
- 1
test/test-xml-c.c View File

@@ -217,6 +217,37 @@ static void test_xml_parse_document_3() {



/**
* 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
}



/**
@@ -227,8 +258,8 @@ int main(int argc, char** argv) {
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);
}


Loading…
Cancel
Save