Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Roblox
GitHub Repository: Roblox/luau
Path: blob/master/tests/AstJsonEncoder.test.cpp
2723 views
1
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
2
#include "Luau/Ast.h"
3
#include "Luau/AstJsonEncoder.h"
4
#include "Luau/Parser.h"
5
#include "ScopedFlags.h"
6
7
#include "doctest.h"
8
9
#include <math.h>
10
#include <ostream>
11
12
LUAU_FASTFLAG(LuauConst2)
13
14
using namespace Luau;
15
16
LUAU_FASTFLAG(DesugaredArrayTypeReferenceIsEmpty)
17
18
struct JsonEncoderFixture
19
{
20
Allocator allocator;
21
AstNameTable names{allocator};
22
23
ParseResult parse(std::string_view src)
24
{
25
ParseOptions opts;
26
opts.allowDeclarationSyntax = true;
27
return Parser::parse(src.data(), src.size(), names, allocator, opts);
28
}
29
30
AstStatBlock* expectParse(std::string_view src)
31
{
32
ParseResult res = parse(src);
33
REQUIRE(res.errors.size() == 0);
34
return res.root;
35
}
36
37
AstStat* expectParseStatement(std::string_view src)
38
{
39
AstStatBlock* root = expectParse(src);
40
REQUIRE(1 == root->body.size);
41
return root->body.data[0];
42
}
43
44
AstExpr* expectParseExpr(std::string_view src)
45
{
46
std::string s = "a = ";
47
s.append(src);
48
AstStatBlock* root = expectParse(s);
49
50
AstStatAssign* statAssign = root->body.data[0]->as<AstStatAssign>();
51
REQUIRE(statAssign != nullptr);
52
REQUIRE(statAssign->values.size == 1);
53
54
return statAssign->values.data[0];
55
}
56
};
57
58
TEST_SUITE_BEGIN("JsonEncoderTests");
59
60
TEST_CASE("encode_constants")
61
{
62
AstExprConstantNil nil{Location()};
63
AstExprConstantBool b{Location(), true};
64
AstExprConstantNumber n{Location(), 8.2};
65
AstExprConstantNumber bigNum{Location(), 0.1677721600000003};
66
AstExprConstantNumber positiveInfinity{Location(), INFINITY};
67
AstExprConstantNumber negativeInfinity{Location(), -INFINITY};
68
AstExprConstantNumber nan{Location(), NAN};
69
70
AstArray<char> charString;
71
charString.data = const_cast<char*>("a\x1d\0\\\"b");
72
charString.size = 6;
73
74
AstExprConstantString needsEscaping{Location(), charString, AstExprConstantString::QuotedSimple};
75
76
CHECK_EQ(R"({"type":"AstExprConstantNil","location":"0,0 - 0,0"})", toJson(&nil));
77
CHECK_EQ(R"({"type":"AstExprConstantBool","location":"0,0 - 0,0","value":true})", toJson(&b));
78
CHECK_EQ(R"({"type":"AstExprConstantNumber","location":"0,0 - 0,0","value":8.1999999999999993})", toJson(&n));
79
CHECK_EQ(R"({"type":"AstExprConstantNumber","location":"0,0 - 0,0","value":0.16777216000000031})", toJson(&bigNum));
80
CHECK_EQ(R"({"type":"AstExprConstantNumber","location":"0,0 - 0,0","value":Infinity})", toJson(&positiveInfinity));
81
CHECK_EQ(R"({"type":"AstExprConstantNumber","location":"0,0 - 0,0","value":-Infinity})", toJson(&negativeInfinity));
82
CHECK_EQ(R"({"type":"AstExprConstantNumber","location":"0,0 - 0,0","value":NaN})", toJson(&nan));
83
CHECK_EQ("{\"type\":\"AstExprConstantString\",\"location\":\"0,0 - 0,0\",\"value\":\"a\\u001d\\u0000\\\\\\\"b\"}", toJson(&needsEscaping));
84
}
85
86
TEST_CASE("basic_escaping")
87
{
88
std::string s = "hello \"world\"";
89
AstArray<char> theString{s.data(), s.size()};
90
AstExprConstantString str{Location(), theString, AstExprConstantString::QuotedSimple};
91
92
std::string expected = R"({"type":"AstExprConstantString","location":"0,0 - 0,0","value":"hello \"world\""})";
93
CHECK_EQ(expected, toJson(&str));
94
}
95
96
TEST_CASE("encode_AstStatBlock")
97
{
98
AstLocal astlocal{AstName{"a_local"}, Location(), nullptr, 0, 0, nullptr, false};
99
AstLocal* astlocalarray[] = {&astlocal};
100
101
AstArray<AstLocal*> vars{astlocalarray, 1};
102
AstArray<AstExpr*> values{nullptr, 0};
103
AstStatLocal local{Location(), vars, values, std::nullopt};
104
AstStat* statArray[] = {&local};
105
106
AstArray<AstStat*> bodyArray{statArray, 1};
107
108
AstStatBlock block{Location(), bodyArray};
109
110
if (FFlag::LuauConst2)
111
CHECK(
112
toJson(&block) ==
113
(R"({"type":"AstStatBlock","location":"0,0 - 0,0","hasEnd":true,"body":[{"type":"AstStatLocal","location":"0,0 - 0,0","vars":[{"luauType":null,"name":"a_local","isConst":false,"type":"AstLocal","location":"0,0 - 0,0"}],"values":[]}]})")
114
);
115
else
116
CHECK(
117
toJson(&block) ==
118
(R"({"type":"AstStatBlock","location":"0,0 - 0,0","hasEnd":true,"body":[{"type":"AstStatLocal","location":"0,0 - 0,0","vars":[{"luauType":null,"name":"a_local","type":"AstLocal","location":"0,0 - 0,0"}],"values":[]}]})")
119
);
120
}
121
122
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_tables")
123
{
124
std::string src = R"(
125
local x: {
126
foo: number
127
} = {
128
foo = 123,
129
}
130
)";
131
132
AstStatBlock* root = expectParse(src);
133
std::string json = toJson(root);
134
135
if (FFlag::LuauConst2)
136
CHECK(
137
json ==
138
(R"({"type":"AstStatBlock","location":"0,0 - 6,4","hasEnd":true,"body":[{"type":"AstStatLocal","location":"1,8 - 5,9","vars":[{"luauType":{"type":"AstTypeTable","location":"1,17 - 3,9","props":[{"name":"foo","type":"AstTableProp","location":"2,12 - 2,15","propType":{"type":"AstTypeReference","location":"2,17 - 2,23","name":"number","nameLocation":"2,17 - 2,23","parameters":[]}}],"indexer":null},"name":"x","isConst":false,"type":"AstLocal","location":"1,14 - 1,15"}],"values":[{"type":"AstExprTable","location":"3,12 - 5,9","items":[{"type":"AstExprTableItem","kind":"record","key":{"type":"AstExprConstantString","location":"4,12 - 4,15","value":"foo"},"value":{"type":"AstExprConstantNumber","location":"4,18 - 4,21","value":123}}]}]}]})")
139
);
140
else
141
CHECK(
142
json ==
143
R"({"type":"AstStatBlock","location":"0,0 - 6,4","hasEnd":true,"body":[{"type":"AstStatLocal","location":"1,8 - 5,9","vars":[{"luauType":{"type":"AstTypeTable","location":"1,17 - 3,9","props":[{"name":"foo","type":"AstTableProp","location":"2,12 - 2,15","propType":{"type":"AstTypeReference","location":"2,17 - 2,23","name":"number","nameLocation":"2,17 - 2,23","parameters":[]}}],"indexer":null},"name":"x","type":"AstLocal","location":"1,14 - 1,15"}],"values":[{"type":"AstExprTable","location":"3,12 - 5,9","items":[{"type":"AstExprTableItem","kind":"record","key":{"type":"AstExprConstantString","location":"4,12 - 4,15","value":"foo"},"value":{"type":"AstExprConstantNumber","location":"4,18 - 4,21","value":123}}]}]}]})"
144
);
145
}
146
147
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_table_array")
148
{
149
std::string src = R"(type X = {string})";
150
151
AstStatBlock* root = expectParse(src);
152
std::string json = toJson(root);
153
154
if (FFlag::DesugaredArrayTypeReferenceIsEmpty)
155
{
156
CHECK(
157
json ==
158
R"({"type":"AstStatBlock","location":"0,0 - 0,17","hasEnd":true,"body":[{"type":"AstStatTypeAlias","location":"0,0 - 0,17","name":"X","generics":[],"genericPacks":[],"value":{"type":"AstTypeTable","location":"0,9 - 0,17","props":[],"indexer":{"location":"0,10 - 0,16","indexType":{"type":"AstTypeReference","location":"0,9 - 0,9","name":"number","nameLocation":"0,9 - 0,9","parameters":[]},"resultType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"string","nameLocation":"0,10 - 0,16","parameters":[]}}},"exported":false}]})"
159
);
160
}
161
else
162
{
163
CHECK(
164
json ==
165
R"({"type":"AstStatBlock","location":"0,0 - 0,17","hasEnd":true,"body":[{"type":"AstStatTypeAlias","location":"0,0 - 0,17","name":"X","generics":[],"genericPacks":[],"value":{"type":"AstTypeTable","location":"0,9 - 0,17","props":[],"indexer":{"location":"0,10 - 0,16","indexType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"number","nameLocation":"0,10 - 0,16","parameters":[]},"resultType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"string","nameLocation":"0,10 - 0,16","parameters":[]}}},"exported":false}]})"
166
);
167
}
168
}
169
170
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_table_indexer")
171
{
172
std::string src = R"(type X = {string})";
173
174
AstStatBlock* root = expectParse(src);
175
std::string json = toJson(root);
176
177
if (FFlag::DesugaredArrayTypeReferenceIsEmpty)
178
{
179
CHECK(
180
json ==
181
R"({"type":"AstStatBlock","location":"0,0 - 0,17","hasEnd":true,"body":[{"type":"AstStatTypeAlias","location":"0,0 - 0,17","name":"X","generics":[],"genericPacks":[],"value":{"type":"AstTypeTable","location":"0,9 - 0,17","props":[],"indexer":{"location":"0,10 - 0,16","indexType":{"type":"AstTypeReference","location":"0,9 - 0,9","name":"number","nameLocation":"0,9 - 0,9","parameters":[]},"resultType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"string","nameLocation":"0,10 - 0,16","parameters":[]}}},"exported":false}]})"
182
);
183
}
184
else
185
{
186
CHECK(
187
json ==
188
R"({"type":"AstStatBlock","location":"0,0 - 0,17","hasEnd":true,"body":[{"type":"AstStatTypeAlias","location":"0,0 - 0,17","name":"X","generics":[],"genericPacks":[],"value":{"type":"AstTypeTable","location":"0,9 - 0,17","props":[],"indexer":{"location":"0,10 - 0,16","indexType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"number","nameLocation":"0,10 - 0,16","parameters":[]},"resultType":{"type":"AstTypeReference","location":"0,10 - 0,16","name":"string","nameLocation":"0,10 - 0,16","parameters":[]}}},"exported":false}]})"
189
);
190
}
191
}
192
193
TEST_CASE("encode_AstExprGroup")
194
{
195
AstExprConstantNumber number{Location{}, 5.0};
196
AstExprGroup group{Location{}, &number};
197
198
std::string json = toJson(&group);
199
200
const std::string expected =
201
R"({"type":"AstExprGroup","location":"0,0 - 0,0","expr":{"type":"AstExprConstantNumber","location":"0,0 - 0,0","value":5}})";
202
203
CHECK(json == expected);
204
}
205
206
TEST_CASE("encode_AstExprGlobal")
207
{
208
AstExprGlobal global{Location{}, AstName{"print"}};
209
210
std::string json = toJson(&global);
211
std::string expected = R"({"type":"AstExprGlobal","location":"0,0 - 0,0","global":"print"})";
212
213
CHECK(json == expected);
214
}
215
216
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprIfThen")
217
{
218
AstStat* statement = expectParseStatement("local a = if x then y else z");
219
220
std::string_view expected =
221
FFlag::LuauConst2
222
? R"({"type":"AstStatLocal","location":"0,0 - 0,28","vars":[{"luauType":null,"name":"a","isConst":false,"type":"AstLocal","location":"0,6 - 0,7"}],"values":[{"type":"AstExprIfElse","location":"0,10 - 0,28","condition":{"type":"AstExprGlobal","location":"0,13 - 0,14","global":"x"},"hasThen":true,"trueExpr":{"type":"AstExprGlobal","location":"0,20 - 0,21","global":"y"},"hasElse":true,"falseExpr":{"type":"AstExprGlobal","location":"0,27 - 0,28","global":"z"}}]})"
223
: R"({"type":"AstStatLocal","location":"0,0 - 0,28","vars":[{"luauType":null,"name":"a","type":"AstLocal","location":"0,6 - 0,7"}],"values":[{"type":"AstExprIfElse","location":"0,10 - 0,28","condition":{"type":"AstExprGlobal","location":"0,13 - 0,14","global":"x"},"hasThen":true,"trueExpr":{"type":"AstExprGlobal","location":"0,20 - 0,21","global":"y"},"hasElse":true,"falseExpr":{"type":"AstExprGlobal","location":"0,27 - 0,28","global":"z"}}]})";
224
225
CHECK(toJson(statement) == expected);
226
}
227
228
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprInterpString")
229
{
230
AstStat* statement = expectParseStatement("local a = `var = {x}`");
231
232
std::string_view expected =
233
FFlag::LuauConst2
234
? R"({"type":"AstStatLocal","location":"0,0 - 0,21","vars":[{"luauType":null,"name":"a","isConst":false,"type":"AstLocal","location":"0,6 - 0,7"}],"values":[{"type":"AstExprInterpString","location":"0,10 - 0,21","strings":["var = ",""],"expressions":[{"type":"AstExprGlobal","location":"0,18 - 0,19","global":"x"}]}]})"
235
: R"({"type":"AstStatLocal","location":"0,0 - 0,21","vars":[{"luauType":null,"name":"a","type":"AstLocal","location":"0,6 - 0,7"}],"values":[{"type":"AstExprInterpString","location":"0,10 - 0,21","strings":["var = ",""],"expressions":[{"type":"AstExprGlobal","location":"0,18 - 0,19","global":"x"}]}]})";
236
237
CHECK(toJson(statement) == expected);
238
}
239
240
TEST_CASE("encode_AstExprLocal")
241
{
242
AstLocal local{AstName{"foo"}, Location{}, nullptr, 0, 0, nullptr, false};
243
AstExprLocal exprLocal{Location{}, &local, false};
244
245
if (FFlag::LuauConst2)
246
CHECK(
247
toJson(&exprLocal) ==
248
R"({"type":"AstExprLocal","location":"0,0 - 0,0","local":{"luauType":null,"name":"foo","isConst":false,"type":"AstLocal","location":"0,0 - 0,0"}})"
249
);
250
else
251
CHECK(
252
toJson(&exprLocal) ==
253
R"({"type":"AstExprLocal","location":"0,0 - 0,0","local":{"luauType":null,"name":"foo","type":"AstLocal","location":"0,0 - 0,0"}})"
254
);
255
}
256
257
TEST_CASE("encode_AstExprVarargs")
258
{
259
AstExprVarargs varargs{Location{}};
260
261
CHECK(toJson(&varargs) == R"({"type":"AstExprVarargs","location":"0,0 - 0,0"})");
262
}
263
264
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprCall")
265
{
266
AstExpr* expr = expectParseExpr("foo(1, 2, 3)");
267
std::string_view expected =
268
R"({"type":"AstExprCall","location":"0,4 - 0,16","func":{"type":"AstExprGlobal","location":"0,4 - 0,7","global":"foo"},"args":[{"type":"AstExprConstantNumber","location":"0,8 - 0,9","value":1},{"type":"AstExprConstantNumber","location":"0,11 - 0,12","value":2},{"type":"AstExprConstantNumber","location":"0,14 - 0,15","value":3}],"self":false,"argLocation":"0,8 - 0,16"})";
269
270
CHECK(toJson(expr) == expected);
271
}
272
273
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprIndexName")
274
{
275
AstExpr* expr = expectParseExpr("foo.bar");
276
277
std::string_view expected =
278
R"({"type":"AstExprIndexName","location":"0,4 - 0,11","expr":{"type":"AstExprGlobal","location":"0,4 - 0,7","global":"foo"},"index":"bar","indexLocation":"0,8 - 0,11","op":"."})";
279
280
CHECK(toJson(expr) == expected);
281
}
282
283
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprIndexExpr")
284
{
285
AstExpr* expr = expectParseExpr("foo['bar']");
286
287
std::string_view expected =
288
R"({"type":"AstExprIndexExpr","location":"0,4 - 0,14","expr":{"type":"AstExprGlobal","location":"0,4 - 0,7","global":"foo"},"index":{"type":"AstExprConstantString","location":"0,8 - 0,13","value":"bar"}})";
289
290
CHECK(toJson(expr) == expected);
291
}
292
293
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprFunction")
294
{
295
AstExpr* expr = expectParseExpr("function (a) return a end");
296
297
std::string_view expected =
298
FFlag::LuauConst2
299
? R"({"type":"AstExprFunction","location":"0,4 - 0,29","attributes":[],"generics":[],"genericPacks":[],"args":[{"luauType":null,"name":"a","isConst":false,"type":"AstLocal","location":"0,14 - 0,15"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,16 - 0,26","hasEnd":true,"body":[{"type":"AstStatReturn","location":"0,17 - 0,25","list":[{"type":"AstExprLocal","location":"0,24 - 0,25","local":{"luauType":null,"name":"a","isConst":false,"type":"AstLocal","location":"0,14 - 0,15"}}]}]},"functionDepth":1,"debugname":""})"
300
: R"({"type":"AstExprFunction","location":"0,4 - 0,29","attributes":[],"generics":[],"genericPacks":[],"args":[{"luauType":null,"name":"a","type":"AstLocal","location":"0,14 - 0,15"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,16 - 0,26","hasEnd":true,"body":[{"type":"AstStatReturn","location":"0,17 - 0,25","list":[{"type":"AstExprLocal","location":"0,24 - 0,25","local":{"luauType":null,"name":"a","type":"AstLocal","location":"0,14 - 0,15"}}]}]},"functionDepth":1,"debugname":""})";
301
302
CHECK(toJson(expr) == expected);
303
}
304
305
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprTable")
306
{
307
AstExpr* expr = expectParseExpr("{true, key=true, [key2]=true}");
308
309
std::string_view expected =
310
R"({"type":"AstExprTable","location":"0,4 - 0,33","items":[{"type":"AstExprTableItem","kind":"item","value":{"type":"AstExprConstantBool","location":"0,5 - 0,9","value":true}},{"type":"AstExprTableItem","kind":"record","key":{"type":"AstExprConstantString","location":"0,11 - 0,14","value":"key"},"value":{"type":"AstExprConstantBool","location":"0,15 - 0,19","value":true}},{"type":"AstExprTableItem","kind":"general","key":{"type":"AstExprGlobal","location":"0,22 - 0,26","global":"key2"},"value":{"type":"AstExprConstantBool","location":"0,28 - 0,32","value":true}}]})";
311
312
CHECK(toJson(expr) == expected);
313
}
314
315
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprUnary")
316
{
317
AstExpr* expr = expectParseExpr("-b");
318
319
std::string_view expected =
320
R"({"type":"AstExprUnary","location":"0,4 - 0,6","op":"Minus","expr":{"type":"AstExprGlobal","location":"0,5 - 0,6","global":"b"}})";
321
322
CHECK(toJson(expr) == expected);
323
}
324
325
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprBinary")
326
{
327
AstExpr* expr = expectParseExpr("b + c");
328
329
std::string_view expected =
330
R"({"type":"AstExprBinary","location":"0,4 - 0,9","op":"Add","left":{"type":"AstExprGlobal","location":"0,4 - 0,5","global":"b"},"right":{"type":"AstExprGlobal","location":"0,8 - 0,9","global":"c"}})";
331
332
CHECK(toJson(expr) == expected);
333
}
334
335
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprTypeAssertion")
336
{
337
AstExpr* expr = expectParseExpr("b :: any");
338
339
std::string_view expected =
340
R"({"type":"AstExprTypeAssertion","location":"0,4 - 0,12","expr":{"type":"AstExprGlobal","location":"0,4 - 0,5","global":"b"},"annotation":{"type":"AstTypeReference","location":"0,9 - 0,12","name":"any","nameLocation":"0,9 - 0,12","parameters":[]}})";
341
342
CHECK(toJson(expr) == expected);
343
}
344
345
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstExprError")
346
{
347
std::string_view src = "a = ";
348
ParseResult parseResult = Parser::parse(src.data(), src.size(), names, allocator);
349
350
REQUIRE(1 == parseResult.root->body.size);
351
352
AstStatAssign* statAssign = parseResult.root->body.data[0]->as<AstStatAssign>();
353
REQUIRE(statAssign != nullptr);
354
REQUIRE(1 == statAssign->values.size);
355
356
AstExpr* expr = statAssign->values.data[0];
357
358
std::string_view expected = R"({"type":"AstExprError","location":"0,4 - 0,4","expressions":[],"messageIndex":0})";
359
360
CHECK(toJson(expr) == expected);
361
}
362
363
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatIf")
364
{
365
AstStat* statement = expectParseStatement("if true then else end");
366
367
std::string_view expected =
368
R"({"type":"AstStatIf","location":"0,0 - 0,21","condition":{"type":"AstExprConstantBool","location":"0,3 - 0,7","value":true},"thenbody":{"type":"AstStatBlock","location":"0,12 - 0,13","hasEnd":true,"body":[]},"elsebody":{"type":"AstStatBlock","location":"0,17 - 0,18","hasEnd":true,"body":[]},"hasThen":true})";
369
370
CHECK(toJson(statement) == expected);
371
}
372
373
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatWhile")
374
{
375
AstStat* statement = expectParseStatement("while true do end");
376
377
std::string_view expected =
378
R"({"type":"AstStatWhile","location":"0,0 - 0,17","condition":{"type":"AstExprConstantBool","location":"0,6 - 0,10","value":true},"body":{"type":"AstStatBlock","location":"0,13 - 0,14","hasEnd":true,"body":[]},"hasDo":true})";
379
380
CHECK(toJson(statement) == expected);
381
}
382
383
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatRepeat")
384
{
385
AstStat* statement = expectParseStatement("repeat until true");
386
387
std::string_view expected =
388
R"({"type":"AstStatRepeat","location":"0,0 - 0,17","condition":{"type":"AstExprConstantBool","location":"0,13 - 0,17","value":true},"body":{"type":"AstStatBlock","location":"0,6 - 0,7","hasEnd":true,"body":[]}})";
389
390
CHECK(toJson(statement) == expected);
391
}
392
393
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatBreak")
394
{
395
AstStat* statement = expectParseStatement("while true do break end");
396
397
std::string_view expected =
398
R"({"type":"AstStatWhile","location":"0,0 - 0,23","condition":{"type":"AstExprConstantBool","location":"0,6 - 0,10","value":true},"body":{"type":"AstStatBlock","location":"0,13 - 0,20","hasEnd":true,"body":[{"type":"AstStatBreak","location":"0,14 - 0,19"}]},"hasDo":true})";
399
400
CHECK(toJson(statement) == expected);
401
}
402
403
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatContinue")
404
{
405
AstStat* statement = expectParseStatement("while true do continue end");
406
407
std::string_view expected =
408
R"({"type":"AstStatWhile","location":"0,0 - 0,26","condition":{"type":"AstExprConstantBool","location":"0,6 - 0,10","value":true},"body":{"type":"AstStatBlock","location":"0,13 - 0,23","hasEnd":true,"body":[{"type":"AstStatContinue","location":"0,14 - 0,22"}]},"hasDo":true})";
409
410
CHECK(toJson(statement) == expected);
411
}
412
413
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatFor")
414
{
415
AstStat* statement = expectParseStatement("for a=0,1 do end");
416
417
std::string_view expected =
418
FFlag::LuauConst2
419
? R"({"type":"AstStatFor","location":"0,0 - 0,16","var":{"luauType":null,"name":"a","isConst":false,"type":"AstLocal","location":"0,4 - 0,5"},"from":{"type":"AstExprConstantNumber","location":"0,6 - 0,7","value":0},"to":{"type":"AstExprConstantNumber","location":"0,8 - 0,9","value":1},"body":{"type":"AstStatBlock","location":"0,12 - 0,13","hasEnd":true,"body":[]},"hasDo":true})"
420
: R"({"type":"AstStatFor","location":"0,0 - 0,16","var":{"luauType":null,"name":"a","type":"AstLocal","location":"0,4 - 0,5"},"from":{"type":"AstExprConstantNumber","location":"0,6 - 0,7","value":0},"to":{"type":"AstExprConstantNumber","location":"0,8 - 0,9","value":1},"body":{"type":"AstStatBlock","location":"0,12 - 0,13","hasEnd":true,"body":[]},"hasDo":true})";
421
422
CHECK(toJson(statement) == expected);
423
}
424
425
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatForIn")
426
{
427
AstStat* statement = expectParseStatement("for a in b do end");
428
429
std::string_view expected =
430
FFlag::LuauConst2
431
? R"({"type":"AstStatForIn","location":"0,0 - 0,17","vars":[{"luauType":null,"name":"a","isConst":false,"type":"AstLocal","location":"0,4 - 0,5"}],"values":[{"type":"AstExprGlobal","location":"0,9 - 0,10","global":"b"}],"body":{"type":"AstStatBlock","location":"0,13 - 0,14","hasEnd":true,"body":[]},"hasIn":true,"hasDo":true})"
432
: R"({"type":"AstStatForIn","location":"0,0 - 0,17","vars":[{"luauType":null,"name":"a","type":"AstLocal","location":"0,4 - 0,5"}],"values":[{"type":"AstExprGlobal","location":"0,9 - 0,10","global":"b"}],"body":{"type":"AstStatBlock","location":"0,13 - 0,14","hasEnd":true,"body":[]},"hasIn":true,"hasDo":true})";
433
434
CHECK(toJson(statement) == expected);
435
}
436
437
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatCompoundAssign")
438
{
439
AstStat* statement = expectParseStatement("a += b");
440
441
std::string_view expected =
442
R"({"type":"AstStatCompoundAssign","location":"0,0 - 0,6","op":"Add","var":{"type":"AstExprGlobal","location":"0,0 - 0,1","global":"a"},"value":{"type":"AstExprGlobal","location":"0,5 - 0,6","global":"b"}})";
443
444
CHECK(toJson(statement) == expected);
445
}
446
447
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatLocalFunction")
448
{
449
AstStat* statement = expectParseStatement("local function a(b) return end");
450
451
std::string_view expected =
452
FFlag::LuauConst2
453
? R"({"type":"AstStatLocalFunction","location":"0,0 - 0,30","name":{"luauType":null,"name":"a","isConst":false,"type":"AstLocal","location":"0,15 - 0,16"},"func":{"type":"AstExprFunction","location":"0,0 - 0,30","attributes":[],"generics":[],"genericPacks":[],"args":[{"luauType":null,"name":"b","isConst":false,"type":"AstLocal","location":"0,17 - 0,18"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,19 - 0,27","hasEnd":true,"body":[{"type":"AstStatReturn","location":"0,20 - 0,26","list":[]}]},"functionDepth":1,"debugname":"a"}})"
454
: R"({"type":"AstStatLocalFunction","location":"0,0 - 0,30","name":{"luauType":null,"name":"a","type":"AstLocal","location":"0,15 - 0,16"},"func":{"type":"AstExprFunction","location":"0,0 - 0,30","attributes":[],"generics":[],"genericPacks":[],"args":[{"luauType":null,"name":"b","type":"AstLocal","location":"0,17 - 0,18"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,19 - 0,27","hasEnd":true,"body":[{"type":"AstStatReturn","location":"0,20 - 0,26","list":[]}]},"functionDepth":1,"debugname":"a"}})";
455
456
CHECK(toJson(statement) == expected);
457
}
458
459
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatTypeAlias")
460
{
461
AstStat* statement = expectParseStatement("type A = B");
462
463
std::string_view expected =
464
R"({"type":"AstStatTypeAlias","location":"0,0 - 0,10","name":"A","generics":[],"genericPacks":[],"value":{"type":"AstTypeReference","location":"0,9 - 0,10","name":"B","nameLocation":"0,9 - 0,10","parameters":[]},"exported":false})";
465
466
CHECK(toJson(statement) == expected);
467
}
468
469
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatDeclareFunction")
470
{
471
AstStat* statement = expectParseStatement("declare function foo(x: number): string");
472
473
std::string_view expected =
474
R"({"type":"AstStatDeclareFunction","location":"0,0 - 0,39","attributes":[],"name":"foo","nameLocation":"0,17 - 0,20","params":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,24 - 0,30","name":"number","nameLocation":"0,24 - 0,30","parameters":[]}]},"paramNames":[{"type":"AstArgumentName","name":"x","location":"0,21 - 0,22"}],"vararg":false,"varargLocation":"0,0 - 0,0","retTypes":{"type":"AstTypePackExplicit","location":"0,33 - 0,39","typeList":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,33 - 0,39","name":"string","nameLocation":"0,33 - 0,39","parameters":[]}]}},"generics":[],"genericPacks":[]})";
475
CHECK(toJson(statement) == expected);
476
}
477
478
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatDeclareFunction2")
479
{
480
AstStat* statement = expectParseStatement("declare function foo(x: number, ...: string): string");
481
482
std::string_view expected =
483
R"({"type":"AstStatDeclareFunction","location":"0,0 - 0,52","attributes":[],"name":"foo","nameLocation":"0,17 - 0,20","params":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,24 - 0,30","name":"number","nameLocation":"0,24 - 0,30","parameters":[]}],"tailType":{"type":"AstTypePackVariadic","location":"0,37 - 0,43","variadicType":{"type":"AstTypeReference","location":"0,37 - 0,43","name":"string","nameLocation":"0,37 - 0,43","parameters":[]}}},"paramNames":[{"type":"AstArgumentName","name":"x","location":"0,21 - 0,22"}],"vararg":true,"varargLocation":"0,32 - 0,35","retTypes":{"type":"AstTypePackExplicit","location":"0,46 - 0,52","typeList":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,46 - 0,52","name":"string","nameLocation":"0,46 - 0,52","parameters":[]}]}},"generics":[],"genericPacks":[]})";
484
485
CHECK(toJson(statement) == expected);
486
}
487
488
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstAttr")
489
{
490
AstStat* expr = expectParseStatement("@checked function a(b) return c end");
491
492
std::string_view expected =
493
FFlag::LuauConst2
494
? R"({"type":"AstStatFunction","location":"0,0 - 0,35","name":{"type":"AstExprGlobal","location":"0,18 - 0,19","global":"a"},"func":{"type":"AstExprFunction","location":"0,0 - 0,35","attributes":[{"type":"AstAttr","location":"0,0 - 0,8","name":"checked"}],"generics":[],"genericPacks":[],"args":[{"luauType":null,"name":"b","isConst":false,"type":"AstLocal","location":"0,20 - 0,21"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,22 - 0,32","hasEnd":true,"body":[{"type":"AstStatReturn","location":"0,23 - 0,31","list":[{"type":"AstExprGlobal","location":"0,30 - 0,31","global":"c"}]}]},"functionDepth":1,"debugname":"a"}})"
495
: R"({"type":"AstStatFunction","location":"0,0 - 0,35","name":{"type":"AstExprGlobal","location":"0,18 - 0,19","global":"a"},"func":{"type":"AstExprFunction","location":"0,0 - 0,35","attributes":[{"type":"AstAttr","location":"0,0 - 0,8","name":"checked"}],"generics":[],"genericPacks":[],"args":[{"luauType":null,"name":"b","type":"AstLocal","location":"0,20 - 0,21"}],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"0,22 - 0,32","hasEnd":true,"body":[{"type":"AstStatReturn","location":"0,23 - 0,31","list":[{"type":"AstExprGlobal","location":"0,30 - 0,31","global":"c"}]}]},"functionDepth":1,"debugname":"a"}})";
496
497
CHECK(toJson(expr) == expected);
498
}
499
500
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstStatDeclareClass")
501
{
502
AstStatBlock* root = expectParse(R"(
503
declare class Foo
504
prop: number
505
function method(self, foo: number): string
506
end
507
508
declare class Bar extends Foo
509
prop2: string
510
end
511
)");
512
513
REQUIRE(2 == root->body.size);
514
515
std::string_view expected1 =
516
R"({"type":"AstStatDeclareClass","location":"1,22 - 4,11","name":"Foo","props":[{"name":"prop","nameLocation":"2,12 - 2,16","type":"AstDeclaredClassProp","luauType":{"type":"AstTypeReference","location":"2,18 - 2,24","name":"number","nameLocation":"2,18 - 2,24","parameters":[]},"location":"2,12 - 2,24"},{"name":"method","nameLocation":"3,21 - 3,27","type":"AstDeclaredClassProp","luauType":{"type":"AstTypeFunction","location":"3,12 - 3,54","attributes":[],"generics":[],"genericPacks":[],"argTypes":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"3,39 - 3,45","name":"number","nameLocation":"3,39 - 3,45","parameters":[]}]},"argNames":[{"type":"AstArgumentName","name":"foo","location":"3,34 - 3,37"}],"returnTypes":{"type":"AstTypePackExplicit","location":"3,48 - 3,54","typeList":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"3,48 - 3,54","name":"string","nameLocation":"3,48 - 3,54","parameters":[]}]}}},"location":"3,12 - 3,54"}],"indexer":null})";
517
CHECK(toJson(root->body.data[0]) == expected1);
518
519
std::string_view expected2 =
520
R"({"type":"AstStatDeclareClass","location":"6,22 - 8,11","name":"Bar","superName":"Foo","props":[{"name":"prop2","nameLocation":"7,12 - 7,17","type":"AstDeclaredClassProp","luauType":{"type":"AstTypeReference","location":"7,19 - 7,25","name":"string","nameLocation":"7,19 - 7,25","parameters":[]},"location":"7,12 - 7,25"}],"indexer":null})";
521
CHECK(toJson(root->body.data[1]) == expected2);
522
}
523
524
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_annotation")
525
{
526
AstStat* statement = expectParseStatement("type T = ((number) -> (string | nil)) & ((string) -> ())");
527
528
std::string_view expected =
529
R"({"type":"AstStatTypeAlias","location":"0,0 - 0,56","name":"T","generics":[],"genericPacks":[],"value":{"type":"AstTypeIntersection","location":"0,9 - 0,56","types":[{"type":"AstTypeGroup","location":"0,9 - 0,37","inner":{"type":"AstTypeFunction","location":"0,10 - 0,36","attributes":[],"generics":[],"genericPacks":[],"argTypes":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,11 - 0,17","name":"number","nameLocation":"0,11 - 0,17","parameters":[]}]},"argNames":[],"returnTypes":{"type":"AstTypePackExplicit","location":"0,22 - 0,36","typeList":{"type":"AstTypeList","types":[{"type":"AstTypeGroup","location":"0,22 - 0,36","inner":{"type":"AstTypeUnion","location":"0,23 - 0,35","types":[{"type":"AstTypeReference","location":"0,23 - 0,29","name":"string","nameLocation":"0,23 - 0,29","parameters":[]},{"type":"AstTypeReference","location":"0,32 - 0,35","name":"nil","nameLocation":"0,32 - 0,35","parameters":[]}]}}]}}}},{"type":"AstTypeGroup","location":"0,40 - 0,56","inner":{"type":"AstTypeFunction","location":"0,41 - 0,55","attributes":[],"generics":[],"genericPacks":[],"argTypes":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,42 - 0,48","name":"string","nameLocation":"0,42 - 0,48","parameters":[]}]},"argNames":[],"returnTypes":{"type":"AstTypePackExplicit","location":"0,53 - 0,55","typeList":{"type":"AstTypeList","types":[]}}}}]},"exported":false})";
530
CHECK(toJson(statement) == expected);
531
}
532
533
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_type_literal")
534
{
535
AstStat* statement = expectParseStatement(R"(type Action = { strings: "A" | "B" | "C", mixed: "This" | "That" | true })");
536
537
auto json = toJson(statement);
538
539
std::string_view expected =
540
R"({"type":"AstStatTypeAlias","location":"0,0 - 0,73","name":"Action","generics":[],"genericPacks":[],"value":{"type":"AstTypeTable","location":"0,14 - 0,73","props":[{"name":"strings","type":"AstTableProp","location":"0,16 - 0,23","propType":{"type":"AstTypeUnion","location":"0,25 - 0,40","types":[{"type":"AstTypeSingletonString","location":"0,25 - 0,28","value":"A"},{"type":"AstTypeSingletonString","location":"0,31 - 0,34","value":"B"},{"type":"AstTypeSingletonString","location":"0,37 - 0,40","value":"C"}]}},{"name":"mixed","type":"AstTableProp","location":"0,42 - 0,47","propType":{"type":"AstTypeUnion","location":"0,49 - 0,71","types":[{"type":"AstTypeSingletonString","location":"0,49 - 0,55","value":"This"},{"type":"AstTypeSingletonString","location":"0,58 - 0,64","value":"That"},{"type":"AstTypeSingletonBool","location":"0,67 - 0,71","value":true}]}}],"indexer":null},"exported":false})";
541
542
CHECK(toJson(statement) == expected);
543
}
544
545
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_indexed_type_literal")
546
{
547
AstStat* statement = expectParseStatement(R"(type StringSet = { [string]: true })");
548
549
std::string_view expected =
550
R"({"type":"AstStatTypeAlias","location":"0,0 - 0,35","name":"StringSet","generics":[],"genericPacks":[],"value":{"type":"AstTypeTable","location":"0,17 - 0,35","props":[],"indexer":{"location":"0,19 - 0,33","indexType":{"type":"AstTypeReference","location":"0,20 - 0,26","name":"string","nameLocation":"0,20 - 0,26","parameters":[]},"resultType":{"type":"AstTypeSingletonBool","location":"0,29 - 0,33","value":true}}},"exported":false})";
551
552
CHECK(toJson(statement) == expected);
553
}
554
555
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstTypeFunction")
556
{
557
AstStat* statement = expectParseStatement(R"(type fun = (string, bool, named: number) -> ())");
558
559
std::string_view expected =
560
R"({"type":"AstStatTypeAlias","location":"0,0 - 0,46","name":"fun","generics":[],"genericPacks":[],"value":{"type":"AstTypeFunction","location":"0,11 - 0,46","attributes":[],"generics":[],"genericPacks":[],"argTypes":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"0,12 - 0,18","name":"string","nameLocation":"0,12 - 0,18","parameters":[]},{"type":"AstTypeReference","location":"0,20 - 0,24","name":"bool","nameLocation":"0,20 - 0,24","parameters":[]},{"type":"AstTypeReference","location":"0,33 - 0,39","name":"number","nameLocation":"0,33 - 0,39","parameters":[]}]},"argNames":[null,null,{"type":"AstArgumentName","name":"named","location":"0,26 - 0,31"}],"returnTypes":{"type":"AstTypePackExplicit","location":"0,44 - 0,46","typeList":{"type":"AstTypeList","types":[]}}},"exported":false})";
561
CHECK(toJson(statement) == expected);
562
}
563
564
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstTypeError")
565
{
566
ParseResult parseResult = parse("type T = ");
567
REQUIRE(1 == parseResult.root->body.size);
568
569
AstStat* statement = parseResult.root->body.data[0];
570
571
std::string_view expected =
572
R"({"type":"AstStatTypeAlias","location":"0,0 - 0,9","name":"T","generics":[],"genericPacks":[],"value":{"type":"AstTypeError","location":"0,8 - 0,9","types":[],"messageIndex":0},"exported":false})";
573
574
CHECK(toJson(statement) == expected);
575
}
576
577
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstTypePackExplicit")
578
{
579
AstStatBlock* root = expectParse(R"(
580
type A<T...> = () -> T...
581
local a: A<(number, string)>
582
)");
583
584
CHECK(2 == root->body.size);
585
586
std::string_view expected =
587
FFlag::LuauConst2
588
? R"({"type":"AstStatLocal","location":"2,8 - 2,36","vars":[{"luauType":{"type":"AstTypeReference","location":"2,17 - 2,36","name":"A","nameLocation":"2,17 - 2,18","parameters":[{"type":"AstTypePackExplicit","location":"2,19 - 2,20","typeList":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"2,20 - 2,26","name":"number","nameLocation":"2,20 - 2,26","parameters":[]},{"type":"AstTypeReference","location":"2,28 - 2,34","name":"string","nameLocation":"2,28 - 2,34","parameters":[]}]}}]},"name":"a","isConst":false,"type":"AstLocal","location":"2,14 - 2,15"}],"values":[]})"
589
: R"({"type":"AstStatLocal","location":"2,8 - 2,36","vars":[{"luauType":{"type":"AstTypeReference","location":"2,17 - 2,36","name":"A","nameLocation":"2,17 - 2,18","parameters":[{"type":"AstTypePackExplicit","location":"2,19 - 2,20","typeList":{"type":"AstTypeList","types":[{"type":"AstTypeReference","location":"2,20 - 2,26","name":"number","nameLocation":"2,20 - 2,26","parameters":[]},{"type":"AstTypeReference","location":"2,28 - 2,34","name":"string","nameLocation":"2,28 - 2,34","parameters":[]}]}}]},"name":"a","type":"AstLocal","location":"2,14 - 2,15"}],"values":[]})";
590
591
CHECK(toJson(root->body.data[1]) == expected);
592
}
593
594
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstGenericType")
595
{
596
AstStatBlock* root = expectParse(R"(
597
a = function<b, c>()
598
end
599
)");
600
601
CHECK(1 == root->body.size);
602
603
std::string_view expected =
604
R"({"type":"AstStatAssign","location":"1,8 - 2,11","vars":[{"type":"AstExprGlobal","location":"1,8 - 1,9","global":"a"}],"values":[{"type":"AstExprFunction","location":"1,12 - 2,11","attributes":[],"generics":[{"type":"AstGenericType","name":"b"},{"type":"AstGenericType","name":"c"}],"genericPacks":[],"args":[],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"1,28 - 2,8","hasEnd":true,"body":[]},"functionDepth":1,"debugname":""}]})";
605
606
CHECK(toJson(root->body.data[0]) == expected);
607
}
608
609
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstGenericTypeWithDefault")
610
{
611
AstStatBlock* root = expectParse(R"(
612
type Foo<X = string> = X
613
)");
614
615
CHECK(1 == root->body.size);
616
617
std::string_view expected =
618
R"({"type":"AstStatTypeAlias","location":"1,8 - 1,32","name":"Foo","generics":[{"type":"AstGenericType","name":"X","luauType":{"type":"AstTypeReference","location":"1,21 - 1,27","name":"string","nameLocation":"1,21 - 1,27","parameters":[]}}],"genericPacks":[],"value":{"type":"AstTypeReference","location":"1,31 - 1,32","name":"X","nameLocation":"1,31 - 1,32","parameters":[]},"exported":false})";
619
620
CHECK(toJson(root->body.data[0]) == expected);
621
}
622
623
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstGenericTypePack")
624
{
625
AstStatBlock* root = expectParse(R"(
626
a = function<b..., c...>()
627
end
628
)");
629
630
CHECK(1 == root->body.size);
631
632
std::string_view expected =
633
R"({"type":"AstStatAssign","location":"1,8 - 2,11","vars":[{"type":"AstExprGlobal","location":"1,8 - 1,9","global":"a"}],"values":[{"type":"AstExprFunction","location":"1,12 - 2,11","attributes":[],"generics":[],"genericPacks":[{"type":"AstGenericTypePack","name":"b"},{"type":"AstGenericTypePack","name":"c"}],"args":[],"vararg":false,"varargLocation":"0,0 - 0,0","body":{"type":"AstStatBlock","location":"1,34 - 2,8","hasEnd":true,"body":[]},"functionDepth":1,"debugname":""}]})";
634
635
CHECK(toJson(root->body.data[0]) == expected);
636
}
637
638
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstGenericTypePackWithDefault")
639
{
640
AstStatBlock* root = expectParse(R"(
641
type Foo<X... = ...string> = any
642
)");
643
644
CHECK(1 == root->body.size);
645
646
std::string_view expected =
647
R"({"type":"AstStatTypeAlias","location":"1,8 - 1,40","name":"Foo","generics":[],"genericPacks":[{"type":"AstGenericTypePack","name":"X","luauType":{"type":"AstTypePackVariadic","location":"1,24 - 1,33","variadicType":{"type":"AstTypeReference","location":"1,27 - 1,33","name":"string","nameLocation":"1,27 - 1,33","parameters":[]}}}],"value":{"type":"AstTypeReference","location":"1,37 - 1,40","name":"any","nameLocation":"1,37 - 1,40","parameters":[]},"exported":false})";
648
649
CHECK(toJson(root->body.data[0]) == expected);
650
}
651
652
TEST_CASE_FIXTURE(JsonEncoderFixture, "encode_AstTypeOptional")
653
{
654
AstStatBlock* root = expectParse(R"(
655
type Foo = string?
656
)");
657
658
CHECK(1 == root->body.size);
659
660
std::string_view expected =
661
R"({"type":"AstStatTypeAlias","location":"1,12 - 1,30","name":"Foo","generics":[],"genericPacks":[],"value":{"type":"AstTypeUnion","location":"1,23 - 1,30","types":[{"type":"AstTypeReference","location":"1,23 - 1,29","name":"string","nameLocation":"1,23 - 1,29","parameters":[]},{"type":"AstTypeOptional","location":"1,29 - 1,30"}]},"exported":false})";
662
663
CHECK(toJson(root->body.data[0]) == expected);
664
}
665
666
TEST_SUITE_END();
667
668