OXYGENHUB
◆ main openmsx / src / unittest / XMLOutputStream_test.cc
3.5 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#include "catch.hpp"
2
#include "XMLOutputStream.hh"
3
4
#include <sstream>
5
6
// Write to a 'stringstream' instead of a file.
7
// Throws an exception instead of assert'ing on error.
8
class TestWriter
9
{
10
public:
11
	explicit TestWriter(std::stringstream& ss_)
12
		: ss(ss_) {}
13
	void write(std::span<const char> buf) {
14
		ss.write(buf.data(), buf.size());
15
	}
16
	void write1(char c) {
17
		ss.put(c);
18
	}
19
	void check(bool condition) const {
20
		if (!condition) {
21
			throw std::logic_error("assertion failed");
22
		}
23
	}
24
private:
25
	std::stringstream& ss;
26
};
27
28
TEST_CASE("XMLOutputStream: simple")
29
{
30
	std::stringstream ss;
31
	TestWriter writer(ss);
32
	XMLOutputStream xml(writer);
33
34
	SECTION("empty") {
35
		CHECK(ss.str().empty());
36
	}
37
	SECTION("2 nested tags, inner tag empty") {
38
		xml.begin("abc");
39
		  xml.begin("def");
40
		  xml.end("def");
41
		xml.end("abc");
42
		CHECK(ss.str() == "<abc>\n  <def/>\n</abc>\n");
43
	}
44
	SECTION("2 nested tags, inner tag with data") {
45
		xml.begin("abc");
46
		  xml.begin("def");
47
		    xml.data("foobar");
48
		  xml.end("def");
49
		xml.end("abc");
50
		CHECK(ss.str() == "<abc>\n  <def>foobar</def>\n</abc>\n");
51
	}
52
	SECTION("2 nested tags, inner tag with attribute, no data") {
53
		xml.begin("abc");
54
		  xml.begin("def");
55
		    xml.attribute("foo", "bar");
56
		  xml.end("def");
57
		xml.end("abc");
58
		CHECK(ss.str() == "<abc>\n  <def foo=\"bar\"/>\n</abc>\n");
59
	}
60
	SECTION("2 nested tags, inner tag with attribute and data") {
61
		xml.begin("abc");
62
		  xml.begin("def");
63
		    xml.attribute("foo", "bar");
64
		    xml.data("qux");
65
		  xml.end("def");
66
		xml.end("abc");
67
		CHECK(ss.str() == "<abc>\n  <def foo=\"bar\">qux</def>\n</abc>\n");
68
	}
69
}
70
71
TEST_CASE("XMLOutputStream: complex")
72
{
73
	std::stringstream ss;
74
	TestWriter writer(ss);
75
	XMLOutputStream xml(writer);
76
77
	xml.begin("settings");
78
	  xml.begin("settings");
79
	    xml.begin("setting");
80
	      xml.attribute("id", "noise");
81
	      xml.data("3.0");
82
	    xml.end("setting");
83
	  xml.end("settings");
84
	  xml.begin("bindings");
85
	    xml.begin("bind");
86
	      xml.attribute("key", "keyb F6");
87
	      xml.data("cycle \"videosource\"");
88
	    xml.end("bind");
89
	  xml.end("bindings");
90
	xml.end("settings");
91
92
	std::string expected =
93
		"<settings>\n"
94
		"  <settings>\n"
95
		"    <setting id=\"noise\">3.0</setting>\n"
96
		"  </settings>\n"
97
		"  <bindings>\n"
98
		"    <bind key=\"keyb F6\">cycle &quot;videosource&quot;</bind>\n"
99
		"  </bindings>\n"
100
		"</settings>\n";
101
	CHECK(ss.str() == expected);
102
}
103
104
TEST_CASE("XMLOutputStream: errors")
105
{
106
	std::stringstream ss;
107
	TestWriter writer(ss);
108
	XMLOutputStream xml(writer);
109
110
	SECTION("more end than begin") {
111
		xml.begin("bla");
112
		xml.end("bla");
113
		CHECK_THROWS(xml.end("bla"));
114
	}
115
	SECTION("attribute after data") {
116
		xml.begin("bla");
117
		  xml.data("qux");
118
		  CHECK_THROWS(xml.attribute("foo", "bar"));
119
		//xml.end("bla");
120
	}
121
	SECTION("attribute after end") {
122
		xml.begin("bla");
123
		  xml.begin("bla");
124
		  xml.end("bla");
125
		CHECK_THROWS(xml.attribute("foo", "bar"));
126
		//xml.end("bla");
127
	}
128
	SECTION("begin after data") {
129
		xml.begin("bla");
130
		  xml.data("qux");
131
		  CHECK_THROWS(xml.begin("bla"));
132
		//  xml.end("bla");
133
		//xml.end("bla");
134
	}
135
	SECTION("data after end") {
136
		xml.begin("bla");
137
		  xml.begin("bla");
138
		  xml.end("bla");
139
		CHECK_THROWS(xml.data("qux"));
140
		//xml.end("bla");
141
	}
142
	SECTION("data after data") {
143
		xml.begin("bla");
144
		  xml.begin("bla");
145
		    xml.data("bla");
146
		CHECK_THROWS(xml.data("qux"));
147
		//xml.end("bla");
148
		//xml.end("bla");
149
	}
150
#ifdef DEBUG // only detected when compiled with -DDEBUG
151
	SECTION("non-matching begin/end") {
152
		xml.begin("bla");
153
		  xml.begin("bla");
154
		  xml.data("foobar");
155
		  xml.end("bla");
156
		CHECK_THROWS(xml.end("err"));
157
	}
158
#endif
159
}