OXYGENHUB
◆ main openmsx / src / unittest / ConsoleLine_test.cc
6.7 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "catch.hpp"
2
3
#include "ConsoleLine.hh"
4
5
#include <algorithm>
6
7
using namespace openmsx;
8
9
static void invariants(const ConsoleLine& line)
10
{
11
	const auto& str = line.str();
12
	const auto& chunks = line.getChunks();
13
14
	CHECK(std::ranges::is_sorted(chunks, {}, &ConsoleLine::Chunk::pos));
15
	if (!str.empty()) {
16
		REQUIRE(!chunks.empty());
17
		CHECK(chunks.front().pos == 0);
18
		CHECK(chunks.back().pos <= str.size());
19
	} else {
20
		if (!chunks.empty()) {
21
			CHECK(chunks.back().pos == 0);
22
		}
23
	}
24
}
25
26
static void invariants(const ConsoleLine& line1, const ConsoleLine& line2)
27
{
28
	invariants(line1);
29
	invariants(line2);
30
}
31
32
static void isEmpty(const ConsoleLine& line)
33
{
34
	CHECK(line.str().empty());
35
	CHECK(line.getChunks().empty());
36
}
37
38
static void checkString(const ConsoleLine& line1, const ConsoleLine& line2)
39
{
40
	auto full = line1.str() + line2.str();
41
	CHECK(full == "abcdefghijklmnopqrstuvwxyz");
42
}
43
44
TEST_CASE("ConsoleLine")
45
{
46
	SECTION("empty") {
47
		ConsoleLine line;
48
		SECTION("at-end") {
49
			auto rest = line.splitAtColumn(0);
50
			invariants(line, rest);
51
			isEmpty(line);
52
			isEmpty(rest);
53
		}
54
		SECTION("past-end") {
55
			auto rest = line.splitAtColumn(10);
56
			invariants(line, rest);
57
			isEmpty(line);
58
			isEmpty(rest);
59
		}
60
	}
61
	SECTION("single chunk") {
62
		ConsoleLine line("abcdefghijklmnopqrstuvwxyz");
63
		SECTION("front") {
64
			auto rest = line.splitAtColumn(0);
65
			invariants(line, rest);
66
			checkString(line, rest);
67
			isEmpty(line);
68
			CHECK(rest.str().size() == 26);
69
			CHECK(rest.getChunks().size() == 1);
70
		}
71
		SECTION("middle") {
72
			auto rest = line.splitAtColumn(13);
73
			invariants(line, rest);
74
			checkString(line, rest);
75
			CHECK(line.str().size() == 13);
76
			CHECK(line.getChunks().size() == 1);
77
			CHECK(rest.str().size() == 13);
78
			CHECK(rest.getChunks().size() == 1);
79
		}
80
		SECTION("end") {
81
			auto rest = line.splitAtColumn(26);
82
			invariants(line, rest);
83
			checkString(line, rest);
84
			CHECK(line.str().size() == 26);
85
			CHECK(line.getChunks().size() == 1);
86
			isEmpty(rest);
87
		}
88
		SECTION("past") {
89
			auto rest = line.splitAtColumn(40);
90
			invariants(line, rest);
91
			checkString(line, rest);
92
			CHECK(line.str().size() == 26);
93
			CHECK(line.getChunks().size() == 1);
94
			isEmpty(rest);
95
		}
96
	}
97
	SECTION("multiple chunks") {
98
		auto col1 = static_cast<imColor>(101);
99
		auto col2 = static_cast<imColor>(102);
100
		auto col3 = static_cast<imColor>(103);
101
		ConsoleLine line;
102
		line.addChunk("abcdef",       col1); // [0..6)
103
		line.addChunk("ghijklmnopqr", col2); // [6..18)
104
		line.addChunk("stuvwxyz",     col3); // [16..26)
105
		SECTION("front") {
106
			auto rest = line.splitAtColumn(0);
107
			invariants(line, rest);
108
			checkString(line, rest);
109
			isEmpty(line);
110
			CHECK(rest.str().size() == 26);
111
			CHECK(rest.getChunks().size() == 3);
112
			CHECK(rest.getChunks()[0].color == col1);
113
			CHECK(rest.getChunks()[0].pos == 0);
114
			CHECK(rest.getChunks()[1].color == col2);
115
			CHECK(rest.getChunks()[1].pos == 6);
116
			CHECK(rest.getChunks()[2].color == col3);
117
			CHECK(rest.getChunks()[2].pos == 18);
118
		}
119
		SECTION("split 1st chunk") {
120
			auto rest = line.splitAtColumn(3);
121
			invariants(line, rest);
122
			checkString(line, rest);
123
			CHECK(line.str().size() == 3);
124
			CHECK(line.getChunks().size() == 1);
125
			CHECK(line.getChunks()[0].color == col1);
126
			CHECK(line.getChunks()[0].pos == 0);
127
			CHECK(rest.str().size() == 23);
128
			CHECK(rest.getChunks().size() == 3);
129
			CHECK(rest.getChunks()[0].color == col1);
130
			CHECK(rest.getChunks()[0].pos == 0);
131
			CHECK(rest.getChunks()[1].color == col2);
132
			CHECK(rest.getChunks()[1].pos == 3);
133
			CHECK(rest.getChunks()[2].color == col3);
134
			CHECK(rest.getChunks()[2].pos == 15);
135
		}
136
		SECTION("at 1st chunk") {
137
			auto rest = line.splitAtColumn(6);
138
			invariants(line, rest);
139
			checkString(line, rest);
140
			CHECK(line.str().size() == 6);
141
			CHECK(line.getChunks().size() == 1);
142
			CHECK(line.getChunks()[0].color == col1);
143
			CHECK(line.getChunks()[0].pos == 0);
144
			CHECK(rest.str().size() == 20);
145
			CHECK(rest.getChunks().size() == 2);
146
			CHECK(rest.getChunks()[0].color == col2);
147
			CHECK(rest.getChunks()[0].pos == 0);
148
			CHECK(rest.getChunks()[1].color == col3);
149
			CHECK(rest.getChunks()[1].pos == 12);
150
		}
151
		SECTION("split 2nd chunk") {
152
			auto rest = line.splitAtColumn(13);
153
			invariants(line, rest);
154
			checkString(line, rest);
155
			CHECK(line.str().size() == 13);
156
			CHECK(line.getChunks().size() == 2);
157
			CHECK(line.getChunks()[0].color == col1);
158
			CHECK(line.getChunks()[0].pos == 0);
159
			CHECK(line.getChunks()[1].color == col2);
160
			CHECK(line.getChunks()[1].pos == 6);
161
			CHECK(rest.str().size() == 13);
162
			CHECK(rest.getChunks().size() == 2);
163
			CHECK(rest.getChunks()[0].color == col2);
164
			CHECK(rest.getChunks()[0].pos == 0);
165
			CHECK(rest.getChunks()[1].color == col3);
166
			CHECK(rest.getChunks()[1].pos == 5);
167
		}
168
		SECTION("at 2nd chunk") {
169
			auto rest = line.splitAtColumn(18);
170
			invariants(line, rest);
171
			checkString(line, rest);
172
			CHECK(line.str().size() == 18);
173
			CHECK(line.getChunks().size() == 2);
174
			CHECK(line.getChunks()[0].color == col1);
175
			CHECK(line.getChunks()[0].pos == 0);
176
			CHECK(line.getChunks()[1].color == col2);
177
			CHECK(line.getChunks()[1].pos == 6);
178
			CHECK(rest.str().size() == 8);
179
			CHECK(rest.getChunks().size() == 1);
180
			CHECK(rest.getChunks()[0].color == col3);
181
			CHECK(rest.getChunks()[0].pos == 0);
182
		}
183
		SECTION("split 3rd chunk") {
184
			auto rest = line.splitAtColumn(20);
185
			invariants(line, rest);
186
			checkString(line, rest);
187
			CHECK(line.str().size() == 20);
188
			CHECK(line.getChunks().size() == 3);
189
			CHECK(line.getChunks()[0].color == col1);
190
			CHECK(line.getChunks()[0].pos == 0);
191
			CHECK(line.getChunks()[1].color == col2);
192
			CHECK(line.getChunks()[1].pos == 6);
193
			CHECK(line.getChunks()[2].color == col3);
194
			CHECK(line.getChunks()[2].pos == 18);
195
			CHECK(rest.str().size() == 6);
196
			CHECK(rest.getChunks().size() == 1);
197
			CHECK(rest.getChunks()[0].color == col3);
198
			CHECK(rest.getChunks()[0].pos == 0);
199
		}
200
		SECTION("at 3rd chunk") {
201
			auto rest = line.splitAtColumn(26);
202
			invariants(line, rest);
203
			checkString(line, rest);
204
			CHECK(line.str().size() == 26);
205
			CHECK(line.getChunks().size() == 3);
206
			CHECK(line.getChunks()[0].color == col1);
207
			CHECK(line.getChunks()[0].pos == 0);
208
			CHECK(line.getChunks()[1].color == col2);
209
			CHECK(line.getChunks()[1].pos == 6);
210
			CHECK(line.getChunks()[2].color == col3);
211
			CHECK(line.getChunks()[2].pos == 18);
212
			isEmpty(rest);
213
		}
214
		SECTION("past end") {
215
			auto rest = line.splitAtColumn(40);
216
			invariants(line, rest);
217
			checkString(line, rest);
218
			CHECK(line.str().size() == 26);
219
			CHECK(line.getChunks().size() == 3);
220
			CHECK(line.getChunks()[0].color == col1);
221
			CHECK(line.getChunks()[0].pos == 0);
222
			CHECK(line.getChunks()[1].color == col2);
223
			CHECK(line.getChunks()[1].pos == 6);
224
			CHECK(line.getChunks()[2].color == col3);
225
			CHECK(line.getChunks()[2].pos == 18);
226
			isEmpty(rest);
227
		}
228
	}
229
}