Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: rewrite TypeScript generator tests #806

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 51 additions & 18 deletions examples/generate-go-enums/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,70 @@

exports[`Should be able to render Go Enums and should log expected output to console 1`] = `
Array [
"// Cities represents an enum of string.
type Cities string

const (
CitiesLondon Cities = \\"London\\"
CitiesRome = \\"Rome\\"
CitiesBrussels = \\"Brussels\\"
)",
"// Root represents a Root model.
type Root struct {
Cities *Cities
Options *Options
}",
]
`;

exports[`Should be able to render Go Enums and should log expected output to console 2`] = `
Array [
"// ClickOptions represents an enum of string.
type ClickOptions string
"// Cities represents an enum of Cities.
type Cities uint

const (
ClickOptionsClickAndPlay ClickOptions = \\"click_and_play\\"
ClickOptionsClickPay = \\"click&pay\\"
)",
CitiesLondon Cities = iota
CitiesRome
CitiesBrussels
)

// Value returns the value of the enum.
func (op Cities) Value() any {
if op >= Cities(len(CitiesValues)) {
return nil
}
return CitiesValues[op]
}

var CitiesValues = []any{\\"London\\",\\"Rome\\",\\"Brussels\\"}
var ValuesToCities = map[any]Cities{
CitiesValues[CitiesLondon]: CitiesLondon,
CitiesValues[CitiesRome]: CitiesRome,
CitiesValues[CitiesBrussels]: CitiesBrussels,
}
",
]
`;

exports[`Should be able to render Go Enums and should log expected output to console 3`] = `
Array [
"// Options represents an enum of int.
type Options int
"// Options represents an enum of Options.
type Options uint

const (
OptionsFirstOption Options = iota
OptionsSecondOption
)",
OptionsNumber_123 Options = iota
OptionsNumber_213
OptionsTrue
OptionsRun
)

// Value returns the value of the enum.
func (op Options) Value() any {
if op >= Options(len(OptionsValues)) {
return nil
}
return OptionsValues[op]
}

var OptionsValues = []any{123,213,true,\\"Run\\"}
var ValuesToOptions = map[any]Options{
OptionsValues[OptionsNumber_123]: OptionsNumber_123,
OptionsValues[OptionsNumber_213]: OptionsNumber_213,
OptionsValues[OptionsTrue]: OptionsTrue,
OptionsValues[OptionsRun]: OptionsRun,
}
",
]
`;
6 changes: 3 additions & 3 deletions examples/generate-go-enums/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ describe('Should be able to render Go Enums', () => {
});
test('and should log expected output to console', async () => {
await generate();
//Generate is called 2x, so even though we expect 4 model (root and three different enums type), we double it
expect(spy.mock.calls.length).toEqual(8);
//Generate is called 2x, so even though we expect 3 model (root and three different enums type), we double it
expect(spy.mock.calls.length).toEqual(6);
expect(spy.mock.calls[0]).toMatchSnapshot();
expect(spy.mock.calls[1]).toMatchSnapshot();
expect(spy.mock.calls[2]).toMatchSnapshot();
expect(spy.mock.calls[3]).toMatchSnapshot();
});
});
9 changes: 2 additions & 7 deletions examples/generate-go-enums/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,10 @@ const jsonSchemaDraft7 = {
type: 'string',
enum: ['London', 'Rome', 'Brussels'],
},
click_options: {
$id: 'click_options',
type: 'string',
enum: ['click_and_play', 'click&pay'],
},
options: {
$id: 'options',
type: 'integer',
enum: ['first_option', 'second_option'],
type: ['integer', 'boolean', 'string'],
enum: [123, 213, true, 'Run'],
},
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class Root {
get event(): Event | undefined { return this._event; }
set event(event: Event | undefined) { this._event = event; }
}
type Event = \\"ping\\" | \\"pong\\";
type Event = Event;
Generator output with Enum:
class Root {
private _event?: Event;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ interface Test {
* @example Example
*/
numberProp?: number;
/**
* @example Example 1, Example 2
*/
objectProp?: NestedTest;
additionalProperties?: Map<String, object | string | number | Array<unknown> | boolean | null>;
additionalProperties?: Map<string, any>;
}",
],
Array [
Expand All @@ -23,7 +26,7 @@ interface Test {
*/
interface NestedTest {
stringProp?: string;
additionalProperties?: Map<String, object | string | number | Array<unknown> | boolean | null>;
additionalProperties?: Map<string, any>;
}",
],
Array [
Expand All @@ -37,8 +40,11 @@ interface Test {
* @example Example
*/
numberProp?: number;
/**
* @example Example 1, Example 2
*/
objectProp?: NestedTest;
additionalProperties?: Map<String, object | string | number | Array<unknown> | boolean | null>;
additionalProperties?: Map<string, any>;
}",
],
Array [
Expand All @@ -47,7 +53,7 @@ interface Test {
*/
interface NestedTest {
stringProp?: string;
additionalProperties?: Map<String, object | string | number | Array<unknown> | boolean | null>;
additionalProperties?: Map<string, any>;
}",
],
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ Array [
if(this.email !== undefined) {
json += \`\\"email\\": \${typeof this.email === 'number' || typeof this.email === 'boolean' ? this.email : JSON.stringify(this.email)},\`;
}




//Remove potential last comma
return \`\${json.charAt(json.length-1) === ',' ? json.slice(0, json.length-1) : json}}\`;
Expand All @@ -34,13 +33,8 @@ Array [
instance.email = obj[\\"email\\"];
}

//Not part of core properties


for (const [key, value] of Object.entries(obj).filter((([key,]) => {return ![\\"email\\"].includes(key);}))) {


}


return instance;
}
}",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
exports[`Should be able to render models to ESM module system and should log expected output to console 1`] = `
Array [
"

class Person {
private _email?: string;

Expand All @@ -23,7 +22,6 @@ module.exports = Person;",
exports[`Should be able to render models to ESM module system and should log expected output to console 2`] = `
Array [
"const Person = require('./Person');

class Root {
private _person?: Person;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
exports[`Should be able to render models to ESM module system and should log expected output to console 1`] = `
Array [
"

class Person {
private _email?: string;

Expand All @@ -24,7 +23,6 @@ export default Person;
exports[`Should be able to render models to ESM module system and should log expected output to console 2`] = `
Array [
"import Person from './Person';

class Root {
private _person?: Person;

Expand Down
10 changes: 5 additions & 5 deletions src/generators/go/GoConstrainer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TypeMapping } from '../../helpers';
import { Constraints, TypeMapping } from '../../helpers';
import { defaultEnumKeyConstraints, defaultEnumValueConstraints } from './constrainer/EnumConstrainer';
import { defaultModelNameConstraints } from './constrainer/ModelNameConstrainer';
import { defaultPropertyKeyConstraints } from './constrainer/PropertyKeyConstrainer';
Expand All @@ -9,7 +9,7 @@ export const GoDefaultTypeMapping: TypeMapping<GoOptions> = {
return constrainedModel.name;
},
Reference ({constrainedModel}): string {
return constrainedModel.name;
return `${constrainedModel.name}`;
},
Any (): string {
return 'interface{}';
Expand All @@ -27,7 +27,7 @@ export const GoDefaultTypeMapping: TypeMapping<GoOptions> = {
return 'bool';
},
Tuple (): string {
//Because Java have no notion of tuples (and no custom implementation), we have to render it as a list of any value.
//Because Go have no notion of tuples (and no custom implementation), we have to render it as a list of any value.
return '[]interface{}';
},
Array ({constrainedModel}): string {
Expand All @@ -37,15 +37,15 @@ export const GoDefaultTypeMapping: TypeMapping<GoOptions> = {
return constrainedModel.name;
},
Union (): string {
//Because Java have no notion of unions (and no custom implementation), we have to render it as any value.
//Because Go have no notion of unions (and no custom implementation), we have to render it as any value.
return 'interface{}';
},
Dictionary ({constrainedModel}): string {
return `map[${constrainedModel.key.type}]${constrainedModel.value.type}`;
}
};

export const GoDefaultConstraints = {
export const GoDefaultConstraints: Constraints = {
enumKey: defaultEnumKeyConstraints(),
enumValue: defaultEnumValueConstraints(),
modelName: defaultModelNameConstraints(),
Expand Down
39 changes: 35 additions & 4 deletions src/generators/go/constrainer/EnumConstrainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import { isReservedGoKeyword } from '../Constants';
export type ModelEnumKeyConstraints = {
NO_SPECIAL_CHAR: (value: string) => string;
NO_NUMBER_START_CHAR: (value: string) => string;
NO_DUPLICATE_KEYS: (constrainedEnumModel: ConstrainedEnumModel, enumModel: EnumModel, value: string, namingFormatter: (value: string) => string) => string;
NO_DUPLICATE_KEYS: (constrainedEnumModel: ConstrainedEnumModel,
enumModel: EnumModel,
newEnumKey: string,
namingFormatter: (value: string) => string,
enumKeyToCheck: string,
onNameChange: () => string,
onNameChangeToCheck: () => string) => string;
NO_EMPTY_VALUE: (value: string) => string;
NAMING_FORMATTER: (value: string) => string;
NO_RESERVED_KEYWORDS: (value: string) => string;
Expand All @@ -20,7 +26,7 @@ export const DefaultEnumKeyConstraints: ModelEnumKeyConstraints = {
NO_NUMBER_START_CHAR,
NO_DUPLICATE_KEYS: NO_DUPLICATE_ENUM_KEYS,
NO_EMPTY_VALUE,
NAMING_FORMATTER: FormatHelpers.toConstantCase,
NAMING_FORMATTER: FormatHelpers.toPascalCase,
NO_RESERVED_KEYWORDS: (value: string) => {
return NO_RESERVED_KEYWORDS(value, isReservedGoKeyword);
}
Expand All @@ -35,14 +41,39 @@ export function defaultEnumKeyConstraints(customConstraints?: Partial<ModelEnumK
constrainedEnumKey = constraints.NO_NUMBER_START_CHAR(constrainedEnumKey);
constrainedEnumKey = constraints.NO_EMPTY_VALUE(constrainedEnumKey);
constrainedEnumKey = constraints.NO_RESERVED_KEYWORDS(constrainedEnumKey);
//If the enum key has been manipulated, lets make sure it don't clash with existing keys
if (constrainedEnumKey !== enumKey) {
//Must check against the enum key with the constrained enum model name
constrainedEnumKey = constraints.NO_DUPLICATE_KEYS(
constrainedEnumModel,
enumModel,
constrainedEnumKey,
constraints.NAMING_FORMATTER,
`${constrainedEnumModel.name}_${constrainedEnumKey}`,
() => {
return `reserved_${constrainedEnumKey}`;
}, () => {
return `${constrainedEnumModel.name}_reserved_${constrainedEnumKey}`;
});
}
constrainedEnumKey = `${constrainedEnumModel.name}_${constrainedEnumKey}`;
constrainedEnumKey = constraints.NAMING_FORMATTER(constrainedEnumKey);
constrainedEnumKey = constraints.NO_DUPLICATE_KEYS(constrainedEnumModel, enumModel, constrainedEnumKey, constraints.NAMING_FORMATTER);
return constrainedEnumKey;
};
}

export function defaultEnumValueConstraints(): EnumValueConstraint {
return ({enumValue}) => {
return `"${enumValue}"`;
let constrainedEnumValue: any = JSON.stringify(enumValue);
switch (typeof enumValue) {
case 'string':
constrainedEnumValue = `"${enumValue}"`;
break;
case 'number':
case 'bigint':
constrainedEnumValue = enumValue;
break;
}
return constrainedEnumValue;
};
}
5 changes: 4 additions & 1 deletion src/generators/go/constrainer/PropertyKeyConstrainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,11 @@ export function defaultPropertyKeyConstraints(customConstraints?: Partial<Proper
constrainedPropertyKey = constraints.NO_NUMBER_START_CHAR(constrainedPropertyKey);
constrainedPropertyKey = constraints.NO_EMPTY_VALUE(constrainedPropertyKey);
constrainedPropertyKey = constraints.NO_RESERVED_KEYWORDS(constrainedPropertyKey);
//If the property name has been manipulated, lets make sure it don't clash with existing properties
if (constrainedPropertyKey !== objectPropertyModel.propertyName) {
constrainedPropertyKey = constraints.NO_DUPLICATE_PROPERTIES(constrainedObjectModel, objectModel, constrainedPropertyKey, constraints.NAMING_FORMATTER);
}
constrainedPropertyKey = constraints.NAMING_FORMATTER(constrainedPropertyKey);
constrainedPropertyKey = constraints.NO_DUPLICATE_PROPERTIES(constrainedObjectModel, objectModel, constrainedPropertyKey, constraints.NAMING_FORMATTER);
return constrainedPropertyKey;
};
}
Loading