@alloy-js/core 0.5.0 → 0.7.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.
- package/CHANGELOG.md +55 -0
- package/babel.config.cjs +4 -1
- package/dist/src/binder.d.ts +8 -2
- package/dist/src/binder.d.ts.map +1 -1
- package/dist/src/binder.js +41 -15
- package/dist/src/binder.js.map +1 -1
- package/dist/src/code.d.ts +2 -2
- package/dist/src/code.d.ts.map +1 -1
- package/dist/src/code.js +4 -4
- package/dist/src/code.js.map +1 -1
- package/dist/src/components/Block.d.ts +25 -0
- package/dist/src/components/Block.d.ts.map +1 -0
- package/dist/src/components/Block.js +25 -0
- package/dist/src/components/Block.js.map +1 -0
- package/dist/src/components/Declaration.d.ts.map +1 -1
- package/dist/src/components/Declaration.js +4 -0
- package/dist/src/components/Declaration.js.map +1 -1
- package/dist/src/components/For.d.ts +44 -0
- package/dist/src/components/For.d.ts.map +1 -0
- package/dist/src/components/For.js +41 -0
- package/dist/src/components/For.js.map +1 -0
- package/dist/src/components/Indent.d.ts +5 -9
- package/dist/src/components/Indent.d.ts.map +1 -1
- package/dist/src/components/Indent.js +7 -18
- package/dist/src/components/Indent.js.map +1 -1
- package/dist/src/components/List.d.ts +38 -0
- package/dist/src/components/List.d.ts.map +1 -0
- package/dist/src/components/List.js +40 -0
- package/dist/src/components/List.js.map +1 -0
- package/dist/src/components/MemberDeclaration.d.ts.map +1 -1
- package/dist/src/components/MemberDeclaration.js.map +1 -1
- package/dist/src/components/MemberName.js +1 -1
- package/dist/src/components/MemberName.js.map +1 -1
- package/dist/src/components/MemberScope.d.ts.map +1 -1
- package/dist/src/components/MemberScope.js.map +1 -1
- package/dist/src/components/Name.js +1 -1
- package/dist/src/components/Name.js.map +1 -1
- package/dist/src/components/Output.d.ts +2 -1
- package/dist/src/components/Output.d.ts.map +1 -1
- package/dist/src/components/Output.js +9 -1
- package/dist/src/components/Output.js.map +1 -1
- package/dist/src/components/Scope.d.ts.map +1 -1
- package/dist/src/components/Scope.js.map +1 -1
- package/dist/src/components/Show.d.ts +8 -0
- package/dist/src/components/Show.d.ts.map +1 -0
- package/dist/src/components/Show.js +4 -0
- package/dist/src/components/Show.js.map +1 -0
- package/dist/src/components/SourceDirectory.d.ts.map +1 -1
- package/dist/src/components/SourceDirectory.js +1 -0
- package/dist/src/components/SourceDirectory.js.map +1 -1
- package/dist/src/components/SourceFile.d.ts +2 -6
- package/dist/src/components/SourceFile.d.ts.map +1 -1
- package/dist/src/components/SourceFile.js +6 -13
- package/dist/src/components/SourceFile.js.map +1 -1
- package/dist/src/components/StatementList.d.ts +9 -0
- package/dist/src/components/StatementList.d.ts.map +1 -0
- package/dist/src/components/StatementList.js +17 -0
- package/dist/src/components/StatementList.js.map +1 -0
- package/dist/src/components/Switch.d.ts +41 -0
- package/dist/src/components/Switch.d.ts.map +1 -0
- package/dist/src/components/Switch.js +41 -0
- package/dist/src/components/Switch.js.map +1 -0
- package/dist/src/components/Wrap.d.ts +20 -0
- package/dist/src/components/Wrap.d.ts.map +1 -0
- package/dist/src/components/Wrap.js +15 -0
- package/dist/src/components/Wrap.js.map +1 -0
- package/dist/src/components/index.d.ts +8 -1
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +7 -0
- package/dist/src/components/index.js.map +1 -1
- package/dist/src/components/stc/index.d.ts +77 -6
- package/dist/src/components/stc/index.d.ts.map +1 -1
- package/dist/src/components/stc/index.js +17 -1
- package/dist/src/components/stc/index.js.map +1 -1
- package/dist/src/context/index.d.ts +0 -1
- package/dist/src/context/index.d.ts.map +1 -1
- package/dist/src/context/index.js +0 -1
- package/dist/src/context/index.js.map +1 -1
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.js +3 -3
- package/dist/src/context.js.map +1 -1
- package/dist/src/index.browser.d.ts +3 -0
- package/dist/src/index.browser.d.ts.map +1 -0
- package/dist/src/index.browser.js +3 -0
- package/dist/src/index.browser.js.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/jsx-runtime.d.ts +139 -8
- package/dist/src/jsx-runtime.d.ts.map +1 -1
- package/dist/src/jsx-runtime.js +102 -12
- package/dist/src/jsx-runtime.js.map +1 -1
- package/dist/src/render.d.ts +107 -132
- package/dist/src/render.d.ts.map +1 -1
- package/dist/src/render.js +281 -177
- package/dist/src/render.js.map +1 -1
- package/dist/src/stc.d.ts +14 -0
- package/dist/src/stc.d.ts.map +1 -0
- package/dist/src/stc.js +52 -0
- package/dist/src/stc.js.map +1 -0
- package/dist/src/utils.d.ts +22 -15
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +95 -59
- package/dist/src/utils.js.map +1 -1
- package/dist/src/write-output.js +3 -3
- package/dist/src/write-output.js.map +1 -1
- package/dist/test/browser-build.test.d.ts +2 -0
- package/dist/test/browser-build.test.d.ts.map +1 -0
- package/dist/test/components/block.test.d.ts +2 -0
- package/dist/test/components/block.test.d.ts.map +1 -0
- package/dist/test/components/declaration.test.d.ts +2 -0
- package/dist/test/components/declaration.test.d.ts.map +1 -0
- package/dist/test/components/list.test.d.ts +2 -0
- package/dist/test/components/list.test.d.ts.map +1 -0
- package/dist/test/components/wrap.test.d.ts +2 -0
- package/dist/test/components/wrap.test.d.ts.map +1 -0
- package/dist/test/control-flow/for.test.d.ts +2 -0
- package/dist/test/control-flow/for.test.d.ts.map +1 -0
- package/dist/test/control-flow/match.test.d.ts +2 -0
- package/dist/test/control-flow/match.test.d.ts.map +1 -0
- package/dist/test/control-flow/show.test.d.ts +2 -0
- package/dist/test/control-flow/show.test.d.ts.map +1 -0
- package/dist/test/reactivity/cleanup.test.d.ts +2 -0
- package/dist/test/reactivity/cleanup.test.d.ts.map +1 -0
- package/dist/test/reactivity/memo.test.d.ts +2 -0
- package/dist/test/reactivity/memo.test.d.ts.map +1 -0
- package/dist/test/reactivity/untrack.test.d.ts +2 -0
- package/dist/test/reactivity/untrack.test.d.ts.map +1 -0
- package/dist/test/rendering/formatting.test.d.ts +2 -0
- package/dist/test/rendering/formatting.test.d.ts.map +1 -0
- package/dist/test/rendering/memoization.test.d.ts +2 -0
- package/dist/test/rendering/memoization.test.d.ts.map +1 -0
- package/dist/test/split-props.test.d.ts +2 -0
- package/dist/test/split-props.test.d.ts.map +1 -0
- package/dist/test/stc.test.d.ts.map +1 -1
- package/dist/test/utils.test.d.ts.map +1 -1
- package/dist/testing/extend-expect.js +4 -4
- package/dist/testing/extend-expect.js.map +1 -1
- package/dist/testing/render.d.ts +2 -3
- package/dist/testing/render.d.ts.map +1 -1
- package/dist/testing/render.js +2 -4
- package/dist/testing/render.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -8
- package/src/binder.ts +54 -18
- package/src/code.ts +17 -12
- package/src/components/Block.tsx +44 -0
- package/src/components/Declaration.tsx +10 -4
- package/src/components/For.tsx +81 -0
- package/src/components/Indent.tsx +20 -27
- package/src/components/List.tsx +94 -0
- package/src/components/MemberDeclaration.tsx +9 -6
- package/src/components/MemberScope.tsx +4 -2
- package/src/components/Output.tsx +25 -13
- package/src/components/Scope.tsx +4 -2
- package/src/components/Show.tsx +11 -0
- package/src/components/SourceDirectory.tsx +5 -1
- package/src/components/SourceFile.tsx +12 -16
- package/src/components/StatementList.tsx +16 -0
- package/src/components/Switch.tsx +62 -0
- package/src/components/Wrap.tsx +29 -0
- package/src/components/index.tsx +8 -1
- package/src/components/stc/index.ts +18 -1
- package/src/context/index.ts +0 -1
- package/src/context.ts +2 -3
- package/src/index.browser.ts +2 -0
- package/src/index.ts +1 -0
- package/src/jsx-runtime.ts +245 -23
- package/src/render.ts +392 -198
- package/src/stc.ts +95 -0
- package/src/utils.ts +162 -95
- package/src/write-output.ts +3 -3
- package/temp/api.json +8407 -3301
- package/test/browser-build.test.ts +91 -0
- package/test/children.test.tsx +8 -10
- package/test/components/block.test.tsx +48 -0
- package/test/components/declaration.test.tsx +37 -0
- package/test/components/list.test.tsx +91 -0
- package/test/components/slot.test.tsx +31 -25
- package/test/components/source-file.test.tsx +11 -31
- package/test/components/wrap.test.tsx +42 -0
- package/test/control-flow/for.test.tsx +194 -0
- package/test/control-flow/match.test.tsx +49 -0
- package/test/control-flow/show.test.tsx +25 -0
- package/test/name-policy.test.tsx +5 -5
- package/test/reactivity/cleanup.test.tsx +91 -0
- package/test/reactivity/memo.test.tsx +17 -0
- package/test/reactivity/ref-rendering.test.tsx +3 -8
- package/test/reactivity/test.test.tsx +7 -6
- package/test/reactivity/untrack.test.ts +33 -0
- package/test/rendering/basic.test.tsx +25 -47
- package/test/rendering/code.test.tsx +3 -3
- package/test/rendering/formatting.test.tsx +487 -0
- package/test/rendering/indent.test.tsx +42 -529
- package/test/rendering/memoization.test.tsx +30 -0
- package/test/split-props.test.ts +87 -0
- package/test/stc.test.tsx +29 -8
- package/test/symbols.test.ts +87 -8
- package/test/utils.test.tsx +129 -20
- package/testing/extend-expect.ts +14 -4
- package/testing/render.ts +2 -4
- package/testing/vitest.d.ts +6 -1
- package/vitest.config.ts +1 -1
- package/dist/src/context/indent.d.ts +0 -5
- package/dist/src/context/indent.d.ts.map +0 -1
- package/dist/src/context/indent.js +0 -8
- package/dist/src/context/indent.js.map +0 -1
- package/dist/test/rendering/linebreaks.test.d.ts +0 -2
- package/dist/test/rendering/linebreaks.test.d.ts.map +0 -1
- package/src/context/indent.ts +0 -17
- package/test/rendering/linebreaks.test.tsx +0 -72
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import { existsSync, mkdirSync, rmSync, writeFileSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
5
|
+
|
|
6
|
+
const testDir = join(__dirname, ".temp", "vite-test-project");
|
|
7
|
+
|
|
8
|
+
describe("Browser Build Test", () => {
|
|
9
|
+
beforeAll(() => {
|
|
10
|
+
// Cleanup previous runs
|
|
11
|
+
if (existsSync(testDir)) {
|
|
12
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Create a temporary Vite project
|
|
16
|
+
mkdirSync(testDir, { recursive: true });
|
|
17
|
+
|
|
18
|
+
execSync("npm init -y", { cwd: testDir });
|
|
19
|
+
execSync("npm install vite", { cwd: testDir });
|
|
20
|
+
execSync("npm install ../../..", { cwd: testDir });
|
|
21
|
+
|
|
22
|
+
// Create a minimal Vite app
|
|
23
|
+
writeFileSync(
|
|
24
|
+
join(testDir, "index.js"),
|
|
25
|
+
`
|
|
26
|
+
import { writeOutput } from "@alloy-js/core";
|
|
27
|
+
console.log("Alloy-js core imported successfully!", writeOutput);
|
|
28
|
+
`,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
writeFileSync(
|
|
32
|
+
join(testDir, "vite.config.js"),
|
|
33
|
+
`
|
|
34
|
+
import { defineConfig } from "vite";
|
|
35
|
+
|
|
36
|
+
export default defineConfig({
|
|
37
|
+
build: {
|
|
38
|
+
outDir: "dist",
|
|
39
|
+
target: "esnext",
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
`,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Create an index.html file
|
|
46
|
+
writeFileSync(
|
|
47
|
+
join(testDir, "index.html"),
|
|
48
|
+
`
|
|
49
|
+
<!DOCTYPE html>
|
|
50
|
+
<html lang="en">
|
|
51
|
+
<head>
|
|
52
|
+
<meta charset="UTF-8">
|
|
53
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
54
|
+
<title>Vite Test</title>
|
|
55
|
+
</head>
|
|
56
|
+
<body>
|
|
57
|
+
<script type="module" src="/index.js"></script>
|
|
58
|
+
</body>
|
|
59
|
+
</html>
|
|
60
|
+
`,
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
writeFileSync(
|
|
64
|
+
join(testDir, "package.json"),
|
|
65
|
+
JSON.stringify(
|
|
66
|
+
{
|
|
67
|
+
type: "module",
|
|
68
|
+
scripts: {
|
|
69
|
+
build: "vite build",
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
null,
|
|
73
|
+
2,
|
|
74
|
+
),
|
|
75
|
+
);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("Vite should build successfully", () => {
|
|
79
|
+
// Run Vite build process and wait for completion
|
|
80
|
+
expect(() => {
|
|
81
|
+
execSync("npm run build", { cwd: testDir, stdio: "inherit" });
|
|
82
|
+
}).not.toThrow();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
afterAll(() => {
|
|
86
|
+
// Ensure testDir exists before attempting to remove it
|
|
87
|
+
if (existsSync(testDir)) {
|
|
88
|
+
rmSync(testDir, { recursive: true, force: true });
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
});
|
package/test/children.test.tsx
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { children, Children, renderTree } from "@alloy-js/core";
|
|
1
|
+
import { children, Children, printTree, renderTree } from "@alloy-js/core";
|
|
2
2
|
import { expect, it } from "vitest";
|
|
3
|
-
import { d, printTree } from "../testing/render.js";
|
|
4
3
|
|
|
5
4
|
it("handles a single element", () => {
|
|
6
5
|
function Foo(props: { children?: Children }) {
|
|
@@ -21,13 +20,12 @@ it("handles a multiple elements", () => {
|
|
|
21
20
|
return "Bar";
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
const res = renderTree(
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
const res = renderTree(
|
|
24
|
+
<Foo>
|
|
25
|
+
<Bar />
|
|
26
|
+
<Bar />
|
|
27
|
+
</Foo>,
|
|
28
|
+
);
|
|
28
29
|
|
|
29
|
-
expect(printTree(res)).toBe(
|
|
30
|
-
Bar
|
|
31
|
-
Bar
|
|
32
|
-
`);
|
|
30
|
+
expect(printTree(res)).toBe(`BarBar`);
|
|
33
31
|
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { expect, it } from "vitest";
|
|
2
|
+
import { Block } from "../../src/components/Block.jsx";
|
|
3
|
+
import "../../testing/extend-expect.js";
|
|
4
|
+
it("renders properly with no children", () => {
|
|
5
|
+
const template = (
|
|
6
|
+
<Block>
|
|
7
|
+
<></>
|
|
8
|
+
</Block>
|
|
9
|
+
);
|
|
10
|
+
expect(template).toRenderTo(`{}`);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it("renders properly with children", () => {
|
|
14
|
+
const template = <Block>Contents!!</Block>;
|
|
15
|
+
expect(template).toRenderTo(`
|
|
16
|
+
{
|
|
17
|
+
Contents!!
|
|
18
|
+
}
|
|
19
|
+
`);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("renders properly with newline and no children", () => {
|
|
23
|
+
const template = (
|
|
24
|
+
<>
|
|
25
|
+
class
|
|
26
|
+
<Block newline>
|
|
27
|
+
<></>
|
|
28
|
+
</Block>
|
|
29
|
+
</>
|
|
30
|
+
);
|
|
31
|
+
expect(template).toRenderTo(`
|
|
32
|
+
class {}
|
|
33
|
+
`);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("renders properly with newline and no children", () => {
|
|
37
|
+
const template = (
|
|
38
|
+
<>
|
|
39
|
+
class<Block newline>contents!!</Block>
|
|
40
|
+
</>
|
|
41
|
+
);
|
|
42
|
+
expect(template).toRenderTo(`
|
|
43
|
+
class
|
|
44
|
+
{
|
|
45
|
+
contents!!
|
|
46
|
+
}
|
|
47
|
+
`);
|
|
48
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { expect, it } from "vitest";
|
|
2
|
+
import { Output } from "../../src/components/Output.jsx";
|
|
3
|
+
import {
|
|
4
|
+
Declaration,
|
|
5
|
+
ref,
|
|
6
|
+
renderTree,
|
|
7
|
+
Scope,
|
|
8
|
+
useBinder,
|
|
9
|
+
} from "../../src/index.js";
|
|
10
|
+
import { createTap } from "../../src/tap.js";
|
|
11
|
+
|
|
12
|
+
it("creates and cleans up a symbol", () => {
|
|
13
|
+
const GetBinder = createTap(() => {
|
|
14
|
+
return useBinder();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const binderRef = GetBinder.ref;
|
|
18
|
+
const doDecl = ref(true);
|
|
19
|
+
const template = (
|
|
20
|
+
<Output>
|
|
21
|
+
<GetBinder />
|
|
22
|
+
<Scope>
|
|
23
|
+
{doDecl.value ?
|
|
24
|
+
<Declaration name="foo"></Declaration>
|
|
25
|
+
: ""}
|
|
26
|
+
</Scope>
|
|
27
|
+
</Output>
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
renderTree(template);
|
|
31
|
+
|
|
32
|
+
const binder = binderRef.value!;
|
|
33
|
+
const subScope = [...binder.globalScope.children][0];
|
|
34
|
+
expect(subScope.symbols.size).toBe(1);
|
|
35
|
+
doDecl.value = false;
|
|
36
|
+
expect(subScope.symbols.size).toBe(0);
|
|
37
|
+
});
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { expect, it } from "vitest";
|
|
2
|
+
import { List, printTree, ref, renderTree } from "../../src/index.js";
|
|
3
|
+
import "../../testing/extend-expect.js";
|
|
4
|
+
import { d } from "../../testing/render.js";
|
|
5
|
+
|
|
6
|
+
it("creates a list with default options", () => {
|
|
7
|
+
const template = (
|
|
8
|
+
<group>
|
|
9
|
+
<List>
|
|
10
|
+
<>1</>
|
|
11
|
+
<>2</>
|
|
12
|
+
<>3</>
|
|
13
|
+
</List>
|
|
14
|
+
</group>
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
expect(template).toRenderTo(`
|
|
18
|
+
1
|
|
19
|
+
2
|
|
20
|
+
3
|
|
21
|
+
`);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("creates a list with some options", () => {
|
|
25
|
+
expect(
|
|
26
|
+
<group>
|
|
27
|
+
<List comma line>
|
|
28
|
+
<>1</>
|
|
29
|
+
<>2</>
|
|
30
|
+
<>3</>
|
|
31
|
+
</List>
|
|
32
|
+
</group>,
|
|
33
|
+
).toRenderTo(`1, 2, 3`);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("creates a list item for substitutions", () => {
|
|
37
|
+
expect(
|
|
38
|
+
<group>
|
|
39
|
+
<List comma line>
|
|
40
|
+
{1}
|
|
41
|
+
{2}
|
|
42
|
+
{3}
|
|
43
|
+
</List>
|
|
44
|
+
</group>,
|
|
45
|
+
).toRenderTo(`1, 2, 3`);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("doesn't create list items for undefined, null, and boolean values", () => {
|
|
49
|
+
expect(
|
|
50
|
+
<group>
|
|
51
|
+
<List comma line>
|
|
52
|
+
{false}
|
|
53
|
+
{1}
|
|
54
|
+
{true}
|
|
55
|
+
{2}
|
|
56
|
+
{null}
|
|
57
|
+
{3}
|
|
58
|
+
{undefined}
|
|
59
|
+
</List>
|
|
60
|
+
</group>,
|
|
61
|
+
).toRenderTo(`1, 2, 3`);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("is useful for statements", () => {
|
|
65
|
+
function Statement() {
|
|
66
|
+
return "console.log(true)";
|
|
67
|
+
}
|
|
68
|
+
const includeStatement = ref(false);
|
|
69
|
+
const tree = renderTree(
|
|
70
|
+
<List semicolon hardline ender>
|
|
71
|
+
<Statement />
|
|
72
|
+
{includeStatement.value && <Statement />}
|
|
73
|
+
<Statement />
|
|
74
|
+
</List>,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
expect(printTree(tree)).toEqual(d`
|
|
78
|
+
console.log(true);
|
|
79
|
+
console.log(true);
|
|
80
|
+
|
|
81
|
+
`);
|
|
82
|
+
|
|
83
|
+
includeStatement.value = true;
|
|
84
|
+
|
|
85
|
+
expect(printTree(tree)).toEqual(d`
|
|
86
|
+
console.log(true);
|
|
87
|
+
console.log(true);
|
|
88
|
+
console.log(true);
|
|
89
|
+
|
|
90
|
+
`);
|
|
91
|
+
});
|
|
@@ -33,7 +33,7 @@ it("works with string keys", () => {
|
|
|
33
33
|
{ ...props, additionalProp: "hi" },
|
|
34
34
|
<>
|
|
35
35
|
function {props.name}() {"{"}
|
|
36
|
-
|
|
36
|
+
console.log("hello world");
|
|
37
37
|
{"}"}
|
|
38
38
|
</>,
|
|
39
39
|
);
|
|
@@ -43,10 +43,12 @@ it("works with string keys", () => {
|
|
|
43
43
|
|
|
44
44
|
// extension.tsx
|
|
45
45
|
replace(FunctionSlot.find({ name: "foo" }), (props: any) => {
|
|
46
|
-
return
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
return (
|
|
47
|
+
<>
|
|
48
|
+
// original
|
|
49
|
+
{props.original}
|
|
50
|
+
</>
|
|
51
|
+
);
|
|
50
52
|
});
|
|
51
53
|
|
|
52
54
|
const tree = render(
|
|
@@ -65,12 +67,12 @@ it("works with symbols", () => {
|
|
|
65
67
|
additionalProp: string;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
const FunctionSlot = defineSlot<FunctionSlotProps>(
|
|
69
|
-
fqn: string
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
const FunctionSlot = defineSlot<FunctionSlotProps>(
|
|
71
|
+
(query: { fqn: string }) => {
|
|
72
|
+
const binder = useBinder();
|
|
73
|
+
return binder.resolveFQN(query.fqn);
|
|
74
|
+
},
|
|
75
|
+
);
|
|
74
76
|
|
|
75
77
|
interface FunctionComponentProps {
|
|
76
78
|
name: string;
|
|
@@ -87,8 +89,9 @@ it("works with symbols", () => {
|
|
|
87
89
|
sym,
|
|
88
90
|
{ ...props, additionalProp: "hi" },
|
|
89
91
|
<Declaration symbol={sym}>
|
|
90
|
-
function <Name />
|
|
91
|
-
|
|
92
|
+
function <Name />
|
|
93
|
+
() {"{"}
|
|
94
|
+
console.log("hello world");
|
|
92
95
|
{"}"}
|
|
93
96
|
</Declaration>,
|
|
94
97
|
);
|
|
@@ -98,10 +101,12 @@ it("works with symbols", () => {
|
|
|
98
101
|
|
|
99
102
|
// extension.tsx
|
|
100
103
|
replace(FunctionSlot.find({ fqn: "foo.bar" }), (props: any) => {
|
|
101
|
-
return
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
return (
|
|
105
|
+
<>
|
|
106
|
+
// original
|
|
107
|
+
{props.original}
|
|
108
|
+
</>
|
|
109
|
+
);
|
|
105
110
|
});
|
|
106
111
|
|
|
107
112
|
const tree = render(
|
|
@@ -122,12 +127,12 @@ it("can rename", () => {
|
|
|
122
127
|
additionalProp: string;
|
|
123
128
|
}
|
|
124
129
|
|
|
125
|
-
const FunctionSlot = defineSlot<FunctionSlotProps>(
|
|
126
|
-
fqn: string
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
const FunctionSlot = defineSlot<FunctionSlotProps>(
|
|
131
|
+
(query: { fqn: string }) => {
|
|
132
|
+
const binder = useBinder();
|
|
133
|
+
return binder.resolveFQN(query.fqn);
|
|
134
|
+
},
|
|
135
|
+
);
|
|
131
136
|
|
|
132
137
|
interface FunctionComponentProps {
|
|
133
138
|
name: string;
|
|
@@ -144,8 +149,9 @@ it("can rename", () => {
|
|
|
144
149
|
sym,
|
|
145
150
|
{ ...props, additionalProp: "hi" },
|
|
146
151
|
<Declaration symbol={sym}>
|
|
147
|
-
function <Name />
|
|
148
|
-
|
|
152
|
+
function <Name />
|
|
153
|
+
() {"{"}
|
|
154
|
+
console.log("hello world");
|
|
149
155
|
{"}"}
|
|
150
156
|
</Declaration>,
|
|
151
157
|
);
|
|
@@ -18,7 +18,9 @@ it("tracks its content", () => {
|
|
|
18
18
|
const _ = renderTree(
|
|
19
19
|
<Output>
|
|
20
20
|
<Test />
|
|
21
|
-
<SourceFile path="hi.txt" filetype="text">
|
|
21
|
+
<SourceFile path="hi.txt" filetype="text">
|
|
22
|
+
hello!
|
|
23
|
+
</SourceFile>
|
|
22
24
|
</Output>,
|
|
23
25
|
);
|
|
24
26
|
expect(context!.contents.length).toEqual(1);
|
|
@@ -31,43 +33,21 @@ it("has reactive context", () => {
|
|
|
31
33
|
return sdContext.contents.map((v) => v.path).join(" ");
|
|
32
34
|
});
|
|
33
35
|
|
|
34
|
-
return
|
|
36
|
+
return (
|
|
37
|
+
<SourceFile path="contents.txt" filetype="text">
|
|
38
|
+
{allFiles.value}
|
|
39
|
+
</SourceFile>
|
|
40
|
+
);
|
|
35
41
|
}
|
|
36
42
|
|
|
37
43
|
const tree = render(
|
|
38
44
|
<Output>
|
|
39
|
-
<SourceFile path="hi.txt" filetype="text">
|
|
45
|
+
<SourceFile path="hi.txt" filetype="text">
|
|
46
|
+
hello!
|
|
47
|
+
</SourceFile>
|
|
40
48
|
<TrackContents />
|
|
41
49
|
</Output>,
|
|
42
50
|
);
|
|
43
51
|
|
|
44
52
|
expect(tree.contents[1].contents).toEqual("hi.txt contents.txt");
|
|
45
53
|
});
|
|
46
|
-
|
|
47
|
-
it("can change its indent level", () => {
|
|
48
|
-
function Nested() {
|
|
49
|
-
return <>
|
|
50
|
-
base
|
|
51
|
-
indented
|
|
52
|
-
</>;
|
|
53
|
-
}
|
|
54
|
-
expect(
|
|
55
|
-
<Output>
|
|
56
|
-
<SourceFile path="hi.txt" filetype="text" indent=" ">
|
|
57
|
-
hello
|
|
58
|
-
there
|
|
59
|
-
|
|
60
|
-
<Nested />
|
|
61
|
-
<Nested />
|
|
62
|
-
</SourceFile>
|
|
63
|
-
</Output>,
|
|
64
|
-
).toRenderTo(`
|
|
65
|
-
hello
|
|
66
|
-
there
|
|
67
|
-
|
|
68
|
-
base
|
|
69
|
-
indented
|
|
70
|
-
base
|
|
71
|
-
indented
|
|
72
|
-
`);
|
|
73
|
-
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ref } from "@vue/reactivity";
|
|
2
|
+
import { expect, it } from "vitest";
|
|
3
|
+
import { Wrap } from "../../src/components/Wrap.jsx";
|
|
4
|
+
import { printTree, renderTree } from "../../src/render.js";
|
|
5
|
+
import "../../testing/extend-expect.js";
|
|
6
|
+
|
|
7
|
+
function Wrapper(props: any) {
|
|
8
|
+
return <>[{props.children}]</>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
it("conditionally wraps", () => {
|
|
12
|
+
const template = (
|
|
13
|
+
<>
|
|
14
|
+
<Wrap when={true} with={Wrapper}>
|
|
15
|
+
testing
|
|
16
|
+
</Wrap>
|
|
17
|
+
<Wrap when={false} with={Wrapper}>
|
|
18
|
+
testing
|
|
19
|
+
</Wrap>
|
|
20
|
+
</>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
expect(template).toRenderTo(`[testing]testing`);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("works reactively", () => {
|
|
27
|
+
const doWrap = ref(false);
|
|
28
|
+
const template = (
|
|
29
|
+
<>
|
|
30
|
+
<Wrap when={doWrap.value} with={Wrapper}>
|
|
31
|
+
testing
|
|
32
|
+
</Wrap>
|
|
33
|
+
</>
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const tree = renderTree(template);
|
|
37
|
+
expect(printTree(tree)).toEqual(`testing`);
|
|
38
|
+
|
|
39
|
+
doWrap.value = true;
|
|
40
|
+
|
|
41
|
+
expect(printTree(tree)).toEqual(`testing`);
|
|
42
|
+
});
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import "@alloy-js/core/testing";
|
|
2
|
+
import { d } from "@alloy-js/core/testing";
|
|
3
|
+
import { expect, it } from "vitest";
|
|
4
|
+
import { For } from "../../src/components/For.jsx";
|
|
5
|
+
import { onCleanup, printTree, reactive, renderTree } from "../../src/index.js";
|
|
6
|
+
|
|
7
|
+
it("works", () => {
|
|
8
|
+
const messages = ["hi", "bye"];
|
|
9
|
+
|
|
10
|
+
const template = (
|
|
11
|
+
<For each={messages}>{(message) => <>{message}, Jose!</>}</For>
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
expect(template).toRenderTo(`
|
|
15
|
+
hi, Jose!
|
|
16
|
+
bye, Jose!
|
|
17
|
+
`);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("handles map entries", () => {
|
|
21
|
+
const map = new Map([["a", { name: "foo" }]]);
|
|
22
|
+
const entries = Array.from(map.entries());
|
|
23
|
+
const template = (
|
|
24
|
+
<For each={entries}>
|
|
25
|
+
{([key, value]) => (
|
|
26
|
+
<>
|
|
27
|
+
{key}: {value.name}
|
|
28
|
+
</>
|
|
29
|
+
)}
|
|
30
|
+
</For>
|
|
31
|
+
);
|
|
32
|
+
expect(template).toRenderTo(`
|
|
33
|
+
a: foo
|
|
34
|
+
`);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("handles maps", () => {
|
|
38
|
+
const map = new Map([["a", { name: "foo" }]]);
|
|
39
|
+
const template = (
|
|
40
|
+
<For each={map}>
|
|
41
|
+
{(key, value) => (
|
|
42
|
+
<>
|
|
43
|
+
{key}: {value.name}
|
|
44
|
+
</>
|
|
45
|
+
)}
|
|
46
|
+
</For>
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
expect(template).toRenderTo(`
|
|
50
|
+
a: foo
|
|
51
|
+
`);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("doesn't rerender mappers", () => {
|
|
55
|
+
const messages = reactive(["hi", "bye"]);
|
|
56
|
+
let count = 0;
|
|
57
|
+
const template = <For each={messages}>{() => <>item {count++}</>}</For>;
|
|
58
|
+
const tree = renderTree(template);
|
|
59
|
+
expect(count).toBe(2);
|
|
60
|
+
|
|
61
|
+
messages.push("maybe");
|
|
62
|
+
|
|
63
|
+
expect(count).toBe(3);
|
|
64
|
+
expect(printTree(tree)).toBe(d`
|
|
65
|
+
item 0
|
|
66
|
+
item 1
|
|
67
|
+
item 2
|
|
68
|
+
`);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("doesn't rerender mappers with sets", () => {
|
|
72
|
+
const messages = reactive(new Set(["hi", "bye"]));
|
|
73
|
+
let count = 0;
|
|
74
|
+
const template = <For each={messages}>{() => <>item {count++}</>}</For>;
|
|
75
|
+
const tree = renderTree(template);
|
|
76
|
+
expect(count).toBe(2);
|
|
77
|
+
|
|
78
|
+
messages.add("maybe");
|
|
79
|
+
|
|
80
|
+
expect(count).toBe(3);
|
|
81
|
+
expect(printTree(tree)).toBe(d`
|
|
82
|
+
item 0
|
|
83
|
+
item 1
|
|
84
|
+
item 2
|
|
85
|
+
`);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("doesn't rerender mappers with maps", () => {
|
|
89
|
+
const messages = reactive(
|
|
90
|
+
new Map([
|
|
91
|
+
["hi", "one"],
|
|
92
|
+
["bye", "two"],
|
|
93
|
+
]),
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
let count = 0;
|
|
97
|
+
const template = <For each={messages}>{() => <>item {count++}</>}</For>;
|
|
98
|
+
const tree = renderTree(template);
|
|
99
|
+
expect(count).toBe(2);
|
|
100
|
+
|
|
101
|
+
messages.set("maybe", "three");
|
|
102
|
+
|
|
103
|
+
expect(count).toBe(3);
|
|
104
|
+
expect(printTree(tree)).toBe(d`
|
|
105
|
+
item 0
|
|
106
|
+
item 1
|
|
107
|
+
item 2
|
|
108
|
+
`);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("doesn't rerender mappers (with splice)", () => {
|
|
112
|
+
const messages = reactive(["hi", "maybe", "bye"]);
|
|
113
|
+
let count = 0;
|
|
114
|
+
const template = <For each={messages}>{(msg) => <>item {count++}</>}</For>;
|
|
115
|
+
const tree = renderTree(template);
|
|
116
|
+
expect(count).toBe(3);
|
|
117
|
+
messages.splice(1, 1);
|
|
118
|
+
// A sufficiently smart mapJoin would be able to handle this case...
|
|
119
|
+
// but for now we re-render everything after the splice point.
|
|
120
|
+
expect(count).toBe(4);
|
|
121
|
+
expect(printTree(tree)).toBe(d`
|
|
122
|
+
item 0
|
|
123
|
+
item 3
|
|
124
|
+
`);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("cleans up things which end up removed (with push)", () => {
|
|
128
|
+
const cleanups: string[] = [];
|
|
129
|
+
|
|
130
|
+
function Letter(props: any) {
|
|
131
|
+
onCleanup(() => {
|
|
132
|
+
cleanups.push(props.letter);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return <>Letter {props.letter}</>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const items = reactive(["a", "b"]);
|
|
139
|
+
|
|
140
|
+
const template = <For each={items}>{(item) => <Letter letter={item} />}</For>;
|
|
141
|
+
|
|
142
|
+
const tree = renderTree(template);
|
|
143
|
+
|
|
144
|
+
expect(cleanups).toEqual([]);
|
|
145
|
+
expect(printTree(tree)).toBe(d`
|
|
146
|
+
Letter a
|
|
147
|
+
Letter b
|
|
148
|
+
`);
|
|
149
|
+
|
|
150
|
+
items.pop();
|
|
151
|
+
expect(cleanups).toEqual(["b"]);
|
|
152
|
+
expect(printTree(tree)).toBe(d`
|
|
153
|
+
Letter a
|
|
154
|
+
`);
|
|
155
|
+
|
|
156
|
+
items.pop();
|
|
157
|
+
expect(cleanups).toEqual(["b", "a"]);
|
|
158
|
+
expect(printTree(tree)).toBe("");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("cleans up things which end up removed (with splice)", () => {
|
|
162
|
+
const cleanups: string[] = [];
|
|
163
|
+
|
|
164
|
+
function Letter(props: any) {
|
|
165
|
+
onCleanup(() => {
|
|
166
|
+
cleanups.push(props.letter);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return <>Letter {props.letter}</>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const items = reactive(["a", "b", "c"]);
|
|
173
|
+
|
|
174
|
+
const template = <For each={items}>{(item) => <Letter letter={item} />}</For>;
|
|
175
|
+
|
|
176
|
+
const tree = renderTree(template);
|
|
177
|
+
|
|
178
|
+
expect(cleanups).toEqual([]);
|
|
179
|
+
expect(printTree(tree)).toBe(d`
|
|
180
|
+
Letter a
|
|
181
|
+
Letter b
|
|
182
|
+
Letter c
|
|
183
|
+
`);
|
|
184
|
+
|
|
185
|
+
items.splice(1, 1);
|
|
186
|
+
|
|
187
|
+
// A sufficiently smart mapJoin would be able to handle this case...
|
|
188
|
+
// but for now we re-render everything after the splice point.
|
|
189
|
+
expect(cleanups).toEqual(["b", "c"]);
|
|
190
|
+
expect(printTree(tree)).toBe(d`
|
|
191
|
+
Letter a
|
|
192
|
+
Letter c
|
|
193
|
+
`);
|
|
194
|
+
});
|