Serenity Operating System
1/*
2 * Copyright (c) 2021, the SerenityOS developers.
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#include <LibTest/TestCase.h>
8
9#include <AK/GenericLexer.h>
10#include <AK/StringView.h>
11
12TEST_CASE(should_constexpr_construct_from_empty_string_view)
13{
14 constexpr GenericLexer sut(StringView {});
15 static_assert(sut.is_eof());
16}
17
18TEST_CASE(should_construct_from_string_view)
19{
20 constexpr GenericLexer sut("abcdef"sv);
21 static_assert(!sut.is_eof());
22}
23
24TEST_CASE(should_constexpr_tell)
25{
26 constexpr GenericLexer sut("abcdef"sv);
27 static_assert(sut.tell() == 0);
28}
29
30TEST_CASE(should_constexpr_tell_remaining)
31{
32 constexpr GenericLexer sut("abcdef"sv);
33 static_assert(sut.tell_remaining() == 6);
34}
35
36TEST_CASE(should_constexpr_peek)
37{
38 constexpr GenericLexer sut("abcdef"sv);
39 static_assert(sut.peek() == 'a');
40 static_assert(sut.peek(2) == 'c');
41 static_assert(sut.peek(100) == '\0');
42}
43
44TEST_CASE(should_constexpr_next_is)
45{
46 constexpr GenericLexer sut("abcdef"sv);
47 static_assert(sut.next_is('a'));
48 static_assert(sut.next_is("abc"));
49 static_assert(sut.next_is("abc"sv));
50}
51
52TEST_CASE(should_constexpr_retreat)
53{
54 constexpr auto sut = [] {
55 GenericLexer sut("abcdef"sv);
56 sut.consume();
57 sut.retreat();
58 return sut;
59 }();
60 static_assert(sut.peek() == 'a');
61}
62
63TEST_CASE(should_constexpr_consume_1)
64{
65 constexpr auto sut = [] {
66 GenericLexer sut("abcdef"sv);
67 sut.consume();
68 return sut;
69 }();
70 static_assert(sut.peek() == 'b');
71}
72
73TEST_CASE(should_constexpr_consume_specific_char)
74{
75 constexpr auto sut = [] {
76 GenericLexer sut("abcdef"sv);
77 sut.consume_specific('a');
78 return sut;
79 }();
80 static_assert(sut.peek() == 'b');
81}
82
83TEST_CASE(should_constexpr_consume_specific_string_view)
84{
85 constexpr auto sut = [] {
86 GenericLexer sut("abcdef"sv);
87 sut.consume_specific("ab"sv);
88 return sut;
89 }();
90 static_assert(sut.peek() == 'c');
91}
92
93TEST_CASE(should_constexpr_consume_specific_cstring)
94{
95 constexpr auto sut = [] {
96 GenericLexer sut("abcdef"sv);
97 sut.consume_specific("abcd");
98 return sut;
99 }();
100 static_assert(sut.peek() == 'e');
101}
102
103TEST_CASE(should_constexpr_ignore_until)
104{
105 constexpr auto sut = [] {
106 GenericLexer sut("abcdef"sv);
107 sut.ignore_until('d');
108 return sut;
109 }();
110 static_assert(sut.peek() == 'd');
111}
112
113TEST_CASE(should_constexpr_ignore_until_cstring)
114{
115 constexpr auto sut = [] {
116 GenericLexer sut("abcdef"sv);
117 sut.ignore_until("cde");
118 return sut;
119 }();
120 static_assert(sut.peek() == 'c');
121}
122
123TEST_CASE(should_constexpr_next_is_pred)
124{
125 constexpr auto pred = [](auto c) {
126 return c == 'a';
127 };
128 constexpr GenericLexer sut("abcdef"sv);
129 static_assert(sut.next_is(pred));
130}
131
132TEST_CASE(should_constexpr_ignore_while_pred)
133{
134 constexpr auto sut = [] {
135 constexpr auto pred = [](auto c) {
136 return c == 'a';
137 };
138
139 GenericLexer sut("abcdef"sv);
140 sut.ignore_while(pred);
141 return sut;
142 }();
143 static_assert(sut.peek() == 'b');
144}
145
146TEST_CASE(should_constexpr_ignore_until_pred)
147{
148 constexpr auto sut = [] {
149 constexpr auto pred = [](auto c) {
150 return c == 'c';
151 };
152
153 GenericLexer sut("abcdef"sv);
154 sut.ignore_until(pred);
155 return sut;
156 }();
157 static_assert(sut.peek() == 'c');
158}
159
160TEST_CASE(consume_escaped_code_point)
161{
162 auto test = [](StringView test, Result<u32, GenericLexer::UnicodeEscapeError> expected, bool combine_surrogate_pairs = true) {
163 GenericLexer lexer(test);
164
165 auto actual = lexer.consume_escaped_code_point(combine_surrogate_pairs);
166 EXPECT_EQ(actual.is_error(), expected.is_error());
167
168 if (actual.is_error() && expected.is_error())
169 EXPECT_EQ(actual.error(), expected.error());
170 else
171 EXPECT_EQ(actual.value(), expected.value());
172 };
173
174 test("\\u"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
175 test("\\u{"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
176 test("\\u{1"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
177 test("\\u{}"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
178 test("\\u{x}"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
179
180 test("\\u{110000}"sv, GenericLexer::UnicodeEscapeError::UnicodeEscapeOverflow);
181 test("\\u{f00000000}"sv, GenericLexer::UnicodeEscapeError::UnicodeEscapeOverflow);
182
183 test("\\u{0}"sv, 0);
184 test("\\u{41}"sv, 0x41);
185 test("\\u{ffff}"sv, 0xffff);
186 test("\\u{10ffff}"sv, 0x10ffff);
187
188 test("\\u1"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
189 test("\\u11"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
190 test("\\u111"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
191 test("\\u111x"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
192 test("\\ud800\\u"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
193 test("\\ud800\\u1"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
194 test("\\ud800\\u11"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
195 test("\\ud800\\u111"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
196 test("\\ud800\\u111x"sv, GenericLexer::UnicodeEscapeError::MalformedUnicodeEscape);
197
198 test("\\u0000"sv, 0x0);
199 test("\\u0041"sv, 0x41);
200 test("\\uffff"sv, 0xffff);
201
202 test("\\ud83d"sv, 0xd83d);
203 test("\\ud83d\\u1111"sv, 0xd83d);
204 test("\\ud83d\\ude00"sv, 0x1f600);
205 test("\\ud83d\\ude00"sv, 0xd83d, false);
206}