xbintsc 0.3.15 → 0.3.16

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.
Files changed (156) hide show
  1. package/dist/src/cli/main.js +4 -4
  2. package/dist/src/cli/main.js.map +1 -1
  3. package/dist/src/codegen/generator/state.js +8 -0
  4. package/dist/src/codegen/generator/state.js.map +1 -1
  5. package/dist/src/codegen/generator/tables.js +8 -0
  6. package/dist/src/codegen/generator/tables.js.map +1 -1
  7. package/dist/src/driver/bundler/graph.d.ts +8 -0
  8. package/dist/src/driver/bundler/graph.js +85 -0
  9. package/dist/src/driver/bundler/graph.js.map +1 -0
  10. package/dist/src/driver/bundler/merge.d.ts +11 -0
  11. package/dist/src/driver/bundler/merge.js +288 -0
  12. package/dist/src/driver/bundler/merge.js.map +1 -0
  13. package/dist/src/driver/bundler/resolve.d.ts +12 -0
  14. package/dist/src/driver/bundler/resolve.js +246 -0
  15. package/dist/src/driver/bundler/resolve.js.map +1 -0
  16. package/dist/src/driver/bundler/symbols.d.ts +15 -0
  17. package/dist/src/driver/bundler/symbols.js +51 -0
  18. package/dist/src/driver/bundler/symbols.js.map +1 -0
  19. package/dist/src/driver/bundler/types.d.ts +36 -0
  20. package/dist/src/driver/bundler/types.js +5 -0
  21. package/dist/src/driver/bundler/types.js.map +1 -0
  22. package/dist/src/driver/modules.d.ts +9 -16
  23. package/dist/src/driver/modules.js +8 -644
  24. package/dist/src/driver/modules.js.map +1 -1
  25. package/dist/src/extensions/catalog.js +2 -1
  26. package/dist/src/extensions/catalog.js.map +1 -1
  27. package/dist/src/extensions/gui/index.d.ts +24 -0
  28. package/dist/src/extensions/gui/index.js +101 -0
  29. package/dist/src/extensions/gui/index.js.map +1 -0
  30. package/dist/tests/e2e/compile-basics.test.d.ts +4 -0
  31. package/dist/tests/e2e/compile-basics.test.js +134 -0
  32. package/dist/tests/e2e/compile-basics.test.js.map +1 -0
  33. package/dist/tests/e2e/compile-builtins.test.d.ts +4 -0
  34. package/dist/tests/e2e/compile-builtins.test.js +191 -0
  35. package/dist/tests/e2e/compile-builtins.test.js.map +1 -0
  36. package/dist/tests/e2e/compile-control-flow.test.d.ts +4 -0
  37. package/dist/tests/e2e/compile-control-flow.test.js +190 -0
  38. package/dist/tests/e2e/compile-control-flow.test.js.map +1 -0
  39. package/dist/tests/e2e/compile-modules.test.d.ts +4 -0
  40. package/dist/tests/e2e/compile-modules.test.js +48 -0
  41. package/dist/tests/e2e/compile-modules.test.js.map +1 -0
  42. package/dist/tests/e2e/compile-objects-classes.test.d.ts +4 -0
  43. package/dist/tests/e2e/compile-objects-classes.test.js +362 -0
  44. package/dist/tests/e2e/compile-objects-classes.test.js.map +1 -0
  45. package/dist/tests/e2e/differential-helpers.d.ts +12 -0
  46. package/dist/tests/e2e/differential-helpers.js +16 -0
  47. package/dist/tests/e2e/differential-helpers.js.map +1 -0
  48. package/dist/tests/e2e/differential-language.test.d.ts +4 -0
  49. package/dist/tests/e2e/{differential.test.js → differential-language.test.js} +5 -287
  50. package/dist/tests/e2e/differential-language.test.js.map +1 -0
  51. package/dist/tests/e2e/differential-symbols.test.d.ts +4 -0
  52. package/dist/tests/e2e/differential-symbols.test.js +92 -0
  53. package/dist/tests/e2e/differential-symbols.test.js.map +1 -0
  54. package/dist/tests/e2e/differential-values.test.d.ts +4 -0
  55. package/dist/tests/e2e/differential-values.test.js +197 -0
  56. package/dist/tests/e2e/differential-values.test.js.map +1 -0
  57. package/dist/tests/e2e/gui.test.d.ts +12 -0
  58. package/dist/tests/e2e/gui.test.js +493 -0
  59. package/dist/tests/e2e/gui.test.js.map +1 -0
  60. package/dist/tests/e2e/runtime-coverage-buffer.test.d.ts +4 -0
  61. package/dist/tests/e2e/runtime-coverage-buffer.test.js +97 -0
  62. package/dist/tests/e2e/runtime-coverage-buffer.test.js.map +1 -0
  63. package/dist/tests/e2e/runtime-coverage-globals.test.d.ts +4 -0
  64. package/dist/tests/e2e/runtime-coverage-globals.test.js +149 -0
  65. package/dist/tests/e2e/runtime-coverage-globals.test.js.map +1 -0
  66. package/dist/tests/e2e/runtime-coverage-node-modules.test.d.ts +4 -0
  67. package/dist/tests/e2e/runtime-coverage-node-modules.test.js +177 -0
  68. package/dist/tests/e2e/runtime-coverage-node-modules.test.js.map +1 -0
  69. package/dist/tests/e2e/runtime-coverage-streams.test.d.ts +4 -0
  70. package/dist/tests/e2e/runtime-coverage-streams.test.js +161 -0
  71. package/dist/tests/e2e/runtime-coverage-streams.test.js.map +1 -0
  72. package/dist/tests/e2e/runtime-coverage-system.test.d.ts +4 -0
  73. package/dist/tests/e2e/runtime-coverage-system.test.js +91 -0
  74. package/dist/tests/e2e/runtime-coverage-system.test.js.map +1 -0
  75. package/dist/tests/e2e/timers.test.d.ts +7 -0
  76. package/dist/tests/e2e/timers.test.js +63 -0
  77. package/dist/tests/e2e/timers.test.js.map +1 -0
  78. package/package.json +2 -1
  79. package/runtime/ext_gui/css.cpp +743 -0
  80. package/runtime/ext_gui/css.h +98 -0
  81. package/runtime/ext_gui/document.cpp +264 -0
  82. package/runtime/ext_gui/document.h +89 -0
  83. package/runtime/ext_gui/dom.cpp +472 -0
  84. package/runtime/ext_gui/dom.h +71 -0
  85. package/runtime/ext_gui/gui.cpp +457 -0
  86. package/runtime/ext_gui/gui_engine.h +81 -0
  87. package/runtime/ext_gui/image.cpp +125 -0
  88. package/runtime/ext_gui/image.h +42 -0
  89. package/runtime/ext_gui/layout.cpp +748 -0
  90. package/runtime/ext_gui/layout.h +93 -0
  91. package/runtime/ext_gui/paint.cpp +137 -0
  92. package/runtime/ext_gui/paint.h +75 -0
  93. package/runtime/ext_gui/renderer.cpp +959 -0
  94. package/runtime/ext_gui/renderer.h +68 -0
  95. package/runtime/ext_gui/stb_image.h +7988 -0
  96. package/runtime/ext_gui/style.cpp +771 -0
  97. package/runtime/ext_gui/style.h +117 -0
  98. package/runtime/ext_gui/text.cpp +378 -0
  99. package/runtime/ext_gui/text.h +78 -0
  100. package/runtime/ext_gui/window.cpp +405 -0
  101. package/runtime/ext_node/fs/fs_common.h +13 -527
  102. package/runtime/ext_node/fs/parts/buffer-bridge.inc +6 -0
  103. package/runtime/ext_node/fs/parts/builtins.inc +69 -0
  104. package/runtime/ext_node/fs/parts/dir.inc +47 -0
  105. package/runtime/ext_node/fs/parts/encoding.inc +186 -0
  106. package/runtime/ext_node/fs/parts/errors.inc +66 -0
  107. package/runtime/ext_node/fs/parts/flags.inc +39 -0
  108. package/runtime/ext_node/fs/parts/platform.inc +86 -0
  109. package/runtime/ext_node/fs/parts/promisify.inc +15 -0
  110. package/runtime/ext_node/fs/parts/time.inc +9 -0
  111. package/runtime/rt.h +33 -0
  112. package/runtime/xt_builtins.c +4 -0
  113. package/runtime/xt_containers/access.inc +168 -0
  114. package/runtime/xt_containers/arrays.inc +108 -0
  115. package/runtime/xt_containers/boxes.inc +11 -0
  116. package/runtime/xt_containers/objects.inc +326 -0
  117. package/runtime/xt_containers.c +8 -618
  118. package/runtime/xt_io/base64.inc +87 -0
  119. package/runtime/xt_io/console.inc +119 -0
  120. package/runtime/xt_io/exception.inc +142 -0
  121. package/runtime/xt_io/inspect.inc +212 -0
  122. package/runtime/xt_io.c +8 -553
  123. package/runtime/xt_loop.c +262 -24
  124. package/runtime/xt_regex/api.inc +58 -0
  125. package/runtime/xt_regex/helpers.inc +68 -0
  126. package/runtime/xt_regex/matcher.inc +248 -0
  127. package/runtime/xt_regex/parser.inc +236 -0
  128. package/runtime/xt_regex/types.inc +58 -0
  129. package/runtime/xt_regex.h +9 -672
  130. package/runtime/xt_values/arithmetic.inc +150 -0
  131. package/runtime/xt_values/comparison.inc +112 -0
  132. package/runtime/xt_values/constructors.inc +41 -0
  133. package/runtime/xt_values/conversions.inc +115 -0
  134. package/runtime/xt_values/number-format.inc +180 -0
  135. package/runtime/xt_values/strings.inc +22 -0
  136. package/runtime/xt_values.c +10 -626
  137. package/scripts/build-gui.ts +317 -0
  138. package/src/cli/main.ts +4 -3
  139. package/src/codegen/generator/state.ts +8 -0
  140. package/src/codegen/generator/tables.ts +8 -0
  141. package/src/driver/bundler/graph.ts +95 -0
  142. package/src/driver/bundler/merge.ts +312 -0
  143. package/src/driver/bundler/resolve.ts +240 -0
  144. package/src/driver/bundler/symbols.ts +55 -0
  145. package/src/driver/bundler/types.ts +37 -0
  146. package/src/driver/modules.ts +9 -693
  147. package/src/extensions/catalog.ts +2 -1
  148. package/src/extensions/gui/index.ts +107 -0
  149. package/dist/tests/e2e/compile.test.d.ts +0 -8
  150. package/dist/tests/e2e/compile.test.js +0 -893
  151. package/dist/tests/e2e/compile.test.js.map +0 -1
  152. package/dist/tests/e2e/differential.test.d.ts +0 -7
  153. package/dist/tests/e2e/differential.test.js.map +0 -1
  154. package/dist/tests/e2e/runtime-coverage.test.d.ts +0 -11
  155. package/dist/tests/e2e/runtime-coverage.test.js +0 -646
  156. package/dist/tests/e2e/runtime-coverage.test.js.map +0 -1
@@ -0,0 +1,190 @@
1
+ /**
2
+ * End-to-end tests for control flow: exceptions, equality, labels and optional chains.
3
+ */
4
+ import { expect, it } from "vitest";
5
+ import { describeE2E } from "./harness.js";
6
+ describeE2E("end-to-end control flow", (harness) => {
7
+ const { runProgram } = harness;
8
+ it("supports try/catch/finally including returns and loop breaks", () => {
9
+ const source = `
10
+ function safe(n: number): number {
11
+ try {
12
+ if (n < 0) throw "negative";
13
+ return n * 2;
14
+ } catch (err) {
15
+ return -1;
16
+ }
17
+ }
18
+ function cleanup(): string {
19
+ let log = "";
20
+ try {
21
+ log += "try;";
22
+ throw "boom";
23
+ } catch (e) {
24
+ log += "catch:" + e + ";";
25
+ } finally {
26
+ log += "finally";
27
+ }
28
+ return log;
29
+ }
30
+ console.log(safe(5), safe(-2), cleanup());
31
+ `;
32
+ expect(runProgram(source)).toBe("10 -1 try;catch:boom;finally");
33
+ });
34
+ it("runs finally blocks on early return, break and continue", () => {
35
+ const source = `
36
+ const events: string[] = [];
37
+ function f(n: number): string {
38
+ try {
39
+ events.push("try" + n);
40
+ if (n === 1) return "ret1";
41
+ if (n === 2) throw "boom" + n;
42
+ } catch (e) {
43
+ events.push("catch" + e);
44
+ if (n === 3) return "ret3";
45
+ } finally {
46
+ events.push("finally" + n);
47
+ }
48
+ return "done" + n;
49
+ }
50
+ console.log(f(0), f(1), f(2), f(3));
51
+ console.log(events.join("|"));
52
+ const loop: string[] = [];
53
+ for (let i = 0; i < 5; i++) {
54
+ try {
55
+ if (i === 2) break;
56
+ if (i === 4) continue;
57
+ loop.push("i" + i);
58
+ } finally {
59
+ loop.push("F" + i);
60
+ }
61
+ }
62
+ console.log(loop.join("|"));
63
+ function nested(): string {
64
+ try {
65
+ try {
66
+ return "inner";
67
+ } finally {
68
+ events.push("innerFinally");
69
+ }
70
+ } finally {
71
+ events.push("outerFinally");
72
+ }
73
+ }
74
+ console.log(nested(), events[events.length - 2], events[events.length - 1]);
75
+ `;
76
+ expect(runProgram(source)).toBe([
77
+ "done0 ret1 done2 done3",
78
+ "try0|finally0|try1|finally1|try2|catchboom2|finally2|try3|finally3",
79
+ "i0|F0|i1|F1|F2",
80
+ "inner innerFinally outerFinally",
81
+ ].join("\n"));
82
+ });
83
+ it("implements abstract equality with ToPrimitive", () => {
84
+ const source = `
85
+ console.log(([] as any) == 0, ([] as any) == "", ([1] as any) == 1, ([1, 2] as any) == "1,2");
86
+ console.log(({} as any) == "[object Object]");
87
+ console.log(([1] as any) == [1], ([] as any) == false, ([] as any) == null);
88
+ console.log(0 == "0", 0 == false, "" == false, null == undefined, null == 0, undefined == 0);
89
+ console.log(NaN == NaN, (1 as any) == "1");
90
+ `;
91
+ expect(runProgram(source)).toBe([
92
+ "true true true true",
93
+ "true",
94
+ "false true false",
95
+ "true true true true false false",
96
+ "false true",
97
+ ].join("\n"));
98
+ });
99
+ it("supports labeled break and continue across nested loops", () => {
100
+ const source = `
101
+ const out: string[] = [];
102
+ outer: for (let i = 0; i < 3; i++) {
103
+ inner: for (let j = 0; j < 3; j++) {
104
+ if (j === 1) continue outer;
105
+ if (i === 2) break outer;
106
+ out.push(i + "," + j);
107
+ }
108
+ }
109
+ block: {
110
+ out.push("before");
111
+ if (out.length > 0) break block;
112
+ out.push("unreachable");
113
+ }
114
+ out.push("after");
115
+ function f(): number {
116
+ let total = 0;
117
+ loop: for (let i = 0; i < 5; i++) {
118
+ try {
119
+ if (i === 2) continue loop;
120
+ if (i === 4) break loop;
121
+ total += i;
122
+ } finally {
123
+ total += 100;
124
+ }
125
+ }
126
+ return total;
127
+ }
128
+ console.log(out.join("|"), f());
129
+ `;
130
+ expect(runProgram(source)).toBe("0,0|1,0|before|after 504");
131
+ });
132
+ it("supports optional chaining", () => {
133
+ const source = `
134
+ const obj = { a: { b: 5 }, m: (x: number) => x + 1 };
135
+ const empty: any = null;
136
+ console.log(obj?.a?.b, empty?.a?.b, obj?.m?.(10), empty?.m?.(10));
137
+ const arr = [1, 2, 3];
138
+ console.log(arr?.length, arr?.map((x) => x * 2).join(","), empty?.length);
139
+ `;
140
+ expect(runProgram(source)).toBe("5 undefined 11 undefined\n3 2,4,6 undefined");
141
+ });
142
+ it("short-circuits a whole optional chain but throws past the guard", () => {
143
+ const source = `
144
+ const empty: any = null;
145
+ const nested: any = { a: { b: null } };
146
+ // A \`?.\` short-circuits every later member, so nothing past it is evaluated.
147
+ console.log("A", empty?.a.b.c);
148
+ console.log("B", (nested?.a)?.b);
149
+ console.log("C", nested.a?.b?.c);
150
+ // Once the chain has started, a non-optional member on null throws.
151
+ try {
152
+ console.log(nested?.b.c);
153
+ console.log("D-ok");
154
+ } catch (e) {
155
+ console.log("D-threw");
156
+ }
157
+ try {
158
+ console.log(nested.a?.b.c);
159
+ console.log("E-ok");
160
+ } catch (e) {
161
+ console.log("E-threw");
162
+ }
163
+ `;
164
+ expect(runProgram(source)).toBe("A undefined\nB null\nC undefined\nD-threw\nE-threw");
165
+ });
166
+ it("defaults Array.sort to string order and reveals circular references", () => {
167
+ const source = `
168
+ console.log([10, 1, 2, 20].sort().join(","));
169
+ console.log(["banana", "apple", "cherry"].sort().join(","));
170
+ console.log(JSON.stringify([3, undefined, 1, 2, undefined].sort()));
171
+ console.log([5, 3, 8, 1].sort((a, b) => a - b).join(","));
172
+ const o: any = { name: "x" };
173
+ o.self = o;
174
+ o.child = { parent: o };
175
+ console.log(o);
176
+ const arr: any = [1, 2];
177
+ arr.push(arr);
178
+ console.log(arr);
179
+ `;
180
+ expect(runProgram(source)).toBe([
181
+ "1,10,2,20",
182
+ "apple,banana,cherry",
183
+ "[1,2,3,null,null]",
184
+ "1,3,5,8",
185
+ "{ name: 'x', self: [Circular *1], child: { parent: [Circular *1] } }",
186
+ "[ 1, 2, [Circular *1] ]",
187
+ ].join("\n"));
188
+ });
189
+ });
190
+ //# sourceMappingURL=compile-control-flow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-control-flow.test.js","sourceRoot":"","sources":["../../../tests/e2e/compile-control-flow.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,WAAW,CAAC,yBAAyB,EAAE,CAAC,OAAO,EAAE,EAAE;IACjD,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;KAsBd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAwCd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B;YACE,wBAAwB;YACxB,oEAAoE;YACpE,gBAAgB;YAChB,iCAAiC;SAClC,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,MAAM,GAAG;;;;;;KAMd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B;YACE,qBAAqB;YACrB,MAAM;YACN,kBAAkB;YAClB,iCAAiC;YACjC,YAAY;SACb,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6Bd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;QACpC,MAAM,MAAM,GAAG;;;;;;KAMd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;KAoBd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IACxF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC7E,MAAM,MAAM,GAAG;;;;;;;;;;;;KAYd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B;YACE,WAAW;YACX,qBAAqB;YACrB,mBAAmB;YACnB,SAAS;YACT,sEAAsE;YACtE,yBAAyB;SAC1B,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * End-to-end tests for the module bundler.
3
+ */
4
+ export {};
@@ -0,0 +1,48 @@
1
+ /**
2
+ * End-to-end tests for the module bundler.
3
+ */
4
+ import { writeFileSync } from "node:fs";
5
+ import { join } from "node:path";
6
+ import { expect, it } from "vitest";
7
+ import { describeE2E } from "./harness.js";
8
+ describeE2E("end-to-end module bundling", (harness) => {
9
+ const { runProgram } = harness;
10
+ it("supports import and export across modules", () => {
11
+ writeFileSync(join(harness.workdir, "math_dep.ts"), `
12
+ export const PI = 3.14;
13
+ export function add(a: number, b: number): number {
14
+ return a + b;
15
+ }
16
+ export default function greet(name: string): string {
17
+ return "hi " + name;
18
+ }
19
+ `);
20
+ const source = `
21
+ import greet, { add, PI } from "./math_dep";
22
+ console.log(add(2, 3), PI);
23
+ console.log(greet("ada"));
24
+ `;
25
+ expect(runProgram(source)).toBe("5 3.14\nhi ada");
26
+ });
27
+ it("resolves `.js` specifiers to their TypeScript sources", () => {
28
+ writeFileSync(join(harness.workdir, "esm_dep.ts"), `export const value = 42;`);
29
+ const source = `
30
+ import { value } from "./esm_dep.js";
31
+ console.log(value);
32
+ `;
33
+ expect(runProgram(source)).toBe("42");
34
+ });
35
+ it("bundles JavaScript modules through extension-less imports", () => {
36
+ const source = `
37
+ import { add } from "./js_dep";
38
+ console.log(add(2, 3));
39
+ `;
40
+ expect(runProgram(source, {
41
+ files: {
42
+ "js_dep.js": 'export { add } from "./js_math";',
43
+ "js_math.js": "export function add(a, b) { return a + b; }",
44
+ },
45
+ })).toBe("5");
46
+ });
47
+ });
48
+ //# sourceMappingURL=compile-modules.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-modules.test.js","sourceRoot":"","sources":["../../../tests/e2e/compile-modules.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,WAAW,CAAC,4BAA4B,EAAE,CAAC,OAAO,EAAE,EAAE;IACpD,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,aAAa,CACX,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,aAAa,CAAC,EACpC;;;;;;;;OAQC,CACF,CAAC;QACF,MAAM,MAAM,GAAG;;;;KAId,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC,EAAE,0BAA0B,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG;;;KAGd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,MAAM,GAAG;;;KAGd,CAAC;QACF,MAAM,CACJ,UAAU,CAAC,MAAM,EAAE;YACjB,KAAK,EAAE;gBACL,WAAW,EAAE,kCAAkC;gBAC/C,YAAY,EAAE,6CAA6C;aAC5D;SACF,CAAC,CACH,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * End-to-end tests for closures, classes, destructuring and function semantics.
3
+ */
4
+ export {};
@@ -0,0 +1,362 @@
1
+ /**
2
+ * End-to-end tests for closures, classes, destructuring and function semantics.
3
+ */
4
+ import { expect, it } from "vitest";
5
+ import { describeE2E } from "./harness.js";
6
+ describeE2E("end-to-end objects, functions and classes", (harness) => {
7
+ const { runProgram } = harness;
8
+ it("implements closures with by-reference captures", () => {
9
+ const source = `
10
+ const makeCounter = () => {
11
+ let count = 0;
12
+ return () => {
13
+ count += 1;
14
+ return count;
15
+ };
16
+ };
17
+ const next = makeCounter();
18
+ console.log(next(), next(), next());
19
+ `;
20
+ expect(runProgram(source)).toBe("1 2 3");
21
+ });
22
+ it("supports #private fields, methods and static members", () => {
23
+ const source = `
24
+ class Counter {
25
+ #count = 0;
26
+ static #instances = 0;
27
+ constructor() { Counter.#bumpStatic(); }
28
+ #bump(by: number): void { this.#count += by; }
29
+ static #bumpStatic(): void { Counter.#instances++; }
30
+ inc(by: number): number { this.#bump(by); return this.#count; }
31
+ get count(): number { return this.#count; }
32
+ set count(v: number) { this.#count = v; }
33
+ static instances(): number { return Counter.#instances; }
34
+ }
35
+ class Sub extends Counter {
36
+ #label = "sub";
37
+ constructor() { super(); this.inc(5); }
38
+ describe(): string { return this.#label + ":" + this.count; }
39
+ }
40
+ const a = new Counter();
41
+ const b = new Counter();
42
+ a.inc(3);
43
+ a.count = 10;
44
+ console.log(a.count, b.count, Counter.instances());
45
+ console.log(new Sub().describe());
46
+ `;
47
+ expect(runProgram(source)).toBe("10 0 2\nsub:5");
48
+ });
49
+ it("supports classes with new, this, statics, inheritance and instanceof", () => {
50
+ const source = `
51
+ class Animal {
52
+ name: string;
53
+ constructor(name: string) {
54
+ this.name = name;
55
+ }
56
+ speak(): string {
57
+ return this.name + " makes a sound";
58
+ }
59
+ static kind(): string {
60
+ return "animal";
61
+ }
62
+ }
63
+ class Dog extends Animal {
64
+ constructor(name: string) {
65
+ super(name);
66
+ }
67
+ speak(): string {
68
+ return super.speak() + " (woof)";
69
+ }
70
+ }
71
+ const dog = new Dog("Rex");
72
+ console.log(dog.speak());
73
+ console.log(Animal.kind(), dog instanceof Dog, dog instanceof Animal);
74
+ `;
75
+ expect(runProgram(source)).toBe("Rex makes a sound (woof)\nanimal true true");
76
+ });
77
+ it("supports destructuring bindings, enums, regexes and Error", () => {
78
+ const source = `
79
+ const [a, b = 7, ...rest] = [1, undefined, 3, 4];
80
+ const { x, y: z = 9 } = { x: 5 };
81
+ enum Color { Red, Green = 5, Blue }
82
+ const re = /^-[0-9]+/;
83
+ console.log(a, b, rest.join(","), x, z);
84
+ console.log(Color.Red, Color.Green, Color.Blue, Color[5]);
85
+ console.log(re.test("-42abc"), re.test("nope"));
86
+ try { throw new Error("boom"); } catch (e) { console.log(e.name + ": " + e.message); }
87
+ `;
88
+ expect(runProgram(source)).toBe("1 7 3,4 5 9\n0 5 6 Green\ntrue false\nError: boom");
89
+ });
90
+ it("supports destructuring assignments", () => {
91
+ const source = `
92
+ let a = 1, b = 2;
93
+ [a, b] = [b, a];
94
+ console.log(a, b);
95
+
96
+ let c = 0, d = 0, rest: number[] = [];
97
+ [c, d = 5, ...rest] = [10, undefined, 30, 40];
98
+ console.log(c, d, rest.join(","));
99
+
100
+ let x = 0, y = 0;
101
+ [[x], [y]] = [[100], [200]];
102
+ let p = 0, q = 0, r = 0;
103
+ ({ p, q = 9, p: r } = { q: 7, p: 8 });
104
+ console.log(x, y, p, q, r);
105
+
106
+ const target = { v: 0 } as any;
107
+ const list = [0, 0];
108
+ [target.v, list[0]] = [5, 6];
109
+ console.log(target.v, list[0]);
110
+
111
+ const pairs = [[1, 2], [3, 4]];
112
+ let u = 0, v = 0;
113
+ for ([u, v] of pairs) console.log(u, v);
114
+ for (const [f, s] of pairs) console.log(f + s);
115
+ `;
116
+ expect(runProgram(source)).toBe("2 1\n10 5 30,40\n100 200 8 7 8\n5 6\n1 2\n3 4\n3\n7");
117
+ });
118
+ it("supports destructuring parameters", () => {
119
+ const source = `
120
+ const pairs = [["a", 1], ["b", 2]];
121
+ const mapped = pairs.map(([name, value]) => [name, { value }]);
122
+ console.log(mapped[0][0], mapped[1][0]);
123
+ console.log(mapped[0][1].value, mapped[1][1].value);
124
+
125
+ function sum([a, b]: [number, number]) { return a + b; }
126
+ console.log(sum([3, 4]));
127
+
128
+ function greet({ name, greeting = "Hello" }: { name: string; greeting?: string }) {
129
+ return greeting + ", " + name;
130
+ }
131
+ console.log(greet({ name: "Ada" }), greet({ name: "Bob", greeting: "Hi" }));
132
+
133
+ const withDefault = ([a, b] = [10, 20]) => a + b;
134
+ console.log(withDefault(), withDefault([1, 2]));
135
+ `;
136
+ expect(runProgram(source)).toBe("a b\n1 2\n7\nHello, Ada Hi, Bob\n30 3");
137
+ });
138
+ it("supports Function.prototype.call, apply and bind", () => {
139
+ const source = `
140
+ function add(a: number, b: number): number { return a + b; }
141
+ console.log(add.call(null, 1, 2), add.apply(null, [5, 6]));
142
+
143
+ const obj = {
144
+ base: 10,
145
+ sum(a: number, b: number): number { return this.base + a + b; },
146
+ };
147
+ console.log(obj.sum.call(obj, 1, 2), obj.sum.apply(obj, [3, 4]));
148
+
149
+ const bound = obj.sum.bind(obj, 1);
150
+ console.log(bound(2));
151
+ const bound2 = add.bind(null, 10);
152
+ console.log(bound2(5));
153
+
154
+ class Greeter {
155
+ prefix = "hi";
156
+ greet(name: string): string { return this.prefix + " " + name; }
157
+ }
158
+ const g = new Greeter();
159
+ console.log(g.greet.call(g, "ada"), g.greet.bind(g)("cy"));
160
+ `;
161
+ expect(runProgram(source)).toBe("3 11\n13 17\n13\n15\nhi ada hi cy");
162
+ });
163
+ it("supports object-literal getters and setters", () => {
164
+ const source = `
165
+ const obj = {
166
+ _x: 0,
167
+ get x(): number { return this._x; },
168
+ set x(v: number) { this._x = v * 2; },
169
+ get double(): number { return this._x * 2; },
170
+ method(a: number, b: number) { return a + b; },
171
+ };
172
+ obj.x = 5;
173
+ console.log(obj.x, obj.double);
174
+ console.log(obj.method(2, 3));
175
+ console.log(Object.keys(obj).join(","));
176
+
177
+ const base = 7;
178
+ const o2 = { base, get next() { return base + 1; } };
179
+ console.log(o2.base, o2.next);
180
+
181
+ const o3 = { get ["dyn" + "amic"]() { return 42; } };
182
+ console.log(o3.dynamic);
183
+ `;
184
+ expect(runProgram(source)).toBe("10 20\n5\n_x,x,double,method\n7 8\n42");
185
+ });
186
+ it("supports first-class built-in method values", () => {
187
+ const source = `
188
+ const arr = [1, 2, 3];
189
+ console.log(typeof arr.map, arr.map.name, arr.map.length);
190
+ console.log(arr.map?.((x: number) => x * 2).join(","));
191
+
192
+ const text = "abc";
193
+ console.log(typeof text.slice, text.slice(1), text.split?.("").join("-"));
194
+
195
+ const obj = { base: 10, add(n: number) { return this.base + n; } };
196
+ console.log(obj.add?.(5));
197
+
198
+ const detached = arr.map;
199
+ try {
200
+ (detached as any)((x: number) => x);
201
+ console.log("no throw");
202
+ } catch (e) {
203
+ console.log("threw");
204
+ }
205
+ `;
206
+ expect(runProgram(source)).toBe("function map 1\n2,4,6\nfunction bc a-b-c\n15\nthrew");
207
+ });
208
+ it("calls functions through computed and indexed element access", () => {
209
+ const source = `
210
+ const fns = [(n: number) => n + 1, (n: number) => n * 2];
211
+ console.log(fns[0](10), fns[1](10));
212
+ let total = 0;
213
+ for (let i = 0; i < fns.length; i++) total += fns[i](3);
214
+ const table: any = { a: () => "A", b: () => "B" };
215
+ const key = "b";
216
+ console.log(total, table[key]());
217
+ `;
218
+ expect(runProgram(source)).toBe("11 20\n10 B");
219
+ });
220
+ it("supports the Error family as first-class constructors", () => {
221
+ const source = `
222
+ console.log(typeof Error, typeof TypeError, typeof AggregateError);
223
+ console.log(new Error("a") instanceof Error);
224
+ console.log(new TypeError("b") instanceof TypeError);
225
+ console.log(new TypeError("b") instanceof Error);
226
+ console.log(new RangeError("c") instanceof TypeError);
227
+ const e = new Error("boom");
228
+ console.log(String(e), e.toString(), e.name, e.message);
229
+
230
+ class MyErr extends Error {
231
+ constructor(m: string) { super(m); this.name = "MyErr"; }
232
+ }
233
+ const m = new MyErr("m");
234
+ console.log(m.name, m.message, m instanceof MyErr, m instanceof Error);
235
+
236
+ class CustomRange extends RangeError {}
237
+ const r = new CustomRange("too big");
238
+ console.log(r.name, r.message, r instanceof RangeError, r instanceof Error);
239
+
240
+ const agg = new AggregateError([1, 2], "all failed");
241
+ console.log(agg.name, agg.message, JSON.stringify(agg.errors), agg instanceof Error);
242
+
243
+ Promise.any([Promise.reject("x"), Promise.reject("y")]).catch((reason) => {
244
+ const err = reason as { name: string; errors: unknown[] };
245
+ console.log(err.name, JSON.stringify(err.errors));
246
+ });
247
+ `;
248
+ expect(runProgram(source)).toBe("function function function\ntrue\ntrue\ntrue\nfalse\n" +
249
+ "Error: boom Error: boom Error boom\n" +
250
+ "MyErr m true true\nRangeError too big true true\n" +
251
+ "AggregateError all failed [1,2] true\nAggregateError [\"x\",\"y\"]");
252
+ });
253
+ it("supports generator functions", () => {
254
+ const source = `
255
+ function* nums() { yield 1; yield 2; yield 3; }
256
+ const g = nums();
257
+ console.log(typeof nums, g.next().value, g.next().value, g.next().value);
258
+ console.log(JSON.stringify(g.next()));
259
+
260
+ function* counter(start: number) {
261
+ let x = start;
262
+ while (true) {
263
+ const step = yield x;
264
+ x = step === undefined ? x + 1 : step;
265
+ }
266
+ }
267
+ const c = counter(10);
268
+ console.log(c.next().value, c.next().value, c.next(100).value, c.next().value);
269
+
270
+ class Box {
271
+ private n = 0;
272
+ *gen(): Generator<number> { yield this.n++; yield this.n++; }
273
+ }
274
+ const box = new Box();
275
+ console.log([...box.gen()].join(","), [...box.gen()].join(","));
276
+
277
+ function* inner() { yield 1; yield 2; }
278
+ function* outer() { yield* inner(); yield 9; }
279
+ console.log([...outer()].join("-"), [...outer()].join("-"));
280
+
281
+ function* echo() { const a = yield "first"; const b = yield a; return b; }
282
+ const e = echo();
283
+ console.log(e.next().value, e.next("A").value, JSON.stringify(e.next("B")));
284
+
285
+ function* guarded() {
286
+ try { yield "x"; } catch (err) { yield "caught:" + (err as Error).message; }
287
+ yield "end";
288
+ }
289
+ const t = guarded();
290
+ console.log(t.next().value, t.throw(new Error("E")).value, t.next().value);
291
+
292
+ function* once() { yield 1; }
293
+ const o = once();
294
+ o.next();
295
+ console.log(JSON.stringify(o.next()), typeof o);
296
+
297
+ function* naturals() { let i = 0; while (true) yield i++; }
298
+ const seen: number[] = [];
299
+ for (const v of naturals()) { if (v >= 3) break; seen.push(v); }
300
+ console.log(seen.join(","));
301
+ `;
302
+ expect(runProgram(source)).toBe("function 1 2 3\n{\"done\":true}\n10 11 100 101\n0,1 2,3\n" +
303
+ "1-2-9 1-2-9\nfirst A {\"value\":\"B\",\"done\":true}\n" +
304
+ "x caught:E end\n{\"done\":true} object\n0,1,2");
305
+ });
306
+ it("supports symbols and the well-known symbol protocol", () => {
307
+ const source = `
308
+ const a = Symbol("desc");
309
+ const b = Symbol("desc");
310
+ console.log(typeof Symbol, typeof a, a === a, a === b);
311
+ console.log(a.toString(), String(a), a.description, String(Symbol()));
312
+ console.log(String(Symbol.iterator), typeof Symbol.iterator);
313
+
314
+ const holder: Record<string, unknown> = {};
315
+ (holder as any)[a] = 1;
316
+ (holder as any)[b] = 2;
317
+ holder.x = 3;
318
+ console.log(Object.keys(holder).join(","));
319
+ console.log(Object.getOwnPropertySymbols(holder).length);
320
+ console.log((holder as any)[a], (holder as any)[b], (holder as any)[Symbol("desc")]);
321
+ console.log(JSON.stringify(holder), JSON.stringify(a), JSON.stringify([a, 1]));
322
+ console.log(holder);
323
+
324
+ const reg = Symbol.for("shared");
325
+ console.log(reg === Symbol.for("shared"), Symbol.keyFor(reg), Symbol.keyFor(a));
326
+
327
+ class Range {
328
+ start: number;
329
+ end: number;
330
+ constructor(start: number, end: number) {
331
+ this.start = start;
332
+ this.end = end;
333
+ }
334
+ [Symbol.iterator]() {
335
+ let i = this.start;
336
+ const end = this.end;
337
+ return {
338
+ next() {
339
+ return i < end ? { value: i++, done: false } : { value: undefined, done: true };
340
+ },
341
+ };
342
+ }
343
+ }
344
+ console.log([...new Range(1, 4)].join(","));
345
+ const walked: number[] = [];
346
+ for (const x of new Range(10, 13)) walked.push(x);
347
+ console.log(walked.join(","));
348
+
349
+ function* delegates() { yield* new Range(5, 7); }
350
+ console.log([...delegates()].join(","));
351
+ `;
352
+ expect(runProgram(source)).toBe("function symbol true false\n" +
353
+ "Symbol(desc) Symbol(desc) desc Symbol()\n" +
354
+ "Symbol(Symbol.iterator) symbol\n" +
355
+ "x\n2\n1 2 undefined\n" +
356
+ '{"x":3} undefined [null,1]\n' +
357
+ "{ x: 3, Symbol(desc): 1, Symbol(desc): 2 }\n" +
358
+ "true shared undefined\n" +
359
+ "1,2,3\n10,11,12\n5,6");
360
+ });
361
+ });
362
+ //# sourceMappingURL=compile-objects-classes.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compile-objects-classes.test.js","sourceRoot":"","sources":["../../../tests/e2e/compile-objects-classes.test.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,WAAW,CAAC,2CAA2C,EAAE,CAAC,OAAO,EAAE,EAAE;IACnE,MAAM,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;IAE/B,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,MAAM,GAAG;;;;;;;;;;KAUd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;KAuBd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;KAwBd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,MAAM,GAAG;;;;;;;;;KASd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B,mDAAmD,CACpD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;KAwBd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B,qDAAqD,CACtD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;KAgBd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B,uCAAuC,CACxC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;KAqBd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B,mCAAmC,CACpC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;KAmBd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B,uCAAuC,CACxC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;KAkBd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B,qDAAqD,CACtD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,MAAM,GAAG;;;;;;;;KAQd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;KA0Bd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B,uDAAuD;YACrD,sCAAsC;YACtC,mDAAmD;YACnD,oEAAoE,CACvE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;QACtC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+Cd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B,2DAA2D;YACzD,wDAAwD;YACxD,+CAA+C,CAClD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA4Cd,CAAC;QACF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAC7B,8BAA8B;YAC5B,2CAA2C;YAC3C,kCAAkC;YAClC,uBAAuB;YACvB,8BAA8B;YAC9B,8CAA8C;YAC9C,yBAAyB;YACzB,sBAAsB,CACzB,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shared helpers for the differential suites: register one case per program and
3
+ * build programs that print canonical `JSON.stringify` output.
4
+ */
5
+ import type { E2EHarness } from "./harness.js";
6
+ export interface DifferentialKit {
7
+ /** Register one differential case from a complete program source. */
8
+ diff(name: string, source: string): void;
9
+ /** Wrap a list of expressions so each is printed as a `JSON.stringify` line. */
10
+ printAll(values: string[]): string;
11
+ }
12
+ export declare function makeDifferential(harness: E2EHarness): DifferentialKit;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Shared helpers for the differential suites: register one case per program and
3
+ * build programs that print canonical `JSON.stringify` output.
4
+ */
5
+ import { it } from "vitest";
6
+ export function makeDifferential(harness) {
7
+ const diff = (name, source) => {
8
+ it(name, () => {
9
+ harness.expectSameOutputAsNode(source, { name: `diff_${name.replace(/\W+/g, "_")}` });
10
+ });
11
+ };
12
+ const printAll = (values) => `const values: unknown[] = [\n${values.map((v) => ` ${v},`).join("\n")}\n];\n` +
13
+ `for (const v of values) console.log(JSON.stringify(v));\n`;
14
+ return { diff, printAll };
15
+ }
16
+ //# sourceMappingURL=differential-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"differential-helpers.js","sourceRoot":"","sources":["../../../tests/e2e/differential-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAU5B,MAAM,UAAU,gBAAgB,CAAC,OAAmB;IAClD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,MAAc,EAAQ,EAAE;QAClD,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE;YACZ,OAAO,CAAC,sBAAsB,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;QACxF,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,MAAgB,EAAU,EAAE,CAC5C,gCAAgC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ;QAC/E,2DAA2D,CAAC;IAE9D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Differential tests for control flow, classes, regexes, generators and function semantics.
3
+ */
4
+ export {};