@nudojs/core 0.3.0 → 0.3.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.
- package/dist/chunk-BU4A6XJ3.js +6856 -0
- package/dist/exec.d.ts +2 -0
- package/dist/exec.js +168 -0
- package/dist/index-CVYjXnwU.d.ts +902 -0
- package/dist/index.d.ts +64 -710
- package/dist/index.js +3258 -8426
- package/package.json +18 -5
- package/CHANGELOG.md +0 -34
- package/src/__tests__/environment.test.ts +0 -48
- package/src/__tests__/fn-sig-impl.test.ts +0 -57
- package/src/__tests__/ops-refined.test.ts +0 -196
- package/src/__tests__/ops.test.ts +0 -84
- package/src/__tests__/type-value-phase2.test.ts +0 -117
- package/src/__tests__/type-value-phase3.test.ts +0 -94
- package/src/__tests__/type-value-refined.test.ts +0 -210
- package/src/__tests__/type-value.test.ts +0 -319
- package/src/algebra/__tests__/abs-native.test.ts +0 -176
- package/src/algebra/__tests__/arithmetic.test.ts +0 -170
- package/src/algebra/__tests__/ast-eval.test.ts +0 -154
- package/src/algebra/__tests__/bridge.test.ts +0 -160
- package/src/algebra/__tests__/call-budget.test.ts +0 -117
- package/src/algebra/__tests__/check-case-consistency.test.ts +0 -69
- package/src/algebra/__tests__/check-gold.test.ts +0 -290
- package/src/algebra/__tests__/check-json.test.ts +0 -57
- package/src/algebra/__tests__/check-mini-repo.test.ts +0 -49
- package/src/algebra/__tests__/check-real-commander.test.ts +0 -43
- package/src/algebra/__tests__/check-real-packages.test.ts +0 -165
- package/src/algebra/__tests__/check-recall-gold.test.ts +0 -1024
- package/src/algebra/__tests__/check-require-dep-memo.test.ts +0 -45
- package/src/algebra/__tests__/check-return-contract.test.ts +0 -90
- package/src/algebra/__tests__/check-shape-gold.test.ts +0 -303
- package/src/algebra/__tests__/check-source-memo.test.ts +0 -204
- package/src/algebra/__tests__/check.test.ts +0 -69
- package/src/algebra/__tests__/denote.test.ts +0 -77
- package/src/algebra/__tests__/diagnostics.test.ts +0 -64
- package/src/algebra/__tests__/differential.test.ts +0 -124
- package/src/algebra/__tests__/div-mod.test.ts +0 -38
- package/src/algebra/__tests__/example0.test.ts +0 -103
- package/src/algebra/__tests__/exec-analyze-throws.test.ts +0 -60
- package/src/algebra/__tests__/exec-async.test.ts +0 -46
- package/src/algebra/__tests__/exec-bpath.test.ts +0 -193
- package/src/algebra/__tests__/exec-class.test.ts +0 -56
- package/src/algebra/__tests__/exec-e2e.test.ts +0 -97
- package/src/algebra/__tests__/exec-generator.test.ts +0 -53
- package/src/algebra/__tests__/exec-inherit-default.test.ts +0 -111
- package/src/algebra/__tests__/exec-optional-nested.test.ts +0 -87
- package/src/algebra/__tests__/exec-rest.test.ts +0 -55
- package/src/algebra/__tests__/exec-spread-forof.test.ts +0 -85
- package/src/algebra/__tests__/exec-static-computed.test.ts +0 -61
- package/src/algebra/__tests__/exec-switch.test.ts +0 -74
- package/src/algebra/__tests__/exec-trycatch.test.ts +0 -71
- package/src/algebra/__tests__/fn-fp-memo.test.ts +0 -166
- package/src/algebra/__tests__/fn-fp-multidecl.test.ts +0 -49
- package/src/algebra/__tests__/format.test.ts +0 -34
- package/src/algebra/__tests__/generalize-memo.test.ts +0 -285
- package/src/algebra/__tests__/generalize.test.ts +0 -113
- package/src/algebra/__tests__/hash-source.test.ts +0 -19
- package/src/algebra/__tests__/hof.test.ts +0 -80
- package/src/algebra/__tests__/inlay.test.ts +0 -30
- package/src/algebra/__tests__/language.test.ts +0 -77
- package/src/algebra/__tests__/leq.test.ts +0 -109
- package/src/algebra/__tests__/load-deps-fp-memo.test.ts +0 -132
- package/src/algebra/__tests__/methods.test.ts +0 -37
- package/src/algebra/__tests__/node-types.test.ts +0 -26
- package/src/algebra/__tests__/nudo-constraints.ts +0 -46
- package/src/algebra/__tests__/objects.test.ts +0 -117
- package/src/algebra/__tests__/parse-source-cache.test.ts +0 -42
- package/src/algebra/__tests__/refine-import.test.ts +0 -109
- package/src/algebra/__tests__/stable-source-key-block.test.ts +0 -23
- package/src/algebra/__tests__/stable-source-key.test.ts +0 -31
- package/src/algebra/__tests__/surface.test.ts +0 -41
- package/src/algebra/__tests__/this-inherit.test.ts +0 -130
- package/src/algebra/abs-fn.ts +0 -49
- package/src/algebra/abs-modules.ts +0 -139
- package/src/algebra/abs.ts +0 -206
- package/src/algebra/arithmetic.ts +0 -691
- package/src/algebra/ast-eval.ts +0 -1763
- package/src/algebra/bridge.ts +0 -350
- package/src/algebra/builtins.ts +0 -373
- package/src/algebra/check-report.ts +0 -150
- package/src/algebra/check.ts +0 -1867
- package/src/algebra/constraint.ts +0 -304
- package/src/algebra/denote.ts +0 -166
- package/src/algebra/diagnostics.ts +0 -210
- package/src/algebra/exec/call.ts +0 -29
- package/src/algebra/exec/calls.ts +0 -96
- package/src/algebra/exec/class-registry.ts +0 -29
- package/src/algebra/exec/class.ts +0 -329
- package/src/algebra/exec/index.ts +0 -6
- package/src/algebra/exec/member-diag.ts +0 -141
- package/src/algebra/exec/run.ts +0 -341
- package/src/algebra/exec/runtime.ts +0 -583
- package/src/algebra/exec/transpile.ts +0 -993
- package/src/algebra/fn-fp.ts +0 -294
- package/src/algebra/format.ts +0 -91
- package/src/algebra/generalize.ts +0 -776
- package/src/algebra/hash-source.ts +0 -27
- package/src/algebra/index.ts +0 -34
- package/src/algebra/inlay.ts +0 -198
- package/src/algebra/language.ts +0 -289
- package/src/algebra/leak.ts +0 -68
- package/src/algebra/leq.ts +0 -301
- package/src/algebra/load-deps-fp.ts +0 -97
- package/src/algebra/methods.ts +0 -128
- package/src/algebra/objects.ts +0 -251
- package/src/algebra/parse-source.ts +0 -64
- package/src/algebra/phi.ts +0 -42
- package/src/algebra/pred.ts +0 -395
- package/src/algebra/refine.ts +0 -227
- package/src/algebra/stable-source-key.ts +0 -81
- package/src/algebra/surface.ts +0 -206
- package/src/algebra/template.ts +0 -143
- package/src/algebra/term.ts +0 -119
- package/src/environment.ts +0 -74
- package/src/index.ts +0 -73
- package/src/mock-helpers.ts +0 -166
- package/src/ops.ts +0 -191
- package/src/refinements/range.ts +0 -86
- package/src/refinements/template-predicates.ts +0 -11
- package/src/refinements/template.ts +0 -176
- package/src/strip-types.ts +0 -236
- package/src/type-value.ts +0 -513
- package/tsconfig.json +0 -8
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
$add,
|
|
4
|
-
$lt,
|
|
5
|
-
$lit,
|
|
6
|
-
$fork,
|
|
7
|
-
$for,
|
|
8
|
-
$forIter,
|
|
9
|
-
$obj,
|
|
10
|
-
$get,
|
|
11
|
-
$set,
|
|
12
|
-
$while,
|
|
13
|
-
$whileSeq,
|
|
14
|
-
num,
|
|
15
|
-
numVar,
|
|
16
|
-
litValue,
|
|
17
|
-
absToString,
|
|
18
|
-
transpile,
|
|
19
|
-
} from "@nudojs/core";
|
|
20
|
-
|
|
21
|
-
describe("B-path runtime ops", () => {
|
|
22
|
-
it("add(lit, lit) stays exact literal", () => {
|
|
23
|
-
const r = $add($lit(1), $lit(3));
|
|
24
|
-
expect(litValue(r)).toBe(4);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("add(number, lit) is number", () => {
|
|
28
|
-
const r = $add(num(), $lit(1));
|
|
29
|
-
expect(r.shape.k).toBe("prim");
|
|
30
|
-
if (r.shape.k === "prim") expect(r.shape.type).toBe("number");
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("add(var, lit) keeps term identity", () => {
|
|
34
|
-
const r = $add(numVar("x"), $lit(1));
|
|
35
|
-
expect(r.term?.op).toBe("app");
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
describe("B-path $fork", () => {
|
|
40
|
-
it("literal true takes consequent only", () => {
|
|
41
|
-
const r = $fork($lit(true), () => $lit(1), () => $lit(2));
|
|
42
|
-
expect(litValue(r)).toBe(1);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it("literal false takes alternate only", () => {
|
|
46
|
-
const r = $fork($lit(false), () => $lit(1), () => $lit(2));
|
|
47
|
-
expect(litValue(r)).toBe(2);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("abstract boolean joins both branches", () => {
|
|
51
|
-
const cond = {
|
|
52
|
-
shape: { k: "prim" as const, type: "boolean" as const },
|
|
53
|
-
conf: "exact" as const,
|
|
54
|
-
};
|
|
55
|
-
const r = $fork(cond, () => $lit(1), () => $lit(2));
|
|
56
|
-
expect(litValue(r)).toBeUndefined();
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe("B-path $for (bounded)", () => {
|
|
61
|
-
it("concrete trip count: i goes 0→3", () => {
|
|
62
|
-
const r = $for(
|
|
63
|
-
$lit(0),
|
|
64
|
-
(s) => $lt(s, $lit(3)),
|
|
65
|
-
(s) => $add(s, $lit(1)),
|
|
66
|
-
(s) => s,
|
|
67
|
-
8,
|
|
68
|
-
);
|
|
69
|
-
expect(litValue(r)).toBe(3);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it("abstract bound terminates within budget", () => {
|
|
73
|
-
const n = num();
|
|
74
|
-
const r = $for(
|
|
75
|
-
$lit(0),
|
|
76
|
-
(s) => $lt(s, n),
|
|
77
|
-
(s) => $add(s, $lit(1)),
|
|
78
|
-
(s) => s,
|
|
79
|
-
4,
|
|
80
|
-
);
|
|
81
|
-
expect(r).toBeDefined();
|
|
82
|
-
expect(r.conf).not.toBe("opaque");
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("generator yields at most maxIters", () => {
|
|
86
|
-
const states = [
|
|
87
|
-
...$forIter(
|
|
88
|
-
$lit(0),
|
|
89
|
-
() => $lit(true),
|
|
90
|
-
(s) => $add(s, $lit(1)),
|
|
91
|
-
(s) => s,
|
|
92
|
-
5,
|
|
93
|
-
),
|
|
94
|
-
];
|
|
95
|
-
expect(states.length).toBe(5);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
describe("B-path objects", () => {
|
|
100
|
-
it("$get reads slots; miss is undefined", () => {
|
|
101
|
-
const o = $obj({ id: $lit(1), name: $lit("Ada") });
|
|
102
|
-
expect(litValue($get(o, "id"))).toBe(1);
|
|
103
|
-
expect(litValue($get(o, "name"))).toBe("Ada");
|
|
104
|
-
expect(litValue($get(o, "missing"))).toBeUndefined();
|
|
105
|
-
expect(absToString($get(o, "missing"))).toContain("undefined");
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it("$set returns new object with updated slot", () => {
|
|
109
|
-
const o = $obj({ id: $lit(1) });
|
|
110
|
-
const o2 = $set(o, "id", $lit(2));
|
|
111
|
-
expect(litValue($get(o, "id"))).toBe(1);
|
|
112
|
-
expect(litValue($get(o2, "id"))).toBe(2);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
describe("B-path $while", () => {
|
|
117
|
-
it("concrete countdown", () => {
|
|
118
|
-
const r = $while(
|
|
119
|
-
$obj({ i: $lit(3), acc: $lit(0) }),
|
|
120
|
-
(s) => $lt($lit(0), $get(s, "i")),
|
|
121
|
-
(s) => $set($set(s, "acc", $add($get(s, "acc"), $get(s, "i"))), "i", $lit(0)),
|
|
122
|
-
8,
|
|
123
|
-
);
|
|
124
|
-
// i>0 false immediately after first step sets i=0... actually first test 0<3 true
|
|
125
|
-
// step: acc=0+3=3, i=0 → next test 0<0 false → exit {i:0, acc:3}
|
|
126
|
-
expect(litValue($get(r, "acc"))).toBe(3);
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it("$whileSeq runs body while test true", () => {
|
|
130
|
-
let i = $lit(0);
|
|
131
|
-
const hits: number[] = [];
|
|
132
|
-
$whileSeq(
|
|
133
|
-
() => $lt(i, $lit(3)),
|
|
134
|
-
() => {
|
|
135
|
-
hits.push(litValue(i) as number);
|
|
136
|
-
i = $add(i, $lit(1));
|
|
137
|
-
},
|
|
138
|
-
8,
|
|
139
|
-
);
|
|
140
|
-
expect(hits).toEqual([0, 1, 2]);
|
|
141
|
-
expect(litValue(i)).toBe(3);
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
describe("B-path transpile", () => {
|
|
146
|
-
it("rewrites + to $add", () => {
|
|
147
|
-
const out = transpile(`function add(a, b) { return a + b; }`, {
|
|
148
|
-
runtimeImport: "@nudojs/core/exec",
|
|
149
|
-
});
|
|
150
|
-
expect(out).toContain("$add(a, b)");
|
|
151
|
-
expect(out).not.toMatch(/return a \+ b/);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it("rewrites if to $fork", () => {
|
|
155
|
-
const out = transpile(`function f(x) { if (x > 0) { return 1; } return 2; }`, {
|
|
156
|
-
runtimeImport: "@nudojs/core/exec",
|
|
157
|
-
});
|
|
158
|
-
expect(out).toContain("$fork(");
|
|
159
|
-
expect(out).toContain("$gt(");
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it("emits $for for classic counting loops", () => {
|
|
163
|
-
const out = transpile(
|
|
164
|
-
`function sum(n) { let i = 0; for (let i = 0; i < n; i = i + 1) {} return i; }`,
|
|
165
|
-
{ runtimeImport: "@nudojs/core/exec", maxLoopIters: 4 },
|
|
166
|
-
);
|
|
167
|
-
expect(out).toContain("$for(");
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it("rewrites object literal and member access", () => {
|
|
171
|
-
const out = transpile(
|
|
172
|
-
`function make() { const o = { id: 1, name: "x" }; return o.id; }`,
|
|
173
|
-
{ runtimeImport: "@nudojs/core/exec" },
|
|
174
|
-
);
|
|
175
|
-
expect(out).toContain("$obj(");
|
|
176
|
-
expect(out).toContain('$get(o, "id")');
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it("rewrites while to $whileSeq", () => {
|
|
180
|
-
const out = transpile(
|
|
181
|
-
`function f(n) { let i = 0; while (i < n) { i = i + 1; } return i; }`,
|
|
182
|
-
{ runtimeImport: "@nudojs/core/exec", maxLoopIters: 5 },
|
|
183
|
-
);
|
|
184
|
-
expect(out).toContain("$whileSeq(");
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it("rewrites obj.field = v to $set", () => {
|
|
188
|
-
const out = transpile(`function f() { const o = { a: 1 }; o.a = 2; return o; }`, {
|
|
189
|
-
runtimeImport: "@nudojs/core/exec",
|
|
190
|
-
});
|
|
191
|
-
expect(out).toContain("$set(");
|
|
192
|
-
});
|
|
193
|
-
});
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
runTranspiled,
|
|
4
|
-
callTranspiledExportFull,
|
|
5
|
-
$lit,
|
|
6
|
-
litValue,
|
|
7
|
-
absToString,
|
|
8
|
-
} from "@nudojs/core";
|
|
9
|
-
|
|
10
|
-
describe("B-path class / this", () => {
|
|
11
|
-
it("constructor writes fields; method reads this", () => {
|
|
12
|
-
const src = `
|
|
13
|
-
class Point {
|
|
14
|
-
constructor(x, y) {
|
|
15
|
-
this.x = x;
|
|
16
|
-
this.y = y;
|
|
17
|
-
}
|
|
18
|
-
sum() {
|
|
19
|
-
return this.x + this.y;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
export function go() {
|
|
23
|
-
const p = new Point(1, 2);
|
|
24
|
-
return p.sum();
|
|
25
|
-
}
|
|
26
|
-
`;
|
|
27
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
28
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
29
|
-
expect(litValue(r.result)).toBe(3);
|
|
30
|
-
expect(absToString(r.result)).toContain("3");
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("new + field access", () => {
|
|
34
|
-
const src = `
|
|
35
|
-
class Box {
|
|
36
|
-
constructor(v) { this.v = v; }
|
|
37
|
-
}
|
|
38
|
-
export function get() {
|
|
39
|
-
const b = new Box(9);
|
|
40
|
-
return b.v;
|
|
41
|
-
}
|
|
42
|
-
`;
|
|
43
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
44
|
-
const r = callTranspiledExportFull(exports, "get", []);
|
|
45
|
-
expect(litValue(r.result)).toBe(9);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("transpiles class to $class", async () => {
|
|
49
|
-
const { transpile } = await import("@nudojs/core");
|
|
50
|
-
const out = transpile(`class A { constructor(x) { this.x = x; } m() { return this.x; } }
|
|
51
|
-
export function go() { const a = new A(1); return a.m(); }`);
|
|
52
|
-
expect(out).toContain("$class(");
|
|
53
|
-
expect(out).toContain("$new(");
|
|
54
|
-
expect(out).toContain("$invoke(");
|
|
55
|
-
});
|
|
56
|
-
});
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, afterAll } from "vitest";
|
|
2
|
-
import { mkdtempSync, writeFileSync, rmSync, mkdirSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join, dirname } from "node:path";
|
|
5
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
|
-
import { transpile, litValue, absToString, $lit, $arr, $idx, $len, $get, $obj } from "@nudojs/core";
|
|
7
|
-
|
|
8
|
-
const dirs: string[] = [];
|
|
9
|
-
afterAll(() => {
|
|
10
|
-
for (const d of dirs) rmSync(d, { recursive: true, force: true });
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
const runtimeUrl = pathToFileURL(
|
|
14
|
-
join(dirname(fileURLToPath(import.meta.url)), "../exec/runtime.ts"),
|
|
15
|
-
).href;
|
|
16
|
-
|
|
17
|
-
/** transpile 后写盘并动态 import(真 Node 执行 B 路径程序) */
|
|
18
|
-
async function execTranspiled(source: string, exportName: string) {
|
|
19
|
-
const dir = mkdtempSync(join(tmpdir(), "nudo-bpath-e2e-"));
|
|
20
|
-
dirs.push(dir);
|
|
21
|
-
// 指向 monorepo 内 runtime,vitest/node 均可解析 .ts
|
|
22
|
-
const js = transpile(source, { runtimeImport: runtimeUrl });
|
|
23
|
-
const modPath = join(dir, "mod.mjs");
|
|
24
|
-
writeFileSync(modPath, js, "utf-8");
|
|
25
|
-
const mod = await import(pathToFileURL(modPath).href);
|
|
26
|
-
return mod[exportName] as (...args: unknown[]) => unknown;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
describe("B-path e2e (transpile + Node import)", () => {
|
|
30
|
-
it("add executes on Abs literals", async () => {
|
|
31
|
-
const add = await execTranspiled(
|
|
32
|
-
`export function add(a, b) { return a + b; }`,
|
|
33
|
-
"add",
|
|
34
|
-
);
|
|
35
|
-
const r = add($lit(2), $lit(40)) as ReturnType<typeof $lit>;
|
|
36
|
-
expect(litValue(r)).toBe(42);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("array literal + index + length", async () => {
|
|
40
|
-
const run = await execTranspiled(
|
|
41
|
-
`export function run() {
|
|
42
|
-
const a = [1, 2, 3];
|
|
43
|
-
const x = a[1];
|
|
44
|
-
const n = a.length;
|
|
45
|
-
return x + n;
|
|
46
|
-
}`,
|
|
47
|
-
"run",
|
|
48
|
-
);
|
|
49
|
-
const r = run() as ReturnType<typeof $lit>;
|
|
50
|
-
expect(litValue(r)).toBe(5); // 2 + 3
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("object destructure + member", async () => {
|
|
54
|
-
const run = await execTranspiled(
|
|
55
|
-
`export function run() {
|
|
56
|
-
const o = { id: 10, name: "a" };
|
|
57
|
-
const { id, name } = o;
|
|
58
|
-
return id + name;
|
|
59
|
-
}`,
|
|
60
|
-
"run",
|
|
61
|
-
);
|
|
62
|
-
const r = run() as ReturnType<typeof $lit>;
|
|
63
|
-
expect(absToString(r)).toContain("string"); // 10 + "a" → "10a"
|
|
64
|
-
expect(litValue(r)).toBe("10a");
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it("array destructure", async () => {
|
|
68
|
-
const run = await execTranspiled(
|
|
69
|
-
`export function run() {
|
|
70
|
-
const pair = [3, 4];
|
|
71
|
-
const [x, y] = pair;
|
|
72
|
-
return x * y;
|
|
73
|
-
}`,
|
|
74
|
-
"run",
|
|
75
|
-
);
|
|
76
|
-
const r = run() as ReturnType<typeof $lit>;
|
|
77
|
-
expect(litValue(r)).toBe(12);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
it("local function call + if/else", async () => {
|
|
81
|
-
const go = await execTranspiled(
|
|
82
|
-
`export function go(n) {
|
|
83
|
-
if (n > 0) { return n + 1; } else { return 0; }
|
|
84
|
-
}`,
|
|
85
|
-
"go",
|
|
86
|
-
);
|
|
87
|
-
expect(litValue(go($lit(1)) as never)).toBe(2);
|
|
88
|
-
expect(litValue(go($lit(-1)) as never)).toBe(0);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it("runtime array helpers", () => {
|
|
92
|
-
const a = $arr([$lit(1), $lit(2)]);
|
|
93
|
-
expect(litValue($idx(a, $lit(0)))).toBe(1);
|
|
94
|
-
expect(litValue($len(a))).toBe(2);
|
|
95
|
-
expect(litValue($get($obj({ k: $lit(1) }), "k"))).toBe(1);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
runTranspiled,
|
|
4
|
-
callTranspiledExportFull,
|
|
5
|
-
$lit,
|
|
6
|
-
litValue,
|
|
7
|
-
absToString,
|
|
8
|
-
transpile,
|
|
9
|
-
} from "@nudojs/core";
|
|
10
|
-
|
|
11
|
-
describe("B-path generators", () => {
|
|
12
|
-
it("function* collects yields into tuple", () => {
|
|
13
|
-
const src = `
|
|
14
|
-
export function* gen() {
|
|
15
|
-
yield 1;
|
|
16
|
-
yield 2;
|
|
17
|
-
yield 3;
|
|
18
|
-
}
|
|
19
|
-
export function go() {
|
|
20
|
-
const xs = gen();
|
|
21
|
-
return xs[0] + xs[1] + xs[2];
|
|
22
|
-
}
|
|
23
|
-
`;
|
|
24
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
25
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
26
|
-
expect(litValue(r.result)).toBe(6);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it("for-of over generator", () => {
|
|
30
|
-
const src = `
|
|
31
|
-
export function* nums() {
|
|
32
|
-
yield 1;
|
|
33
|
-
yield 2;
|
|
34
|
-
}
|
|
35
|
-
export function sum() {
|
|
36
|
-
let t = 0;
|
|
37
|
-
for (const x of nums()) {
|
|
38
|
-
t = t + x;
|
|
39
|
-
}
|
|
40
|
-
return t;
|
|
41
|
-
}
|
|
42
|
-
`;
|
|
43
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
44
|
-
const r = callTranspiledExportFull(exports, "sum", []);
|
|
45
|
-
expect(litValue(r.result)).toBe(3);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("transpiles generator to $gen/$yield", () => {
|
|
49
|
-
const out = transpile(`export function* g() { yield 1; }`);
|
|
50
|
-
expect(out).toContain("$gen(");
|
|
51
|
-
expect(out).toContain("$yield(");
|
|
52
|
-
});
|
|
53
|
-
});
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
runTranspiled,
|
|
4
|
-
callTranspiledExportFull,
|
|
5
|
-
$lit,
|
|
6
|
-
$await,
|
|
7
|
-
litValue,
|
|
8
|
-
absToString,
|
|
9
|
-
} from "@nudojs/core";
|
|
10
|
-
|
|
11
|
-
describe("B-path inheritance / super", () => {
|
|
12
|
-
it("child inherits parent method", () => {
|
|
13
|
-
const src = `
|
|
14
|
-
class Base {
|
|
15
|
-
constructor(x) { this.x = x; }
|
|
16
|
-
get() { return this.x; }
|
|
17
|
-
}
|
|
18
|
-
class Child extends Base {
|
|
19
|
-
double() { return this.get() + this.get(); }
|
|
20
|
-
}
|
|
21
|
-
export function go() {
|
|
22
|
-
const c = new Child(5);
|
|
23
|
-
return c.double();
|
|
24
|
-
}
|
|
25
|
-
`;
|
|
26
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
27
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
28
|
-
expect(litValue(r.result)).toBe(10);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it("super() runs parent ctor", () => {
|
|
32
|
-
const src = `
|
|
33
|
-
class Base {
|
|
34
|
-
constructor(x) { this.x = x; }
|
|
35
|
-
}
|
|
36
|
-
class Child extends Base {
|
|
37
|
-
constructor(x, y) {
|
|
38
|
-
super(x);
|
|
39
|
-
this.y = y;
|
|
40
|
-
}
|
|
41
|
-
sum() { return this.x + this.y; }
|
|
42
|
-
}
|
|
43
|
-
export function go() {
|
|
44
|
-
const c = new Child(1, 2);
|
|
45
|
-
return c.sum();
|
|
46
|
-
}
|
|
47
|
-
`;
|
|
48
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
49
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
50
|
-
expect(litValue(r.result)).toBe(3);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("super.method() calls parent implementation", () => {
|
|
54
|
-
const src = `
|
|
55
|
-
class Base {
|
|
56
|
-
hello() { return "base"; }
|
|
57
|
-
}
|
|
58
|
-
class Child extends Base {
|
|
59
|
-
hello() { return super.hello() + "+child"; }
|
|
60
|
-
}
|
|
61
|
-
export function go() {
|
|
62
|
-
const c = new Child();
|
|
63
|
-
return c.hello();
|
|
64
|
-
}
|
|
65
|
-
`;
|
|
66
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
67
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
68
|
-
expect(litValue(r.result)).toBe("base+child");
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
describe("B-path destructure defaults", () => {
|
|
73
|
-
it("object default fills undefined", () => {
|
|
74
|
-
const src = `
|
|
75
|
-
export function go() {
|
|
76
|
-
const o = { a: 1 };
|
|
77
|
-
const { a, b = 99 } = o;
|
|
78
|
-
return a + b;
|
|
79
|
-
}
|
|
80
|
-
`;
|
|
81
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
82
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
83
|
-
expect(litValue(r.result)).toBe(100);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("object present value wins over default", () => {
|
|
87
|
-
const src = `
|
|
88
|
-
export function go() {
|
|
89
|
-
const o = { a: 5 };
|
|
90
|
-
const { a = 1 } = o;
|
|
91
|
-
return a;
|
|
92
|
-
}
|
|
93
|
-
`;
|
|
94
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
95
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
96
|
-
expect(litValue(r.result)).toBe(5);
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it("array default fills out-of-range", () => {
|
|
100
|
-
const src = `
|
|
101
|
-
export function go() {
|
|
102
|
-
const xs = [1];
|
|
103
|
-
const [a, b = 7] = xs;
|
|
104
|
-
return a + b;
|
|
105
|
-
}
|
|
106
|
-
`;
|
|
107
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
108
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
109
|
-
expect(litValue(r.result)).toBe(8);
|
|
110
|
-
});
|
|
111
|
-
});
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
runTranspiled,
|
|
4
|
-
callTranspiledExportFull,
|
|
5
|
-
$lit,
|
|
6
|
-
$obj,
|
|
7
|
-
$arr,
|
|
8
|
-
litValue,
|
|
9
|
-
absToString,
|
|
10
|
-
transpile,
|
|
11
|
-
} from "@nudojs/core";
|
|
12
|
-
|
|
13
|
-
describe("B-path optional chaining", () => {
|
|
14
|
-
it("a?.b short-circuits on nullish", () => {
|
|
15
|
-
const src = `
|
|
16
|
-
export function go(o) {
|
|
17
|
-
return o?.id;
|
|
18
|
-
}
|
|
19
|
-
`;
|
|
20
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
21
|
-
const ok = callTranspiledExportFull(exports, "go", [$obj({ id: $lit(7) })]);
|
|
22
|
-
expect(litValue(ok.result)).toBe(7);
|
|
23
|
-
const nil = callTranspiledExportFull(exports, "go", [$lit(null)]);
|
|
24
|
-
expect(litValue(nil.result)).toBeUndefined();
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it("a?.b.c chains", () => {
|
|
28
|
-
const src = `
|
|
29
|
-
export function go(o) {
|
|
30
|
-
return o?.user?.name;
|
|
31
|
-
}
|
|
32
|
-
`;
|
|
33
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
34
|
-
const ok = callTranspiledExportFull(exports, "go", [
|
|
35
|
-
$obj({ user: $obj({ name: $lit("Ada") }) }),
|
|
36
|
-
]);
|
|
37
|
-
expect(litValue(ok.result)).toBe("Ada");
|
|
38
|
-
const nil = callTranspiledExportFull(exports, "go", [$lit(null)]);
|
|
39
|
-
expect(litValue(nil.result)).toBeUndefined();
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it("transpiles optional member", () => {
|
|
43
|
-
const out = transpile(`export function f(o) { return o?.x; }`);
|
|
44
|
-
expect(out).toContain("$optionalGet(");
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
describe("B-path nested destructure", () => {
|
|
49
|
-
it("nested object pattern", () => {
|
|
50
|
-
const src = `
|
|
51
|
-
export function go() {
|
|
52
|
-
const o = { a: { b: 3 } };
|
|
53
|
-
const { a: { b } } = o;
|
|
54
|
-
return b;
|
|
55
|
-
}
|
|
56
|
-
`;
|
|
57
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
58
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
59
|
-
expect(litValue(r.result)).toBe(3);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("nested with default", () => {
|
|
63
|
-
const src = `
|
|
64
|
-
export function go() {
|
|
65
|
-
const o = { a: {} };
|
|
66
|
-
const { a: { b = 9 } } = o;
|
|
67
|
-
return b;
|
|
68
|
-
}
|
|
69
|
-
`;
|
|
70
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
71
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
72
|
-
expect(litValue(r.result)).toBe(9);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it("array of objects", () => {
|
|
76
|
-
const src = `
|
|
77
|
-
export function go() {
|
|
78
|
-
const xs = [{ v: 4 }];
|
|
79
|
-
const [{ v }] = xs;
|
|
80
|
-
return v;
|
|
81
|
-
}
|
|
82
|
-
`;
|
|
83
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
84
|
-
const r = callTranspiledExportFull(exports, "go", []);
|
|
85
|
-
expect(litValue(r.result)).toBe(4);
|
|
86
|
-
});
|
|
87
|
-
});
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
runTranspiled,
|
|
4
|
-
callTranspiledExportFull,
|
|
5
|
-
$lit,
|
|
6
|
-
$arr,
|
|
7
|
-
litValue,
|
|
8
|
-
} from "@nudojs/core";
|
|
9
|
-
import { isBPathCapable } from "@nudojs/service";
|
|
10
|
-
|
|
11
|
-
describe("B-path rest parameters", () => {
|
|
12
|
-
it("collects rest into $arr", () => {
|
|
13
|
-
const src = `
|
|
14
|
-
export function sum(a, ...rest) {
|
|
15
|
-
let t = a;
|
|
16
|
-
let i = 0;
|
|
17
|
-
while (i < rest.length) {
|
|
18
|
-
t = t + rest[i];
|
|
19
|
-
i = i + 1;
|
|
20
|
-
}
|
|
21
|
-
return t;
|
|
22
|
-
}
|
|
23
|
-
`;
|
|
24
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
25
|
-
const sum = exports.sum as (...a: unknown[]) => unknown;
|
|
26
|
-
// named args then rest as separate args — callTranspiledExport only spreads args
|
|
27
|
-
// Our convention: call with named + rest items as extra args via Function arguments
|
|
28
|
-
const r = sum($lit(1), $lit(2), $lit(3));
|
|
29
|
-
expect(litValue(r as never)).toBe(6);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
it("rest empty when only named args", () => {
|
|
33
|
-
const src = `
|
|
34
|
-
export function first(a, ...rest) {
|
|
35
|
-
return a;
|
|
36
|
-
}
|
|
37
|
-
export function restLen(a, ...rest) {
|
|
38
|
-
return rest.length;
|
|
39
|
-
}
|
|
40
|
-
`;
|
|
41
|
-
const exports = runTranspiled(src, { mode: "analyze" });
|
|
42
|
-
const first = exports.first as (...a: unknown[]) => unknown;
|
|
43
|
-
const restLen = exports.restLen as (...a: unknown[]) => unknown;
|
|
44
|
-
expect(litValue(first($lit(9)) as never)).toBe(9);
|
|
45
|
-
expect(litValue(restLen($lit(9)) as never)).toBe(0);
|
|
46
|
-
expect(litValue(restLen($lit(9), $lit(1), $lit(2)) as never)).toBe(2);
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
describe("B-primary capable files", () => {
|
|
51
|
-
it("isBPathCapable allows require now", () => {
|
|
52
|
-
expect(isBPathCapable("function f(x) { return x + 1; }")).toBe(true);
|
|
53
|
-
expect(isBPathCapable("const x = require('y');")).toBe(true);
|
|
54
|
-
});
|
|
55
|
-
});
|