@weborigami/language 0.0.65-beta.2 → 0.0.66-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,19 +8,29 @@ describe("Origami parser", () => {
8
8
  test("absoluteFilePath", () => {
9
9
  assertParse("absoluteFilePath", "/foo/bar", [
10
10
  [ops.filesRoot],
11
- "foo",
12
- "bar",
11
+ [ops.primitive, "foo"],
12
+ [ops.primitive, "bar"],
13
13
  ]);
14
14
  });
15
15
 
16
16
  test("array", () => {
17
17
  assertParse("array", "[]", [ops.array]);
18
- assertParse("array", "[1, 2, 3]", [ops.array, 1, 2, 3]);
19
- assertParse("array", "[ 1 , 2 , 3 ]", [ops.array, 1, 2, 3]);
18
+ assertParse("array", "[1, 2, 3]", [
19
+ ops.array,
20
+ [ops.primitive, 1],
21
+ [ops.primitive, 2],
22
+ [ops.primitive, 3],
23
+ ]);
24
+ assertParse("array", "[ 1 , 2 , 3 ]", [
25
+ ops.array,
26
+ [ops.primitive, 1],
27
+ [ops.primitive, 2],
28
+ [ops.primitive, 3],
29
+ ]);
20
30
  assertParse("array", "[ 1, ...[2, 3]]", [
21
31
  ops.merge,
22
- [ops.array, 1],
23
- [ops.array, 2, 3],
32
+ [ops.array, [ops.primitive, 1]],
33
+ [ops.array, [ops.primitive, 2], [ops.primitive, 3]],
24
34
  ]);
25
35
  });
26
36
 
@@ -34,19 +44,26 @@ describe("Origami parser", () => {
34
44
  ]);
35
45
  assertParse("expr", "foo.bar('hello', 'world')", [
36
46
  [ops.scope, "foo.bar"],
37
- "hello",
38
- "world",
47
+ [ops.primitive, "hello"],
48
+ [ops.primitive, "world"],
49
+ ]);
50
+ assertParse("expr", "(fn)('a')", [
51
+ [ops.scope, "fn"],
52
+ [ops.primitive, "a"],
53
+ ]);
54
+ assertParse("expr", "1", [ops.primitive, 1]);
55
+ assertParse("expr", "{ a: 1, b: 2 }", [
56
+ ops.object,
57
+ ["a", [ops.primitive, 1]],
58
+ ["b", [ops.primitive, 2]],
39
59
  ]);
40
- assertParse("expr", "(fn)('a')", [[ops.scope, "fn"], "a"]);
41
- assertParse("expr", "1", 1);
42
- assertParse("expr", "{ a: 1, b: 2 }", [ops.object, ["a", 1], ["b", 2]]);
43
60
  assertParse("expr", "serve { index.html: 'hello' }", [
44
61
  [ops.scope, "serve"],
45
- [ops.object, ["index.html", "hello"]],
62
+ [ops.object, ["index.html", [ops.primitive, "hello"]]],
46
63
  ]);
47
64
  assertParse("expr", "fn =`x`", [
48
65
  [ops.scope, "fn"],
49
- [ops.lambda, null, "x"],
66
+ [ops.lambda, null, [ops.primitive, "x"]],
50
67
  ]);
51
68
  assertParse("expr", "copy app(formulas), files 'snapshot'", [
52
69
  [ops.scope, "copy"],
@@ -54,16 +71,31 @@ describe("Origami parser", () => {
54
71
  [ops.scope, "app"],
55
72
  [ops.scope, "formulas"],
56
73
  ],
57
- [[ops.scope, "files"], "snapshot"],
74
+ [
75
+ [ops.scope, "files"],
76
+ [ops.primitive, "snapshot"],
77
+ ],
58
78
  ]);
59
79
  assertParse("expr", "@map =`<li>${_}</li>`", [
60
80
  [ops.scope, "@map"],
61
- [ops.lambda, null, [ops.concat, "<li>", [ops.scope, "_"], "</li>"]],
81
+ [
82
+ ops.lambda,
83
+ null,
84
+ [
85
+ ops.concat,
86
+ [ops.primitive, "<li>"],
87
+ [ops.scope, "_"],
88
+ [ops.primitive, "</li>"],
89
+ ],
90
+ ],
91
+ ]);
92
+ assertParse("expr", `"https://example.com"`, [
93
+ ops.primitive,
94
+ "https://example.com",
62
95
  ]);
63
- assertParse("expr", `"https://example.com"`, "https://example.com");
64
96
  assertParse("expr", "'Hello' -> test.orit", [
65
97
  [ops.scope, "test.orit"],
66
- "Hello",
98
+ [ops.primitive, "Hello"],
67
99
  ]);
68
100
  });
69
101
 
@@ -106,11 +138,14 @@ describe("Origami parser", () => {
106
138
  assertParse("expression", "path//key", [
107
139
  ops.traverse,
108
140
  [ops.scope, "path"],
109
- "",
110
- "key",
141
+ [ops.primitive, ""],
142
+ [ops.primitive, "key"],
111
143
  ]);
112
144
  // Single slash at start of something = absolute file path
113
- assertParse("expression", "/path", [[ops.filesRoot], "path"]);
145
+ assertParse("expression", "/path", [
146
+ [ops.filesRoot],
147
+ [ops.primitive, "path"],
148
+ ]);
114
149
  // Consecutive slashes at start of something = comment
115
150
  assertParse("expression", "path //comment", [ops.scope, "path"], false);
116
151
  });
@@ -138,39 +173,42 @@ describe("Origami parser", () => {
138
173
  assertParse("functionComposition", "fn()/key", [
139
174
  ops.traverse,
140
175
  [[ops.scope, "fn"], undefined],
141
- "key",
176
+ [ops.primitive, "key"],
142
177
  ]);
143
178
  assertParse("functionComposition", "tree/", [
144
179
  ops.traverse,
145
180
  [ops.scope, "tree"],
146
- "",
181
+ [ops.primitive, ""],
147
182
  ]);
148
183
  assertParse("functionComposition", "tree/key", [
149
184
  ops.traverse,
150
185
  [ops.scope, "tree"],
151
- "key",
186
+ [ops.primitive, "key"],
152
187
  ]);
153
188
  assertParse("functionComposition", "tree/foo/bar", [
154
189
  ops.traverse,
155
190
  [ops.scope, "tree"],
156
- "foo",
157
- "bar",
191
+ [ops.primitive, "foo"],
192
+ [ops.primitive, "bar"],
158
193
  ]);
159
194
  assertParse("functionComposition", "tree/key()", [
160
- [ops.traverse, [ops.scope, "tree"], "key"],
195
+ [ops.traverse, [ops.scope, "tree"], [ops.primitive, "key"]],
161
196
  undefined,
162
197
  ]);
163
198
  assertParse("functionComposition", "fn()/key()", [
164
- [ops.traverse, [[ops.scope, "fn"], undefined], "key"],
199
+ [ops.traverse, [[ops.scope, "fn"], undefined], [ops.primitive, "key"]],
165
200
  undefined,
166
201
  ]);
167
202
  assertParse("functionComposition", "(fn())('arg')", [
168
203
  [[ops.scope, "fn"], undefined],
169
- "arg",
204
+ [ops.primitive, "arg"],
170
205
  ]);
171
206
  assertParse("functionComposition", "fn('a')('b')", [
172
- [[ops.scope, "fn"], "a"],
173
- "b",
207
+ [
208
+ [ops.scope, "fn"],
209
+ [ops.primitive, "a"],
210
+ ],
211
+ [ops.primitive, "b"],
174
212
  ]);
175
213
  assertParse("functionComposition", "(fn())(a, b)", [
176
214
  [[ops.scope, "fn"], undefined],
@@ -179,8 +217,8 @@ describe("Origami parser", () => {
179
217
  ]);
180
218
  assertParse("functionComposition", "{ a: 1, b: 2}/b", [
181
219
  ops.traverse,
182
- [ops.object, ["a", 1], ["b", 2]],
183
- "b",
220
+ [ops.object, ["a", [ops.primitive, 1]], ["b", [ops.primitive, 2]]],
221
+ [ops.primitive, "b"],
184
222
  ]);
185
223
  assertParse("functionComposition", "fn arg", [
186
224
  [ops.scope, "fn"],
@@ -188,8 +226,8 @@ describe("Origami parser", () => {
188
226
  ]);
189
227
  assertParse("functionComposition", "fn 'a', 'b'", [
190
228
  [ops.scope, "fn"],
191
- "a",
192
- "b",
229
+ [ops.primitive, "a"],
230
+ [ops.primitive, "b"],
193
231
  ]);
194
232
  assertParse("functionComposition", "fn a(b), c", [
195
233
  [ops.scope, "fn"],
@@ -201,19 +239,22 @@ describe("Origami parser", () => {
201
239
  ]);
202
240
  assertParse("functionComposition", "fn1 fn2 'arg'", [
203
241
  [ops.scope, "fn1"],
204
- [[ops.scope, "fn2"], "arg"],
242
+ [
243
+ [ops.scope, "fn2"],
244
+ [ops.primitive, "arg"],
245
+ ],
205
246
  ]);
206
247
  assertParse("functionComposition", "(fn()) 'arg'", [
207
248
  [[ops.scope, "fn"], undefined],
208
- "arg",
249
+ [ops.primitive, "arg"],
209
250
  ]);
210
251
  assertParse("functionComposition", "tree/key arg", [
211
- [ops.traverse, [ops.scope, "tree"], "key"],
252
+ [ops.traverse, [ops.scope, "tree"], [ops.primitive, "key"]],
212
253
  [ops.scope, "arg"],
213
254
  ]);
214
255
  assertParse("functionComposition", "https://example.com/tree.yaml 'key'", [
215
- [ops.https, "example.com", "tree.yaml"],
216
- "key",
256
+ [ops.https, [ops.primitive, "example.com"], [ops.primitive, "tree.yaml"]],
257
+ [ops.primitive, "key"],
217
258
  ]);
218
259
  });
219
260
 
@@ -224,15 +265,15 @@ describe("Origami parser", () => {
224
265
  });
225
266
 
226
267
  test("host", () => {
227
- assertParse("host", "abc", "abc");
228
- assertParse("host", "abc:123", "abc:123");
268
+ assertParse("host", "abc", [ops.primitive, "abc"]);
269
+ assertParse("host", "abc:123", [ops.primitive, "abc:123"]);
229
270
  });
230
271
 
231
272
  test("identifier", () => {
232
- assertParse("identifier", "abc", "abc");
233
- assertParse("identifier", "index.html", "index.html");
234
- assertParse("identifier", "foo\\ bar", "foo bar");
235
- assertParse("identifier", "x-y-z", "x-y-z");
273
+ assertParse("identifier", "abc", "abc", false);
274
+ assertParse("identifier", "index.html", "index.html", false);
275
+ assertParse("identifier", "foo\\ bar", "foo bar", false);
276
+ assertParse("identifier", "x-y-z", "x-y-z", false);
236
277
  });
237
278
 
238
279
  test("lambda", () => {
@@ -244,71 +285,111 @@ describe("Origami parser", () => {
244
285
  assertParse("lambda", "=`Hello, ${name}.`", [
245
286
  ops.lambda,
246
287
  null,
247
- [ops.concat, "Hello, ", [ops.scope, "name"], "."],
288
+ [
289
+ ops.concat,
290
+ [ops.primitive, "Hello, "],
291
+ [ops.scope, "name"],
292
+ [ops.primitive, "."],
293
+ ],
248
294
  ]);
249
295
  });
250
296
 
251
297
  test("leadingSlashPath", () => {
252
- assertParse("leadingSlashPath", "/tree/", ["tree", ""]);
298
+ assertParse("leadingSlashPath", "/tree/", [
299
+ [ops.primitive, "tree"],
300
+ [ops.primitive, ""],
301
+ ]);
253
302
  });
254
303
 
255
304
  test("list", () => {
256
- assertParse("list", "1", [1]);
257
- assertParse("list", "1,2,3", [1, 2, 3]);
258
- assertParse("list", "1, 2, 3,", [1, 2, 3]);
259
- assertParse("list", "1 , 2 , 3", [1, 2, 3]);
260
- assertParse("list", "1\n2\n3", [1, 2, 3]);
261
- assertParse("list", "'a' , 'b' , 'c'", ["a", "b", "c"]);
305
+ assertParse("list", "1", [[ops.primitive, 1]]);
306
+ assertParse("list", "1,2,3", [
307
+ [ops.primitive, 1],
308
+ [ops.primitive, 2],
309
+ [ops.primitive, 3],
310
+ ]);
311
+ assertParse("list", "1, 2, 3,", [
312
+ [ops.primitive, 1],
313
+ [ops.primitive, 2],
314
+ [ops.primitive, 3],
315
+ ]);
316
+ assertParse("list", "1 , 2 , 3", [
317
+ [ops.primitive, 1],
318
+ [ops.primitive, 2],
319
+ [ops.primitive, 3],
320
+ ]);
321
+ assertParse("list", "1\n2\n3", [
322
+ [ops.primitive, 1],
323
+ [ops.primitive, 2],
324
+ [ops.primitive, 3],
325
+ ]);
326
+ assertParse("list", "'a' , 'b' , 'c'", [
327
+ [ops.primitive, "a"],
328
+ [ops.primitive, "b"],
329
+ [ops.primitive, "c"],
330
+ ]);
262
331
  });
263
332
 
264
333
  test("multiLineComment", () => {
265
- assertParse("multiLineComment", "/*\nHello, world!\n*/", null);
334
+ assertParse("multiLineComment", "/*\nHello, world!\n*/", null, false);
266
335
  });
267
336
 
268
337
  test("new", () => {
269
338
  assertParse("expression", "new:@js/Date('2025-01-01')", [
270
- [ops.constructor, "@js", "Date"],
271
- "2025-01-01",
339
+ [ops.constructor, [ops.primitive, "@js"], [ops.primitive, "Date"]],
340
+ [ops.primitive, "2025-01-01"],
272
341
  ]);
273
342
  });
274
343
 
275
344
  test("number", () => {
276
- assertParse("number", "123", 123);
277
- assertParse("number", "-456", -456);
278
- assertParse("number", ".5", 0.5);
279
- assertParse("number", "123.45", 123.45);
280
- assertParse("number", "-678.90", -678.9);
281
- assertParse("number", "+123", 123);
282
- assertParse("number", "+456.78", 456.78);
345
+ assertParse("number", "123", [ops.primitive, 123]);
346
+ assertParse("number", "-456", [ops.primitive, -456]);
347
+ assertParse("number", ".5", [ops.primitive, 0.5]);
348
+ assertParse("number", "123.45", [ops.primitive, 123.45]);
349
+ assertParse("number", "-678.90", [ops.primitive, -678.9]);
350
+ assertParse("number", "+123", [ops.primitive, 123]);
351
+ assertParse("number", "+456.78", [ops.primitive, 456.78]);
283
352
  });
284
353
 
285
354
  test("object", () => {
286
355
  assertParse("object", "{}", [ops.object]);
287
356
  assertParse("object", "{ a: 1, b }", [
288
357
  ops.object,
289
- ["a", 1],
358
+ ["a", [ops.primitive, 1]],
290
359
  ["b", [ops.inherited, "b"]],
291
360
  ]);
292
361
  assertParse("object", `{ "a": 1, "b": 2 }`, [
293
362
  ops.object,
294
- ["a", 1],
295
- ["b", 2],
363
+ ["a", [ops.primitive, 1]],
364
+ ["b", [ops.primitive, 2]],
296
365
  ]);
297
366
  assertParse("object", "{ a = b, b: 2 }", [
298
367
  ops.object,
299
368
  ["a", [ops.getter, [ops.scope, "b"]]],
300
- ["b", 2],
369
+ ["b", [ops.primitive, 2]],
301
370
  ]);
302
371
  assertParse("object", "{ x = fn('a') }", [
303
372
  ops.object,
304
- ["x", [ops.getter, [[ops.scope, "fn"], "a"]]],
373
+ [
374
+ "x",
375
+ [
376
+ ops.getter,
377
+ [
378
+ [ops.scope, "fn"],
379
+ [ops.primitive, "a"],
380
+ ],
381
+ ],
382
+ ],
305
383
  ]);
306
384
  assertParse("object", "{ a: 1, ...b }", [
307
385
  ops.merge,
308
- [ops.object, ["a", 1]],
386
+ [ops.object, ["a", [ops.primitive, 1]]],
309
387
  [ops.scope, "b"],
310
388
  ]);
311
- assertParse("object", "{ (a): 1 }", [ops.object, ["(a)", 1]]);
389
+ assertParse("object", "{ (a): 1 }", [
390
+ ops.object,
391
+ ["(a)", [ops.primitive, 1]],
392
+ ]);
312
393
  });
313
394
 
314
395
  test("objectEntry", () => {
@@ -323,16 +404,28 @@ describe("Origami parser", () => {
323
404
  ]);
324
405
  assertParse("objectGetter", "foo = fn 'bar'", [
325
406
  "foo",
326
- [ops.getter, [[ops.scope, "fn"], "bar"]],
407
+ [
408
+ ops.getter,
409
+ [
410
+ [ops.scope, "fn"],
411
+ [ops.primitive, "bar"],
412
+ ],
413
+ ],
327
414
  ]);
328
415
  });
329
416
 
330
417
  test("objectProperty", () => {
331
- assertParse("objectProperty", "a: 1", ["a", 1]);
332
- assertParse("objectProperty", "name: 'Alice'", ["name", "Alice"]);
418
+ assertParse("objectProperty", "a: 1", ["a", [ops.primitive, 1]]);
419
+ assertParse("objectProperty", "name: 'Alice'", [
420
+ "name",
421
+ [ops.primitive, "Alice"],
422
+ ]);
333
423
  assertParse("objectProperty", "x: fn('a')", [
334
424
  "x",
335
- [[ops.scope, "fn"], "a"],
425
+ [
426
+ [ops.scope, "fn"],
427
+ [ops.primitive, "a"],
428
+ ],
336
429
  ]);
337
430
  });
338
431
 
@@ -377,9 +470,19 @@ describe("Origami parser", () => {
377
470
  });
378
471
 
379
472
  test("path", () => {
380
- assertParse("path", "tree/", ["tree", ""]);
381
- assertParse("path", "month/12", ["month", "12"]);
382
- assertParse("path", "tree/foo/bar", ["tree", "foo", "bar"]);
473
+ assertParse("path", "tree/", [
474
+ [ops.primitive, "tree"],
475
+ [ops.primitive, ""],
476
+ ]);
477
+ assertParse("path", "month/12", [
478
+ [ops.primitive, "month"],
479
+ [ops.primitive, "12"],
480
+ ]);
481
+ assertParse("path", "tree/foo/bar", [
482
+ [ops.primitive, "tree"],
483
+ [ops.primitive, "foo"],
484
+ [ops.primitive, "bar"],
485
+ ]);
383
486
  });
384
487
 
385
488
  test("pipeline", () => {
@@ -404,18 +507,24 @@ describe("Origami parser", () => {
404
507
  });
405
508
 
406
509
  test("protocolCall", () => {
407
- assertParse("protocolCall", "foo://bar", [[ops.scope, "foo"], "bar"]);
510
+ assertParse("protocolCall", "foo://bar", [
511
+ [ops.scope, "foo"],
512
+ [ops.primitive, "bar"],
513
+ ]);
408
514
  assertParse("protocolCall", "https://example.com/foo/", [
409
515
  ops.https,
410
- "example.com",
411
- "foo",
412
- "",
516
+ [ops.primitive, "example.com"],
517
+ [ops.primitive, "foo"],
518
+ [ops.primitive, ""],
519
+ ]);
520
+ assertParse("protocolCall", "http:example.com", [
521
+ ops.http,
522
+ [ops.primitive, "example.com"],
413
523
  ]);
414
- assertParse("protocolCall", "http:example.com", [ops.http, "example.com"]);
415
524
  assertParse("protocolCall", "http://localhost:5000/foo", [
416
525
  ops.http,
417
- "localhost:5000",
418
- "foo",
526
+ [ops.primitive, "localhost:5000"],
527
+ [ops.primitive, "foo"],
419
528
  ]);
420
529
  });
421
530
 
@@ -425,12 +534,13 @@ describe("Origami parser", () => {
425
534
  `#!/usr/bin/env ori @invoke
426
535
  'Hello'
427
536
  `,
428
- "Hello"
537
+ [ops.primitive, "Hello"],
538
+ false
429
539
  );
430
540
  });
431
541
 
432
542
  test("singleLineComment", () => {
433
- assertParse("singleLineComment", "// Hello, world!", null);
543
+ assertParse("singleLineComment", "// Hello, world!", null, false);
434
544
  });
435
545
 
436
546
  test("scopeReference", () => {
@@ -443,38 +553,49 @@ describe("Origami parser", () => {
443
553
  });
444
554
 
445
555
  test("string", () => {
446
- assertParse("string", '"foo"', "foo");
447
- assertParse("string", "'bar'", "bar");
448
- assertParse("string", '"foo bar"', "foo bar");
449
- assertParse("string", "'bar baz'", "bar baz");
450
- assertParse("string", `"foo\\"s bar"`, `foo"s bar`);
451
- assertParse("string", `'bar\\'s baz'`, `bar's baz`);
452
- assertParse("string", `«string»`, "string");
453
- assertParse("string", `"\\0\\b\\f\\n\\r\\t\\v"`, "\0\b\f\n\r\t\v");
556
+ assertParse("string", '"foo"', [ops.primitive, "foo"]);
557
+ assertParse("string", "'bar'", [ops.primitive, "bar"]);
558
+ assertParse("string", '"foo bar"', [ops.primitive, "foo bar"]);
559
+ assertParse("string", "'bar baz'", [ops.primitive, "bar baz"]);
560
+ assertParse("string", `"foo\\"s bar"`, [ops.primitive, `foo"s bar`]);
561
+ assertParse("string", `'bar\\'s baz'`, [ops.primitive, `bar's baz`]);
562
+ assertParse("string", `«string»`, [ops.primitive, "string"]);
563
+ assertParse("string", `"\\0\\b\\f\\n\\r\\t\\v"`, [
564
+ ops.primitive,
565
+ "\0\b\f\n\r\t\v",
566
+ ]);
454
567
  });
455
568
 
456
569
  test("templateDocument", () => {
457
570
  assertParse("templateDocument", "hello${foo}world", [
458
571
  ops.lambda,
459
572
  null,
460
- [ops.concat, "hello", [ops.scope, "foo"], "world"],
573
+ [
574
+ ops.concat,
575
+ [ops.primitive, "hello"],
576
+ [ops.scope, "foo"],
577
+ [ops.primitive, "world"],
578
+ ],
461
579
  ]);
462
580
  assertParse("templateDocument", "Documents can contain ` backticks", [
463
581
  ops.lambda,
464
582
  null,
465
- "Documents can contain ` backticks",
583
+ [ops.primitive, "Documents can contain ` backticks"],
466
584
  ]);
467
585
  });
468
586
 
469
587
  test("templateLiteral", () => {
470
- assertParse("templateLiteral", "`Hello, world.`", "Hello, world.");
588
+ assertParse("templateLiteral", "`Hello, world.`", [
589
+ ops.primitive,
590
+ "Hello, world.",
591
+ ]);
471
592
  assertParse("templateLiteral", "`foo ${x} bar`", [
472
593
  ops.concat,
473
- "foo ",
594
+ [ops.primitive, "foo "],
474
595
  [ops.scope, "x"],
475
- " bar",
596
+ [ops.primitive, " bar"],
476
597
  ]);
477
- assertParse("templateLiteral", "`${`nested`}`", "nested");
598
+ assertParse("templateLiteral", "`${`nested`}`", [ops.primitive, "nested"]);
478
599
  assertParse("templateLiteral", "`${map(people, =`${name}`)}`", [
479
600
  ops.concat,
480
601
  [
@@ -486,14 +607,17 @@ describe("Origami parser", () => {
486
607
  });
487
608
 
488
609
  test("templateLiteral (JS)", () => {
489
- assertParse("templateLiteral", "`Hello, world.`", "Hello, world.");
610
+ assertParse("templateLiteral", "`Hello, world.`", [
611
+ ops.primitive,
612
+ "Hello, world.",
613
+ ]);
490
614
  assertParse("templateLiteral", "`foo ${x} bar`", [
491
615
  ops.concat,
492
- "foo ",
616
+ [ops.primitive, "foo "],
493
617
  [ops.scope, "x"],
494
- " bar",
618
+ [ops.primitive, " bar"],
495
619
  ]);
496
- assertParse("templateLiteral", "`${`nested`}`", "nested");
620
+ assertParse("templateLiteral", "`${`nested`}`", [ops.primitive, "nested"]);
497
621
  assertParse("templateLiteral", "`${map(people, =`${name}`)}`", [
498
622
  ops.concat,
499
623
  [
@@ -515,13 +639,14 @@ describe("Origami parser", () => {
515
639
  // First comment
516
640
  // Second comment
517
641
  `,
518
- ""
642
+ null,
643
+ false
519
644
  );
520
645
  });
521
646
  });
522
647
 
523
648
  function assertParse(startRule, source, expected, checkLocation = true) {
524
- const parseResult = parse(source, {
649
+ const code = parse(source, {
525
650
  grammarSource: { text: source },
526
651
  startRule,
527
652
  });
@@ -529,16 +654,16 @@ function assertParse(startRule, source, expected, checkLocation = true) {
529
654
  // Verify that the parser returned a `location` property and that it spans the
530
655
  // entire source. We skip this check in cases where the source starts or ends
531
656
  // with a comment; the parser will strip those.
532
- if (checkLocation && parseResult instanceof Array) {
533
- assert(parseResult.location);
534
- const resultSource = parseResult.location.source.text.slice(
535
- parseResult.location.start.offset,
536
- parseResult.location.end.offset
657
+ if (checkLocation) {
658
+ assert(code.location);
659
+ const resultSource = code.location.source.text.slice(
660
+ code.location.start.offset,
661
+ code.location.end.offset
537
662
  );
538
663
  assert.equal(resultSource, source.trim());
539
664
  }
540
665
 
541
- const actual = stripLocations(parseResult);
666
+ const actual = stripLocations(code);
542
667
  assert.deepEqual(actual, expected);
543
668
  }
544
669
 
@@ -7,7 +7,7 @@ import evaluate from "../../src/runtime/evaluate.js";
7
7
 
8
8
  describe("evaluate", () => {
9
9
  test("can retrieve values from scope", async () => {
10
- const code = [ops.scope, "message"];
10
+ const code = createCode([ops.scope, "message"]);
11
11
  const parent = new ObjectTree({
12
12
  message: "Hello",
13
13
  });
@@ -19,10 +19,10 @@ describe("evaluate", () => {
19
19
 
20
20
  test("can invoke functions in scope", async () => {
21
21
  // Match the array representation of code generated by the parser.
22
- const code = [
22
+ const code = createCode([
23
23
  [ops.scope, "greet"],
24
24
  [ops.scope, "name"],
25
- ];
25
+ ]);
26
26
 
27
27
  const tree = new ObjectTree({
28
28
  async greet(name) {
@@ -36,7 +36,7 @@ describe("evaluate", () => {
36
36
  });
37
37
 
38
38
  test("passes context to invoked functions", async () => {
39
- const code = [ops.scope, "fn"];
39
+ const code = createCode([ops.scope, "fn"]);
40
40
  const tree = new ObjectTree({
41
41
  async fn() {
42
42
  assert.equal(this, tree);
@@ -49,7 +49,7 @@ describe("evaluate", () => {
49
49
  const fn = (x, y) => ({
50
50
  c: `${x}${y}c`,
51
51
  });
52
- const code = [ops.traverse, fn, "a", "b", "c"];
52
+ const code = createCode([ops.traverse, fn, "a", "b", "c"]);
53
53
  assert.equal(await evaluate.call(null, code), "abc");
54
54
  });
55
55
 
@@ -57,16 +57,29 @@ describe("evaluate", () => {
57
57
  const fn = (...args) => args.join(",");
58
58
  const packed = new String();
59
59
  /** @type {any} */ (packed).unpack = async () => fn;
60
- const code = [packed, "a", "b", "c"];
60
+ const code = createCode([packed, "a", "b", "c"]);
61
61
  const result = await evaluate.call(null, code);
62
62
  assert.equal(result, "a,b,c");
63
63
  });
64
64
 
65
65
  test("by defalut sets the parent of a returned tree to the current tree", async () => {
66
66
  const fn = () => new ObjectTree({});
67
- const code = [fn];
67
+ const code = createCode([fn]);
68
68
  const tree = new ObjectTree({});
69
69
  const result = await evaluate.call(tree, code);
70
70
  assert.equal(result.parent, tree);
71
71
  });
72
72
  });
73
+
74
+ /**
75
+ * @returns {import("../../index.ts").Code}
76
+ */
77
+ function createCode(array) {
78
+ const code = array;
79
+ /** @type {any} */ (code).location = {
80
+ source: {
81
+ text: "",
82
+ },
83
+ };
84
+ return code;
85
+ }