@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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog - @alloy-js/core
2
2
 
3
+ ## 0.18.1
4
+
5
+ ### Bug Fixes
6
+
7
+ - [#232](https://github.com/alloy-framework/alloy/pull/232) Improve `toRenderTo` test matcher to work better with SourceFiles
8
+
9
+
10
+ ## 0.18.0
11
+
12
+ ### Bug Fixes
13
+
14
+ - [#182](https://github.com/alloy-framework/alloy/pull/182) Added a `@alloy-js/core/testing/matchers` export to be added to `tsconfig.json` `types` in order to load the custom vitest matchers
15
+
16
+ ### Features
17
+
18
+ - [#198](https://github.com/alloy-framework/alloy/pull/198) Add `inline` option for `<Block>` component to define inline blocks
19
+
20
+
3
21
  ## 0.17.0
4
22
 
5
23
  ### Features
@@ -1 +1 @@
1
- {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/debug.ts"],"names":[],"mappings":"AAMA,UAAU,cAAc;IACtB,SAAS,EAAE;QACT,KAAK,IAAI,IAAI,CAAC;QACd,IAAI,IAAI,IAAI,CAAC;QACb,KAAK,IAAI,IAAI,CAAC;QACd,MAAM,IAAI,IAAI,CAAC;QACf,OAAO,IAAI,IAAI,CAAC;KACjB,CAAC;CACH;AAoGD,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,KAAK,EAAE,cAAc,CAAC;CAC3B;AA4FD,wBAAgB,WAAW,YAE1B"}
1
+ {"version":3,"file":"debug.d.ts","sourceRoot":"","sources":["../../src/debug.ts"],"names":[],"mappings":"AAOA,UAAU,cAAc;IACtB,SAAS,EAAE;QACT,KAAK,IAAI,IAAI,CAAC;QACd,IAAI,IAAI,IAAI,CAAC;QACb,KAAK,IAAI,IAAI,CAAC;QACd,MAAM,IAAI,IAAI,CAAC;QACf,OAAO,IAAI,IAAI,CAAC;KACjB,CAAC;CACH;AAoGD,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,KAAK,EAAE,cAAc,CAAC;CAC3B;AA4FD,wBAAgB,WAAW,YAE1B"}
package/dist/src/debug.js CHANGED
@@ -1,3 +1,4 @@
1
+ /* eslint-disable no-console */
1
2
  import { isReactive } from "@vue/reactivity";
2
3
  import Table from "cli-table3";
3
4
  import pc from "picocolors";
@@ -1 +1 @@
1
- {"version":3,"file":"write-output.browser.d.ts","sourceRoot":"","sources":["../../src/write-output.browser.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAE,MAAW,QAE7D"}
1
+ {"version":3,"file":"write-output.browser.d.ts","sourceRoot":"","sources":["../../src/write-output.browser.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAE,MAAW,QAG7D"}
@@ -1,3 +1,4 @@
1
1
  export function writeOutput(output, basePath = "") {
2
+ // eslint-disable-next-line no-console
2
3
  console.warn("writeOutput is not supported in a browser environment.");
3
4
  }
@@ -63,7 +63,7 @@ describe("Browser Build Test", () => {
63
63
  build: "vite build"
64
64
  }
65
65
  }, null, 2));
66
- });
66
+ }, 30_000);
67
67
  it("Vite should build successfully", () => {
68
68
  // Run Vite build process and wait for completion
69
69
  expect(() => {
@@ -23,7 +23,7 @@ it("works with string keys", () => {
23
23
  }), props => {
24
24
  return ["// original", _$memo(() => props.original)];
25
25
  });
26
- const tree = render(_$createComponent(Output, {
26
+ const _tree = render(_$createComponent(Output, {
27
27
  get children() {
28
28
  return _$createComponent(SourceFile, {
29
29
  path: "test.ts",
@@ -36,7 +36,8 @@ it("works with string keys", () => {
36
36
  });
37
37
  }
38
38
  }));
39
- console.log(tree.contents[0].contents);
39
+
40
+ // console.log(tree.contents[0].contents);
40
41
  });
41
42
  it("works with symbols", () => {
42
43
  const FunctionSlot = defineSlot(query => {
@@ -44,7 +45,6 @@ it("works with symbols", () => {
44
45
  return binder.resolveFQN(query.fqn);
45
46
  });
46
47
  function MyFunctionComponent(props) {
47
- const binder = useBinder();
48
48
  const sym = new OutputSymbol(props.name, {
49
49
  refkeys: refkey()
50
50
  });
@@ -66,7 +66,7 @@ it("works with symbols", () => {
66
66
  }), props => {
67
67
  return ["// original", _$memo(() => props.original)];
68
68
  });
69
- const tree = render(_$createComponent(Output, {
69
+ const _tree = render(_$createComponent(Output, {
70
70
  get children() {
71
71
  return _$createComponent(SourceFile, {
72
72
  path: "test.ts",
@@ -84,7 +84,8 @@ it("works with symbols", () => {
84
84
  });
85
85
  }
86
86
  }));
87
- console.log(tree.contents[0].contents);
87
+
88
+ // console.log(tree.contents[0].contents);
88
89
  });
89
90
  it("can rename", () => {
90
91
  const FunctionSlot = defineSlot(query => {
@@ -110,7 +111,7 @@ it("can rename", () => {
110
111
  const binder = useBinder();
111
112
  return binder.resolveFQN("foo.bar");
112
113
  }, "bazxxx");
113
- const tree = render(_$createComponent(Output, {
114
+ const _tree = render(_$createComponent(Output, {
114
115
  get children() {
115
116
  return _$createComponent(SourceFile, {
116
117
  path: "test.ts",
@@ -128,5 +129,6 @@ it("can rename", () => {
128
129
  });
129
130
  }
130
131
  }));
131
- console.log(tree.contents[0].contents);
132
+
133
+ // console.log(tree.contents[0].contents);
132
134
  });
@@ -1,17 +1,3 @@
1
1
  import "vitest";
2
- interface ToRenderToRenderOptions {
3
- printWidth?: number;
4
- tabWidth?: number;
5
- useTabs?: boolean;
6
- }
7
- interface CustomMatchers<R = unknown> {
8
- toRenderTo: (str: string, options?: ToRenderToRenderOptions) => R;
9
- }
10
- declare module "vitest" {
11
- interface Assertion<T = any> extends CustomMatchers<T> {
12
- }
13
- interface AsymmetricMatchersContaining extends CustomMatchers {
14
- }
15
- }
16
- export {};
2
+ import "./vitest.d.ts";
17
3
  //# sourceMappingURL=extend-expect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"extend-expect.d.ts","sourceRoot":"","sources":["../../testing/extend-expect.ts"],"names":[],"mappings":"AA+BA,OAAO,QAAQ,CAAC;AAEhB,UAAU,uBAAuB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AACD,UAAU,cAAc,CAAC,CAAC,GAAG,OAAO;IAClC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,uBAAuB,KAAK,CAAC,CAAC;CACnE;AAED,OAAO,QAAQ,QAAQ,CAAC;IACtB,UAAU,SAAS,CAAC,CAAC,GAAG,GAAG,CAAE,SAAQ,cAAc,CAAC,CAAC,CAAC;KAAG;IACzD,UAAU,4BAA6B,SAAQ,cAAc;KAAG;CACjE"}
1
+ {"version":3,"file":"extend-expect.d.ts","sourceRoot":"","sources":["../../testing/extend-expect.ts"],"names":[],"mappings":"AAOA,OAAO,QAAQ,CAAC;AAGhB,OAAO,eAAe,CAAC"}
@@ -1,22 +1,94 @@
1
- import { printTree, renderTree } from "@alloy-js/core";
1
+ import { getContextForRenderNode, printTree, renderTree } from "@alloy-js/core";
2
+ import "vitest";
2
3
  import { expect } from "vitest";
3
4
  import { dedent } from "./render.js";
5
+ import "./vitest.d.ts";
4
6
  expect.extend({
5
7
  toRenderTo(received, expectedRaw, renderOptions) {
8
+ const message = () => `Render is${isNot ? " not" : ""} incorrect`;
6
9
  const {
7
10
  isNot
8
11
  } = this;
9
- const tree = renderTree(received);
10
- const actual = printTree(tree, renderOptions);
11
- const expected = dedent(expectedRaw);
12
- return {
13
- pass: actual === expected,
14
- message: () => {
15
- return `Render is${isNot ? " not" : ""} incorrect`;
16
- },
17
- actual,
18
- expected
19
- };
12
+ const actual = renderAsFiles(received, renderOptions);
13
+ if (typeof expectedRaw === "string") {
14
+ const expected = dedent(expectedRaw);
15
+ let actualStr;
16
+ if (typeof actual === "string") {
17
+ actualStr = actual;
18
+ } else if (Object.keys(actual).length === 1) {
19
+ // If we have a single file, we can use its content directly.
20
+ actualStr = Object.values(actual)[0];
21
+ } else {
22
+ return {
23
+ pass: false,
24
+ message,
25
+ actual,
26
+ expected
27
+ };
28
+ }
29
+ return {
30
+ pass: actualStr === expected,
31
+ message,
32
+ actual: actualStr,
33
+ expected
34
+ };
35
+ } else if (typeof actual === "object" && typeof expectedRaw === "object") {
36
+ const expected = expectedRaw;
37
+ const dedentExpected = {};
38
+ for (const [key, value] of Object.entries(expected)) {
39
+ dedentExpected[key] = dedent(value);
40
+ }
41
+ const pass = Object.keys(actual).length === Object.keys(expected).length && Object.entries(actual).every(([key, value]) => {
42
+ return dedentExpected[key] === value;
43
+ });
44
+ return {
45
+ pass,
46
+ message,
47
+ actual,
48
+ expected: dedentExpected
49
+ };
50
+ } else {
51
+ return {
52
+ pass: false,
53
+ message,
54
+ actual,
55
+ expected: expectedRaw
56
+ };
57
+ }
20
58
  }
21
59
  });
22
- import "vitest";
60
+ function renderAsFiles(received, options) {
61
+ const files = {};
62
+ const tree = renderTree(received);
63
+
64
+ // when passing Output, the first render tree child is the Output component.
65
+ const rootRenderOptions = Array.isArray(tree) ? getContextForRenderNode(tree[0])?.meta?.printOptions ?? {} : {};
66
+ collectSourceFiles(tree);
67
+ function collectSourceFiles(root) {
68
+ if (!Array.isArray(root)) {
69
+ return;
70
+ }
71
+ const context = getContextForRenderNode(root);
72
+ if (context?.meta?.sourceFile) {
73
+ files[context.meta.sourceFile.path] = printTree(root, {
74
+ printWidth: options?.printWidth ?? context.meta?.printOptions?.printWidth ?? rootRenderOptions.printWidth,
75
+ tabWidth: options?.tabWidth ?? context.meta?.printOptions?.tabWidth ?? rootRenderOptions.tabWidth,
76
+ useTabs: options?.useTabs ?? context.meta?.printOptions?.useTabs ?? rootRenderOptions.useTabs
77
+ });
78
+ } else {
79
+ visitChildren();
80
+ }
81
+ function visitChildren() {
82
+ for (const child of root) {
83
+ collectSourceFiles(child);
84
+ }
85
+ }
86
+ }
87
+
88
+ // If we found no source files, we return the tree as a string.
89
+ if (Object.keys(files).length === 0) {
90
+ return printTree(tree, options);
91
+ } else {
92
+ return files;
93
+ }
94
+ }
@@ -0,0 +1,2 @@
1
+ import "./extend-expect.js";
2
+ //# sourceMappingURL=extend-expect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extend-expect.test.d.ts","sourceRoot":"","sources":["../../testing/extend-expect.test.tsx"],"names":[],"mappings":"AAEA,OAAO,oBAAoB,CAAC"}
@@ -0,0 +1,149 @@
1
+ import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
2
+ import { Indent, Output, SourceDirectory, SourceFile } from "@alloy-js/core";
3
+ import { describe, expect, it } from "vitest";
4
+ import "./extend-expect.js";
5
+ describe("toRenderTo", () => {
6
+ it("can validate structure without source files", () => {
7
+ expect(["base", _$createComponent(Indent, {
8
+ children: "indented"
9
+ })]).toRenderTo(`
10
+ base
11
+ indented
12
+ `);
13
+ });
14
+ it("can expect the content of the single source file used", () => {
15
+ expect(_$createComponent(Output, {
16
+ get children() {
17
+ return _$createComponent(SourceFile, {
18
+ path: "Test.cs",
19
+ tabWidth: 4,
20
+ filetype: "csharp",
21
+ get children() {
22
+ return ["base", _$createComponent(Indent, {
23
+ children: "indented"
24
+ })];
25
+ }
26
+ });
27
+ }
28
+ })).toRenderTo(`
29
+ base
30
+ indented
31
+ `);
32
+ });
33
+ it("expect with specific file name", () => {
34
+ expect(_$createComponent(Output, {
35
+ get children() {
36
+ return _$createComponent(SourceFile, {
37
+ path: "Test.cs",
38
+ tabWidth: 4,
39
+ filetype: "csharp",
40
+ get children() {
41
+ return ["base", _$createComponent(Indent, {
42
+ children: "indented"
43
+ })];
44
+ }
45
+ });
46
+ }
47
+ })).toRenderTo({
48
+ "Test.cs": `
49
+ base
50
+ indented
51
+ `
52
+ });
53
+ });
54
+ it("expect with specific file name in SourceDirectory", () => {
55
+ expect(_$createComponent(Output, {
56
+ get children() {
57
+ return _$createComponent(SourceDirectory, {
58
+ path: "src",
59
+ get children() {
60
+ return _$createComponent(SourceFile, {
61
+ path: "test.txt",
62
+ filetype: "text",
63
+ children: "content"
64
+ });
65
+ }
66
+ });
67
+ }
68
+ })).toRenderTo({
69
+ "src/test.txt": `
70
+ content
71
+ `
72
+ });
73
+ });
74
+ it("each source file respect their print options", () => {
75
+ expect(_$createComponent(Output, {
76
+ get children() {
77
+ return [_$createComponent(SourceFile, {
78
+ path: "Test.cs",
79
+ tabWidth: 4,
80
+ filetype: "csharp",
81
+ get children() {
82
+ return ["base1", _$createComponent(Indent, {
83
+ children: "indented"
84
+ })];
85
+ }
86
+ }), _$createComponent(SourceFile, {
87
+ path: "Test.ts",
88
+ tabWidth: 2,
89
+ filetype: "csharp",
90
+ get children() {
91
+ return ["base2", _$createComponent(Indent, {
92
+ children: "indented"
93
+ })];
94
+ }
95
+ })];
96
+ }
97
+ })).toRenderTo({
98
+ "Test.cs": `
99
+ base1
100
+ indented
101
+ `,
102
+ "Test.ts": `
103
+ base2
104
+ indented
105
+ `
106
+ });
107
+ });
108
+ it("fails when content does not match", () => {
109
+ expect(() => expect(["base", _$createComponent(Indent, {
110
+ children: "indented"
111
+ })]).toRenderTo(`
112
+ base
113
+ wrong
114
+ `)).toThrowError(/Render is incorrect/);
115
+ });
116
+ it("fails when files don't match", () => {
117
+ expect(() => expect(_$createComponent(Output, {
118
+ get children() {
119
+ return [_$createComponent(SourceFile, {
120
+ path: "Test.cs",
121
+ tabWidth: 4,
122
+ filetype: "csharp",
123
+ get children() {
124
+ return ["base1", _$createComponent(Indent, {
125
+ children: "indented"
126
+ })];
127
+ }
128
+ }), _$createComponent(SourceFile, {
129
+ path: "Test.ts",
130
+ tabWidth: 2,
131
+ filetype: "typescript",
132
+ get children() {
133
+ return ["base2", _$createComponent(Indent, {
134
+ children: "indented"
135
+ })];
136
+ }
137
+ })];
138
+ }
139
+ })).toRenderTo({
140
+ "Test.cs": `
141
+ bad
142
+ `,
143
+ "Test.ts": `
144
+ base2
145
+ indented
146
+ `
147
+ })).toThrowError(/Render is incorrect/);
148
+ });
149
+ });