@typespec/emitter-framework 0.6.0-dev.4 → 0.6.0-dev.6
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/src/core/context/name-policy-context.js +1 -2
- package/dist/src/core/index.js +1 -2
- package/dist/src/core/transport-name-policy.js +1 -2
- package/dist/src/core/write-output.js +1 -2
- package/dist/src/lib.js +1 -2
- package/dist/src/testing/index.js +1 -2
- package/dist/src/testing/scenario-test/harness.js +1 -2
- package/dist/src/testing/scenario-test/index.js +1 -2
- package/dist/src/testing/scenario-test/snippet-extractor.js +1 -2
- package/dist/src/testing/scenario-test/test-host.js +1 -2
- package/dist/src/typescript/components/array-expression.js +1 -2
- package/dist/src/typescript/components/arrow-function.js +2 -5
- package/dist/src/typescript/components/class-method.js +2 -4
- package/dist/src/typescript/components/enum-declaration.js +2 -4
- package/dist/src/typescript/components/function-declaration.js +2 -4
- package/dist/src/typescript/components/function-expression.js +2 -5
- package/dist/src/typescript/components/function-type.js +2 -5
- package/dist/src/typescript/components/index.js +1 -2
- package/dist/src/typescript/components/interface-declaration.js +2 -5
- package/dist/src/typescript/components/interface-member.js +2 -4
- package/dist/src/typescript/components/interface-method.d.ts.map +1 -1
- package/dist/src/typescript/components/interface-method.js +5 -8
- package/dist/src/typescript/components/record-expression.js +1 -2
- package/dist/src/typescript/components/static-serializers.js +1 -2
- package/dist/src/typescript/components/type-alias-declaration.js +2 -5
- package/dist/src/typescript/components/type-declaration.js +2 -4
- package/dist/src/typescript/components/type-expression.js +2 -4
- package/dist/src/typescript/components/type-transform.js +2 -4
- package/dist/src/typescript/components/union-declaration.js +2 -4
- package/dist/src/typescript/components/union-expression.js +2 -4
- package/dist/src/typescript/components/value-expression.js +2 -4
- package/dist/src/typescript/index.js +1 -2
- package/dist/src/typescript/lib.js +1 -2
- package/dist/src/typescript/utils/operation.js +1 -2
- package/dist/test/testing/snippet-extractor-csharp.test.js +96 -0
- package/dist/test/testing/snippet-extractor-java.test.js +104 -0
- package/dist/test/testing/snippet-extractor-python.test.js +33 -0
- package/dist/test/testing/snippet-extractor-typescript.test.js +161 -0
- package/dist/test/typescript/components/arrow-function.test.js +88 -0
- package/dist/test/typescript/components/enum-declaration.test.js +118 -0
- package/dist/test/typescript/components/function-declaration.test.js +246 -0
- package/dist/test/typescript/components/function-expression.test.js +88 -0
- package/dist/test/typescript/components/function-type.test.js +85 -0
- package/dist/test/typescript/components/interface-declaration.test.js +775 -0
- package/dist/test/typescript/components/interface-method.test.js +272 -0
- package/dist/test/typescript/components/member-expression.test.js +155 -0
- package/dist/test/typescript/components/type-alias-declaration.test.js +155 -0
- package/dist/test/typescript/components/type-transform.test.js +682 -0
- package/dist/test/typescript/components/union-declaration.test.js +205 -0
- package/dist/test/typescript/components/value-expression.test.js +199 -0
- package/dist/test/typescript/test-host.js +40 -0
- package/dist/test/utils.js +18 -0
- package/package.json +5 -10
- package/src/typescript/components/interface-method.tsx +2 -4
- package/test/typescript/components/interface-method.test.tsx +167 -2
- package/vitest.config.ts +2 -9
- package/babel.config.js +0 -4
- package/dist/src/core/context/index.js.map +0 -1
- package/dist/src/core/context/name-policy-context.js.map +0 -1
- package/dist/src/core/index.js.map +0 -1
- package/dist/src/core/transport-name-policy.js.map +0 -1
- package/dist/src/core/write-output.js.map +0 -1
- package/dist/src/lib.js.map +0 -1
- package/dist/src/testing/index.js.map +0 -1
- package/dist/src/testing/scenario-test/harness.js.map +0 -1
- package/dist/src/testing/scenario-test/index.js.map +0 -1
- package/dist/src/testing/scenario-test/snippet-extractor.js.map +0 -1
- package/dist/src/testing/scenario-test/test-host.js.map +0 -1
- package/dist/src/typescript/components/array-expression.js.map +0 -1
- package/dist/src/typescript/components/arrow-function.js.map +0 -1
- package/dist/src/typescript/components/class-method.js.map +0 -1
- package/dist/src/typescript/components/enum-declaration.js.map +0 -1
- package/dist/src/typescript/components/function-declaration.js.map +0 -1
- package/dist/src/typescript/components/function-expression.js.map +0 -1
- package/dist/src/typescript/components/function-type.js.map +0 -1
- package/dist/src/typescript/components/index.js.map +0 -1
- package/dist/src/typescript/components/interface-declaration.js.map +0 -1
- package/dist/src/typescript/components/interface-member.js.map +0 -1
- package/dist/src/typescript/components/interface-method.js.map +0 -1
- package/dist/src/typescript/components/record-expression.js.map +0 -1
- package/dist/src/typescript/components/static-serializers.js.map +0 -1
- package/dist/src/typescript/components/type-alias-declaration.js.map +0 -1
- package/dist/src/typescript/components/type-declaration.js.map +0 -1
- package/dist/src/typescript/components/type-expression.js.map +0 -1
- package/dist/src/typescript/components/type-transform.js.map +0 -1
- package/dist/src/typescript/components/union-declaration.js.map +0 -1
- package/dist/src/typescript/components/union-expression.js.map +0 -1
- package/dist/src/typescript/components/value-expression.js.map +0 -1
- package/dist/src/typescript/index.js.map +0 -1
- package/dist/src/typescript/lib.js.map +0 -1
- package/dist/src/typescript/utils/index.js.map +0 -1
- package/dist/src/typescript/utils/operation.js.map +0 -1
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { d } from "@alloy-js/core/testing";
|
|
2
|
+
import { beforeEach, describe, expect, it } from "vitest";
|
|
3
|
+
import { createSnipperExtractor, createTypeScriptExtractorConfig } from "../../src/testing/index.js";
|
|
4
|
+
describe("TypeScript Snippet Extractor", () => {
|
|
5
|
+
let extractor;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
extractor = createSnipperExtractor(createTypeScriptExtractorConfig());
|
|
8
|
+
});
|
|
9
|
+
it("should extract a class", async () => {
|
|
10
|
+
const content = d`
|
|
11
|
+
function bar(): number {
|
|
12
|
+
return 1;
|
|
13
|
+
}
|
|
14
|
+
class Foo {
|
|
15
|
+
constructor() {
|
|
16
|
+
console.log("Hello");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
`;
|
|
20
|
+
const snippet = extractor.getClass(content, "Foo");
|
|
21
|
+
expect(snippet).toBe(d`
|
|
22
|
+
class Foo {
|
|
23
|
+
constructor() {
|
|
24
|
+
console.log("Hello");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
`);
|
|
28
|
+
});
|
|
29
|
+
it("should extract an exported class", async () => {
|
|
30
|
+
const content = d`
|
|
31
|
+
function bar(): number {
|
|
32
|
+
return 1;
|
|
33
|
+
}
|
|
34
|
+
export class Foo {
|
|
35
|
+
constructor() {
|
|
36
|
+
console.log("Hello");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
const snippet = extractor.getClass(content, "Foo");
|
|
41
|
+
expect(snippet).toBe(d`
|
|
42
|
+
export class Foo {
|
|
43
|
+
constructor() {
|
|
44
|
+
console.log("Hello");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
`);
|
|
48
|
+
});
|
|
49
|
+
it("should extract a class that extends another", async () => {
|
|
50
|
+
const content = d`
|
|
51
|
+
export class Bar {
|
|
52
|
+
constructor() {
|
|
53
|
+
console.log("Hello");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export class Foo extends Bar {
|
|
57
|
+
constructor() {
|
|
58
|
+
console.log("Hello");
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
const snippet = extractor.getClass(content, "Foo");
|
|
63
|
+
expect(snippet).toBe(d`
|
|
64
|
+
export class Foo extends Bar {
|
|
65
|
+
constructor() {
|
|
66
|
+
console.log("Hello");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
`);
|
|
70
|
+
});
|
|
71
|
+
it("should extract a class that implements an interface", async () => {
|
|
72
|
+
const content = d`
|
|
73
|
+
export interface MyFoo {
|
|
74
|
+
bar(): number;
|
|
75
|
+
}
|
|
76
|
+
export class Foo implements MyFoo {
|
|
77
|
+
constructor() {
|
|
78
|
+
console.log("Hello");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
bar() {
|
|
82
|
+
return 1;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
`;
|
|
86
|
+
const snippet = extractor.getClass(content, "Foo");
|
|
87
|
+
expect(snippet).toBe(d`
|
|
88
|
+
export class Foo implements MyFoo {
|
|
89
|
+
constructor() {
|
|
90
|
+
console.log("Hello");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
bar() {
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
`);
|
|
98
|
+
});
|
|
99
|
+
it("should extract a generic class", async () => {
|
|
100
|
+
const content = d`
|
|
101
|
+
export interface MyFoo {
|
|
102
|
+
bar(): number;
|
|
103
|
+
}
|
|
104
|
+
class Box<Type> {
|
|
105
|
+
contents: Type;
|
|
106
|
+
constructor(value: Type) {
|
|
107
|
+
this.contents = value;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
`;
|
|
111
|
+
const snippet = extractor.getClass(content, "Box");
|
|
112
|
+
expect(snippet).toBe(d`
|
|
113
|
+
class Box<Type> {
|
|
114
|
+
contents: Type;
|
|
115
|
+
constructor(value: Type) {
|
|
116
|
+
this.contents = value;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
`);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
describe("TypeScript Snippet Extractor - Enums", () => {
|
|
123
|
+
let extractor;
|
|
124
|
+
beforeEach(() => {
|
|
125
|
+
extractor = createSnipperExtractor(createTypeScriptExtractorConfig());
|
|
126
|
+
});
|
|
127
|
+
it("should extract a basic enum", async () => {
|
|
128
|
+
const content = d`
|
|
129
|
+
enum Direction {
|
|
130
|
+
Up,
|
|
131
|
+
Down,
|
|
132
|
+
Left,
|
|
133
|
+
Right
|
|
134
|
+
}
|
|
135
|
+
`;
|
|
136
|
+
const snippet = extractor.getEnum(content, "Direction");
|
|
137
|
+
expect(snippet).toBe(d`
|
|
138
|
+
enum Direction {
|
|
139
|
+
Up,
|
|
140
|
+
Down,
|
|
141
|
+
Left,
|
|
142
|
+
Right
|
|
143
|
+
}
|
|
144
|
+
`);
|
|
145
|
+
});
|
|
146
|
+
it("should extract an exported enum", async () => {
|
|
147
|
+
const content = d`
|
|
148
|
+
export enum Status {
|
|
149
|
+
Active,
|
|
150
|
+
Inactive
|
|
151
|
+
}
|
|
152
|
+
`;
|
|
153
|
+
const snippet = extractor.getEnum(content, "Status");
|
|
154
|
+
expect(snippet).toBe(d`
|
|
155
|
+
export enum Status {
|
|
156
|
+
Active,
|
|
157
|
+
Inactive
|
|
158
|
+
}
|
|
159
|
+
`);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import { Output, render } from "@alloy-js/core";
|
|
3
|
+
import { d } from "@alloy-js/core/testing";
|
|
4
|
+
import { SourceFile } from "@alloy-js/typescript";
|
|
5
|
+
import { beforeEach, describe, it } from "vitest";
|
|
6
|
+
import { ArrowFunction } from "../../../src/typescript/components/arrow-function.js";
|
|
7
|
+
import { assertFileContents } from "../../utils.js";
|
|
8
|
+
import { createEmitterFrameworkTestRunner } from "../test-host.js";
|
|
9
|
+
describe("arrow functions with a `type` prop", () => {
|
|
10
|
+
let runner;
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
runner = await createEmitterFrameworkTestRunner();
|
|
13
|
+
});
|
|
14
|
+
it("creates a function", async () => {
|
|
15
|
+
const {
|
|
16
|
+
getName
|
|
17
|
+
} = await runner.compile(`
|
|
18
|
+
@test op getName(id: string): string;
|
|
19
|
+
`);
|
|
20
|
+
const res = render(_$createComponent(Output, {
|
|
21
|
+
get children() {
|
|
22
|
+
return _$createComponent(SourceFile, {
|
|
23
|
+
path: "test.ts",
|
|
24
|
+
get children() {
|
|
25
|
+
return _$createComponent(ArrowFunction, {
|
|
26
|
+
type: getName,
|
|
27
|
+
children: "console.log(\"Hello!\");"
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}));
|
|
33
|
+
assertFileContents(res, d`
|
|
34
|
+
(id: string): string => {
|
|
35
|
+
console.log("Hello!");
|
|
36
|
+
}
|
|
37
|
+
`);
|
|
38
|
+
});
|
|
39
|
+
it("creates an async function", async () => {
|
|
40
|
+
const {
|
|
41
|
+
getName
|
|
42
|
+
} = await runner.compile(`
|
|
43
|
+
@test op getName(id: string): string;
|
|
44
|
+
`);
|
|
45
|
+
const res = render(_$createComponent(Output, {
|
|
46
|
+
get children() {
|
|
47
|
+
return _$createComponent(SourceFile, {
|
|
48
|
+
path: "test.ts",
|
|
49
|
+
get children() {
|
|
50
|
+
return _$createComponent(ArrowFunction, {
|
|
51
|
+
async: true,
|
|
52
|
+
type: getName
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
assertFileContents(res, d`
|
|
59
|
+
async (id: string): Promise<string> => {}
|
|
60
|
+
`);
|
|
61
|
+
});
|
|
62
|
+
it("can append extra parameters with raw params provided", async () => {
|
|
63
|
+
const {
|
|
64
|
+
getName
|
|
65
|
+
} = await runner.compile(`
|
|
66
|
+
@test op getName(id: string): string;
|
|
67
|
+
`);
|
|
68
|
+
const res = render(_$createComponent(Output, {
|
|
69
|
+
get children() {
|
|
70
|
+
return _$createComponent(SourceFile, {
|
|
71
|
+
path: "test.ts",
|
|
72
|
+
get children() {
|
|
73
|
+
return _$createComponent(ArrowFunction, {
|
|
74
|
+
type: getName,
|
|
75
|
+
parameters: [{
|
|
76
|
+
name: "additionalParam",
|
|
77
|
+
type: "number"
|
|
78
|
+
}]
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}));
|
|
84
|
+
assertFileContents(res, d`
|
|
85
|
+
(additionalParam: number, id: string): string => {}
|
|
86
|
+
`);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { createComponent as _$createComponent, memo as _$memo } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import { List, refkey, StatementList } from "@alloy-js/core";
|
|
3
|
+
import { d } from "@alloy-js/core/testing";
|
|
4
|
+
import { describe, expect, it } from "vitest";
|
|
5
|
+
import { EnumDeclaration } from "../../../src/typescript/components/enum-declaration.js";
|
|
6
|
+
import { getEmitOutput } from "../../utils.js";
|
|
7
|
+
describe("Typescript Enum Declaration", () => {
|
|
8
|
+
it("takes an enum type parameter", async () => {
|
|
9
|
+
const code = `
|
|
10
|
+
enum Foo {
|
|
11
|
+
one: 1,
|
|
12
|
+
two: 2,
|
|
13
|
+
three: 3
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
const output = await getEmitOutput(code, program => {
|
|
17
|
+
const Foo = program.resolveTypeReference("Foo")[0];
|
|
18
|
+
return _$createComponent(EnumDeclaration, {
|
|
19
|
+
type: Foo
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
expect(output).toBe(d`
|
|
23
|
+
enum Foo {
|
|
24
|
+
one = 1,
|
|
25
|
+
two = 2,
|
|
26
|
+
three = 3
|
|
27
|
+
}
|
|
28
|
+
`);
|
|
29
|
+
});
|
|
30
|
+
it("takes a union type parameter", async () => {
|
|
31
|
+
const code = `
|
|
32
|
+
union Foo {
|
|
33
|
+
one: 1,
|
|
34
|
+
two: 2,
|
|
35
|
+
three: 3
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
const output = await getEmitOutput(code, program => {
|
|
39
|
+
const Foo = program.resolveTypeReference("Foo")[0];
|
|
40
|
+
return _$createComponent(EnumDeclaration, {
|
|
41
|
+
type: Foo
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
expect(output).toBe(d`
|
|
45
|
+
enum Foo {
|
|
46
|
+
one = 1,
|
|
47
|
+
two = 2,
|
|
48
|
+
three = 3
|
|
49
|
+
}
|
|
50
|
+
`);
|
|
51
|
+
});
|
|
52
|
+
it("can be referenced", async () => {
|
|
53
|
+
const code = `
|
|
54
|
+
enum Foo {
|
|
55
|
+
one: 1,
|
|
56
|
+
two: 2,
|
|
57
|
+
three: 3
|
|
58
|
+
}
|
|
59
|
+
`;
|
|
60
|
+
const output = await getEmitOutput(code, program => {
|
|
61
|
+
const Foo = program.resolveTypeReference("Foo")[0];
|
|
62
|
+
return _$createComponent(List, {
|
|
63
|
+
hardline: true,
|
|
64
|
+
get children() {
|
|
65
|
+
return [_$createComponent(EnumDeclaration, {
|
|
66
|
+
type: Foo
|
|
67
|
+
}), _$createComponent(StatementList, {
|
|
68
|
+
get children() {
|
|
69
|
+
return [_$memo(() => refkey(Foo)), _$memo(() => refkey(Foo.members.get("one")))];
|
|
70
|
+
}
|
|
71
|
+
})];
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
expect(output).toBe(d`
|
|
76
|
+
enum Foo {
|
|
77
|
+
one = 1,
|
|
78
|
+
two = 2,
|
|
79
|
+
three = 3
|
|
80
|
+
}
|
|
81
|
+
Foo;
|
|
82
|
+
Foo.one;
|
|
83
|
+
`);
|
|
84
|
+
});
|
|
85
|
+
it("can be referenced using union", async () => {
|
|
86
|
+
const code = `
|
|
87
|
+
union Foo {
|
|
88
|
+
one: 1,
|
|
89
|
+
two: 2,
|
|
90
|
+
three: 3
|
|
91
|
+
}
|
|
92
|
+
`;
|
|
93
|
+
const output = await getEmitOutput(code, program => {
|
|
94
|
+
const Foo = program.resolveTypeReference("Foo")[0];
|
|
95
|
+
return _$createComponent(List, {
|
|
96
|
+
hardline: true,
|
|
97
|
+
get children() {
|
|
98
|
+
return [_$createComponent(EnumDeclaration, {
|
|
99
|
+
type: Foo
|
|
100
|
+
}), _$createComponent(StatementList, {
|
|
101
|
+
get children() {
|
|
102
|
+
return [_$memo(() => refkey(Foo)), _$memo(() => refkey(Foo.variants.get("one")))];
|
|
103
|
+
}
|
|
104
|
+
})];
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
expect(output).toBe(d`
|
|
109
|
+
enum Foo {
|
|
110
|
+
one = 1,
|
|
111
|
+
two = 2,
|
|
112
|
+
three = 3
|
|
113
|
+
}
|
|
114
|
+
Foo;
|
|
115
|
+
Foo.one;
|
|
116
|
+
`);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import { Output, render } from "@alloy-js/core";
|
|
3
|
+
import { d } from "@alloy-js/core/testing";
|
|
4
|
+
import { SourceFile } from "@alloy-js/typescript";
|
|
5
|
+
import { format } from "prettier";
|
|
6
|
+
import { assert, describe, expect, it } from "vitest";
|
|
7
|
+
import { FunctionDeclaration } from "../../../src/typescript/components/function-declaration.js";
|
|
8
|
+
import { getProgram } from "../test-host.js";
|
|
9
|
+
describe("Typescript Function Declaration", () => {
|
|
10
|
+
describe("Function bound to Typespec Types", () => {
|
|
11
|
+
describe("Bound to Operation", () => {
|
|
12
|
+
it("creates a function", async () => {
|
|
13
|
+
const program = await getProgram(`
|
|
14
|
+
namespace DemoService;
|
|
15
|
+
op getName(id: string): string;
|
|
16
|
+
`);
|
|
17
|
+
const [namespace] = program.resolveTypeReference("DemoService");
|
|
18
|
+
const operation = Array.from(namespace.operations.values())[0];
|
|
19
|
+
const res = render(_$createComponent(Output, {
|
|
20
|
+
get children() {
|
|
21
|
+
return _$createComponent(SourceFile, {
|
|
22
|
+
path: "test.ts",
|
|
23
|
+
get children() {
|
|
24
|
+
return _$createComponent(FunctionDeclaration, {
|
|
25
|
+
type: operation
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}));
|
|
31
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
32
|
+
assert(testFile, "test.ts file not rendered");
|
|
33
|
+
const actualContent = await format(testFile.contents, {
|
|
34
|
+
parser: "typescript"
|
|
35
|
+
});
|
|
36
|
+
const expectedContent = await format(`function getName(id: string): string{}`, {
|
|
37
|
+
parser: "typescript"
|
|
38
|
+
});
|
|
39
|
+
expect(actualContent).toBe(expectedContent);
|
|
40
|
+
});
|
|
41
|
+
it("creates an async function", async () => {
|
|
42
|
+
const program = await getProgram(`
|
|
43
|
+
namespace DemoService;
|
|
44
|
+
op getName(id: string): string;
|
|
45
|
+
`);
|
|
46
|
+
const [namespace] = program.resolveTypeReference("DemoService");
|
|
47
|
+
const operation = Array.from(namespace.operations.values())[0];
|
|
48
|
+
const res = render(_$createComponent(Output, {
|
|
49
|
+
get children() {
|
|
50
|
+
return _$createComponent(SourceFile, {
|
|
51
|
+
path: "test.ts",
|
|
52
|
+
get children() {
|
|
53
|
+
return _$createComponent(FunctionDeclaration, {
|
|
54
|
+
async: true,
|
|
55
|
+
type: operation
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}));
|
|
61
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
62
|
+
assert(testFile, "test.ts file not rendered");
|
|
63
|
+
const actualContent = await format(testFile.contents, {
|
|
64
|
+
parser: "typescript"
|
|
65
|
+
});
|
|
66
|
+
const expectedContent = await format(d`async function getName(id: string): Promise<string> {
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
}`, {
|
|
70
|
+
parser: "typescript"
|
|
71
|
+
});
|
|
72
|
+
expect(actualContent).toBe(expectedContent);
|
|
73
|
+
});
|
|
74
|
+
it("exports a function", async () => {
|
|
75
|
+
const program = await getProgram(`
|
|
76
|
+
namespace DemoService;
|
|
77
|
+
op getName(id: string): string;
|
|
78
|
+
`);
|
|
79
|
+
const [namespace] = program.resolveTypeReference("DemoService");
|
|
80
|
+
const operation = Array.from(namespace.operations.values())[0];
|
|
81
|
+
const res = render(_$createComponent(Output, {
|
|
82
|
+
get children() {
|
|
83
|
+
return _$createComponent(SourceFile, {
|
|
84
|
+
path: "test.ts",
|
|
85
|
+
get children() {
|
|
86
|
+
return _$createComponent(FunctionDeclaration, {
|
|
87
|
+
"export": true,
|
|
88
|
+
type: operation
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}));
|
|
94
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
95
|
+
assert(testFile, "test.ts file not rendered");
|
|
96
|
+
const actualContent = await format(testFile.contents, {
|
|
97
|
+
parser: "typescript"
|
|
98
|
+
});
|
|
99
|
+
const expectedContent = await format(`export function getName(id: string): string{}`, {
|
|
100
|
+
parser: "typescript"
|
|
101
|
+
});
|
|
102
|
+
expect(actualContent).toBe(expectedContent);
|
|
103
|
+
});
|
|
104
|
+
it("can override name", async () => {
|
|
105
|
+
const program = await getProgram(`
|
|
106
|
+
namespace DemoService;
|
|
107
|
+
op getName(id: string): string;
|
|
108
|
+
`);
|
|
109
|
+
const [namespace] = program.resolveTypeReference("DemoService");
|
|
110
|
+
const operation = Array.from(namespace.operations.values())[0];
|
|
111
|
+
const res = render(_$createComponent(Output, {
|
|
112
|
+
get children() {
|
|
113
|
+
return _$createComponent(SourceFile, {
|
|
114
|
+
path: "test.ts",
|
|
115
|
+
get children() {
|
|
116
|
+
return _$createComponent(FunctionDeclaration, {
|
|
117
|
+
name: "newName",
|
|
118
|
+
type: operation
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}));
|
|
124
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
125
|
+
assert(testFile, "test.ts file not rendered");
|
|
126
|
+
const actualContent = await format(testFile.contents, {
|
|
127
|
+
parser: "typescript"
|
|
128
|
+
});
|
|
129
|
+
const expectedContent = await format(`function newName(id: string): string{}`, {
|
|
130
|
+
parser: "typescript"
|
|
131
|
+
});
|
|
132
|
+
expect(actualContent).toBe(expectedContent);
|
|
133
|
+
});
|
|
134
|
+
it("can append extra parameters with raw params provided", async () => {
|
|
135
|
+
const program = await getProgram(`
|
|
136
|
+
namespace DemoService;
|
|
137
|
+
op createPerson(id: string): string;
|
|
138
|
+
`);
|
|
139
|
+
const [namespace] = program.resolveTypeReference("DemoService");
|
|
140
|
+
const operation = Array.from(namespace.operations.values())[0];
|
|
141
|
+
const res = render(_$createComponent(Output, {
|
|
142
|
+
get children() {
|
|
143
|
+
return _$createComponent(SourceFile, {
|
|
144
|
+
path: "test.ts",
|
|
145
|
+
get children() {
|
|
146
|
+
return _$createComponent(FunctionDeclaration, {
|
|
147
|
+
type: operation,
|
|
148
|
+
parameters: [{
|
|
149
|
+
name: "name",
|
|
150
|
+
type: "string"
|
|
151
|
+
}, {
|
|
152
|
+
name: "age",
|
|
153
|
+
type: "number"
|
|
154
|
+
}]
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}));
|
|
160
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
161
|
+
assert(testFile, "test.ts file not rendered");
|
|
162
|
+
const actualContent = await format(testFile.contents, {
|
|
163
|
+
parser: "typescript"
|
|
164
|
+
});
|
|
165
|
+
const expectedContent = await format(`function createPerson(name: string, age: number, id: string): string{}`, {
|
|
166
|
+
parser: "typescript"
|
|
167
|
+
});
|
|
168
|
+
expect(actualContent).toBe(expectedContent);
|
|
169
|
+
});
|
|
170
|
+
it.skip("can override parameters with an array of ModelProperties", async () => {
|
|
171
|
+
const program = await getProgram(`
|
|
172
|
+
namespace DemoService;
|
|
173
|
+
op createPerson(id: string): string;
|
|
174
|
+
|
|
175
|
+
model Foo {
|
|
176
|
+
name: string;
|
|
177
|
+
age: int32;
|
|
178
|
+
}
|
|
179
|
+
`);
|
|
180
|
+
const [namespace] = program.resolveTypeReference("DemoService");
|
|
181
|
+
const operation = Array.from(namespace.operations.values())[0];
|
|
182
|
+
const model = Array.from(namespace.models.values())[0];
|
|
183
|
+
const res = render(_$createComponent(Output, {
|
|
184
|
+
get children() {
|
|
185
|
+
return _$createComponent(SourceFile, {
|
|
186
|
+
path: "test.ts",
|
|
187
|
+
get children() {
|
|
188
|
+
return _$createComponent(FunctionDeclaration, {
|
|
189
|
+
type: operation,
|
|
190
|
+
get children() {
|
|
191
|
+
return _$createComponent(FunctionDeclaration.Parameters, {
|
|
192
|
+
type: model
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}));
|
|
200
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
201
|
+
assert(testFile, "test.ts file not rendered");
|
|
202
|
+
const actualContent = await format(testFile.contents, {
|
|
203
|
+
parser: "typescript"
|
|
204
|
+
});
|
|
205
|
+
const expectedContent = await format(`function createPerson(name: string, age: number): string{}`, {
|
|
206
|
+
parser: "typescript"
|
|
207
|
+
});
|
|
208
|
+
expect(actualContent).toBe(expectedContent);
|
|
209
|
+
});
|
|
210
|
+
it("can render function body", async () => {
|
|
211
|
+
const program = await getProgram(`
|
|
212
|
+
namespace DemoService;
|
|
213
|
+
op createPerson(id: string): string;
|
|
214
|
+
`);
|
|
215
|
+
const [namespace] = program.resolveTypeReference("DemoService");
|
|
216
|
+
const operation = Array.from(namespace.operations.values())[0];
|
|
217
|
+
const res = render(_$createComponent(Output, {
|
|
218
|
+
get children() {
|
|
219
|
+
return _$createComponent(SourceFile, {
|
|
220
|
+
path: "test.ts",
|
|
221
|
+
get children() {
|
|
222
|
+
return _$createComponent(FunctionDeclaration, {
|
|
223
|
+
"export": true,
|
|
224
|
+
type: operation,
|
|
225
|
+
children: "const message = \"Hello World!\"; console.log(message);"
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}));
|
|
231
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
232
|
+
assert(testFile, "test.ts file not rendered");
|
|
233
|
+
const actualContent = await format(testFile.contents, {
|
|
234
|
+
parser: "typescript"
|
|
235
|
+
});
|
|
236
|
+
const expectedContent = await format(`export function createPerson(id: string): string {
|
|
237
|
+
const message = "Hello World!";
|
|
238
|
+
console.log(message);
|
|
239
|
+
}`, {
|
|
240
|
+
parser: "typescript"
|
|
241
|
+
});
|
|
242
|
+
expect(actualContent).toBe(expectedContent);
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { createComponent as _$createComponent } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import { Output, render } from "@alloy-js/core";
|
|
3
|
+
import { d } from "@alloy-js/core/testing";
|
|
4
|
+
import { SourceFile } from "@alloy-js/typescript";
|
|
5
|
+
import { beforeEach, describe, it } from "vitest";
|
|
6
|
+
import { FunctionExpression } from "../../../src/typescript/components/function-expression.js";
|
|
7
|
+
import { assertFileContents } from "../../utils.js";
|
|
8
|
+
import { createEmitterFrameworkTestRunner } from "../test-host.js";
|
|
9
|
+
describe("function expressions with a `type` prop", () => {
|
|
10
|
+
let runner;
|
|
11
|
+
beforeEach(async () => {
|
|
12
|
+
runner = await createEmitterFrameworkTestRunner();
|
|
13
|
+
});
|
|
14
|
+
it("creates a function", async () => {
|
|
15
|
+
const {
|
|
16
|
+
getName
|
|
17
|
+
} = await runner.compile(`
|
|
18
|
+
@test op getName(id: string): string;
|
|
19
|
+
`);
|
|
20
|
+
const res = render(_$createComponent(Output, {
|
|
21
|
+
get children() {
|
|
22
|
+
return _$createComponent(SourceFile, {
|
|
23
|
+
path: "test.ts",
|
|
24
|
+
get children() {
|
|
25
|
+
return _$createComponent(FunctionExpression, {
|
|
26
|
+
type: getName,
|
|
27
|
+
children: "console.log(\"Hello!\");"
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
}));
|
|
33
|
+
assertFileContents(res, d`
|
|
34
|
+
function (id: string): string {
|
|
35
|
+
console.log("Hello!");
|
|
36
|
+
}
|
|
37
|
+
`);
|
|
38
|
+
});
|
|
39
|
+
it("creates an async function", async () => {
|
|
40
|
+
const {
|
|
41
|
+
getName
|
|
42
|
+
} = await runner.compile(`
|
|
43
|
+
@test op getName(id: string): string;
|
|
44
|
+
`);
|
|
45
|
+
const res = render(_$createComponent(Output, {
|
|
46
|
+
get children() {
|
|
47
|
+
return _$createComponent(SourceFile, {
|
|
48
|
+
path: "test.ts",
|
|
49
|
+
get children() {
|
|
50
|
+
return _$createComponent(FunctionExpression, {
|
|
51
|
+
async: true,
|
|
52
|
+
type: getName
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}));
|
|
58
|
+
assertFileContents(res, d`
|
|
59
|
+
async function (id: string): Promise<string> {}
|
|
60
|
+
`);
|
|
61
|
+
});
|
|
62
|
+
it("can append extra parameters with raw params provided", async () => {
|
|
63
|
+
const {
|
|
64
|
+
getName
|
|
65
|
+
} = await runner.compile(`
|
|
66
|
+
@test op getName(id: string): string;
|
|
67
|
+
`);
|
|
68
|
+
const res = render(_$createComponent(Output, {
|
|
69
|
+
get children() {
|
|
70
|
+
return _$createComponent(SourceFile, {
|
|
71
|
+
path: "test.ts",
|
|
72
|
+
get children() {
|
|
73
|
+
return _$createComponent(FunctionExpression, {
|
|
74
|
+
type: getName,
|
|
75
|
+
parameters: [{
|
|
76
|
+
name: "additionalParam",
|
|
77
|
+
type: "number"
|
|
78
|
+
}]
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}));
|
|
84
|
+
assertFileContents(res, d`
|
|
85
|
+
function (additionalParam: number, id: string): string {}
|
|
86
|
+
`);
|
|
87
|
+
});
|
|
88
|
+
});
|