@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,682 @@
|
|
|
1
|
+
import { createComponent as _$createComponent, memo as _$memo } from "@alloy-js/core/jsx-runtime";
|
|
2
|
+
import { code, Output, render } from "@alloy-js/core";
|
|
3
|
+
import { d } from "@alloy-js/core/testing";
|
|
4
|
+
import * as ts from "@alloy-js/typescript";
|
|
5
|
+
import { SourceFile } from "@alloy-js/typescript";
|
|
6
|
+
import { assert, beforeEach, describe, expect, it } from "vitest";
|
|
7
|
+
import { ArraySerializer, DateDeserializer, RecordSerializer } from "../../../src/typescript/components/static-serializers.js";
|
|
8
|
+
import { getTypeTransformerRefkey, ModelTransformExpression, TypeTransformCall, TypeTransformDeclaration } from "../../../src/typescript/components/type-transform.js";
|
|
9
|
+
import { TypeDeclaration } from "../../../src/typescript/index.js";
|
|
10
|
+
import { createEmitterFrameworkTestRunner } from "../test-host.js";
|
|
11
|
+
describe.skip("Typescript Type Transform", () => {
|
|
12
|
+
let testRunner;
|
|
13
|
+
const namePolicy = ts.createTSNamePolicy();
|
|
14
|
+
beforeEach(async () => {
|
|
15
|
+
testRunner = await createEmitterFrameworkTestRunner();
|
|
16
|
+
});
|
|
17
|
+
describe("Model Transforms", () => {
|
|
18
|
+
describe("ModelTransformExpression", () => {
|
|
19
|
+
it("should render a transform expression to client", async () => {
|
|
20
|
+
const spec = `
|
|
21
|
+
namespace DemoService;
|
|
22
|
+
@test model Widget {
|
|
23
|
+
id: string;
|
|
24
|
+
birth_year: int32;
|
|
25
|
+
color: "blue" | "red";
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
const {
|
|
29
|
+
Widget
|
|
30
|
+
} = await testRunner.compile(spec);
|
|
31
|
+
const res = render(_$createComponent(Output, {
|
|
32
|
+
namePolicy: namePolicy,
|
|
33
|
+
get children() {
|
|
34
|
+
return _$createComponent(SourceFile, {
|
|
35
|
+
path: "test.ts",
|
|
36
|
+
get children() {
|
|
37
|
+
return [code`
|
|
38
|
+
const wireWidget = {id: "1", birth_year: 1988, color: "blue"};
|
|
39
|
+
`, "const clientWidget =", " ", _$createComponent(ModelTransformExpression, {
|
|
40
|
+
type: Widget,
|
|
41
|
+
target: "application",
|
|
42
|
+
itemPath: ["wireWidget"]
|
|
43
|
+
})];
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}));
|
|
48
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
49
|
+
assert(testFile, "test.ts file not rendered");
|
|
50
|
+
const actualContent = testFile.contents;
|
|
51
|
+
const expectedContent = d`
|
|
52
|
+
const wireWidget = {id: "1", birth_year: 1988, color: "blue"};
|
|
53
|
+
const clientWidget = {
|
|
54
|
+
"id": wireWidget.id,
|
|
55
|
+
"birthYear": wireWidget.birth_year,
|
|
56
|
+
"color": wireWidget.color
|
|
57
|
+
}`;
|
|
58
|
+
expect(actualContent).toBe(expectedContent);
|
|
59
|
+
});
|
|
60
|
+
it("should render a transform expression to wire", async () => {
|
|
61
|
+
const spec = `
|
|
62
|
+
namespace DemoService;
|
|
63
|
+
@test model Widget {
|
|
64
|
+
id: string;
|
|
65
|
+
birth_year: int32;
|
|
66
|
+
color: "blue" | "red";
|
|
67
|
+
}
|
|
68
|
+
`;
|
|
69
|
+
const {
|
|
70
|
+
Widget
|
|
71
|
+
} = await testRunner.compile(spec);
|
|
72
|
+
const res = render(_$createComponent(Output, {
|
|
73
|
+
namePolicy: namePolicy,
|
|
74
|
+
get children() {
|
|
75
|
+
return _$createComponent(SourceFile, {
|
|
76
|
+
path: "test.ts",
|
|
77
|
+
get children() {
|
|
78
|
+
return [code`
|
|
79
|
+
const clientWidget = {id: "1", birthYear: 1988, color: "blue"};
|
|
80
|
+
`, "const wireWidget =", " ", _$createComponent(ModelTransformExpression, {
|
|
81
|
+
type: Widget,
|
|
82
|
+
target: "transport",
|
|
83
|
+
itemPath: ["clientWidget"]
|
|
84
|
+
})];
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}));
|
|
89
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
90
|
+
assert(testFile, "test.ts file not rendered");
|
|
91
|
+
const actualContent = testFile.contents;
|
|
92
|
+
const expectedContent = d`
|
|
93
|
+
const clientWidget = {id: "1", birthYear: 1988, color: "blue"};
|
|
94
|
+
const wireWidget = {
|
|
95
|
+
"id": clientWidget.id,
|
|
96
|
+
"birth_year": clientWidget.birthYear,
|
|
97
|
+
"color": clientWidget.color
|
|
98
|
+
}`;
|
|
99
|
+
expect(actualContent).toBe(expectedContent);
|
|
100
|
+
});
|
|
101
|
+
it("should render a transform expression that contains a utcDateTime to client", async () => {
|
|
102
|
+
const spec = `
|
|
103
|
+
namespace DemoService;
|
|
104
|
+
@test model Widget {
|
|
105
|
+
id: string;
|
|
106
|
+
birth_date: utcDateTime;
|
|
107
|
+
color: "blue" | "red";
|
|
108
|
+
}
|
|
109
|
+
`;
|
|
110
|
+
const {
|
|
111
|
+
Widget
|
|
112
|
+
} = await testRunner.compile(spec);
|
|
113
|
+
const res = render(_$createComponent(Output, {
|
|
114
|
+
namePolicy: namePolicy,
|
|
115
|
+
get children() {
|
|
116
|
+
return [_$createComponent(SourceFile, {
|
|
117
|
+
path: "static-serializers.ts",
|
|
118
|
+
get children() {
|
|
119
|
+
return _$createComponent(DateDeserializer, {});
|
|
120
|
+
}
|
|
121
|
+
}), _$createComponent(SourceFile, {
|
|
122
|
+
path: "test.ts",
|
|
123
|
+
get children() {
|
|
124
|
+
return [code`
|
|
125
|
+
const wireWidget = {id: "1", birth_date: "1988-04-29T19:30:00Z", color: "blue"};
|
|
126
|
+
`, "const clientWidget =", " ", _$createComponent(ModelTransformExpression, {
|
|
127
|
+
type: Widget,
|
|
128
|
+
target: "application",
|
|
129
|
+
itemPath: ["wireWidget"]
|
|
130
|
+
})];
|
|
131
|
+
}
|
|
132
|
+
})];
|
|
133
|
+
}
|
|
134
|
+
}));
|
|
135
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
136
|
+
assert(testFile, "test.ts file not rendered");
|
|
137
|
+
const actualContent = testFile.contents;
|
|
138
|
+
const expectedContent = d`
|
|
139
|
+
import { dateDeserializer } from "./static-serializers.js";
|
|
140
|
+
|
|
141
|
+
const wireWidget = {id: "1", birth_date: "1988-04-29T19:30:00Z", color: "blue"};
|
|
142
|
+
const clientWidget = {
|
|
143
|
+
"id": wireWidget.id,
|
|
144
|
+
"birthDate": dateDeserializer(wireWidget.birth_date),
|
|
145
|
+
"color": wireWidget.color
|
|
146
|
+
}`;
|
|
147
|
+
expect(actualContent).toBe(expectedContent);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
describe("TypeTransformDeclaration", () => {
|
|
151
|
+
it("should render a transform functions for a model containing array", async () => {
|
|
152
|
+
const spec = `
|
|
153
|
+
namespace DemoService;
|
|
154
|
+
@test model Widget {
|
|
155
|
+
id: string;
|
|
156
|
+
my_color: "blue" | "red";
|
|
157
|
+
simple?: string[];
|
|
158
|
+
complex: Widget[];
|
|
159
|
+
nested: Widget[][];
|
|
160
|
+
optionalString?: string;
|
|
161
|
+
}
|
|
162
|
+
`;
|
|
163
|
+
const {
|
|
164
|
+
Widget
|
|
165
|
+
} = await testRunner.compile(spec);
|
|
166
|
+
const res = render(_$createComponent(Output, {
|
|
167
|
+
namePolicy: namePolicy,
|
|
168
|
+
get children() {
|
|
169
|
+
return [_$createComponent(SourceFile, {
|
|
170
|
+
path: "serializers.ts",
|
|
171
|
+
get children() {
|
|
172
|
+
return _$createComponent(ArraySerializer, {});
|
|
173
|
+
}
|
|
174
|
+
}), _$createComponent(SourceFile, {
|
|
175
|
+
path: "test.ts",
|
|
176
|
+
get children() {
|
|
177
|
+
return [_$createComponent(TypeDeclaration, {
|
|
178
|
+
"export": true,
|
|
179
|
+
type: Widget
|
|
180
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
181
|
+
type: Widget,
|
|
182
|
+
target: "application"
|
|
183
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
184
|
+
type: Widget,
|
|
185
|
+
target: "transport"
|
|
186
|
+
})];
|
|
187
|
+
}
|
|
188
|
+
})];
|
|
189
|
+
}
|
|
190
|
+
}));
|
|
191
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
192
|
+
assert(testFile, "test.ts file not rendered");
|
|
193
|
+
const actualContent = testFile.contents;
|
|
194
|
+
const expectedContent = d`
|
|
195
|
+
import { arraySerializer } from "./serializers.js";
|
|
196
|
+
|
|
197
|
+
export interface Widget {
|
|
198
|
+
"id": string;
|
|
199
|
+
"myColor": "blue" | "red";
|
|
200
|
+
"simple"?: Array<string>;
|
|
201
|
+
"complex": Array<Widget>;
|
|
202
|
+
"nested": Array<Array<Widget>>;
|
|
203
|
+
"optionalString"?: string;
|
|
204
|
+
}
|
|
205
|
+
export function widgetToApplication(item: any) {
|
|
206
|
+
return {
|
|
207
|
+
"id": item.id,
|
|
208
|
+
"myColor": item.my_color,
|
|
209
|
+
"simple": item.simple ? arraySerializer(item.simple, ) : item.simple,
|
|
210
|
+
"complex": arraySerializer(item.complex, widgetToApplication),
|
|
211
|
+
"nested": arraySerializer(item.nested, (i: any) => arraySerializer(i, widgetToApplication)),
|
|
212
|
+
"optionalString": item.optionalString
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
export function widgetToTransport(item: Widget) {
|
|
216
|
+
return {
|
|
217
|
+
"id": item.id,
|
|
218
|
+
"my_color": item.myColor,
|
|
219
|
+
"simple": item.simple ? arraySerializer(item.simple, ) : item.simple,
|
|
220
|
+
"complex": arraySerializer(item.complex, widgetToTransport),
|
|
221
|
+
"nested": arraySerializer(item.nested, (i: any) => arraySerializer(i, widgetToTransport)),
|
|
222
|
+
"optionalString": item.optionalString
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
`;
|
|
226
|
+
expect(actualContent).toBe(expectedContent);
|
|
227
|
+
});
|
|
228
|
+
it("should render a transform functions for a model containing record", async () => {
|
|
229
|
+
const spec = `
|
|
230
|
+
namespace DemoService;
|
|
231
|
+
@test model Widget {
|
|
232
|
+
id: string;
|
|
233
|
+
my_color: "blue" | "red";
|
|
234
|
+
simple: Record<string>;
|
|
235
|
+
complex: Record<Widget>;
|
|
236
|
+
nested: Record<Record<Widget>>;
|
|
237
|
+
}
|
|
238
|
+
`;
|
|
239
|
+
const {
|
|
240
|
+
Widget
|
|
241
|
+
} = await testRunner.compile(spec);
|
|
242
|
+
const res = render(_$createComponent(Output, {
|
|
243
|
+
namePolicy: namePolicy,
|
|
244
|
+
get children() {
|
|
245
|
+
return [_$createComponent(SourceFile, {
|
|
246
|
+
path: "serializers.ts",
|
|
247
|
+
get children() {
|
|
248
|
+
return _$createComponent(RecordSerializer, {});
|
|
249
|
+
}
|
|
250
|
+
}), _$createComponent(SourceFile, {
|
|
251
|
+
path: "test.ts",
|
|
252
|
+
get children() {
|
|
253
|
+
return [_$createComponent(TypeDeclaration, {
|
|
254
|
+
"export": true,
|
|
255
|
+
type: Widget
|
|
256
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
257
|
+
type: Widget,
|
|
258
|
+
target: "application"
|
|
259
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
260
|
+
type: Widget,
|
|
261
|
+
target: "transport"
|
|
262
|
+
})];
|
|
263
|
+
}
|
|
264
|
+
})];
|
|
265
|
+
}
|
|
266
|
+
}));
|
|
267
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
268
|
+
assert(testFile, "test.ts file not rendered");
|
|
269
|
+
const actualContent = testFile.contents;
|
|
270
|
+
const expectedContent = d`
|
|
271
|
+
import { recordSerializer } from "./serializers.js";
|
|
272
|
+
|
|
273
|
+
export interface Widget {
|
|
274
|
+
"id": string;
|
|
275
|
+
"myColor": "blue" | "red";
|
|
276
|
+
"simple": Record<string, string>;
|
|
277
|
+
"complex": Record<string, Widget>;
|
|
278
|
+
"nested": Record<string, Record<string, Widget>>;
|
|
279
|
+
}
|
|
280
|
+
export function widgetToApplication(item: any) {
|
|
281
|
+
return {
|
|
282
|
+
"id": item.id,
|
|
283
|
+
"myColor": item.my_color,
|
|
284
|
+
"simple": recordSerializer(item.simple, ),
|
|
285
|
+
"complex": recordSerializer(item.complex, widgetToApplication),
|
|
286
|
+
"nested": recordSerializer(item.nested, (i: any) => recordSerializer(i, widgetToApplication))
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
export function widgetToTransport(item: Widget) {
|
|
290
|
+
return {
|
|
291
|
+
"id": item.id,
|
|
292
|
+
"my_color": item.myColor,
|
|
293
|
+
"simple": recordSerializer(item.simple, ),
|
|
294
|
+
"complex": recordSerializer(item.complex, widgetToTransport),
|
|
295
|
+
"nested": recordSerializer(item.nested, (i: any) => recordSerializer(i, widgetToTransport))
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
`;
|
|
299
|
+
expect(actualContent).toBe(expectedContent);
|
|
300
|
+
});
|
|
301
|
+
it("should render a transform functions for a model", async () => {
|
|
302
|
+
const spec = `
|
|
303
|
+
namespace DemoService;
|
|
304
|
+
@test model Widget {
|
|
305
|
+
id: string;
|
|
306
|
+
my_color: "blue" | "red";
|
|
307
|
+
}
|
|
308
|
+
`;
|
|
309
|
+
const {
|
|
310
|
+
Widget
|
|
311
|
+
} = await testRunner.compile(spec);
|
|
312
|
+
const res = render(_$createComponent(Output, {
|
|
313
|
+
namePolicy: namePolicy,
|
|
314
|
+
get children() {
|
|
315
|
+
return _$createComponent(SourceFile, {
|
|
316
|
+
path: "test.ts",
|
|
317
|
+
get children() {
|
|
318
|
+
return [_$createComponent(TypeDeclaration, {
|
|
319
|
+
"export": true,
|
|
320
|
+
type: Widget
|
|
321
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
322
|
+
type: Widget,
|
|
323
|
+
target: "application"
|
|
324
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
325
|
+
type: Widget,
|
|
326
|
+
target: "transport"
|
|
327
|
+
})];
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}));
|
|
332
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
333
|
+
assert(testFile, "test.ts file not rendered");
|
|
334
|
+
const actualContent = testFile.contents;
|
|
335
|
+
const expectedContent = d`
|
|
336
|
+
export interface Widget {
|
|
337
|
+
"id": string;
|
|
338
|
+
"myColor": "blue" | "red";
|
|
339
|
+
}
|
|
340
|
+
export function widgetToApplication(item: any) {
|
|
341
|
+
return {
|
|
342
|
+
"id": item.id,
|
|
343
|
+
"myColor": item.my_color
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
export function widgetToTransport(item: Widget) {
|
|
347
|
+
return {
|
|
348
|
+
"id": item.id,
|
|
349
|
+
"my_color": item.myColor
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
`;
|
|
353
|
+
expect(actualContent).toBe(expectedContent);
|
|
354
|
+
});
|
|
355
|
+
});
|
|
356
|
+
describe("Calling a model transform functions", () => {
|
|
357
|
+
it("should collapse a model with single property", async () => {
|
|
358
|
+
const spec = `
|
|
359
|
+
namespace DemoService;
|
|
360
|
+
@test model Widget {
|
|
361
|
+
id: string;
|
|
362
|
+
}
|
|
363
|
+
`;
|
|
364
|
+
const {
|
|
365
|
+
Widget
|
|
366
|
+
} = await testRunner.compile(spec);
|
|
367
|
+
const res = render(_$createComponent(Output, {
|
|
368
|
+
namePolicy: namePolicy,
|
|
369
|
+
get children() {
|
|
370
|
+
return _$createComponent(SourceFile, {
|
|
371
|
+
path: "test.ts",
|
|
372
|
+
get children() {
|
|
373
|
+
return code`
|
|
374
|
+
const clientWidget = {id: "1", my_color: "blue"};
|
|
375
|
+
const wireWidget = ${_$createComponent(TypeTransformCall, {
|
|
376
|
+
itemPath: ["clientWidget"],
|
|
377
|
+
type: Widget,
|
|
378
|
+
collapse: true,
|
|
379
|
+
target: "transport"
|
|
380
|
+
})}
|
|
381
|
+
`;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
}));
|
|
386
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
387
|
+
assert(testFile, "test.ts file not rendered");
|
|
388
|
+
const actualContent = testFile.contents;
|
|
389
|
+
const expectedContent = d`
|
|
390
|
+
const clientWidget = {id: "1", my_color: "blue"};
|
|
391
|
+
const wireWidget = clientWidget.id
|
|
392
|
+
`;
|
|
393
|
+
expect(actualContent).toBe(expectedContent);
|
|
394
|
+
});
|
|
395
|
+
it("should call transform functions for a model", async () => {
|
|
396
|
+
const spec = `
|
|
397
|
+
namespace DemoService;
|
|
398
|
+
@test model Widget {
|
|
399
|
+
id: string;
|
|
400
|
+
my_color: "blue" | "red";
|
|
401
|
+
}
|
|
402
|
+
`;
|
|
403
|
+
const {
|
|
404
|
+
Widget
|
|
405
|
+
} = await testRunner.compile(spec);
|
|
406
|
+
const res = render(_$createComponent(Output, {
|
|
407
|
+
namePolicy: namePolicy,
|
|
408
|
+
get children() {
|
|
409
|
+
return [_$createComponent(SourceFile, {
|
|
410
|
+
path: "types.ts",
|
|
411
|
+
get children() {
|
|
412
|
+
return [_$createComponent(TypeDeclaration, {
|
|
413
|
+
"export": true,
|
|
414
|
+
type: Widget
|
|
415
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
416
|
+
type: Widget,
|
|
417
|
+
target: "application"
|
|
418
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
419
|
+
type: Widget,
|
|
420
|
+
target: "transport"
|
|
421
|
+
})];
|
|
422
|
+
}
|
|
423
|
+
}), _$createComponent(SourceFile, {
|
|
424
|
+
path: "test.ts",
|
|
425
|
+
get children() {
|
|
426
|
+
return code`
|
|
427
|
+
const wireWidget = {id: "1", my_color: "blue"};
|
|
428
|
+
const clientWidget = ${_$createComponent(ts.FunctionCallExpression, {
|
|
429
|
+
get target() {
|
|
430
|
+
return getTypeTransformerRefkey(Widget, "application");
|
|
431
|
+
},
|
|
432
|
+
get args() {
|
|
433
|
+
return [["wireWidget"]];
|
|
434
|
+
}
|
|
435
|
+
})};
|
|
436
|
+
const wireWidget2 = ${_$createComponent(ts.FunctionCallExpression, {
|
|
437
|
+
get target() {
|
|
438
|
+
return getTypeTransformerRefkey(Widget, "transport");
|
|
439
|
+
},
|
|
440
|
+
args: ["clientWidget"]
|
|
441
|
+
})};
|
|
442
|
+
`;
|
|
443
|
+
}
|
|
444
|
+
})];
|
|
445
|
+
}
|
|
446
|
+
}));
|
|
447
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
448
|
+
assert(testFile, "test.ts file not rendered");
|
|
449
|
+
const actualContent = testFile.contents;
|
|
450
|
+
const expectedContent = d`
|
|
451
|
+
import { widgetToApplication, widgetToTransport } from "./types.js";
|
|
452
|
+
|
|
453
|
+
const wireWidget = {id: "1", my_color: "blue"};
|
|
454
|
+
const clientWidget = widgetToApplication(wireWidget);
|
|
455
|
+
const wireWidget2 = widgetToTransport(clientWidget);
|
|
456
|
+
`;
|
|
457
|
+
expect(actualContent).toBe(expectedContent);
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
describe("Discriminated Model Transforms", () => {
|
|
462
|
+
it("should handle a discriminated union", async () => {
|
|
463
|
+
const {
|
|
464
|
+
Pet,
|
|
465
|
+
Cat,
|
|
466
|
+
Dog
|
|
467
|
+
} = await testRunner.compile(`
|
|
468
|
+
@discriminator("kind")
|
|
469
|
+
@test model Pet {
|
|
470
|
+
kind: string;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
@test model Cat extends Pet {
|
|
474
|
+
kind: "cat";
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
@test model Dog extends Pet {
|
|
478
|
+
kind: "dog";
|
|
479
|
+
}
|
|
480
|
+
`);
|
|
481
|
+
const res = render(_$createComponent(Output, {
|
|
482
|
+
namePolicy: namePolicy,
|
|
483
|
+
get children() {
|
|
484
|
+
return _$createComponent(SourceFile, {
|
|
485
|
+
path: "test.ts",
|
|
486
|
+
get children() {
|
|
487
|
+
return [_$createComponent(TypeDeclaration, {
|
|
488
|
+
"export": true,
|
|
489
|
+
type: Pet
|
|
490
|
+
}), _$createComponent(TypeDeclaration, {
|
|
491
|
+
"export": true,
|
|
492
|
+
type: Dog
|
|
493
|
+
}), _$createComponent(TypeDeclaration, {
|
|
494
|
+
"export": true,
|
|
495
|
+
type: Cat
|
|
496
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
497
|
+
type: Dog,
|
|
498
|
+
target: "application"
|
|
499
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
500
|
+
type: Dog,
|
|
501
|
+
target: "transport"
|
|
502
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
503
|
+
type: Cat,
|
|
504
|
+
target: "application"
|
|
505
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
506
|
+
type: Cat,
|
|
507
|
+
target: "transport"
|
|
508
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
509
|
+
type: Pet,
|
|
510
|
+
target: "application"
|
|
511
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
512
|
+
type: Pet,
|
|
513
|
+
target: "transport"
|
|
514
|
+
})];
|
|
515
|
+
}
|
|
516
|
+
});
|
|
517
|
+
}
|
|
518
|
+
}));
|
|
519
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
520
|
+
assert(testFile, "test.ts file not rendered");
|
|
521
|
+
const actualContent = testFile.contents;
|
|
522
|
+
const expectedContent = d`
|
|
523
|
+
export interface Pet {
|
|
524
|
+
"kind": string;
|
|
525
|
+
}
|
|
526
|
+
export interface Dog extends Pet {
|
|
527
|
+
"kind": "dog";
|
|
528
|
+
}
|
|
529
|
+
export interface Cat extends Pet {
|
|
530
|
+
"kind": "cat";
|
|
531
|
+
}
|
|
532
|
+
export function dogToApplication(item: any): Dog {
|
|
533
|
+
return {
|
|
534
|
+
"kind": item.kind
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
export function dogToTransport(item: Dog) {
|
|
538
|
+
return {
|
|
539
|
+
"kind": item.kind
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
export function catToApplication(item: any) {
|
|
543
|
+
return {
|
|
544
|
+
"kind": item.kind
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
export function catToTransport(item: Cat) {
|
|
548
|
+
return {
|
|
549
|
+
"kind": item.kind
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
export function petToApplication(item: any) {
|
|
553
|
+
if(item.kind === "cat") {
|
|
554
|
+
return catToApplication(item)
|
|
555
|
+
}
|
|
556
|
+
if(item.kind === "dog") {
|
|
557
|
+
return dogToApplication(item)
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
export function petToTransport(item: Pet) {
|
|
561
|
+
if(item.kind === "cat") {
|
|
562
|
+
return catToTransport(item)
|
|
563
|
+
}
|
|
564
|
+
if(item.kind === "dog") {
|
|
565
|
+
return dogToTransport(item)
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
`;
|
|
569
|
+
expect(actualContent).toBe(expectedContent);
|
|
570
|
+
});
|
|
571
|
+
});
|
|
572
|
+
describe("Discriminated Union Transforms", () => {
|
|
573
|
+
it("should handle a discriminated union", async () => {
|
|
574
|
+
const {
|
|
575
|
+
Pet,
|
|
576
|
+
Cat,
|
|
577
|
+
Dog
|
|
578
|
+
} = await testRunner.compile(`
|
|
579
|
+
@discriminator("kind")
|
|
580
|
+
@test union Pet {
|
|
581
|
+
cat: Cat;
|
|
582
|
+
dog: Dog;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
@test model Cat {
|
|
586
|
+
kind: "cat";
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
@test model Dog {
|
|
590
|
+
kind: "dog";
|
|
591
|
+
}
|
|
592
|
+
`);
|
|
593
|
+
const res = render(_$createComponent(Output, {
|
|
594
|
+
namePolicy: namePolicy,
|
|
595
|
+
get children() {
|
|
596
|
+
return _$createComponent(SourceFile, {
|
|
597
|
+
path: "test.ts",
|
|
598
|
+
get children() {
|
|
599
|
+
return [_$createComponent(TypeDeclaration, {
|
|
600
|
+
"export": true,
|
|
601
|
+
type: Pet
|
|
602
|
+
}), _$createComponent(TypeDeclaration, {
|
|
603
|
+
"export": true,
|
|
604
|
+
type: Dog
|
|
605
|
+
}), _$createComponent(TypeDeclaration, {
|
|
606
|
+
"export": true,
|
|
607
|
+
type: Cat
|
|
608
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
609
|
+
type: Dog,
|
|
610
|
+
target: "application"
|
|
611
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
612
|
+
type: Dog,
|
|
613
|
+
target: "transport"
|
|
614
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
615
|
+
type: Cat,
|
|
616
|
+
target: "application"
|
|
617
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
618
|
+
type: Cat,
|
|
619
|
+
target: "transport"
|
|
620
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
621
|
+
type: Pet,
|
|
622
|
+
target: "application"
|
|
623
|
+
}), _$createComponent(TypeTransformDeclaration, {
|
|
624
|
+
type: Pet,
|
|
625
|
+
target: "transport"
|
|
626
|
+
})];
|
|
627
|
+
}
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
}));
|
|
631
|
+
const testFile = res.contents.find(file => file.path === "test.ts");
|
|
632
|
+
assert(testFile, "test.ts file not rendered");
|
|
633
|
+
const actualContent = testFile.contents;
|
|
634
|
+
const expectedContent = d`
|
|
635
|
+
export type Pet = Cat | Dog;
|
|
636
|
+
export interface Dog {
|
|
637
|
+
"kind": "dog";
|
|
638
|
+
}
|
|
639
|
+
export interface Cat {
|
|
640
|
+
"kind": "cat";
|
|
641
|
+
}
|
|
642
|
+
export function dogToApplication(item: any): Dog {
|
|
643
|
+
return {
|
|
644
|
+
"kind": item.kind
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
export function dogToTransport(item: Dog) {
|
|
648
|
+
return {
|
|
649
|
+
"kind": item.kind
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
export function catToApplication(item: any) {
|
|
653
|
+
return {
|
|
654
|
+
"kind": item.kind
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
export function catToTransport(item: Cat) {
|
|
658
|
+
return {
|
|
659
|
+
"kind": item.kind
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
export function petToApplication(item: any) {
|
|
663
|
+
if(item.kind === "cat") {
|
|
664
|
+
return catToApplication(item)
|
|
665
|
+
}
|
|
666
|
+
if(item.kind === "dog") {
|
|
667
|
+
return dogToApplication(item)
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
export function petToTransport(item: Pet) {
|
|
671
|
+
if(item.kind === "cat") {
|
|
672
|
+
return catToTransport(item)
|
|
673
|
+
}
|
|
674
|
+
if(item.kind === "dog") {
|
|
675
|
+
return dogToTransport(item)
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
`;
|
|
679
|
+
expect(actualContent).toBe(expectedContent);
|
|
680
|
+
});
|
|
681
|
+
});
|
|
682
|
+
});
|