@typespec/emitter-framework 0.9.0-dev.1 → 0.9.0-dev.3
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/csharp/components/class-declaration.d.ts +9 -0
- package/dist/src/csharp/components/class-declaration.d.ts.map +1 -0
- package/dist/src/csharp/components/class-declaration.js +97 -0
- package/dist/src/csharp/components/enum-declaration.d.ts +9 -0
- package/dist/src/csharp/components/enum-declaration.d.ts.map +1 -0
- package/dist/src/csharp/components/enum-declaration.js +52 -0
- package/dist/src/csharp/components/index.d.ts +4 -0
- package/dist/src/csharp/components/index.d.ts.map +1 -0
- package/dist/src/csharp/components/index.js +3 -0
- package/dist/src/csharp/components/type-expression.d.ts +11 -0
- package/dist/src/csharp/components/type-expression.d.ts.map +1 -0
- package/dist/src/csharp/components/type-expression.js +129 -0
- package/dist/src/csharp/components/utils/refkey.d.ts +23 -0
- package/dist/src/csharp/components/utils/refkey.d.ts.map +1 -0
- package/dist/src/csharp/components/utils/refkey.js +35 -0
- package/dist/src/csharp/index.d.ts +2 -0
- package/dist/src/csharp/index.d.ts.map +1 -0
- package/dist/src/csharp/index.js +1 -0
- package/dist/test/csharp/components/class-declaration.test.d.ts +2 -0
- package/dist/test/csharp/components/class-declaration.test.d.ts.map +1 -0
- package/dist/test/csharp/components/class-declaration.test.js +421 -0
- package/dist/test/csharp/components/enum-declaration.test.d.ts +2 -0
- package/dist/test/csharp/components/enum-declaration.test.d.ts.map +1 -0
- package/dist/test/csharp/components/enum-declaration.test.js +355 -0
- package/dist/test/csharp/test-host.d.ts +11 -0
- package/dist/test/csharp/test-host.d.ts.map +1 -0
- package/dist/test/csharp/test-host.js +32 -0
- package/dist/test/csharp/utils.d.ts +3 -0
- package/dist/test/csharp/utils.d.ts.map +1 -0
- package/dist/test/csharp/utils.js +6 -0
- package/package.json +5 -1
- package/src/csharp/components/class-declaration.tsx +87 -0
- package/src/csharp/components/enum-declaration.tsx +48 -0
- package/src/csharp/components/index.ts +3 -0
- package/src/csharp/components/type-expression.tsx +112 -0
- package/src/csharp/components/utils/refkey.ts +36 -0
- package/src/csharp/index.ts +1 -0
- package/test/csharp/components/class-declaration.test.tsx +344 -0
- package/test/csharp/components/enum-declaration.test.tsx +296 -0
- package/test/csharp/test-host.ts +42 -0
- package/test/csharp/utils.ts +8 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { refkey as ayRefkey, type Refkey } from "@alloy-js/core";
|
|
2
|
+
|
|
3
|
+
const refKeyPrefix = Symbol.for("emitter-framework:csharp");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A wrapper around `refkey` that uses a custom symbol to avoid collisions with
|
|
7
|
+
* other libraries that use `refkey`.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
*
|
|
11
|
+
* The underlying refkey function is called with the {@link refKeyPrefix} symbol as the first argument.
|
|
12
|
+
*
|
|
13
|
+
* @param args The parameters of the refkey.
|
|
14
|
+
* @returns A refkey object that can be used to identify the value.
|
|
15
|
+
*/
|
|
16
|
+
export function efRefkey(...args: unknown[]): Refkey {
|
|
17
|
+
if (args.length === 0) {
|
|
18
|
+
return ayRefkey(); // Generates a unique refkey
|
|
19
|
+
}
|
|
20
|
+
return ayRefkey(refKeyPrefix, ...args);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a refkey for a declaration by combining the provided refkey with an internal
|
|
25
|
+
* refkey generated from the provided arguments.
|
|
26
|
+
*
|
|
27
|
+
* @param refkey The refkey provided by the user to be passed as is.
|
|
28
|
+
* @param args The parameters of the refkey.
|
|
29
|
+
* @returns An array of refkeys that can be passed to an Alloy declaration.
|
|
30
|
+
*/
|
|
31
|
+
export function declarationRefkeys(refkey?: Refkey | Refkey[], ...args: unknown[]): Refkey[] {
|
|
32
|
+
if (refkey) {
|
|
33
|
+
return [refkey, efRefkey(...args)].flat();
|
|
34
|
+
}
|
|
35
|
+
return [efRefkey(...args)];
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./components/index.js";
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { render } from "@alloy-js/core";
|
|
2
|
+
import { d } from "@alloy-js/core/testing";
|
|
3
|
+
import * as cs from "@alloy-js/csharp";
|
|
4
|
+
import { Namespace, SourceFile } from "@alloy-js/csharp";
|
|
5
|
+
import { Enum, Interface, Model } from "@typespec/compiler";
|
|
6
|
+
import { BasicTestRunner } from "@typespec/compiler/testing";
|
|
7
|
+
import { beforeEach, describe, it } from "vitest";
|
|
8
|
+
import { Output } from "../../../src/core/index.js";
|
|
9
|
+
import { ClassDeclaration, EnumDeclaration } from "../../../src/csharp/index.js";
|
|
10
|
+
import { createEmitterFrameworkTestRunner } from "../test-host.js";
|
|
11
|
+
import { assertFileContents } from "../utils.js";
|
|
12
|
+
|
|
13
|
+
let runner: BasicTestRunner;
|
|
14
|
+
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
runner = await createEmitterFrameworkTestRunner();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("renders an empty class declaration", async () => {
|
|
20
|
+
const { TestModel } = (await runner.compile(`
|
|
21
|
+
@test model TestModel {}
|
|
22
|
+
`)) as { TestModel: Model };
|
|
23
|
+
|
|
24
|
+
const res = render(
|
|
25
|
+
<Output program={runner.program}>
|
|
26
|
+
<Namespace name="TestNamespace">
|
|
27
|
+
<SourceFile path="test.cs">
|
|
28
|
+
<ClassDeclaration type={TestModel} />
|
|
29
|
+
</SourceFile>
|
|
30
|
+
</Namespace>
|
|
31
|
+
</Output>,
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
assertFileContents(
|
|
35
|
+
res,
|
|
36
|
+
d`
|
|
37
|
+
namespace TestNamespace
|
|
38
|
+
{
|
|
39
|
+
class TestModel
|
|
40
|
+
{
|
|
41
|
+
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
`,
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("renders a class declaration with properties", async () => {
|
|
49
|
+
const { TestModel } = (await runner.compile(`
|
|
50
|
+
@test model TestModel {
|
|
51
|
+
@test Prop1: string;
|
|
52
|
+
@test Prop2: int32;
|
|
53
|
+
}
|
|
54
|
+
`)) as { TestModel: Model };
|
|
55
|
+
|
|
56
|
+
const res = render(
|
|
57
|
+
<Output program={runner.program}>
|
|
58
|
+
<Namespace name="TestNamespace">
|
|
59
|
+
<SourceFile path="test.cs">
|
|
60
|
+
<ClassDeclaration type={TestModel} />
|
|
61
|
+
</SourceFile>
|
|
62
|
+
</Namespace>
|
|
63
|
+
</Output>,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
assertFileContents(
|
|
67
|
+
res,
|
|
68
|
+
d`
|
|
69
|
+
namespace TestNamespace
|
|
70
|
+
{
|
|
71
|
+
class TestModel
|
|
72
|
+
{
|
|
73
|
+
public string Prop1
|
|
74
|
+
{
|
|
75
|
+
get;
|
|
76
|
+
set;
|
|
77
|
+
}
|
|
78
|
+
public int Prop2
|
|
79
|
+
{
|
|
80
|
+
get;
|
|
81
|
+
set;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
`,
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it("can override class name", async () => {
|
|
90
|
+
const { TestModel } = (await runner.compile(`
|
|
91
|
+
@test model TestModel {}
|
|
92
|
+
`)) as { TestModel: Model };
|
|
93
|
+
|
|
94
|
+
const res = render(
|
|
95
|
+
<Output program={runner.program}>
|
|
96
|
+
<Namespace name="TestNamespace">
|
|
97
|
+
<SourceFile path="test.cs">
|
|
98
|
+
<ClassDeclaration type={TestModel} name="CustomClassName" />
|
|
99
|
+
</SourceFile>
|
|
100
|
+
</Namespace>
|
|
101
|
+
</Output>,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
assertFileContents(
|
|
105
|
+
res,
|
|
106
|
+
d`
|
|
107
|
+
namespace TestNamespace
|
|
108
|
+
{
|
|
109
|
+
class CustomClassName
|
|
110
|
+
{
|
|
111
|
+
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
`,
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("renders a class with access modifiers", async () => {
|
|
119
|
+
const { TestModel } = (await runner.compile(`
|
|
120
|
+
@test model TestModel {
|
|
121
|
+
}
|
|
122
|
+
`)) as { TestModel: Model };
|
|
123
|
+
|
|
124
|
+
const res = render(
|
|
125
|
+
<Output program={runner.program}>
|
|
126
|
+
<Namespace name="TestNamespace">
|
|
127
|
+
<SourceFile path="test.cs">
|
|
128
|
+
<ClassDeclaration type={TestModel} accessModifier="protected" />
|
|
129
|
+
</SourceFile>
|
|
130
|
+
</Namespace>
|
|
131
|
+
</Output>,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
assertFileContents(
|
|
135
|
+
res,
|
|
136
|
+
d`
|
|
137
|
+
namespace TestNamespace
|
|
138
|
+
{
|
|
139
|
+
protected class TestModel
|
|
140
|
+
{
|
|
141
|
+
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
`,
|
|
145
|
+
);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe("from an interface", () => {
|
|
149
|
+
it("renders an empty class", async () => {
|
|
150
|
+
const { TestInterface } = (await runner.compile(`
|
|
151
|
+
@test interface TestInterface {
|
|
152
|
+
}
|
|
153
|
+
`)) as { TestInterface: Interface };
|
|
154
|
+
|
|
155
|
+
const res = render(
|
|
156
|
+
<Output program={runner.program}>
|
|
157
|
+
<Namespace name="TestNamespace">
|
|
158
|
+
<SourceFile path="test.cs">
|
|
159
|
+
<ClassDeclaration type={TestInterface} />
|
|
160
|
+
</SourceFile>
|
|
161
|
+
</Namespace>
|
|
162
|
+
</Output>,
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
assertFileContents(
|
|
166
|
+
res,
|
|
167
|
+
d`
|
|
168
|
+
namespace TestNamespace
|
|
169
|
+
{
|
|
170
|
+
class TestInterface
|
|
171
|
+
{
|
|
172
|
+
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
`,
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it("renders a class with operations", async () => {
|
|
180
|
+
const { TestInterface } = (await runner.compile(`
|
|
181
|
+
@test interface TestInterface {
|
|
182
|
+
op getName(id: string): string;
|
|
183
|
+
}
|
|
184
|
+
`)) as { TestInterface: Interface };
|
|
185
|
+
|
|
186
|
+
const res = render(
|
|
187
|
+
<Output program={runner.program} namePolicy={cs.createCSharpNamePolicy()}>
|
|
188
|
+
<Namespace name="TestNamespace">
|
|
189
|
+
<SourceFile path="test.cs">
|
|
190
|
+
<ClassDeclaration type={TestInterface} />
|
|
191
|
+
</SourceFile>
|
|
192
|
+
</Namespace>
|
|
193
|
+
</Output>,
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
assertFileContents(
|
|
197
|
+
res,
|
|
198
|
+
d`
|
|
199
|
+
namespace TestNamespace
|
|
200
|
+
{
|
|
201
|
+
class TestInterface
|
|
202
|
+
{
|
|
203
|
+
public abstract string GetName(string id) {}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
`,
|
|
207
|
+
);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("renders a class with model members", async () => {
|
|
212
|
+
const { TestModel, TestReference } = (await runner.compile(`
|
|
213
|
+
@test model TestReference {
|
|
214
|
+
}
|
|
215
|
+
@test model TestModel {
|
|
216
|
+
@test prop1: TestReference;
|
|
217
|
+
}
|
|
218
|
+
`)) as { TestModel: Model; TestReference: Model };
|
|
219
|
+
|
|
220
|
+
const res = render(
|
|
221
|
+
<Output program={runner.program} namePolicy={cs.createCSharpNamePolicy()}>
|
|
222
|
+
<Namespace name="TestNamespace">
|
|
223
|
+
<SourceFile path="test.cs">
|
|
224
|
+
<ClassDeclaration type={TestReference} />
|
|
225
|
+
<hbr />
|
|
226
|
+
<ClassDeclaration type={TestModel} />
|
|
227
|
+
</SourceFile>
|
|
228
|
+
</Namespace>
|
|
229
|
+
</Output>,
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
assertFileContents(
|
|
233
|
+
res,
|
|
234
|
+
d`
|
|
235
|
+
namespace TestNamespace
|
|
236
|
+
{
|
|
237
|
+
class TestReference
|
|
238
|
+
{
|
|
239
|
+
|
|
240
|
+
}
|
|
241
|
+
class TestModel
|
|
242
|
+
{
|
|
243
|
+
public TestReference Prop1
|
|
244
|
+
{
|
|
245
|
+
get;
|
|
246
|
+
set;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
`,
|
|
251
|
+
);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it("renders a class with enum members", async () => {
|
|
255
|
+
const { TestModel, TestEnum } = (await runner.compile(`
|
|
256
|
+
@test enum TestEnum {
|
|
257
|
+
Value1;
|
|
258
|
+
Value2;
|
|
259
|
+
}
|
|
260
|
+
@test model TestModel {
|
|
261
|
+
@test prop1: TestEnum;
|
|
262
|
+
}
|
|
263
|
+
`)) as { TestModel: Model; TestEnum: Enum };
|
|
264
|
+
|
|
265
|
+
const res = render(
|
|
266
|
+
<Output program={runner.program} namePolicy={cs.createCSharpNamePolicy()}>
|
|
267
|
+
<Namespace name="TestNamespace">
|
|
268
|
+
<SourceFile path="test.cs">
|
|
269
|
+
<EnumDeclaration type={TestEnum} />
|
|
270
|
+
<hbr />
|
|
271
|
+
<ClassDeclaration type={TestModel} />
|
|
272
|
+
</SourceFile>
|
|
273
|
+
</Namespace>
|
|
274
|
+
</Output>,
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
assertFileContents(
|
|
278
|
+
res,
|
|
279
|
+
d`
|
|
280
|
+
namespace TestNamespace
|
|
281
|
+
{
|
|
282
|
+
public enum TestEnum
|
|
283
|
+
{
|
|
284
|
+
Value1,
|
|
285
|
+
Value2
|
|
286
|
+
}
|
|
287
|
+
class TestModel
|
|
288
|
+
{
|
|
289
|
+
public TestEnum Prop1
|
|
290
|
+
{
|
|
291
|
+
get;
|
|
292
|
+
set;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
`,
|
|
297
|
+
);
|
|
298
|
+
});
|
|
299
|
+
|
|
300
|
+
it("renders a class with string enums", async () => {
|
|
301
|
+
const { TestModel, TestEnum } = (await runner.compile(`
|
|
302
|
+
@test enum TestEnum {
|
|
303
|
+
Value1;
|
|
304
|
+
Value2;
|
|
305
|
+
}
|
|
306
|
+
@test model TestModel {
|
|
307
|
+
@test prop1: TestEnum;
|
|
308
|
+
}
|
|
309
|
+
`)) as { TestModel: Model; TestEnum: Enum };
|
|
310
|
+
|
|
311
|
+
const res = render(
|
|
312
|
+
<Output program={runner.program} namePolicy={cs.createCSharpNamePolicy()}>
|
|
313
|
+
<Namespace name="TestNamespace">
|
|
314
|
+
<SourceFile path="test.cs">
|
|
315
|
+
<EnumDeclaration type={TestEnum} />
|
|
316
|
+
<hbr />
|
|
317
|
+
<ClassDeclaration type={TestModel} />
|
|
318
|
+
</SourceFile>
|
|
319
|
+
</Namespace>
|
|
320
|
+
</Output>,
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
assertFileContents(
|
|
324
|
+
res,
|
|
325
|
+
d`
|
|
326
|
+
namespace TestNamespace
|
|
327
|
+
{
|
|
328
|
+
public enum TestEnum
|
|
329
|
+
{
|
|
330
|
+
Value1,
|
|
331
|
+
Value2
|
|
332
|
+
}
|
|
333
|
+
class TestModel
|
|
334
|
+
{
|
|
335
|
+
public TestEnum Prop1
|
|
336
|
+
{
|
|
337
|
+
get;
|
|
338
|
+
set;
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
`,
|
|
343
|
+
);
|
|
344
|
+
});
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { render } from "@alloy-js/core";
|
|
2
|
+
import { d } from "@alloy-js/core/testing";
|
|
3
|
+
import * as cs from "@alloy-js/csharp";
|
|
4
|
+
import { Namespace, SourceFile } from "@alloy-js/csharp";
|
|
5
|
+
import { Enum } from "@typespec/compiler";
|
|
6
|
+
import { BasicTestRunner } from "@typespec/compiler/testing";
|
|
7
|
+
import { beforeEach, it } from "vitest";
|
|
8
|
+
import { Output } from "../../../src/core/index.js";
|
|
9
|
+
import { EnumDeclaration } from "../../../src/csharp/index.js";
|
|
10
|
+
import { createEmitterFrameworkTestRunner } from "../test-host.js";
|
|
11
|
+
import { assertFileContents } from "../utils.js";
|
|
12
|
+
|
|
13
|
+
let runner: BasicTestRunner;
|
|
14
|
+
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
runner = await createEmitterFrameworkTestRunner();
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("renders a basic enum declaration", async () => {
|
|
20
|
+
const { TestEnum } = (await runner.compile(`
|
|
21
|
+
@test enum TestEnum {
|
|
22
|
+
Value1;
|
|
23
|
+
Value2;
|
|
24
|
+
Value3;
|
|
25
|
+
}
|
|
26
|
+
`)) as { TestEnum: Enum };
|
|
27
|
+
|
|
28
|
+
const res = render(
|
|
29
|
+
<Output program={runner.program}>
|
|
30
|
+
<Namespace name="TestNamespace">
|
|
31
|
+
<SourceFile path="test.cs">
|
|
32
|
+
<EnumDeclaration type={TestEnum} />
|
|
33
|
+
</SourceFile>
|
|
34
|
+
</Namespace>
|
|
35
|
+
</Output>,
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
assertFileContents(
|
|
39
|
+
res,
|
|
40
|
+
d`
|
|
41
|
+
namespace TestNamespace
|
|
42
|
+
{
|
|
43
|
+
public enum TestEnum
|
|
44
|
+
{
|
|
45
|
+
Value1,
|
|
46
|
+
Value2,
|
|
47
|
+
Value3
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
`,
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("renders an empty enum declaration", async () => {
|
|
55
|
+
const { TestEnum } = (await runner.compile(`
|
|
56
|
+
@test enum TestEnum {}
|
|
57
|
+
`)) as { TestEnum: Enum };
|
|
58
|
+
|
|
59
|
+
const res = render(
|
|
60
|
+
<Output program={runner.program}>
|
|
61
|
+
<Namespace name="TestNamespace">
|
|
62
|
+
<SourceFile path="test.cs">
|
|
63
|
+
<EnumDeclaration type={TestEnum} />
|
|
64
|
+
</SourceFile>
|
|
65
|
+
</Namespace>
|
|
66
|
+
</Output>,
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
assertFileContents(
|
|
70
|
+
res,
|
|
71
|
+
d`
|
|
72
|
+
namespace TestNamespace
|
|
73
|
+
{
|
|
74
|
+
public enum TestEnum
|
|
75
|
+
{
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
`,
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("can override enum name", async () => {
|
|
84
|
+
const { TestEnum } = (await runner.compile(`
|
|
85
|
+
@test enum TestEnum {
|
|
86
|
+
Value1;
|
|
87
|
+
Value2;
|
|
88
|
+
}
|
|
89
|
+
`)) as { TestEnum: Enum };
|
|
90
|
+
|
|
91
|
+
const res = render(
|
|
92
|
+
<Output program={runner.program}>
|
|
93
|
+
<Namespace name="TestNamespace">
|
|
94
|
+
<SourceFile path="test.cs">
|
|
95
|
+
<EnumDeclaration type={TestEnum} name="CustomEnumName" />
|
|
96
|
+
</SourceFile>
|
|
97
|
+
</Namespace>
|
|
98
|
+
</Output>,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
assertFileContents(
|
|
102
|
+
res,
|
|
103
|
+
d`
|
|
104
|
+
namespace TestNamespace
|
|
105
|
+
{
|
|
106
|
+
public enum CustomEnumName
|
|
107
|
+
{
|
|
108
|
+
Value1,
|
|
109
|
+
Value2
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
`,
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("renders an enum with access modifiers", async () => {
|
|
117
|
+
const { TestEnum } = (await runner.compile(`
|
|
118
|
+
@test enum TestEnum {
|
|
119
|
+
Value1;
|
|
120
|
+
Value2;
|
|
121
|
+
}
|
|
122
|
+
`)) as { TestEnum: Enum };
|
|
123
|
+
|
|
124
|
+
const res = render(
|
|
125
|
+
<Output program={runner.program}>
|
|
126
|
+
<Namespace name="TestNamespace">
|
|
127
|
+
<SourceFile path="test.cs">
|
|
128
|
+
<EnumDeclaration type={TestEnum} accessModifier="internal" />
|
|
129
|
+
</SourceFile>
|
|
130
|
+
</Namespace>
|
|
131
|
+
</Output>,
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
assertFileContents(
|
|
135
|
+
res,
|
|
136
|
+
d`
|
|
137
|
+
namespace TestNamespace
|
|
138
|
+
{
|
|
139
|
+
internal enum TestEnum
|
|
140
|
+
{
|
|
141
|
+
Value1,
|
|
142
|
+
Value2
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
`,
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it("renders enum with C# naming conventions", async () => {
|
|
150
|
+
const { TestEnum } = (await runner.compile(`
|
|
151
|
+
@test enum TestEnum {
|
|
152
|
+
value_one;
|
|
153
|
+
value_two;
|
|
154
|
+
value_three;
|
|
155
|
+
}
|
|
156
|
+
`)) as { TestEnum: Enum };
|
|
157
|
+
|
|
158
|
+
const res = render(
|
|
159
|
+
<Output program={runner.program} namePolicy={cs.createCSharpNamePolicy()}>
|
|
160
|
+
<Namespace name="TestNamespace">
|
|
161
|
+
<SourceFile path="test.cs">
|
|
162
|
+
<EnumDeclaration type={TestEnum} />
|
|
163
|
+
</SourceFile>
|
|
164
|
+
</Namespace>
|
|
165
|
+
</Output>,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
assertFileContents(
|
|
169
|
+
res,
|
|
170
|
+
d`
|
|
171
|
+
namespace TestNamespace
|
|
172
|
+
{
|
|
173
|
+
public enum TestEnum
|
|
174
|
+
{
|
|
175
|
+
ValueOne,
|
|
176
|
+
ValueTwo,
|
|
177
|
+
ValueThree
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
`,
|
|
181
|
+
);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("renders enum with single value", async () => {
|
|
185
|
+
const { TestEnum } = (await runner.compile(`
|
|
186
|
+
@test enum TestEnum {
|
|
187
|
+
OnlyValue;
|
|
188
|
+
}
|
|
189
|
+
`)) as { TestEnum: Enum };
|
|
190
|
+
|
|
191
|
+
const res = render(
|
|
192
|
+
<Output program={runner.program}>
|
|
193
|
+
<Namespace name="TestNamespace">
|
|
194
|
+
<SourceFile path="test.cs">
|
|
195
|
+
<EnumDeclaration type={TestEnum} />
|
|
196
|
+
</SourceFile>
|
|
197
|
+
</Namespace>
|
|
198
|
+
</Output>,
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
assertFileContents(
|
|
202
|
+
res,
|
|
203
|
+
d`
|
|
204
|
+
namespace TestNamespace
|
|
205
|
+
{
|
|
206
|
+
public enum TestEnum
|
|
207
|
+
{
|
|
208
|
+
OnlyValue
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
`,
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it("renders enum with numeric-like member names", async () => {
|
|
216
|
+
const { TestEnum } = (await runner.compile(`
|
|
217
|
+
@test enum TestEnum {
|
|
218
|
+
Value0;
|
|
219
|
+
Value1;
|
|
220
|
+
Value10;
|
|
221
|
+
Value100;
|
|
222
|
+
}
|
|
223
|
+
`)) as { TestEnum: Enum };
|
|
224
|
+
|
|
225
|
+
const res = render(
|
|
226
|
+
<Output program={runner.program}>
|
|
227
|
+
<Namespace name="TestNamespace">
|
|
228
|
+
<SourceFile path="test.cs">
|
|
229
|
+
<EnumDeclaration type={TestEnum} />
|
|
230
|
+
</SourceFile>
|
|
231
|
+
</Namespace>
|
|
232
|
+
</Output>,
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
assertFileContents(
|
|
236
|
+
res,
|
|
237
|
+
d`
|
|
238
|
+
namespace TestNamespace
|
|
239
|
+
{
|
|
240
|
+
public enum TestEnum
|
|
241
|
+
{
|
|
242
|
+
Value0,
|
|
243
|
+
Value1,
|
|
244
|
+
Value10,
|
|
245
|
+
Value100
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
`,
|
|
249
|
+
);
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it("renders multiple enums in the same namespace", async () => {
|
|
253
|
+
const { TestEnum1, TestEnum2 } = (await runner.compile(`
|
|
254
|
+
@test enum TestEnum1 {
|
|
255
|
+
Value1;
|
|
256
|
+
Value2;
|
|
257
|
+
}
|
|
258
|
+
@test enum TestEnum2 {
|
|
259
|
+
OptionA;
|
|
260
|
+
OptionB;
|
|
261
|
+
OptionC;
|
|
262
|
+
}
|
|
263
|
+
`)) as { TestEnum1: Enum; TestEnum2: Enum };
|
|
264
|
+
|
|
265
|
+
const res = render(
|
|
266
|
+
<Output program={runner.program}>
|
|
267
|
+
<Namespace name="TestNamespace">
|
|
268
|
+
<SourceFile path="test.cs">
|
|
269
|
+
<EnumDeclaration type={TestEnum1} />
|
|
270
|
+
<hbr />
|
|
271
|
+
<EnumDeclaration type={TestEnum2} />
|
|
272
|
+
</SourceFile>
|
|
273
|
+
</Namespace>
|
|
274
|
+
</Output>,
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
assertFileContents(
|
|
278
|
+
res,
|
|
279
|
+
d`
|
|
280
|
+
namespace TestNamespace
|
|
281
|
+
{
|
|
282
|
+
public enum TestEnum1
|
|
283
|
+
{
|
|
284
|
+
Value1,
|
|
285
|
+
Value2
|
|
286
|
+
}
|
|
287
|
+
public enum TestEnum2
|
|
288
|
+
{
|
|
289
|
+
OptionA,
|
|
290
|
+
OptionB,
|
|
291
|
+
OptionC
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
`,
|
|
295
|
+
);
|
|
296
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Program } from "@typespec/compiler";
|
|
2
|
+
import {
|
|
3
|
+
createTestHost,
|
|
4
|
+
createTestWrapper,
|
|
5
|
+
expectDiagnosticEmpty,
|
|
6
|
+
TypeSpecTestLibrary,
|
|
7
|
+
} from "@typespec/compiler/testing";
|
|
8
|
+
import { HttpTestLibrary } from "@typespec/http/testing";
|
|
9
|
+
|
|
10
|
+
export async function createTypespecCliTestHost(
|
|
11
|
+
options: { libraries: "Http"[] } = { libraries: [] },
|
|
12
|
+
) {
|
|
13
|
+
const libraries: TypeSpecTestLibrary[] = [];
|
|
14
|
+
if (options.libraries.includes("Http")) {
|
|
15
|
+
libraries.push(HttpTestLibrary);
|
|
16
|
+
}
|
|
17
|
+
return createTestHost({
|
|
18
|
+
libraries,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function createEmitterFrameworkTestRunner(options: { autoUsings?: string[] } = {}) {
|
|
23
|
+
const host = await createTypespecCliTestHost();
|
|
24
|
+
return createTestWrapper(host, {
|
|
25
|
+
autoUsings: options.autoUsings,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export async function getProgram(
|
|
30
|
+
code: string,
|
|
31
|
+
options: { libraries: "Http"[] } = { libraries: [] },
|
|
32
|
+
): Promise<Program> {
|
|
33
|
+
const host = await createTypespecCliTestHost(options);
|
|
34
|
+
const wrapper = createTestWrapper(host, {
|
|
35
|
+
compilerOptions: {
|
|
36
|
+
noEmit: true,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
const [_, diagnostics] = await wrapper.compileAndDiagnose(code);
|
|
40
|
+
expectDiagnosticEmpty(diagnostics);
|
|
41
|
+
return wrapper.program;
|
|
42
|
+
}
|