@nudojs/core 0.3.0 → 0.4.0

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 (123) hide show
  1. package/dist/chunk-N7E2A7IK.js +7216 -0
  2. package/dist/exec.d.ts +2 -0
  3. package/dist/exec.js +174 -0
  4. package/dist/index-DgyudAkw.d.ts +911 -0
  5. package/dist/index.d.ts +64 -710
  6. package/dist/index.js +3269 -8426
  7. package/package.json +18 -5
  8. package/CHANGELOG.md +0 -34
  9. package/src/__tests__/environment.test.ts +0 -48
  10. package/src/__tests__/fn-sig-impl.test.ts +0 -57
  11. package/src/__tests__/ops-refined.test.ts +0 -196
  12. package/src/__tests__/ops.test.ts +0 -84
  13. package/src/__tests__/type-value-phase2.test.ts +0 -117
  14. package/src/__tests__/type-value-phase3.test.ts +0 -94
  15. package/src/__tests__/type-value-refined.test.ts +0 -210
  16. package/src/__tests__/type-value.test.ts +0 -319
  17. package/src/algebra/__tests__/abs-native.test.ts +0 -176
  18. package/src/algebra/__tests__/arithmetic.test.ts +0 -170
  19. package/src/algebra/__tests__/ast-eval.test.ts +0 -154
  20. package/src/algebra/__tests__/bridge.test.ts +0 -160
  21. package/src/algebra/__tests__/call-budget.test.ts +0 -117
  22. package/src/algebra/__tests__/check-case-consistency.test.ts +0 -69
  23. package/src/algebra/__tests__/check-gold.test.ts +0 -290
  24. package/src/algebra/__tests__/check-json.test.ts +0 -57
  25. package/src/algebra/__tests__/check-mini-repo.test.ts +0 -49
  26. package/src/algebra/__tests__/check-real-commander.test.ts +0 -43
  27. package/src/algebra/__tests__/check-real-packages.test.ts +0 -165
  28. package/src/algebra/__tests__/check-recall-gold.test.ts +0 -1024
  29. package/src/algebra/__tests__/check-require-dep-memo.test.ts +0 -45
  30. package/src/algebra/__tests__/check-return-contract.test.ts +0 -90
  31. package/src/algebra/__tests__/check-shape-gold.test.ts +0 -303
  32. package/src/algebra/__tests__/check-source-memo.test.ts +0 -204
  33. package/src/algebra/__tests__/check.test.ts +0 -69
  34. package/src/algebra/__tests__/denote.test.ts +0 -77
  35. package/src/algebra/__tests__/diagnostics.test.ts +0 -64
  36. package/src/algebra/__tests__/differential.test.ts +0 -124
  37. package/src/algebra/__tests__/div-mod.test.ts +0 -38
  38. package/src/algebra/__tests__/example0.test.ts +0 -103
  39. package/src/algebra/__tests__/exec-analyze-throws.test.ts +0 -60
  40. package/src/algebra/__tests__/exec-async.test.ts +0 -46
  41. package/src/algebra/__tests__/exec-bpath.test.ts +0 -193
  42. package/src/algebra/__tests__/exec-class.test.ts +0 -56
  43. package/src/algebra/__tests__/exec-e2e.test.ts +0 -97
  44. package/src/algebra/__tests__/exec-generator.test.ts +0 -53
  45. package/src/algebra/__tests__/exec-inherit-default.test.ts +0 -111
  46. package/src/algebra/__tests__/exec-optional-nested.test.ts +0 -87
  47. package/src/algebra/__tests__/exec-rest.test.ts +0 -55
  48. package/src/algebra/__tests__/exec-spread-forof.test.ts +0 -85
  49. package/src/algebra/__tests__/exec-static-computed.test.ts +0 -61
  50. package/src/algebra/__tests__/exec-switch.test.ts +0 -74
  51. package/src/algebra/__tests__/exec-trycatch.test.ts +0 -71
  52. package/src/algebra/__tests__/fn-fp-memo.test.ts +0 -166
  53. package/src/algebra/__tests__/fn-fp-multidecl.test.ts +0 -49
  54. package/src/algebra/__tests__/format.test.ts +0 -34
  55. package/src/algebra/__tests__/generalize-memo.test.ts +0 -285
  56. package/src/algebra/__tests__/generalize.test.ts +0 -113
  57. package/src/algebra/__tests__/hash-source.test.ts +0 -19
  58. package/src/algebra/__tests__/hof.test.ts +0 -80
  59. package/src/algebra/__tests__/inlay.test.ts +0 -30
  60. package/src/algebra/__tests__/language.test.ts +0 -77
  61. package/src/algebra/__tests__/leq.test.ts +0 -109
  62. package/src/algebra/__tests__/load-deps-fp-memo.test.ts +0 -132
  63. package/src/algebra/__tests__/methods.test.ts +0 -37
  64. package/src/algebra/__tests__/node-types.test.ts +0 -26
  65. package/src/algebra/__tests__/nudo-constraints.ts +0 -46
  66. package/src/algebra/__tests__/objects.test.ts +0 -117
  67. package/src/algebra/__tests__/parse-source-cache.test.ts +0 -42
  68. package/src/algebra/__tests__/refine-import.test.ts +0 -109
  69. package/src/algebra/__tests__/stable-source-key-block.test.ts +0 -23
  70. package/src/algebra/__tests__/stable-source-key.test.ts +0 -31
  71. package/src/algebra/__tests__/surface.test.ts +0 -41
  72. package/src/algebra/__tests__/this-inherit.test.ts +0 -130
  73. package/src/algebra/abs-fn.ts +0 -49
  74. package/src/algebra/abs-modules.ts +0 -139
  75. package/src/algebra/abs.ts +0 -206
  76. package/src/algebra/arithmetic.ts +0 -691
  77. package/src/algebra/ast-eval.ts +0 -1763
  78. package/src/algebra/bridge.ts +0 -350
  79. package/src/algebra/builtins.ts +0 -373
  80. package/src/algebra/check-report.ts +0 -150
  81. package/src/algebra/check.ts +0 -1867
  82. package/src/algebra/constraint.ts +0 -304
  83. package/src/algebra/denote.ts +0 -166
  84. package/src/algebra/diagnostics.ts +0 -210
  85. package/src/algebra/exec/call.ts +0 -29
  86. package/src/algebra/exec/calls.ts +0 -96
  87. package/src/algebra/exec/class-registry.ts +0 -29
  88. package/src/algebra/exec/class.ts +0 -329
  89. package/src/algebra/exec/index.ts +0 -6
  90. package/src/algebra/exec/member-diag.ts +0 -141
  91. package/src/algebra/exec/run.ts +0 -341
  92. package/src/algebra/exec/runtime.ts +0 -583
  93. package/src/algebra/exec/transpile.ts +0 -993
  94. package/src/algebra/fn-fp.ts +0 -294
  95. package/src/algebra/format.ts +0 -91
  96. package/src/algebra/generalize.ts +0 -776
  97. package/src/algebra/hash-source.ts +0 -27
  98. package/src/algebra/index.ts +0 -34
  99. package/src/algebra/inlay.ts +0 -198
  100. package/src/algebra/language.ts +0 -289
  101. package/src/algebra/leak.ts +0 -68
  102. package/src/algebra/leq.ts +0 -301
  103. package/src/algebra/load-deps-fp.ts +0 -97
  104. package/src/algebra/methods.ts +0 -128
  105. package/src/algebra/objects.ts +0 -251
  106. package/src/algebra/parse-source.ts +0 -64
  107. package/src/algebra/phi.ts +0 -42
  108. package/src/algebra/pred.ts +0 -395
  109. package/src/algebra/refine.ts +0 -227
  110. package/src/algebra/stable-source-key.ts +0 -81
  111. package/src/algebra/surface.ts +0 -206
  112. package/src/algebra/template.ts +0 -143
  113. package/src/algebra/term.ts +0 -119
  114. package/src/environment.ts +0 -74
  115. package/src/index.ts +0 -73
  116. package/src/mock-helpers.ts +0 -166
  117. package/src/ops.ts +0 -191
  118. package/src/refinements/range.ts +0 -86
  119. package/src/refinements/template-predicates.ts +0 -11
  120. package/src/refinements/template.ts +0 -176
  121. package/src/strip-types.ts +0 -236
  122. package/src/type-value.ts +0 -513
  123. package/tsconfig.json +0 -8
@@ -1,77 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import {
3
- denoteGuard,
4
- abs as makeAbs,
5
- num,
6
- str,
7
- bool,
8
- numLit,
9
- strLit,
10
- never,
11
- unknown,
12
- gt,
13
- lit,
14
- v as termVar,
15
- } from "@nudojs/core";
16
-
17
- describe("denoteGuard", () => {
18
- it("prim number", () => {
19
- expect(denoteGuard(num(), "x")).toBe('typeof x === "number"');
20
- });
21
-
22
- it("literal number keeps exact equality", () => {
23
- expect(denoteGuard(numLit(8), "x")).toBe("x === 8");
24
- });
25
-
26
- it("literal string", () => {
27
- expect(denoteGuard(strLit("hi"), "x")).toBe('x === "hi"');
28
- });
29
-
30
- it("object structure", () => {
31
- const o = makeAbs(
32
- { k: "obj", slots: { id: { value: num() }, name: { value: str() } } },
33
- undefined,
34
- undefined,
35
- "exact",
36
- );
37
- const g = denoteGuard(o, "o");
38
- expect(g).toContain('typeof o === "object"');
39
- expect(g).toContain('typeof o.id === "number"');
40
- expect(g).toContain('typeof o.name === "string"');
41
- });
42
-
43
- it("array element", () => {
44
- const a = makeAbs({ k: "arr", element: num() }, undefined, undefined, "exact");
45
- const g = denoteGuard(a, "a");
46
- expect(g).toContain("Array.isArray(a)");
47
- expect(g).toContain('typeof item === "number"');
48
- });
49
-
50
- it("sum is union of members", () => {
51
- const s = makeAbs(
52
- { k: "sum", members: [numLit(1), numLit(2)] },
53
- undefined,
54
- undefined,
55
- "exact",
56
- );
57
- expect(denoteGuard(s, "x")).toBe("(x === 1 || x === 2)");
58
- });
59
-
60
- it("numeric pred: term > 0 on value", () => {
61
- const a = makeAbs(
62
- { k: "prim", type: "number" },
63
- termVar("x"),
64
- gt(termVar("x"), lit(0)),
65
- "path",
66
- );
67
- const g = denoteGuard(a, "data");
68
- expect(g).toContain('typeof data === "number"');
69
- expect(g).toContain("data > 0");
70
- });
71
-
72
- it("never / unknown / bool", () => {
73
- expect(denoteGuard(never, "x")).toBe("false");
74
- expect(denoteGuard(unknown, "x")).toBe("true");
75
- expect(denoteGuard(bool(), "x")).toBe('typeof x === "boolean"');
76
- });
77
- });
@@ -1,64 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import {
3
- checkCall,
4
- checkArg,
5
- formatDiagnostics,
6
- numLit,
7
- numVar,
8
- gtNum,
9
- v,
10
- unknown,
11
- } from "../index.ts";
12
-
13
- const SRC = `
14
- function scale(x) {
15
- return x + 1;
16
- }
17
- function needsPositive(x) {
18
- if (x > 0) return x;
19
- return 0;
20
- }
21
- `;
22
-
23
- describe("checkArg", () => {
24
- it("literal 5 satisfies >0", () => {
25
- const d = checkArg(numLit(5), gtNum(v("t"), 0));
26
- expect(d).toBeUndefined();
27
- });
28
- it("literal -1 violates >0", () => {
29
- const d = checkArg(numLit(-1), gtNum(v("t"), 0));
30
- expect(d).toBeDefined();
31
- expect(d!.severity).toBe("error");
32
- expect(d!.code).toBe("nudo:constraint-violated");
33
- });
34
- it("unknown without term → opaque warning", () => {
35
- const d = checkArg(unknown, gtNum(v("t"), 0));
36
- expect(d?.code).toBe("nudo:arg-opaque");
37
- });
38
- it("symbolic x>0 satisfies >0 under Φ", () => {
39
- const phi = gtNum(v("x"), 0);
40
- const d = checkArg(numVar("x", gtNum(v("x"), 0)), gtNum(v("t"), 0), phi);
41
- // expect 是 term>0,实参 term 是 var(x),Φ ⊢ x>0 —— implies 需对齐 term
42
- // 当前实现 expect 的 term 是 t,不是 x,所以可能 unproven
43
- // 这里只要不 crash 即可;更严的对齐在后续
44
- expect(d === undefined || d.code === "nudo:constraint-unproven").toBe(true);
45
- });
46
- });
47
-
48
- describe("checkCall", () => {
49
- it("unknown fn", () => {
50
- const diags = checkCall(SRC, "nope", []);
51
- expect(diags[0]?.code).toBe("nudo:fn-not-found");
52
- });
53
- it("arg count mismatch", () => {
54
- const diags = checkCall(SRC, "scale", []);
55
- expect(diags.some((d) => d.code === "nudo:arg-count")).toBe(true);
56
- });
57
- it("scale(5) has no constraint error", () => {
58
- const diags = checkCall(SRC, "scale", [numLit(5)]);
59
- expect(diags.filter((d) => d.severity === "error")).toEqual([]);
60
- });
61
- it("format empty", () => {
62
- expect(formatDiagnostics([])).toBe("No issues found.");
63
- });
64
- });
@@ -1,124 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { execFileSync } from "node:child_process";
3
- import { writeFileSync, mkdtempSync, rmSync } from "node:fs";
4
- import { join } from "node:path";
5
- import { tmpdir } from "node:os";
6
- import {
7
- analyzeFn,
8
- numLit,
9
- litValue,
10
- formatShape,
11
- } from "../index.ts";
12
-
13
- /**
14
- * 差分回归:同一段 JS,代数抽象求值 vs Node 真实执行。
15
- * 规则:若代数给出 exact 字面量,必须等于真实结果。
16
- * 若代数给出 prim(number),真实结果必须是 number。
17
- */
18
-
19
- function runNode(code: string): unknown {
20
- const dir = mkdtempSync(join(tmpdir(), "nudo-diff-"));
21
- const file = join(dir, "run.mjs");
22
- try {
23
- writeFileSync(file, code);
24
- const out = execFileSync(process.execPath, [file], { encoding: "utf8" });
25
- return JSON.parse(out.trim());
26
- } finally {
27
- rmSync(dir, { recursive: true, force: true });
28
- }
29
- }
30
-
31
- function absAndNode(
32
- src: string,
33
- fnName: string,
34
- args: Array<number | string | boolean>,
35
- callExpr: string,
36
- ): { abs: ReturnType<typeof litValue>; shape: string; node: unknown } {
37
- const absArgs = args.map((a) => numLit(a as number));
38
- // string/bool 简化:测试里主要用 number
39
- const result = analyzeFn(src, fnName, absArgs);
40
- const node = runNode(`
41
- ${src}
42
- console.log(JSON.stringify(${callExpr}));
43
- `);
44
- return { abs: litValue(result), shape: formatShape(result), node };
45
- }
46
-
47
- describe("differential: algebra vs Node", () => {
48
- it("add(1,3) → 4 both sides", () => {
49
- const src = `function add(a,b){ return a+b; }`;
50
- const r = absAndNode(src, "add", [1, 3], "add(1,3)");
51
- expect(r.abs).toBe(4);
52
- expect(r.node).toBe(4);
53
- });
54
-
55
- it("scale(5)=x+1 → 6", () => {
56
- const src = `function scale(x){ return x+1; }`;
57
- const r = absAndNode(src, "scale", [5], "scale(5)");
58
- expect(r.abs).toBe(6);
59
- expect(r.node).toBe(6);
60
- });
61
-
62
- it("twice(2) nested add → 4", () => {
63
- const src = `
64
- function add(a,b){ return a+b; }
65
- function twice(x){ return add(add(x,1),1); }
66
- `;
67
- const r = absAndNode(src, "twice", [2], "twice(2)");
68
- // algebra: ((2+1)+1)=4
69
- expect(r.abs).toBe(4);
70
- expect(r.node).toBe(4);
71
- });
72
-
73
- it("mul precedence 1+2*3 → 7", () => {
74
- const src = `function f(){ return 1+2*3; }`;
75
- const r = absAndNode(src, "f", [], "f()");
76
- expect(r.abs).toBe(7);
77
- expect(r.node).toBe(7);
78
- });
79
-
80
- it("negate(5) → -5", () => {
81
- const src = `function negate(x){ return x * -1; }`;
82
- const r = absAndNode(src, "negate", [5], "negate(5)");
83
- expect(r.abs).toBe(-5);
84
- expect(r.node).toBe(-5);
85
- });
86
-
87
- it("if branch true: addOneIfPositive(3) → 4", () => {
88
- const src = `
89
- function addOneIfPositive(x){
90
- if (x > 0) return x + 1;
91
- return 0;
92
- }
93
- `;
94
- const r = absAndNode(src, "addOneIfPositive", [3], "addOneIfPositive(3)");
95
- expect(r.abs).toBe(4);
96
- expect(r.node).toBe(4);
97
- });
98
-
99
- it("if branch false: addOneIfPositive(-2) → 0", () => {
100
- const src = `
101
- function addOneIfPositive(x){
102
- if (x > 0) return x + 1;
103
- return 0;
104
- }
105
- `;
106
- const r = absAndNode(src, "addOneIfPositive", [-2], "addOneIfPositive(-2)");
107
- expect(r.abs).toBe(0);
108
- expect(r.node).toBe(0);
109
- });
110
-
111
- it("spread config exact fields", () => {
112
- const src = `
113
- function createConfig(options){
114
- return { host: "localhost", port: 8080, debug: false, ...options };
115
- }
116
- `;
117
- // 代数用对象实参 —— 这里直接测字面量路径
118
- const node = runNode(`
119
- ${src}
120
- console.log(JSON.stringify(createConfig({ port: 3000 })));
121
- `);
122
- expect(node).toEqual({ host: "localhost", port: 3000, debug: false });
123
- });
124
- });
@@ -1,38 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import { div, mod } from "../arithmetic.ts";
3
- import { numLit, num, abs } from "../abs.ts";
4
- import { v, lit } from "../term.ts";
5
- import { ge, pTrue } from "../pred.ts";
6
- import { typeValueToString } from "../../type-value.ts";
7
- import { absToTypeValue } from "../bridge.ts";
8
- import { formatAbs } from "../format.ts";
9
-
10
- describe("algebra div/mod", () => {
11
- it("lit div", () => {
12
- expect(formatAbs(div(numLit(10), numLit(2)))).toContain("5");
13
- });
14
-
15
- it("div by zero stays number", () => {
16
- const r = div(numLit(1), numLit(0));
17
- expect(r.shape).toEqual({ k: "prim", type: "number" });
18
- });
19
-
20
- it("x>=0 / 2 keeps lower bound", () => {
21
- const x = abs(num().shape, v("x"), ge(v("x"), lit(0)), "path");
22
- const half = div(x, numLit(2));
23
- expect(half.pred).toBeDefined();
24
- const tv = absToTypeValue(half);
25
- expect(typeValueToString(tv)).toContain(">= 0");
26
- });
27
-
28
- it("lit mod", () => {
29
- expect(formatAbs(mod(numLit(10), numLit(3)))).toContain("1");
30
- });
31
-
32
- it("x % 5 has bounds", () => {
33
- const x = abs(num().shape, v("x"), pTrue, "path");
34
- const r = mod(x, numLit(5));
35
- expect(r.pred).toBeDefined();
36
- expect(formatAbs(r)).toContain("5");
37
- });
38
- });
@@ -1,103 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import {
3
- add,
4
- cmp,
5
- numLit,
6
- numVar,
7
- strLit,
8
- gtNum,
9
- lit,
10
- v,
11
- termToString,
12
- predToString,
13
- litValue,
14
- } from "../index.ts";
15
-
16
- /**
17
- * 示例 0 金标:类型即计算
18
- *
19
- * add = (a, b) => a + b
20
- * add(1, 3) → lit(4) #exact
21
- * Φ: x > 0
22
- * add(x, 1) → term=x+1, pred:>1 #path
23
- * twice(x) → term=(x+1)+1, pred:>2 #path
24
- */
25
-
26
- describe("Example 0: add is the computation itself", () => {
27
- it("add(1, 3) evaluates to literal 4 #exact", () => {
28
- const r = add(numLit(1), numLit(3));
29
- expect(litValue(r)).toBe(4);
30
- expect(r.conf).toBe("exact");
31
- expect(r.term?.op).toBe("lit");
32
- expect(r.shape).toEqual({ k: "prim", type: "number" });
33
- });
34
-
35
- it("add keeps term as (x + 1) when a is symbolic", () => {
36
- const x = numVar("x");
37
- const r = add(x, numLit(1));
38
- expect(r.term).toBeDefined();
39
- expect(termToString(r.term!)).toBe("(x + 1)");
40
- expect(r.shape).toEqual({ k: "prim", type: "number" });
41
- expect(r.conf).toBe("path");
42
- });
43
-
44
- it("Φ: x>0 ⇒ add(x,1) has pred term>1", () => {
45
- const x = numVar("x", gtNum(v("x"), 0));
46
- const phi = gtNum(v("x"), 0);
47
- const r = add(x, numLit(1), phi);
48
-
49
- expect(termToString(r.term!)).toBe("(x + 1)");
50
- expect(r.pred).toBeDefined();
51
- const ps = predToString(r.pred!);
52
- expect(ps).toContain(">");
53
- expect(ps).toContain("1");
54
- expect(r.pred!.op).toBe("gt");
55
- if (r.pred!.op === "gt") {
56
- expect(termToString(r.pred!.a)).toBe("(x + 1)");
57
- expect(r.pred!.b).toEqual(lit(1));
58
- }
59
- expect(r.conf).toBe("path");
60
- });
61
-
62
- it("twice: x>0 ⇒ (x+1)+1 with pred >2", () => {
63
- const phi = gtNum(v("x"), 0);
64
- const x = numVar("x", gtNum(v("x"), 0));
65
-
66
- const c = add(x, numLit(1), phi);
67
- const r = add(c, numLit(1), phi);
68
-
69
- expect(r.term).toBeDefined();
70
- const ts = termToString(r.term!);
71
- expect(ts === "(x + 2)" || ts === "((x + 1) + 1)").toBe(true);
72
-
73
- expect(r.pred).toBeDefined();
74
- if (r.pred!.op === "gt") {
75
- expect(r.pred!.b).toEqual(lit(2));
76
- } else {
77
- expect(predToString(r.pred!)).toContain("2");
78
- }
79
- });
80
-
81
- it("non-negativity: x>0 ⇒ x+1 > 0 (weaker but still valid)", () => {
82
- const phi = gtNum(v("x"), 0);
83
- const x = numVar("x", gtNum(v("x"), 0));
84
- const r = add(x, numLit(1), phi);
85
- expect(r.pred!.op).toBe("gt");
86
- });
87
- });
88
-
89
- describe("comparison implies under Φ", () => {
90
- it("x>0 ⊢ x+1 > 1 is true", () => {
91
- const phi = gtNum(v("x"), 0);
92
- const x = numVar("x", gtNum(v("x"), 0));
93
- const sum = add(x, numLit(1), phi);
94
- const c = cmp("gt", sum, numLit(1), phi);
95
- expect(litValue(c)).toBe(true);
96
- });
97
-
98
- it("string concat keeps string shape", () => {
99
- const r = add(strLit("a"), strLit("b"));
100
- expect(litValue(r)).toBe("ab");
101
- expect(r.shape).toEqual({ k: "prim", type: "string" });
102
- });
103
- });
@@ -1,60 +0,0 @@
1
- import { describe, it, expect } from "vitest";
2
- import {
3
- runTranspiled,
4
- callTranspiledExportFull,
5
- $lit,
6
- litValue,
7
- absToString,
8
- never,
9
- } from "@nudojs/core";
10
-
11
- describe("B-path analyze mode", () => {
12
- it("does not run top-level side effects", () => {
13
- const src = `
14
- globalThisNotDefined();
15
- export function id(x) { return x; }
16
- `;
17
- expect(() => runTranspiled(src, { mode: "exec" })).toThrow();
18
- const exports = runTranspiled(src, { mode: "analyze" });
19
- expect(typeof exports.id).toBe("function");
20
- const r = callTranspiledExportFull(exports, "id", [$lit(7)]);
21
- expect(litValue(r.result)).toBe(7);
22
- });
23
-
24
- it("keeps function definitions that call other locals", () => {
25
- const src = `
26
- function helper(x) { return x + 1; }
27
- export function go(n) { return helper(n); }
28
- `;
29
- const exports = runTranspiled(src, { mode: "analyze" });
30
- const r = callTranspiledExportFull(exports, "go", [$lit(1)]);
31
- expect(litValue(r.result)).toBe(2);
32
- expect(r.throws).toBe(never);
33
- });
34
- });
35
-
36
- describe("B-path throws", () => {
37
- it("captures $throw as throws Abs", () => {
38
- const src = `
39
- export function fail(n) {
40
- if (n > 0) { return n; } else { throw new Error("bad"); }
41
- }
42
- `;
43
- // throw new Error → transpile may skip NewExpression; use throw literal path via $throw
44
- const src2 = `
45
- export function fail(n) {
46
- if (n > 0) { return n; } else { throw "bad"; }
47
- }
48
- `;
49
- void src;
50
- const exports = runTranspiled(src2, { mode: "analyze" });
51
- const ok = callTranspiledExportFull(exports, "fail", [$lit(1)]);
52
- expect(litValue(ok.result)).toBe(1);
53
- expect(ok.throws).toBe(never);
54
-
55
- const bad = callTranspiledExportFull(exports, "fail", [$lit(-1)]);
56
- expect(bad.result.shape.k).toBe("never");
57
- expect(bad.throws.shape.k).not.toBe("never");
58
- expect(absToString(bad.throws)).toContain("bad");
59
- });
60
- });
@@ -1,46 +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 async / await", () => {
12
- it("await async call unwraps to concrete", () => {
13
- const src = `
14
- export async function f(n) {
15
- return n + 1;
16
- }
17
- export async function go(n) {
18
- return await f(n);
19
- }
20
- `;
21
- const exports = runTranspiled(src, { mode: "analyze" });
22
- const r = callTranspiledExportFull(exports, "go", [$lit(1)]);
23
- // go 是 async → 外层 promise
24
- expect(absToString(r.result)).toContain("promise");
25
- expect(litValue($await(r.result))).toBe(2);
26
- });
27
-
28
- it("async wraps return as promise", () => {
29
- const src = `
30
- export async function f() {
31
- return 42;
32
- }
33
- `;
34
- const exports = runTranspiled(src, { mode: "analyze" });
35
- const r = callTranspiledExportFull(exports, "f", []);
36
- expect(absToString(r.result)).toContain("promise");
37
- expect(litValue($await(r.result))).toBe(42);
38
- });
39
-
40
- it("transpiles async and await", async () => {
41
- const { transpile } = await import("@nudojs/core");
42
- const out = transpile(`export async function f(n) { return await g(n); }`);
43
- expect(out).toContain("$async(");
44
- expect(out).toContain("$await(");
45
- });
46
- });