Skip to content

Commit 5392cb8

Browse files
fix: enum generation should handle union types (#349)
Co-authored-by: Maciej Urbańczyk <urbanczyk.maciej.95@gmail.com>
1 parent 716cfc8 commit 5392cb8

File tree

9 files changed

+90
-11
lines changed

9 files changed

+90
-11
lines changed

src/generators/csharp/renderers/EnumRenderer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,12 @@ export const CSHARP_DEFAULT_ENUM_PRESET: EnumPreset<EnumRenderer> = {
4242
},
4343
item({ item }) {
4444
let itemName = String(item);
45-
if (typeof item === 'number') {
45+
if (typeof item === 'number' || typeof item === 'bigint') {
4646
itemName = `Number_${itemName}`;
47+
} else if (typeof item === 'object') {
48+
itemName = `${JSON.stringify(item)}`;
4749
}
50+
4851
return pascalCase(itemName);
4952
},
5053
};

src/generators/java/renderers/EnumRenderer.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ ${this.indent(this.renderBlock(content, 2))}
4141
case 'boolean': {
4242
return FormatHelpers.toConstantCase(`boolean ${value}`);
4343
}
44+
case 'object': {
45+
return FormatHelpers.toConstantCase(JSON.stringify(value));
46+
}
4447
default: return FormatHelpers.toConstantCase(String(value));
4548
}
4649
}
@@ -49,6 +52,9 @@ ${this.indent(this.renderBlock(content, 2))}
4952
if (typeof value === 'string') {
5053
return `"${value}"`;
5154
}
55+
if (typeof value === 'object') {
56+
return `"${JSON.stringify(value).replace(/"/g, '\\"')}"`;
57+
}
5258
return String(value);
5359
}
5460

src/generators/typescript/renderers/EnumRenderer.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,57 @@ ${this.indent(this.renderBlock(content, 2))}
3636
runItemPreset(item: any): Promise<string> {
3737
return this.runPreset('item', { item });
3838
}
39+
40+
normalizeKey(value: any): any {
41+
let key;
42+
switch (typeof value) {
43+
case 'bigint':
44+
case 'number': {
45+
key = `number ${value}`;
46+
break;
47+
}
48+
case 'object': {
49+
key = JSON.stringify(value);
50+
break;
51+
}
52+
default: {
53+
key = String(value);
54+
}
55+
}
56+
return FormatHelpers.toConstantCase(key);
57+
}
58+
59+
normalizeValue(value: any): any {
60+
let normalizedValue;
61+
switch (typeof value) {
62+
case 'string':
63+
case 'boolean':
64+
normalizedValue = `"${value}"`;
65+
break;
66+
case 'bigint':
67+
case 'number': {
68+
normalizedValue = value;
69+
break;
70+
}
71+
case 'object': {
72+
normalizedValue = `'${JSON.stringify(value)}'`;
73+
break;
74+
}
75+
default: {
76+
normalizedValue = String(value);
77+
}
78+
}
79+
return normalizedValue;
80+
}
3981
}
4082

4183
export const TS_DEFAULT_ENUM_PRESET: EnumPreset<EnumRenderer> = {
4284
async self({ renderer }) {
4385
return `export ${await renderer.defaultSelf()}`;
4486
},
45-
item({ item }): string {
46-
return `${FormatHelpers.toConstantCase(`${item}`)} = "${item}",`;
87+
item({ item, renderer }): string {
88+
const key = renderer.normalizeKey(item);
89+
const value = renderer.normalizeValue(item);
90+
return `${key} = ${value},`;
4791
}
4892
};

test/generators/csharp/CSharpGenerator.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ describe('CSharpGenerator', () => {
106106
name: 'with enums of mixed types',
107107
doc: {
108108
$id: 'Things',
109-
enum: ['Texas', 1, false],
109+
enum: ['Texas', 1, false, {test: 'test'}],
110110
}
111111
},
112112
])('should render `enum` type $name', ({doc}) => {

test/generators/csharp/__snapshots__/CSharpGenerator.spec.ts.snap

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,13 +202,13 @@ exports[`CSharpGenerator should render \`enum\` type $name should not be empty 2
202202
203203
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 3`] = `
204204
"public enum Things {
205-
Texas, Number_1, False
205+
Texas, Number_1, False, TestTest
206206
}"
207207
`;
208208
209209
exports[`CSharpGenerator should render \`enum\` type $name should not be empty 4`] = `
210210
"public enum Things {
211-
Texas, Number_1, False
211+
Texas, Number_1, False, TestTest
212212
}"
213213
`;
214214

test/generators/go/GoGenerator.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ type States string`,
105105
name: 'with enums of mixed types',
106106
doc: {
107107
$id: 'Things',
108-
enum: ['Texas', 1, false],
108+
enum: ['Texas', 1, false, {test: 'test'}],
109109
},
110110
expected: `// Things represents an enum of mixed types.
111111
type Things interface{}`,

test/generators/java/JavaGenerator.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,10 @@ describe('JavaGenerator', () => {
267267
const doc = {
268268
$id: 'Union',
269269
type: ['string', 'integer', 'boolean'],
270-
enum: ['Texas', 'Alabama', 0, 1, true],
270+
enum: ['Texas', 'Alabama', 0, 1, true, {test: 'test'}],
271271
};
272272
const expected = `public enum Union {
273-
TEXAS("Texas"), ALABAMA("Alabama"), NUMBER_0(0), NUMBER_1(1), BOOLEAN_TRUE(true);
273+
TEXAS("Texas"), ALABAMA("Alabama"), NUMBER_0(0), NUMBER_1(1), BOOLEAN_TRUE(true), TEST_TEST("{\\"test\\":\\"test\\"}");
274274
275275
private Object value;
276276

test/generators/typescript/TypeScriptGenerator.spec.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,30 @@ ${content}`;
294294
expect(enumModel.dependencies).toEqual([]);
295295
});
296296

297+
test('should render union `enum` values', async () => {
298+
const doc = {
299+
$id: 'States',
300+
enum: [2, 'test', true, {test: 'test'}]
301+
};
302+
const expected = `export enum States {
303+
NUMBER_2 = 2,
304+
TEST = "test",
305+
TRUE = "true",
306+
TEST_TEST = '{"test":"test"}',
307+
}`;
308+
309+
const inputModel = await generator.process(doc);
310+
const model = inputModel.models['States'];
311+
312+
let enumModel = await generator.render(model, inputModel);
313+
expect(enumModel.result).toEqual(expected);
314+
expect(enumModel.dependencies).toEqual([]);
315+
316+
enumModel = await generator.renderEnum(model, inputModel);
317+
expect(enumModel.result).toEqual(expected);
318+
expect(enumModel.dependencies).toEqual([]);
319+
});
320+
297321
test('should work custom preset for `enum` type', async () => {
298322
const doc = {
299323
$id: 'CustomEnum',

test/generators/typescript/preset/MarshallingPreset.spec.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const doc = {
1414
required: ['string prop'],
1515
properties: {
1616
'string prop': { type: 'string' },
17-
enumProp: { $id: 'EnumTest', enum: ['Some enum String', "some other enum string"]},
17+
enumProp: { $id: 'EnumTest', enum: ['Some enum String', true, {test: 'test'}, 2]},
1818
numberProp: { type: 'number' },
1919
objectProp: { $ref: '#/definitions/NestedTest' }
2020
},
@@ -50,7 +50,9 @@ describe('Marshalling preset', () => {
5050
test('should provide a two way conversion', async () => {
5151
enum EnumTest {
5252
SOME_ENUM_STRING = "Some enum String",
53-
SOME_OTHER_ENUM_STRING = "some other enum string"
53+
NUMBER_2 = 2,
54+
TRUE = "true",
55+
TEST_TEST = '{"test": "test"}',
5456
}
5557
class NestedTest {
5658
private _stringProp?: string;

0 commit comments

Comments
 (0)