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