26 #include <strings/Scanner.h> 27 #include <strings/StringPiece.h> 47 TEST_CASE(
"Scanner",
"[core/strings]") {
54 .GetResult(&remaining, &match));
55 REQUIRE(
" horse" == match);
56 REQUIRE(
"0123" == remaining);
62 .GetResult(&remaining, &match));
63 REQUIRE(
"" == remaining);
70 .GetResult(&remaining, &match));
71 REQUIRE(
"----" == remaining);
81 .GetResult(&remaining, &match));
82 REQUIRE(
" a " == match);
83 REQUIRE(
"b " == remaining);
86 SECTION(
"AnyEscapedNewline") {
89 .Any(Scanner::LETTER_DIGIT_UNDERSCORE)
90 .GetResult(&remaining, &match));
91 REQUIRE(
"\\\n" == remaining);
95 SECTION(
"AnyEmptyString") {
98 .Any(Scanner::LETTER_DIGIT_UNDERSCORE)
99 .GetResult(&remaining, &match));
100 REQUIRE(
"" == remaining);
101 REQUIRE(
"" == match);
105 REQUIRE_FALSE(
Scanner(
"a").Eos().GetResult());
106 REQUIRE(
Scanner(
"").Eos().GetResult());
107 REQUIRE_FALSE(
Scanner(
"abc").OneLiteral(
"ab").Eos().GetResult());
108 REQUIRE(
Scanner(
"abc").OneLiteral(
"abc").Eos().GetResult());
113 REQUIRE(
Scanner(
"abc").Many(Scanner::LETTER).GetResult());
114 REQUIRE_FALSE(
Scanner(
"0").Many(Scanner::LETTER).GetResult());
115 REQUIRE_FALSE(
Scanner(
"").Many(Scanner::LETTER).GetResult());
118 Scanner(
"abc ").Many(Scanner::LETTER).GetResult(&remaining, &match));
119 REQUIRE(
" " == remaining);
120 REQUIRE(
"abc" == match);
122 Scanner(
"abc").Many(Scanner::LETTER).GetResult(&remaining, &match));
123 REQUIRE(
"" == remaining);
124 REQUIRE(
"abc" == match);
129 REQUIRE(
Scanner(
"abc").One(Scanner::LETTER).GetResult());
130 REQUIRE_FALSE(
Scanner(
"0").One(Scanner::LETTER).GetResult());
131 REQUIRE_FALSE(
Scanner(
"").One(Scanner::LETTER).GetResult());
134 .One(Scanner::LETTER)
135 .One(Scanner::LETTER)
136 .GetResult(&remaining, &match));
137 REQUIRE(
"c" == remaining);
138 REQUIRE(
"ab" == match);
139 REQUIRE(
Scanner(
"a").One(Scanner::LETTER).GetResult(&remaining, &match));
140 REQUIRE(
"" == remaining);
141 REQUIRE(
"a" == match);
144 SECTION(
"OneLiteral") {
145 REQUIRE_FALSE(
Scanner(
"abc").OneLiteral(
"abC").GetResult());
146 REQUIRE(
Scanner(
"abc").OneLiteral(
"ab").OneLiteral(
"c").GetResult());
149 SECTION(
"ScanUntil") {
151 REQUIRE(
Scanner(R
"(' \1 \2 \3 \' \\'rest)") 155 .GetResult(&remaining, &match));
156 REQUIRE(R
"( \\'rest)" == remaining); 157 REQUIRE(R"(' \1 \2 \3 \')" == match); 160 remaining = match =
"unset";
161 REQUIRE_FALSE(
Scanner(R
"(' \1 \2 \3 \\rest)") 164 .GetResult(&remaining, &match));
165 REQUIRE(
"unset" == remaining);
166 REQUIRE(
"unset" == match);
169 remaining = match =
"";
171 Scanner(R
"(123\456)").ScanUntil('\\').GetResult(&remaining, &match));
172 REQUIRE(R
"(\456)" == remaining); 173 REQUIRE("123" == match);
176 SECTION(
"ScanEscapedUntil") {
178 REQUIRE(
Scanner(R
"(' \1 \2 \3 \' \\'rest)") 180 .ScanEscapedUntil(
'\'')
182 .GetResult(&remaining, &match));
183 REQUIRE(
"rest" == remaining);
184 REQUIRE(R
"(' \1 \2 \3 \' \\')" == match); 187 remaining = match =
"unset";
188 REQUIRE_FALSE(
Scanner(R
"(' \1 \2 \3 \' \\rest)") 190 .ScanEscapedUntil(
'\'')
191 .GetResult(&remaining, &match));
192 REQUIRE(
"unset" == remaining);
193 REQUIRE(
"unset" == match);
196 SECTION(
"ZeroOrOneLiteral") {
199 Scanner(
"abc").ZeroOrOneLiteral(
"abC").GetResult(&remaining, &match));
200 REQUIRE(
"abc" == remaining);
201 REQUIRE(
"" == match);
204 Scanner(
"abcd").ZeroOrOneLiteral(
"ab").ZeroOrOneLiteral(
"c").GetResult(
205 &remaining, &match));
206 REQUIRE(
"d" == remaining);
207 REQUIRE(
"abc" == match);
210 Scanner(
"").ZeroOrOneLiteral(
"abc").GetResult(&remaining, &match));
211 REQUIRE(
"" == remaining);
212 REQUIRE(
"" == match);
217 SECTION(
"CaptureAndGetResult") {
221 REQUIRE(scan.Any(Scanner::SPACE)
223 .One(Scanner::LETTER)
224 .Any(Scanner::LETTER_DIGIT)
227 .GetResult(&remaining, &match));
228 REQUIRE(
"second" == remaining);
229 REQUIRE(
"first" == match);
230 REQUIRE(scan.GetResult());
232 REQUIRE(scan.GetResult(&remaining));
233 REQUIRE(
"second" == remaining);
236 REQUIRE(scan.GetResult(&remaining, &match));
237 REQUIRE(
"second" == remaining);
238 REQUIRE(
"first" == match);
240 scan.RestartCapture().One(Scanner::LETTER).One(Scanner::LETTER);
243 REQUIRE(scan.GetResult(&remaining, &match));
244 REQUIRE(
"cond" == remaining);
245 REQUIRE(
"se" == match);
250 SECTION(
"MultipleGetResultExtendsCapture") {
254 REQUIRE(scan.Many(Scanner::LETTER).GetResult(&remaining, &match));
255 REQUIRE(
"2three" == remaining);
256 REQUIRE(
"one" == match);
257 REQUIRE(scan.Many(Scanner::DIGIT).GetResult(&remaining, &match));
258 REQUIRE(
"three" == remaining);
259 REQUIRE(
"one2" == match);
260 REQUIRE(scan.Many(Scanner::LETTER).GetResult(&remaining, &match));
261 REQUIRE(
"" == remaining);
262 REQUIRE(
"one2three" == match);
265 SECTION(
"FailedMatchDoesntChangeResult") {
270 REQUIRE_FALSE(scan.One(Scanner::SPACE).GetResult(&remaining, &match));
271 REQUIRE(
"rem" == remaining);
272 REQUIRE(
"match" == match);
275 SECTION(
"DefaultCapturesAll") {
280 REQUIRE(scan.Any(Scanner::LETTER)
282 .Any(Scanner::LETTER)
283 .GetResult(&remaining, &match));
284 REQUIRE(
"" == remaining);
285 REQUIRE(
"a b" == match);
288 SECTION(
"AllCharClasses") {
290 auto ClassStr = [](Scanner::CharClass clz) -> std::string {
292 for (
int i = 0; i < 256; ++i) {
294 if (Scanner::Matches(clz, ch)) {
301 REQUIRE(256 == ClassStr(Scanner::ALL).size());
302 REQUIRE(
"0123456789" == ClassStr(Scanner::DIGIT));
303 REQUIRE(
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ==
304 ClassStr(Scanner::LETTER));
305 REQUIRE(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ==
306 ClassStr(Scanner::LETTER_DIGIT));
308 "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_" 309 "abcdefghijklmnopqrstuvwxyz" ==
310 ClassStr(Scanner::LETTER_DIGIT_DASH_UNDERSCORE));
312 "-./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 313 "abcdefghijklmnopqrstuvwxyz" ==
314 ClassStr(Scanner::LETTER_DIGIT_DASH_DOT_SLASH));
316 "-./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_" 317 "abcdefghijklmnopqrstuvwxyz" ==
318 ClassStr(Scanner::LETTER_DIGIT_DASH_DOT_SLASH_UNDERSCORE));
319 REQUIRE(
".0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ==
320 ClassStr(Scanner::LETTER_DIGIT_DOT));
321 REQUIRE(
"+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ==
322 ClassStr(Scanner::LETTER_DIGIT_DOT_PLUS_MINUS));
323 REQUIRE(
".0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" ==
324 ClassStr(Scanner::LETTER_DIGIT_DOT_UNDERSCORE));
325 REQUIRE(
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" ==
326 ClassStr(Scanner::LETTER_DIGIT_UNDERSCORE));
327 REQUIRE(
"abcdefghijklmnopqrstuvwxyz" == ClassStr(Scanner::LOWERLETTER));
328 REQUIRE(
"0123456789abcdefghijklmnopqrstuvwxyz" ==
329 ClassStr(Scanner::LOWERLETTER_DIGIT));
330 REQUIRE(
"0123456789_abcdefghijklmnopqrstuvwxyz" ==
331 ClassStr(Scanner::LOWERLETTER_DIGIT_UNDERSCORE));
332 REQUIRE(
"123456789" == ClassStr(Scanner::NON_ZERO_DIGIT));
333 REQUIRE(
"\t\n\v\f\r " == ClassStr(Scanner::SPACE));
334 REQUIRE(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" == ClassStr(Scanner::UPPERLETTER));
338 REQUIRE(
'a' ==
Scanner(
"abc").Peek());
339 REQUIRE(
'a' ==
Scanner(
"abc").Peek(
'b'));
340 REQUIRE(
'\0' ==
Scanner(
"").Peek());
341 REQUIRE(
'z' ==
Scanner(
"").Peek(
'z'));
342 REQUIRE(
'A' ==
Scanner(
"0123A").Any(Scanner::DIGIT).Peek());
343 REQUIRE(
'\0' ==
Scanner(
"0123A").Any(Scanner::LETTER_DIGIT).Peek());