@alloy-js/core 0.18.0-dev.5 → 0.18.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/CHANGELOG.md +18 -0
- package/dist/src/debug.d.ts.map +1 -1
- package/dist/src/debug.js +1 -0
- package/dist/src/write-output.browser.d.ts.map +1 -1
- package/dist/src/write-output.browser.js +1 -0
- package/dist/test/browser-build.test.js +1 -1
- package/dist/test/components/slot.test.js +9 -7
- package/dist/testing/extend-expect.d.ts +1 -15
- package/dist/testing/extend-expect.d.ts.map +1 -1
- package/dist/testing/extend-expect.js +85 -13
- package/dist/testing/extend-expect.test.d.ts +2 -0
- package/dist/testing/extend-expect.test.d.ts.map +1 -0
- package/dist/testing/extend-expect.test.js +149 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/debug.ts +1 -0
- package/src/write-output.browser.ts +1 -0
- package/test/browser-build.test.ts +1 -1
- package/test/components/slot.test.tsx +6 -7
- package/testing/extend-expect.test.tsx +126 -0
- package/testing/extend-expect.ts +110 -25
- package/testing/vitest.d.ts +5 -1
- package/tsconfig.json +2 -1
|
@@ -51,7 +51,7 @@ it("works with string keys", () => {
|
|
|
51
51
|
);
|
|
52
52
|
});
|
|
53
53
|
|
|
54
|
-
const
|
|
54
|
+
const _tree = render(
|
|
55
55
|
<Output>
|
|
56
56
|
<SourceFile path="test.ts" filetype="ts">
|
|
57
57
|
<MyFunctionComponent name="foo" />
|
|
@@ -59,7 +59,7 @@ it("works with string keys", () => {
|
|
|
59
59
|
</Output>,
|
|
60
60
|
);
|
|
61
61
|
|
|
62
|
-
console.log(tree.contents[0].contents);
|
|
62
|
+
// console.log(tree.contents[0].contents);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
it("works with symbols", () => {
|
|
@@ -79,7 +79,6 @@ it("works with symbols", () => {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function MyFunctionComponent(props: FunctionComponentProps) {
|
|
82
|
-
const binder = useBinder();
|
|
83
82
|
const sym = new OutputSymbol(props.name, {
|
|
84
83
|
refkeys: refkey(),
|
|
85
84
|
});
|
|
@@ -108,7 +107,7 @@ it("works with symbols", () => {
|
|
|
108
107
|
);
|
|
109
108
|
});
|
|
110
109
|
|
|
111
|
-
const
|
|
110
|
+
const _tree = render(
|
|
112
111
|
<Output>
|
|
113
112
|
<SourceFile path="test.ts" filetype="ts">
|
|
114
113
|
<Scope name="foo">
|
|
@@ -118,7 +117,7 @@ it("works with symbols", () => {
|
|
|
118
117
|
</Output>,
|
|
119
118
|
);
|
|
120
119
|
|
|
121
|
-
console.log(tree.contents[0].contents);
|
|
120
|
+
// console.log(tree.contents[0].contents);
|
|
122
121
|
});
|
|
123
122
|
|
|
124
123
|
it("can rename", () => {
|
|
@@ -161,7 +160,7 @@ it("can rename", () => {
|
|
|
161
160
|
return binder!.resolveFQN("foo.bar") as Ref<OutputSymbol | undefined>;
|
|
162
161
|
}, "bazxxx");
|
|
163
162
|
|
|
164
|
-
const
|
|
163
|
+
const _tree = render(
|
|
165
164
|
<Output>
|
|
166
165
|
<SourceFile path="test.ts" filetype="ts">
|
|
167
166
|
<Scope name="foo">
|
|
@@ -171,5 +170,5 @@ it("can rename", () => {
|
|
|
171
170
|
</Output>,
|
|
172
171
|
);
|
|
173
172
|
|
|
174
|
-
console.log(tree.contents[0].contents);
|
|
173
|
+
// console.log(tree.contents[0].contents);
|
|
175
174
|
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Indent, Output, SourceDirectory, SourceFile } from "@alloy-js/core";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import "./extend-expect.js";
|
|
4
|
+
|
|
5
|
+
describe("toRenderTo", () => {
|
|
6
|
+
it("can validate structure without source files", () => {
|
|
7
|
+
expect(
|
|
8
|
+
<>
|
|
9
|
+
base
|
|
10
|
+
<Indent>indented</Indent>
|
|
11
|
+
</>,
|
|
12
|
+
).toRenderTo(`
|
|
13
|
+
base
|
|
14
|
+
indented
|
|
15
|
+
`);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("can expect the content of the single source file used", () => {
|
|
19
|
+
expect(
|
|
20
|
+
<Output>
|
|
21
|
+
<SourceFile path="Test.cs" tabWidth={4} filetype="csharp">
|
|
22
|
+
base
|
|
23
|
+
<Indent>indented</Indent>
|
|
24
|
+
</SourceFile>
|
|
25
|
+
</Output>,
|
|
26
|
+
).toRenderTo(`
|
|
27
|
+
base
|
|
28
|
+
indented
|
|
29
|
+
`);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("expect with specific file name", () => {
|
|
33
|
+
expect(
|
|
34
|
+
<Output>
|
|
35
|
+
<SourceFile path="Test.cs" tabWidth={4} filetype="csharp">
|
|
36
|
+
base
|
|
37
|
+
<Indent>indented</Indent>
|
|
38
|
+
</SourceFile>
|
|
39
|
+
</Output>,
|
|
40
|
+
).toRenderTo({
|
|
41
|
+
"Test.cs": `
|
|
42
|
+
base
|
|
43
|
+
indented
|
|
44
|
+
`,
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("expect with specific file name in SourceDirectory", () => {
|
|
49
|
+
expect(
|
|
50
|
+
<Output>
|
|
51
|
+
<SourceDirectory path="src">
|
|
52
|
+
<SourceFile path="test.txt" filetype="text">
|
|
53
|
+
content
|
|
54
|
+
</SourceFile>
|
|
55
|
+
</SourceDirectory>
|
|
56
|
+
</Output>,
|
|
57
|
+
).toRenderTo({
|
|
58
|
+
"src/test.txt": `
|
|
59
|
+
content
|
|
60
|
+
`,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("each source file respect their print options", () => {
|
|
65
|
+
expect(
|
|
66
|
+
<Output>
|
|
67
|
+
<SourceFile path="Test.cs" tabWidth={4} filetype="csharp">
|
|
68
|
+
base1
|
|
69
|
+
<Indent>indented</Indent>
|
|
70
|
+
</SourceFile>
|
|
71
|
+
<SourceFile path="Test.ts" tabWidth={2} filetype="csharp">
|
|
72
|
+
base2
|
|
73
|
+
<Indent>indented</Indent>
|
|
74
|
+
</SourceFile>
|
|
75
|
+
</Output>,
|
|
76
|
+
).toRenderTo({
|
|
77
|
+
"Test.cs": `
|
|
78
|
+
base1
|
|
79
|
+
indented
|
|
80
|
+
`,
|
|
81
|
+
"Test.ts": `
|
|
82
|
+
base2
|
|
83
|
+
indented
|
|
84
|
+
`,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
it("fails when content does not match", () => {
|
|
89
|
+
expect(() =>
|
|
90
|
+
expect(
|
|
91
|
+
<>
|
|
92
|
+
base
|
|
93
|
+
<Indent>indented</Indent>
|
|
94
|
+
</>,
|
|
95
|
+
).toRenderTo(`
|
|
96
|
+
base
|
|
97
|
+
wrong
|
|
98
|
+
`),
|
|
99
|
+
).toThrowError(/Render is incorrect/);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("fails when files don't match", () => {
|
|
103
|
+
expect(() =>
|
|
104
|
+
expect(
|
|
105
|
+
<Output>
|
|
106
|
+
<SourceFile path="Test.cs" tabWidth={4} filetype="csharp">
|
|
107
|
+
base1
|
|
108
|
+
<Indent>indented</Indent>
|
|
109
|
+
</SourceFile>
|
|
110
|
+
<SourceFile path="Test.ts" tabWidth={2} filetype="typescript">
|
|
111
|
+
base2
|
|
112
|
+
<Indent>indented</Indent>
|
|
113
|
+
</SourceFile>
|
|
114
|
+
</Output>,
|
|
115
|
+
).toRenderTo({
|
|
116
|
+
"Test.cs": `
|
|
117
|
+
bad
|
|
118
|
+
`,
|
|
119
|
+
"Test.ts": `
|
|
120
|
+
base2
|
|
121
|
+
indented
|
|
122
|
+
`,
|
|
123
|
+
}),
|
|
124
|
+
).toThrowError(/Render is incorrect/);
|
|
125
|
+
});
|
|
126
|
+
});
|
package/testing/extend-expect.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Children,
|
|
3
|
+
getContextForRenderNode,
|
|
4
|
+
printTree,
|
|
5
|
+
RenderedTextTree,
|
|
6
|
+
renderTree,
|
|
7
|
+
} from "@alloy-js/core";
|
|
8
|
+
import "vitest";
|
|
2
9
|
import { expect } from "vitest";
|
|
3
10
|
import { dedent } from "./render.js";
|
|
11
|
+
import "./vitest.d.ts";
|
|
4
12
|
|
|
5
13
|
interface ToRenderToOptions {
|
|
6
14
|
printWidth?: number;
|
|
@@ -11,36 +19,113 @@ interface ToRenderToOptions {
|
|
|
11
19
|
expect.extend({
|
|
12
20
|
toRenderTo(
|
|
13
21
|
received: Children,
|
|
14
|
-
expectedRaw: string,
|
|
22
|
+
expectedRaw: string | Record<string, string>,
|
|
15
23
|
renderOptions?: ToRenderToOptions,
|
|
16
24
|
) {
|
|
25
|
+
const message = () => `Render is${isNot ? " not" : ""} incorrect`;
|
|
26
|
+
|
|
17
27
|
const { isNot } = this;
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
const actual = renderAsFiles(received, renderOptions);
|
|
29
|
+
if (typeof expectedRaw === "string") {
|
|
30
|
+
const expected = dedent(expectedRaw);
|
|
31
|
+
let actualStr;
|
|
32
|
+
if (typeof actual === "string") {
|
|
33
|
+
actualStr = actual;
|
|
34
|
+
} else if (Object.keys(actual).length === 1) {
|
|
35
|
+
// If we have a single file, we can use its content directly.
|
|
36
|
+
actualStr = Object.values(actual)[0];
|
|
37
|
+
} else {
|
|
38
|
+
return {
|
|
39
|
+
pass: false,
|
|
40
|
+
message,
|
|
41
|
+
actual,
|
|
42
|
+
expected,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
pass: actualStr === expected,
|
|
47
|
+
message,
|
|
48
|
+
actual: actualStr,
|
|
49
|
+
expected,
|
|
50
|
+
};
|
|
51
|
+
} else if (typeof actual === "object" && typeof expectedRaw === "object") {
|
|
52
|
+
const expected = expectedRaw;
|
|
53
|
+
const dedentExpected: Record<string, string> = {};
|
|
54
|
+
for (const [key, value] of Object.entries(expected)) {
|
|
55
|
+
dedentExpected[key] = dedent(value);
|
|
56
|
+
}
|
|
57
|
+
const pass =
|
|
58
|
+
Object.keys(actual).length === Object.keys(expected).length &&
|
|
59
|
+
Object.entries(actual).every(([key, value]) => {
|
|
60
|
+
return dedentExpected[key] === value;
|
|
61
|
+
});
|
|
62
|
+
return {
|
|
63
|
+
pass,
|
|
64
|
+
message,
|
|
65
|
+
actual,
|
|
66
|
+
expected: dedentExpected,
|
|
67
|
+
};
|
|
68
|
+
} else {
|
|
69
|
+
return {
|
|
70
|
+
pass: false,
|
|
71
|
+
message,
|
|
72
|
+
actual,
|
|
73
|
+
expected: expectedRaw,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
29
76
|
},
|
|
30
77
|
});
|
|
31
78
|
|
|
32
|
-
|
|
79
|
+
function renderAsFiles(
|
|
80
|
+
received: Children,
|
|
81
|
+
options?: ToRenderToOptions,
|
|
82
|
+
): Record<string, string> | string {
|
|
83
|
+
const files: Record<string, string> = {};
|
|
84
|
+
const tree = renderTree(received);
|
|
33
85
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
86
|
+
// when passing Output, the first render tree child is the Output component.
|
|
87
|
+
const rootRenderOptions =
|
|
88
|
+
Array.isArray(tree) ?
|
|
89
|
+
(getContextForRenderNode(tree[0] as RenderedTextTree)?.meta
|
|
90
|
+
?.printOptions ?? {})
|
|
91
|
+
: {};
|
|
92
|
+
|
|
93
|
+
collectSourceFiles(tree);
|
|
94
|
+
function collectSourceFiles(root: RenderedTextTree) {
|
|
95
|
+
if (!Array.isArray(root)) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const context = getContextForRenderNode(root);
|
|
99
|
+
if (context?.meta?.sourceFile) {
|
|
100
|
+
files[context.meta.sourceFile.path] = printTree(root, {
|
|
101
|
+
printWidth:
|
|
102
|
+
options?.printWidth ??
|
|
103
|
+
context.meta?.printOptions?.printWidth ??
|
|
104
|
+
rootRenderOptions.printWidth,
|
|
105
|
+
tabWidth:
|
|
106
|
+
options?.tabWidth ??
|
|
107
|
+
context.meta?.printOptions?.tabWidth ??
|
|
108
|
+
rootRenderOptions.tabWidth,
|
|
109
|
+
useTabs:
|
|
110
|
+
options?.useTabs ??
|
|
111
|
+
context.meta?.printOptions?.useTabs ??
|
|
112
|
+
rootRenderOptions.useTabs,
|
|
113
|
+
});
|
|
114
|
+
} else {
|
|
115
|
+
visitChildren();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function visitChildren() {
|
|
119
|
+
for (const child of root) {
|
|
120
|
+
collectSourceFiles(child as RenderedTextTree);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
42
124
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
125
|
+
// If we found no source files, we return the tree as a string.
|
|
126
|
+
if (Object.keys(files).length === 0) {
|
|
127
|
+
return printTree(tree, options);
|
|
128
|
+
} else {
|
|
129
|
+
return files;
|
|
130
|
+
}
|
|
46
131
|
}
|
package/testing/vitest.d.ts
CHANGED
|
@@ -5,8 +5,12 @@ interface ToRenderToRenderOptions {
|
|
|
5
5
|
tabWidth?: number;
|
|
6
6
|
useTabs?: boolean;
|
|
7
7
|
}
|
|
8
|
+
|
|
8
9
|
interface CustomMatchers<R = unknown> {
|
|
9
|
-
toRenderTo: (
|
|
10
|
+
toRenderTo: (
|
|
11
|
+
str: string | Record<string, string>,
|
|
12
|
+
options?: ToRenderToRenderOptions,
|
|
13
|
+
) => R;
|
|
10
14
|
}
|
|
11
15
|
|
|
12
16
|
declare module "vitest" {
|