lib/std/lang/scanner/tests.rad 13.3 KiB raw
1
use std::lang::strings;
2
use std::mem;
3
use std::testing;
4
5
/// String pool for testing.
6
static TEST_STRING_POOL: strings::Pool = strings::Pool { table: undefined, count: 0 };
7
8
fn testScanner(source: *[u8]) -> super::Scanner {
9
    return super::scanner(super::SourceLoc::File("test.r"), source, &mut TEST_STRING_POOL);
10
}
11
12
@test fn testScanTokens() throws (testing::TestError) {
13
    let mut s = testScanner(
14
        "'x' < fnord fnord: 0 => >> mod and nil"
15
    );
16
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Char);
17
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Lt);
18
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
19
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
20
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Colon);
21
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Number);
22
    try testing::expect(super::next(&mut s).kind == super::TokenKind::FatArrow);
23
    try testing::expect(super::next(&mut s).kind == super::TokenKind::GtGt);
24
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Mod);
25
    try testing::expect(super::next(&mut s).kind == super::TokenKind::And);
26
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Nil);
27
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof);
28
}
29
30
@test fn testScanChars() throws (testing::TestError) {
31
    let mut s = testScanner(
32
        "'\\0'"
33
    );
34
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Char);
35
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof);
36
}
37
38
@test fn testScanWhitespace() throws (testing::TestError) {
39
    let mut s = testScanner(
40
        " X\n\nY //\n Z//1 \n"
41
    );
42
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
43
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
44
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
45
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof);
46
}
47
48
@test fn testScanIdentsAndKeywords() throws (testing::TestError) {
49
    let mut s = testScanner(
50
        "m mo mod modo"
51
    );
52
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
53
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
54
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Mod);
55
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
56
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof);
57
}
58
59
@test fn testScanIdentifiers() throws (testing::TestError) {
60
    let mut s = testScanner(
61
        "fnord::yikes no1 4j"
62
    );
63
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
64
    try testing::expect(super::next(&mut s).kind == super::TokenKind::ColonColon);
65
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
66
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
67
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Number);
68
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
69
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof);
70
}
71
72
@test fn testScanAtIdentifiers() throws (testing::TestError) {
73
    let mut s = testScanner(
74
        "@default @"
75
    );
76
    try testing::expect(super::next(&mut s).kind == super::TokenKind::AtIdent);
77
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Invalid);
78
}
79
80
@test fn testScanStrings() throws (testing::TestError) {
81
    let mut s = testScanner(
82
        "\"Hello World!\" \"\\\"\""
83
    );
84
    let mut t: super::Token = super::next(&mut s);
85
    try testing::expect(t.kind == super::TokenKind::String);
86
    try testing::expect(t.source.len == 14); // Includes quotes.
87
    try testing::expect(mem::eq(t.source, "\"Hello World!\""));
88
89
    t = super::next(&mut s);
90
    try testing::expect(t.kind == super::TokenKind::String);
91
    try testing::expect(t.source.len == 4);
92
    try testing::expect(mem::eq(t.source, "\"\\\"\""));
93
}
94
95
@test fn testGetLocation() throws (testing::TestError) {
96
    let mut s = testScanner(
97
        "abc\n  def\n    ghi"
98
    );
99
    let mut tok: super::Token = super::next(&mut s);
100
    try testing::expect(tok.kind == super::TokenKind::Ident);
101
    try testing::expect(tok.source.len == 3);
102
103
    if let loc = super::getLocation(s.sourceLoc, s.source, tok.offset) {
104
        try testing::expect(loc.line == 1);
105
        try testing::expect(loc.col == 1);
106
    } else {
107
        try testing::expect(false);
108
    }
109
    tok = super::next(&mut s);
110
    try testing::expect(tok.kind == super::TokenKind::Ident);
111
    try testing::expect(tok.source.len == 3);
112
113
    if let loc = super::getLocation(s.sourceLoc, s.source, tok.offset) {
114
        try testing::expect(loc.line == 2);
115
        try testing::expect(loc.col == 3);
116
    } else {
117
        try testing::expect(false);
118
    }
119
    tok = super::next(&mut s);
120
    try testing::expect(tok.kind == super::TokenKind::Ident);
121
    try testing::expect(tok.source.len == 3);
122
123
    if let loc = super::getLocation(s.sourceLoc, s.source, tok.offset) {
124
        try testing::expect(loc.line == 3);
125
        try testing::expect(loc.col == 5);
126
    } else {
127
        try testing::expect(false);
128
    }
129
}
130
131
@test fn testScanEmptyInput() throws (testing::TestError) {
132
    let mut s = super::Scanner {
133
        sourceLoc: super::SourceLoc::File("test.r"),
134
        source: "",
135
        token: 0,
136
        cursor: 0,
137
        pool: &mut TEST_STRING_POOL,
138
    };
139
    let tok: super::Token = super::next(&mut s);
140
141
    try testing::expect(tok.kind == super::TokenKind::Eof);
142
    try testing::expect(tok.source.len == 0);
143
    try testing::expect(tok.offset == 0);
144
}
145
146
@test fn testScanSingleCharTokens() throws (testing::TestError) {
147
    let mut s = testScanner(
148
        "(){}[] ,;+-*~|&"
149
    );
150
    try testing::expect(super::next(&mut s).kind == super::TokenKind::LParen);
151
    try testing::expect(super::next(&mut s).kind == super::TokenKind::RParen);
152
    try testing::expect(super::next(&mut s).kind == super::TokenKind::LBrace);
153
    try testing::expect(super::next(&mut s).kind == super::TokenKind::RBrace);
154
    try testing::expect(super::next(&mut s).kind == super::TokenKind::LBracket);
155
    try testing::expect(super::next(&mut s).kind == super::TokenKind::RBracket);
156
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Comma);
157
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Semicolon);
158
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Plus);
159
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Minus);
160
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Star);
161
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Tilde);
162
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Pipe);
163
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Amp);
164
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof);
165
}
166
167
@test fn testScanDoubleCharTokens() throws (testing::TestError) {
168
    let mut s = testScanner(
169
        "== != <= >= < > >> << -> =>"
170
    );
171
    try testing::expect(super::next(&mut s).kind == super::TokenKind::EqualEqual);
172
    try testing::expect(super::next(&mut s).kind == super::TokenKind::BangEqual);
173
    try testing::expect(super::next(&mut s).kind == super::TokenKind::LtEqual);
174
    try testing::expect(super::next(&mut s).kind == super::TokenKind::GtEqual);
175
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Lt);
176
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Gt);
177
    try testing::expect(super::next(&mut s).kind == super::TokenKind::GtGt);
178
    try testing::expect(super::next(&mut s).kind == super::TokenKind::LtLt);
179
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Arrow);
180
    try testing::expect(super::next(&mut s).kind == super::TokenKind::FatArrow);
181
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof);
182
}
183
184
@test fn testScanIdentifierLengths() throws (testing::TestError) {
185
    let mut s = testScanner(
186
        "sho xyz981 lal_lel"
187
    );
188
    let mut tok: super::Token = super::next(&mut s);
189
    try testing::expect(tok.kind == super::TokenKind::Ident);
190
    try testing::expect(tok.source.len == 3);
191
192
    tok = super::next(&mut s);
193
    try testing::expect(tok.kind == super::TokenKind::Ident);
194
    try testing::expect(tok.source.len == 6);
195
196
    tok = super::next(&mut s);
197
    try testing::expect(tok.kind == super::TokenKind::Ident);
198
    try testing::expect(tok.source.len == 7);
199
}
200
201
@test fn testScanNumbers() throws (testing::TestError) {
202
    let mut s = testScanner(
203
        "9841029 45.67 -128 +0x2A +0b11"
204
    );
205
    let mut tok: super::Token = super::next(&mut s);
206
    try testing::expect(tok.kind == super::TokenKind::Number);
207
    try testing::expect(mem::eq(tok.source, "9841029"));
208
    try testing::expect(tok.source.len == 7);
209
210
    tok = super::next(&mut s);
211
    try testing::expect(tok.kind == super::TokenKind::Number);
212
    try testing::expect(tok.source.len == 5);
213
214
    tok = super::next(&mut s);
215
    try testing::expect(tok.kind == super::TokenKind::Number);
216
    try testing::expect(mem::eq(tok.source, "-128"));
217
    try testing::expect(tok.source.len == 4);
218
219
    tok = super::next(&mut s);
220
    try testing::expect(tok.kind == super::TokenKind::Number);
221
    try testing::expect(mem::eq(tok.source, "+0x2A"));
222
    try testing::expect(tok.source.len == 5);
223
224
    tok = super::next(&mut s);
225
    try testing::expect(tok.kind == super::TokenKind::Number);
226
    try testing::expect(mem::eq(tok.source, "+0b11"));
227
    try testing::expect(tok.source.len == 5);
228
}
229
230
@test fn testScanKeywords() throws (testing::TestError) {
231
    let mut s = testScanner("nil mod not static");
232
    let tok1: super::Token = super::next(&mut s);
233
234
    try testing::expect(tok1.kind == super::TokenKind::Nil);
235
    try testing::expect(tok1.source.len == 3);
236
237
    let tok2: super::Token = super::next(&mut s);
238
    try testing::expect(tok2.kind == super::TokenKind::Mod);
239
    try testing::expect(tok2.source.len == 3);
240
241
    let tok3: super::Token = super::next(&mut s);
242
    try testing::expect(tok3.kind == super::TokenKind::Not);
243
    try testing::expect(tok3.source.len == 3);
244
245
    let tok4: super::Token = super::next(&mut s);
246
    try testing::expect(tok4.kind == super::TokenKind::Static);
247
    try testing::expect(tok4.source.len == 6);
248
}
249
250
@test fn testScanWhitespaceAndComments() throws (testing::TestError) {
251
    let mut s = testScanner(
252
        "  \t\n  // This is a comment..\n  42"
253
    );
254
    let tok: super::Token = super::next(&mut s);
255
    try testing::expect(tok.kind == super::TokenKind::Number);
256
    try testing::expect(tok.source.len == 2);
257
    try testing::expect(super::isEof(&s));
258
}
259
260
@test fn testScanInvalidCharacters() throws (testing::TestError) {
261
    let mut s = testScanner(
262
        "`#$"
263
    );
264
    let mut tok: super::Token = super::next(&mut s);
265
    try testing::expect(tok.kind == super::TokenKind::Invalid);
266
    try testing::expect(tok.offset == 0);
267
268
    tok = super::next(&mut s);
269
    try testing::expect(tok.kind == super::TokenKind::Invalid);
270
    try testing::expect(tok.offset == 1);
271
272
    tok = super::next(&mut s);
273
    try testing::expect(tok.kind == super::TokenKind::Invalid);
274
    try testing::expect(tok.offset == 2);
275
}
276
277
@test fn testScanUnterminatedString() throws (testing::TestError) {
278
    let mut s = testScanner("\"Hello World!");
279
    let tok: super::Token = super::next(&mut s);
280
281
    try testing::expect(tok.kind == super::TokenKind::Invalid);
282
    try testing::expect(tok.source == "unterminated string");
283
    try testing::expect(tok.offset == 0);
284
}
285
286
@test fn testScanFunctionDefinition() throws (testing::TestError) {
287
    let mut s = testScanner(
288
        "fn add(a: i32, b: i32) -> i32 { return a + b; }"
289
    );
290
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Fn);
291
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
292
    try testing::expect(super::next(&mut s).kind == super::TokenKind::LParen);
293
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
294
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Colon);
295
    try testing::expect(super::next(&mut s).kind == super::TokenKind::I32);
296
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Comma);
297
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
298
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Colon);
299
    try testing::expect(super::next(&mut s).kind == super::TokenKind::I32);
300
    try testing::expect(super::next(&mut s).kind == super::TokenKind::RParen);
301
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Arrow);
302
    try testing::expect(super::next(&mut s).kind == super::TokenKind::I32);
303
    try testing::expect(super::next(&mut s).kind == super::TokenKind::LBrace);
304
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Return);
305
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
306
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Plus);
307
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Ident);
308
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Semicolon);
309
    try testing::expect(super::next(&mut s).kind == super::TokenKind::RBrace);
310
    try testing::expect(super::next(&mut s).kind == super::TokenKind::Eof);
311
}