Skip to content

Commit 18dbd9d

Browse files
Merge pull request #9 from dreamer-coding/main
2 parents a2cd08a + 3e65c1a commit 18dbd9d

File tree

4 files changed

+356
-11
lines changed

4 files changed

+356
-11
lines changed

code/logic/fossil/media/xml.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ char *fossil_media_xml_stringify(const fossil_media_xml_node_t *node, int pretty
192192
* @param t Node type enum value.
193193
* @return String representation (static).
194194
*/
195-
const char *fossil_media_xml_type_name(fossil_media_xml_type_t t);
195+
const char* fossil_media_xml_type_name(int type);
196196

197197
#ifdef __cplusplus
198198
}

code/logic/xml.c

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,20 +60,28 @@ fossil_media_xml_node_t *fossil_media_xml_new_comment(const char *comment) {
6060

6161
void fossil_media_xml_free(fossil_media_xml_node_t *node) {
6262
if (!node) return;
63-
free(node->name);
64-
free(node->content);
63+
if (node->name) free(node->name);
64+
if (node->content) free(node->content);
6565

66-
for (size_t i = 0; i < node->child_count; i++) {
67-
fossil_media_xml_free(node->children[i]);
66+
if (node->children) {
67+
for (size_t i = 0; i < node->child_count; i++) {
68+
fossil_media_xml_free(node->children[i]);
69+
}
70+
free(node->children);
6871
}
69-
free(node->children);
7072

71-
for (size_t i = 0; i < node->attr_count; i++) {
72-
free(node->attr_names[i]);
73-
free(node->attr_values[i]);
73+
if (node->attr_names) {
74+
for (size_t i = 0; i < node->attr_count; i++) {
75+
if (node->attr_names[i]) free(node->attr_names[i]);
76+
}
77+
free(node->attr_names);
78+
}
79+
if (node->attr_values) {
80+
for (size_t i = 0; i < node->attr_count; i++) {
81+
if (node->attr_values[i]) free(node->attr_values[i]);
82+
}
83+
free(node->attr_values);
7484
}
75-
free(node->attr_names);
76-
free(node->attr_values);
7785

7886
free(node);
7987
}
@@ -294,3 +302,15 @@ fossil_media_xml_node_t *fossil_media_xml_new_cdata(const char *data) {
294302
node->content = data ? fossil_media_strdup(data) : NULL;
295303
return node;
296304
}
305+
306+
// Provide a stub implementation for fossil_media_xml_type_name if missing
307+
const char* fossil_media_xml_type_name(int type) {
308+
switch (type) {
309+
case FOSSIL_MEDIA_XML_ELEMENT: return "element";
310+
case FOSSIL_MEDIA_XML_TEXT: return "text";
311+
case FOSSIL_MEDIA_XML_COMMENT: return "comment";
312+
case FOSSIL_MEDIA_XML_PI: return "pi";
313+
case FOSSIL_MEDIA_XML_CDATA: return "cdata";
314+
default: return "unknown";
315+
}
316+
}

code/tests/cases/test_xml.c

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* -----------------------------------------------------------------------------
3+
* Project: Fossil Logic
4+
*
5+
* This file is part of the Fossil Logic project, which aims to develop high-
6+
* performance, cross-platform applications and libraries. The code contained
7+
* herein is subject to the terms and conditions defined in the project license.
8+
*
9+
* Author: Michael Gene Brockus (Dreamer)
10+
*
11+
* Copyright (C) 2024 Fossil Logic. All rights reserved.
12+
* -----------------------------------------------------------------------------
13+
*/
14+
#include <fossil/pizza/framework.h>
15+
#include "fossil/media/framework.h"
16+
17+
// * * * * * * * * * * * * * * * * * * * * * * * *
18+
// * Fossil Logic Test Utilities
19+
// * * * * * * * * * * * * * * * * * * * * * * * *
20+
// Setup steps for things like test fixtures and
21+
// mock objects are set here.
22+
// * * * * * * * * * * * * * * * * * * * * * * * *
23+
24+
FOSSIL_TEST_SUITE(c_xml_fixture);
25+
26+
FOSSIL_SETUP(c_xml_fixture) {
27+
// Setup for XML tests
28+
}
29+
30+
FOSSIL_TEARDOWN(c_xml_fixture) {
31+
// Teardown for XML tests
32+
}
33+
34+
// * * * * * * * * * * * * * * * * * * * * * * * *
35+
// * Fossil Logic Test Cases
36+
// * * * * * * * * * * * * * * * * * * * * * * * *
37+
// The test cases below are provided as samples, inspired
38+
// by the Meson build system's approach of using test cases
39+
// as samples for library usage.
40+
// * * * * * * * * * * * * * * * * * * * * * * * *
41+
42+
FOSSIL_TEST_CASE(c_test_xml_new_element) {
43+
fossil_media_xml_node_t *node = fossil_media_xml_new_element("foo");
44+
ASSUME_NOT_CNULL(node);
45+
ASSUME_ITS_EQUAL_CSTR(node->name, "foo");
46+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(node->type), "element");
47+
fossil_media_xml_free(node);
48+
}
49+
50+
FOSSIL_TEST_CASE(c_test_xml_new_text) {
51+
fossil_media_xml_node_t *node = fossil_media_xml_new_text("bar");
52+
ASSUME_NOT_CNULL(node);
53+
ASSUME_ITS_EQUAL_CSTR(node->content, "bar");
54+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(node->type), "text");
55+
fossil_media_xml_free(node);
56+
}
57+
58+
FOSSIL_TEST_CASE(c_test_xml_new_comment) {
59+
fossil_media_xml_node_t *node = fossil_media_xml_new_comment("baz");
60+
ASSUME_NOT_CNULL(node);
61+
ASSUME_ITS_EQUAL_CSTR(node->content, "baz");
62+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(node->type), "comment");
63+
fossil_media_xml_free(node);
64+
}
65+
66+
FOSSIL_TEST_CASE(c_test_xml_new_cdata) {
67+
fossil_media_xml_node_t *node = fossil_media_xml_new_cdata("cdata content");
68+
ASSUME_NOT_CNULL(node);
69+
ASSUME_ITS_EQUAL_CSTR(node->content, "cdata content");
70+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(node->type), "cdata");
71+
fossil_media_xml_free(node);
72+
}
73+
74+
FOSSIL_TEST_CASE(c_test_xml_new_pi) {
75+
fossil_media_xml_node_t *node = fossil_media_xml_new_pi("xml-stylesheet", "type=\"text/xsl\" href=\"style.xsl\"");
76+
ASSUME_NOT_CNULL(node);
77+
ASSUME_ITS_EQUAL_CSTR(node->name, "xml-stylesheet");
78+
ASSUME_ITS_EQUAL_CSTR(node->content, "type=\"text/xsl\" href=\"style.xsl\"");
79+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(node->type), "pi");
80+
fossil_media_xml_free(node);
81+
}
82+
83+
FOSSIL_TEST_CASE(c_test_xml_append_child_and_first_child) {
84+
fossil_media_xml_node_t *parent = fossil_media_xml_new_element("parent");
85+
fossil_media_xml_node_t *child = fossil_media_xml_new_element("child");
86+
int rc = fossil_media_xml_append_child(parent, child);
87+
ASSUME_ITS_EQUAL_I32(rc, 0);
88+
fossil_media_xml_node_t *first = fossil_media_xml_first_child(parent);
89+
ASSUME_NOT_CNULL(first);
90+
ASSUME_ITS_EQUAL_CSTR(first->name, "child");
91+
fossil_media_xml_free(parent);
92+
}
93+
94+
FOSSIL_TEST_CASE(c_test_xml_set_and_get_attribute) {
95+
fossil_media_xml_node_t *node = fossil_media_xml_new_element("item");
96+
int rc = fossil_media_xml_set_attribute(node, "id", "42");
97+
ASSUME_ITS_EQUAL_I32(rc, 0);
98+
const char *val = fossil_media_xml_get_attribute(node, "id");
99+
ASSUME_NOT_CNULL(val);
100+
ASSUME_ITS_EQUAL_CSTR(val, "42");
101+
fossil_media_xml_free(node);
102+
}
103+
104+
FOSSIL_TEST_CASE(c_test_xml_set_attribute_replace) {
105+
fossil_media_xml_node_t *node = fossil_media_xml_new_element("item");
106+
fossil_media_xml_set_attribute(node, "id", "42");
107+
fossil_media_xml_set_attribute(node, "id", "43");
108+
const char *val = fossil_media_xml_get_attribute(node, "id");
109+
ASSUME_NOT_CNULL(val);
110+
ASSUME_ITS_EQUAL_CSTR(val, "43");
111+
fossil_media_xml_free(node);
112+
}
113+
114+
FOSSIL_TEST_CASE(c_test_xml_stringify_simple) {
115+
fossil_media_xml_error_t err = FOSSIL_MEDIA_XML_OK;
116+
fossil_media_xml_node_t *node = fossil_media_xml_new_element("root");
117+
fossil_media_xml_set_attribute(node, "foo", "bar");
118+
char *xml = fossil_media_xml_stringify(node, 0, &err);
119+
ASSUME_NOT_CNULL(xml);
120+
ASSUME_ITS_EQUAL_I32(err, FOSSIL_MEDIA_XML_OK);
121+
ASSUME_ITS_TRUE(strstr(xml, "<root foo=\"bar\"/>") != NULL);
122+
free(xml);
123+
fossil_media_xml_free(node);
124+
}
125+
126+
FOSSIL_TEST_CASE(c_test_xml_stringify_pretty) {
127+
fossil_media_xml_error_t err = FOSSIL_MEDIA_XML_OK;
128+
fossil_media_xml_node_t *root = fossil_media_xml_new_element("root");
129+
fossil_media_xml_node_t *child = fossil_media_xml_new_element("child");
130+
fossil_media_xml_append_child(root, child);
131+
char *xml = fossil_media_xml_stringify(root, 1, &err);
132+
ASSUME_NOT_CNULL(xml);
133+
ASSUME_ITS_EQUAL_I32(err, FOSSIL_MEDIA_XML_OK);
134+
ASSUME_ITS_TRUE(strstr(xml, "<root>") != NULL);
135+
ASSUME_ITS_TRUE(strstr(xml, "<child/>") != NULL);
136+
free(xml);
137+
fossil_media_xml_free(root);
138+
}
139+
140+
FOSSIL_TEST_CASE(c_test_xml_parse_dummy) {
141+
fossil_media_xml_error_t err = FOSSIL_MEDIA_XML_OK;
142+
const char *xml = "<foo>bar</foo>";
143+
fossil_media_xml_node_t *node = fossil_media_xml_parse(xml, &err);
144+
ASSUME_NOT_CNULL(node);
145+
ASSUME_ITS_EQUAL_I32(err, FOSSIL_MEDIA_XML_OK);
146+
ASSUME_ITS_EQUAL_CSTR(node->name, "root"); // Dummy parser returns "root"
147+
fossil_media_xml_free(node);
148+
}
149+
150+
FOSSIL_TEST_CASE(c_test_xml_type_name) {
151+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(FOSSIL_MEDIA_XML_ELEMENT), "element");
152+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(FOSSIL_MEDIA_XML_TEXT), "text");
153+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(FOSSIL_MEDIA_XML_COMMENT), "comment");
154+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(FOSSIL_MEDIA_XML_PI), "pi");
155+
ASSUME_ITS_EQUAL_CSTR(fossil_media_xml_type_name(FOSSIL_MEDIA_XML_CDATA), "cdata");
156+
}
157+
158+
// * * * * * * * * * * * * * * * * * * * * * * * *
159+
// * Fossil Logic Test Pool
160+
// * * * * * * * * * * * * * * * * * * * * * * * *
161+
FOSSIL_TEST_GROUP(c_xml_tests) {
162+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_new_element);
163+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_new_text);
164+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_new_comment);
165+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_new_cdata);
166+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_new_pi);
167+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_append_child_and_first_child);
168+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_set_and_get_attribute);
169+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_set_attribute_replace);
170+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_stringify_simple);
171+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_stringify_pretty);
172+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_parse_dummy);
173+
FOSSIL_TEST_ADD(c_xml_fixture, c_test_xml_type_name);
174+
175+
FOSSIL_TEST_REGISTER(c_xml_fixture);
176+
} // end of tests

code/tests/cases/test_xml.cpp

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
/*
2+
* -----------------------------------------------------------------------------
3+
* Project: Fossil Logic
4+
*
5+
* This file is part of the Fossil Logic project, which aims to develop high-
6+
* performance, cross-platform applications and libraries. The code contained
7+
* herein is subject to the terms and conditions defined in the project license.
8+
*
9+
* Author: Michael Gene Brockus (Dreamer)
10+
*
11+
* Copyright (C) 2024 Fossil Logic. All rights reserved.
12+
* -----------------------------------------------------------------------------
13+
*/
14+
#include <fossil/pizza/framework.h>
15+
#include "fossil/media/framework.h"
16+
17+
18+
// * * * * * * * * * * * * * * * * * * * * * * * *
19+
// * Fossil Logic Test Utilities
20+
// * * * * * * * * * * * * * * * * * * * * * * * *
21+
// Setup steps for things like test fixtures and
22+
// mock objects are set here.
23+
// * * * * * * * * * * * * * * * * * * * * * * * *
24+
25+
FOSSIL_TEST_SUITE(cpp_xml_fixture);
26+
27+
FOSSIL_SETUP(cpp_xml_fixture) {
28+
// Setup for XML tests
29+
}
30+
31+
FOSSIL_TEARDOWN(cpp_xml_fixture) {
32+
// Teardown for XML tests
33+
}
34+
35+
// * * * * * * * * * * * * * * * * * * * * * * * *
36+
// * Fossil Logic Test Cases
37+
// * * * * * * * * * * * * * * * * * * * * * * * *
38+
// The test cases below are provided as samples, inspired
39+
// by the Meson build system's approach of using test cases
40+
// as samples for library usage.
41+
// * * * * * * * * * * * * * * * * * * * * * * * *
42+
43+
FOSSIL_TEST_CASE(cpp_test_xml_new_element) {
44+
fossil::media::Xml node = fossil::media::Xml::new_element("foo");
45+
ASSUME_NOT_CNULL(node.get());
46+
ASSUME_ITS_EQUAL_CSTR(node.get()->name, "foo");
47+
ASSUME_ITS_EQUAL_CSTR(node.type_name(), "element");
48+
}
49+
50+
FOSSIL_TEST_CASE(cpp_test_xml_new_text) {
51+
fossil::media::Xml node = fossil::media::Xml::new_text("bar");
52+
ASSUME_NOT_CNULL(node.get());
53+
ASSUME_ITS_EQUAL_CSTR(node.get()->content, "bar");
54+
ASSUME_ITS_EQUAL_CSTR(node.type_name(), "text");
55+
}
56+
57+
FOSSIL_TEST_CASE(cpp_test_xml_new_comment) {
58+
fossil::media::Xml node = fossil::media::Xml::new_comment("baz");
59+
ASSUME_NOT_CNULL(node.get());
60+
ASSUME_ITS_EQUAL_CSTR(node.get()->content, "baz");
61+
ASSUME_ITS_EQUAL_CSTR(node.type_name(), "comment");
62+
}
63+
64+
FOSSIL_TEST_CASE(cpp_test_xml_new_cdata) {
65+
fossil::media::Xml node = fossil::media::Xml::new_cdata("cdata content");
66+
ASSUME_NOT_CNULL(node.get());
67+
ASSUME_ITS_EQUAL_CSTR(node.get()->content, "cdata content");
68+
ASSUME_ITS_EQUAL_CSTR(node.type_name(), "cdata");
69+
}
70+
71+
FOSSIL_TEST_CASE(cpp_test_xml_new_pi) {
72+
fossil::media::Xml node = fossil::media::Xml::new_pi("xml-stylesheet", "type=\"text/xsl\" href=\"style.xsl\"");
73+
ASSUME_NOT_CNULL(node.get());
74+
ASSUME_ITS_EQUAL_CSTR(node.get()->name, "xml-stylesheet");
75+
ASSUME_ITS_EQUAL_CSTR(node.get()->content, "type=\"text/xsl\" href=\"style.xsl\"");
76+
ASSUME_ITS_EQUAL_CSTR(node.type_name(), "pi");
77+
}
78+
79+
FOSSIL_TEST_CASE(cpp_test_xml_set_and_get_attribute) {
80+
fossil::media::Xml node = fossil::media::Xml::new_element("item");
81+
node.set_attribute("id", "42");
82+
const char *val = node.get_attribute("id");
83+
ASSUME_NOT_CNULL(val);
84+
ASSUME_ITS_EQUAL_CSTR(val, "42");
85+
}
86+
87+
FOSSIL_TEST_CASE(cpp_test_xml_set_attribute_replace) {
88+
fossil::media::Xml node = fossil::media::Xml::new_element("item");
89+
node.set_attribute("id", "42");
90+
node.set_attribute("id", "43");
91+
const char *val = node.get_attribute("id");
92+
ASSUME_NOT_CNULL(val);
93+
ASSUME_ITS_EQUAL_CSTR(val, "43");
94+
}
95+
96+
FOSSIL_TEST_CASE(cpp_test_xml_stringify_simple) {
97+
fossil::media::Xml node = fossil::media::Xml::new_element("root");
98+
node.set_attribute("foo", "bar");
99+
std::string xml = node.stringify(false);
100+
ASSUME_ITS_TRUE(xml.find("<root foo=\"bar\"/>") != std::string::npos);
101+
}
102+
103+
FOSSIL_TEST_CASE(cpp_test_xml_stringify_pretty) {
104+
fossil::media::Xml root = fossil::media::Xml::new_element("root");
105+
fossil::media::Xml child = fossil::media::Xml::new_element("child");
106+
root.append_child(std::move(child));
107+
std::string xml = root.stringify(true);
108+
ASSUME_ITS_TRUE(xml.find("<root>") != std::string::npos);
109+
ASSUME_ITS_TRUE(xml.find("<child/>") != std::string::npos);
110+
}
111+
112+
FOSSIL_TEST_CASE(cpp_test_xml_parse_dummy) {
113+
const char *xml = "<foo>bar</foo>";
114+
fossil::media::Xml node(xml);
115+
ASSUME_NOT_CNULL(node.get());
116+
ASSUME_ITS_EQUAL_CSTR(node.get()->name, "root"); // Dummy parser returns "root"
117+
}
118+
119+
FOSSIL_TEST_CASE(cpp_test_xml_type_name) {
120+
fossil::media::Xml elem = fossil::media::Xml::new_element("e");
121+
fossil::media::Xml txt = fossil::media::Xml::new_text("t");
122+
fossil::media::Xml com = fossil::media::Xml::new_comment("c");
123+
fossil::media::Xml pi = fossil::media::Xml::new_pi("p", "d");
124+
fossil::media::Xml cdata = fossil::media::Xml::new_cdata("cd");
125+
ASSUME_ITS_EQUAL_CSTR(elem.type_name(), "element");
126+
ASSUME_ITS_EQUAL_CSTR(txt.type_name(), "text");
127+
ASSUME_ITS_EQUAL_CSTR(com.type_name(), "comment");
128+
ASSUME_ITS_EQUAL_CSTR(pi.type_name(), "pi");
129+
ASSUME_ITS_EQUAL_CSTR(cdata.type_name(), "cdata");
130+
}
131+
132+
// * * * * * * * * * * * * * * * * * * * * * * * *
133+
// * Fossil Logic Test Pool
134+
// * * * * * * * * * * * * * * * * * * * * * * * *
135+
FOSSIL_TEST_GROUP(cpp_xml_tests) {
136+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_new_element);
137+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_new_text);
138+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_new_comment);
139+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_new_cdata);
140+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_new_pi);
141+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_set_and_get_attribute);
142+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_set_attribute_replace);
143+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_stringify_simple);
144+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_stringify_pretty);
145+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_parse_dummy);
146+
FOSSIL_TEST_ADD(cpp_xml_fixture, cpp_test_xml_type_name);
147+
148+
FOSSIL_TEST_REGISTER(cpp_xml_fixture);
149+
} // end of tests

0 commit comments

Comments
 (0)