diff --git a/test/generators/javascript/constrainer/EnumConstrainer.spec.ts b/test/generators/javascript/constrainer/EnumConstrainer.spec.ts index 53e11edcec..e5d08d778e 100644 --- a/test/generators/javascript/constrainer/EnumConstrainer.spec.ts +++ b/test/generators/javascript/constrainer/EnumConstrainer.spec.ts @@ -59,7 +59,7 @@ describe('EnumConstrainer', () => { }); expect(constrainedKey).toEqual(''); }); - test('should use constant naming format', () => { + test('should use pascal naming format', () => { const constrainedKey = JavaScriptDefaultConstraints.enumKey({ enumModel, constrainedEnumModel, diff --git a/test/generators/javascript/constrainer/ModelNameConstrainer.spec.ts b/test/generators/javascript/constrainer/ModelNameConstrainer.spec.ts index 5cae1a39f8..edd4531e86 100644 --- a/test/generators/javascript/constrainer/ModelNameConstrainer.spec.ts +++ b/test/generators/javascript/constrainer/ModelNameConstrainer.spec.ts @@ -23,7 +23,7 @@ describe('ModelNameConstrainer', () => { }); expect(constrainedKey).toEqual('Empty'); }); - test('should use constant naming format', () => { + test('should use pascal naming format', () => { const constrainedKey = JavaScriptDefaultConstraints.modelName({ modelName: 'some weird_value!"#2' }); diff --git a/test/generators/javascript/constrainer/PropertyKeyConstrainer.spec.ts b/test/generators/javascript/constrainer/PropertyKeyConstrainer.spec.ts index 330e8c36a6..f53bd83d87 100644 --- a/test/generators/javascript/constrainer/PropertyKeyConstrainer.spec.ts +++ b/test/generators/javascript/constrainer/PropertyKeyConstrainer.spec.ts @@ -52,7 +52,7 @@ describe('PropertyKeyConstrainer', () => { const constrainedKey = constrainPropertyName(''); expect(constrainedKey).toEqual('empty'); }); - test('should use constant naming format', () => { + test('should use pascal naming format', () => { const constrainedKey = constrainPropertyName('some weird_value!"#2'); expect(constrainedKey).toEqual('someWeirdValueExclamationQuotationHash_2'); }); diff --git a/test/generators/python/constrainer/ConstantConstrainer.spec.ts b/test/generators/python/constrainer/ConstantConstrainer.spec.ts new file mode 100644 index 0000000000..f41fcc3fad --- /dev/null +++ b/test/generators/python/constrainer/ConstantConstrainer.spec.ts @@ -0,0 +1,19 @@ +import { defaultConstantConstraints } from '../../../../src/generators/python/constrainer/ConstantConstrainer'; + +const mockConstantContext = { + constrainedMetaModel: {} as any +}; + +describe('defaultConstantConstraints', () => { + it('should return a function that returns undefined', () => { + const constantConstraintsFunction = defaultConstantConstraints(); + const result = constantConstraintsFunction(mockConstantContext); + expect(result).toBeUndefined(); + }); + + it('should return a ConstantConstraint type', () => { + const constantConstraintsFunction = defaultConstantConstraints(); + const result = constantConstraintsFunction; + expect(typeof result).toBe('function'); + }); +}); diff --git a/test/generators/python/constrainer/EnumConstrainer.spec.ts b/test/generators/python/constrainer/EnumConstrainer.spec.ts new file mode 100644 index 0000000000..7a9635ceed --- /dev/null +++ b/test/generators/python/constrainer/EnumConstrainer.spec.ts @@ -0,0 +1,134 @@ +import { PythonDefaultConstraints } from '../../../../src/generators/python/PythonConstrainer'; +import { EnumModel } from '../../../../src/models/MetaModel'; +import { + ConstrainedEnumModel, + ConstrainedEnumValueModel +} from '../../../../src'; + +describe('EnumConstrainer', () => { + const enumModel = new EnumModel('test', undefined, {}, []); + const constrainedEnumModel = new ConstrainedEnumModel( + 'test', + undefined, + {}, + '', + [] + ); + + describe('enum keys', () => { + test('should never render special chars', () => { + const constrainedKey = PythonDefaultConstraints.enumKey({ + enumModel, + constrainedEnumModel, + enumKey: '%' + }); + expect(constrainedKey).toEqual('PERCENT'); + }); + + test('should not render number as start char', () => { + const constrainedKey = PythonDefaultConstraints.enumKey({ + enumModel, + constrainedEnumModel, + enumKey: '1' + }); + expect(constrainedKey).toEqual('NUMBER_1'); + }); + + test('should not contain duplicate keys', () => { + const existingConstrainedEnumValueModel = new ConstrainedEnumValueModel( + 'EMPTY', + 'return', + 'return' + ); + const constrainedEnumModel = new ConstrainedEnumModel( + 'test', + undefined, + {}, + '', + [existingConstrainedEnumValueModel] + ); + const constrainedKey = PythonDefaultConstraints.enumKey({ + enumModel, + constrainedEnumModel, + enumKey: '' + }); + expect(constrainedKey).toEqual('RESERVED_EMPTY'); + }); + + test('should never contain empty keys', () => { + const constrainedKey = PythonDefaultConstraints.enumKey({ + enumModel, + constrainedEnumModel, + enumKey: '' + }); + expect(constrainedKey).toEqual('EMPTY'); + }); + + test('should use constant naming format', () => { + const constrainedKey = PythonDefaultConstraints.enumKey({ + enumModel, + constrainedEnumModel, + enumKey: 'some weird_value!"#2' + }); + expect(constrainedKey).toEqual( + 'SOME_WEIRD_VALUE_EXCLAMATION_QUOTATION_HASH_2' + ); + }); + + test('should never render reserved keywords', () => { + const constrainedKey = PythonDefaultConstraints.enumKey({ + enumModel, + constrainedEnumModel, + enumKey: 'return' + }); + expect(constrainedKey).toEqual('RESERVED_RETURN'); + }); + }); + + describe('enum values', () => { + test('should render value as is', () => { + const constrainedValue = PythonDefaultConstraints.enumValue({ + enumModel, + constrainedEnumModel, + enumValue: 'string value' + }); + expect(constrainedValue).toEqual('"string value"'); + }); + + test('should render boolean values', () => { + const constrainedValue = PythonDefaultConstraints.enumValue({ + enumModel, + constrainedEnumModel, + enumValue: true + }); + expect(constrainedValue).toEqual('"true"'); + }); + + test('should render numbers', () => { + const constrainedValue = PythonDefaultConstraints.enumValue({ + enumModel, + constrainedEnumModel, + enumValue: 123 + }); + expect(constrainedValue).toEqual(123); + }); + + test('should render object', () => { + const constrainedValue = PythonDefaultConstraints.enumValue({ + enumModel, + constrainedEnumModel, + enumValue: { test: 'test' } + }); + expect(constrainedValue).toEqual('"{\\"test\\":\\"test\\"}"'); + }); + + test('should render unknown value', () => { + const constrainedValue = PythonDefaultConstraints.enumValue({ + enumModel, + constrainedEnumModel, + enumValue: undefined + }); + expect(constrainedValue).toEqual(`"undefined"`); + }); + }); +}); diff --git a/test/generators/python/constrainer/ModelNameConstrainer.spec.ts b/test/generators/python/constrainer/ModelNameConstrainer.spec.ts new file mode 100644 index 0000000000..3ee47faf81 --- /dev/null +++ b/test/generators/python/constrainer/ModelNameConstrainer.spec.ts @@ -0,0 +1,76 @@ +import { PythonDefaultConstraints } from '../../../../src/generators/python/PythonConstrainer'; +import { + DefaultModelNameConstraints, + defaultModelNameConstraints, + ModelNameConstraints +} from '../../../../src/generators/python/constrainer/ModelNameConstrainer'; + +describe('ModelNameConstrainer', () => { + test('should never render special chars', () => { + const constrainedKey = PythonDefaultConstraints.modelName({ + modelName: '%' + }); + expect(constrainedKey).toEqual('Percent'); + }); + test('should never render number as start char', () => { + const constrainedKey = PythonDefaultConstraints.modelName({ + modelName: '1' + }); + expect(constrainedKey).toEqual('Number_1'); + }); + test('should never contain empty name', () => { + const constrainedKey = PythonDefaultConstraints.modelName({ + modelName: '' + }); + expect(constrainedKey).toEqual('Empty'); + }); + test('should use pascal naming format', () => { + const constrainedKey = PythonDefaultConstraints.modelName({ + modelName: 'some weird_value!"#2' + }); + expect(constrainedKey).toEqual('SomeWeirdValueExclamationQuotationHash_2'); + }); + test('should never render reserved keywords', () => { + const constrainedKey = PythonDefaultConstraints.modelName({ + modelName: 'return' + }); + expect(constrainedKey).toEqual('ReservedReturn'); + }); + describe('custom constraints', () => { + test('should be able to overwrite all hooks', () => { + const mockedConstraintCallbacks: ModelNameConstraints = { + NAMING_FORMATTER: jest.fn().mockReturnValue(''), + NO_SPECIAL_CHAR: jest.fn().mockReturnValue(''), + NO_NUMBER_START_CHAR: jest.fn().mockReturnValue(''), + NO_EMPTY_VALUE: jest.fn().mockReturnValue(''), + NO_RESERVED_KEYWORDS: jest.fn().mockReturnValue('') + }; + const constrainFunction = defaultModelNameConstraints( + mockedConstraintCallbacks + ); + constrainFunction({ modelName: '' }); + //Expect all callbacks to be called + for (const jestMockCallback of Object.values(mockedConstraintCallbacks)) { + expect(jestMockCallback).toHaveBeenCalled(); + } + }); + test('should be able to overwrite one hooks', () => { + //All but NAMING_FORMATTER, as we customize that + const spies = [ + jest.spyOn(DefaultModelNameConstraints, 'NO_SPECIAL_CHAR'), + jest.spyOn(DefaultModelNameConstraints, 'NO_NUMBER_START_CHAR'), + jest.spyOn(DefaultModelNameConstraints, 'NO_EMPTY_VALUE'), + jest.spyOn(DefaultModelNameConstraints, 'NO_RESERVED_KEYWORDS') + ]; + const jestCallback = jest.fn().mockReturnValue(''); + const constrainFunction = defaultModelNameConstraints({ + NAMING_FORMATTER: jestCallback + }); + const constrainedValue = constrainFunction({ modelName: '' }); + expect(constrainedValue).toEqual(''); + for (const jestMockCallback of spies) { + expect(jestMockCallback).toHaveBeenCalled(); + } + }); + }); +}); diff --git a/test/generators/python/constrainer/PropertyKeyConstrainer.spec.ts b/test/generators/python/constrainer/PropertyKeyConstrainer.spec.ts new file mode 100644 index 0000000000..8f3d8b83ca --- /dev/null +++ b/test/generators/python/constrainer/PropertyKeyConstrainer.spec.ts @@ -0,0 +1,183 @@ +import { PythonDefaultConstraints } from '../../../../src/generators/python/PythonConstrainer'; +import { + ConstrainedObjectModel, + ConstrainedObjectPropertyModel, + ObjectModel, + ObjectPropertyModel +} from '../../../../src'; +import { + DefaultPropertyKeyConstraints, + defaultPropertyKeyConstraints, + PropertyKeyConstraintOptions +} from '../../../../src/generators/python/constrainer/PropertyKeyConstrainer'; + +describe('PropertyKeyConstrainer', () => { + const objectModel = new ObjectModel('test', undefined, {}, {}); + const constrainedObjectModel = new ConstrainedObjectModel( + 'test', + undefined, + {}, + '', + {} + ); + + const constrainPropertyName = (propertyName: string) => { + const objectPropertyModel = new ObjectPropertyModel( + propertyName, + false, + objectModel + ); + const constrainedObjectPropertyModel = new ConstrainedObjectPropertyModel( + '', + '', + objectPropertyModel.required, + constrainedObjectModel + ); + return PythonDefaultConstraints.propertyKey({ + constrainedObjectModel, + objectModel, + objectPropertyModel, + constrainedObjectPropertyModel + }); + }; + + test('should never render special chars', () => { + const constrainedKey = constrainPropertyName('%'); + expect(constrainedKey).toEqual('percent'); + }); + test('should not render number as start char', () => { + const constrainedKey = constrainPropertyName('1'); + expect(constrainedKey).toEqual('number_1'); + }); + test('should never contain empty name', () => { + const constrainedKey = constrainPropertyName(''); + expect(constrainedKey).toEqual('empty'); + }); + test('should use camel naming format', () => { + const constrainedKey = constrainPropertyName('some weird_value!"#2'); + expect(constrainedKey).toEqual('someWeirdValueExclamationQuotationHash_2'); + }); + test('should not contain duplicate properties', () => { + const objectModel = new ObjectModel('test', undefined, {}, {}); + const constrainedObjectModel = new ConstrainedObjectModel( + 'test', + undefined, + {}, + '', + {} + ); + const objectPropertyModel = new ObjectPropertyModel( + 'reservedReturn', + false, + objectModel + ); + const constrainedObjectPropertyModel = new ConstrainedObjectPropertyModel( + 'reservedReturn', + '', + objectPropertyModel.required, + constrainedObjectModel + ); + const objectPropertyModel2 = new ObjectPropertyModel( + 'return', + false, + objectModel + ); + const constrainedObjectPropertyModel2 = new ConstrainedObjectPropertyModel( + 'return', + '', + objectPropertyModel.required, + constrainedObjectModel + ); + constrainedObjectModel.properties['reservedReturn'] = + constrainedObjectPropertyModel; + constrainedObjectModel.properties['return'] = + constrainedObjectPropertyModel2; + const constrainedKey = PythonDefaultConstraints.propertyKey({ + constrainedObjectModel, + objectModel, + objectPropertyModel: objectPropertyModel2, + constrainedObjectPropertyModel: constrainedObjectPropertyModel2 + }); + expect(constrainedKey).toEqual('reservedReservedReturn'); + }); + test('should never render reserved keywords', () => { + const constrainedKey = constrainPropertyName('return'); + expect(constrainedKey).toEqual('reservedReturn'); + }); + describe('custom constraints', () => { + test('should be able to overwrite all hooks', () => { + const mockedConstraintCallbacks: Partial = { + NAMING_FORMATTER: jest.fn().mockReturnValue(''), + NO_SPECIAL_CHAR: jest.fn().mockReturnValue(''), + NO_NUMBER_START_CHAR: jest.fn().mockReturnValue(''), + NO_EMPTY_VALUE: jest.fn().mockReturnValue(''), + NO_RESERVED_KEYWORDS: jest.fn().mockReturnValue('') + }; + const constrainFunction = defaultPropertyKeyConstraints( + mockedConstraintCallbacks + ); + const objectPropertyModel = new ObjectPropertyModel( + '', + false, + objectModel + ); + const constrainedObjectPropertyModel = new ConstrainedObjectPropertyModel( + '', + '', + objectPropertyModel.required, + constrainedObjectModel + ); + constrainFunction({ + constrainedObjectModel, + objectModel, + objectPropertyModel, + constrainedObjectPropertyModel + }); + //Expect all callbacks to be called + for (const jestMockCallback of Object.values(mockedConstraintCallbacks)) { + expect(jestMockCallback).toHaveBeenCalled(); + } + }); + test('should be able to overwrite one hooks', () => { + //All but NAMING_FORMATTER, as we customize that + const spies = [ + jest.spyOn(DefaultPropertyKeyConstraints, 'NO_SPECIAL_CHAR'), + jest.spyOn(DefaultPropertyKeyConstraints, 'NO_NUMBER_START_CHAR'), + jest.spyOn(DefaultPropertyKeyConstraints, 'NO_EMPTY_VALUE'), + jest.spyOn(DefaultPropertyKeyConstraints, 'NO_RESERVED_KEYWORDS'), + jest.spyOn(DefaultPropertyKeyConstraints, 'NO_DUPLICATE_PROPERTIES') + ]; + const overwrittenDefaultFunction = jest.spyOn( + DefaultPropertyKeyConstraints, + 'NAMING_FORMATTER' + ); + const jestCallback = jest.fn().mockReturnValue(''); + const constrainFunction = defaultPropertyKeyConstraints({ + NAMING_FORMATTER: jestCallback + }); + const objectPropertyModel = new ObjectPropertyModel( + '', + false, + objectModel + ); + const constrainedObjectPropertyModel = new ConstrainedObjectPropertyModel( + '', + '', + objectPropertyModel.required, + constrainedObjectModel + ); + const constrainedValue = constrainFunction({ + constrainedObjectModel, + objectModel, + objectPropertyModel, + constrainedObjectPropertyModel + }); + expect(constrainedValue).toEqual(''); + expect(jestCallback).toHaveBeenCalled(); + expect(overwrittenDefaultFunction).not.toHaveBeenCalled(); + for (const jestMockCallback of spies) { + expect(jestMockCallback).toHaveBeenCalled(); + } + }); + }); +});