From 903edaccbea81416d574c7d17482d4e8a11a2965 Mon Sep 17 00:00:00 2001 From: Tom de Vroomen Date: Fri, 19 Jul 2024 10:59:40 +0200 Subject: [PATCH] feat: Allow to use constraints from jakarta namespace for Java and Kotlin models Description The JAVA_CONSTRAINT_PRESET uses constraints from the javax namespace. Since Java 17 the constraints are moved to the jakarta namespace. Add an options to the JAVA_CONSTRAINT_PRESET to use the jakarta namespace for constraint imports. Related issue fixes: (#1807)[https://github.com/asyncapi/modelina/issues/1807] --- .../README.md | 17 ++ .../__snapshots__/index.spec.ts.snap | 35 ++++ .../index.spec.ts | 15 ++ .../index.ts | 34 ++++ .../package-lock.json | 10 ++ .../package.json | 10 ++ .../README.md | 17 ++ .../__snapshots__/index.spec.ts.snap | 22 +++ .../index.spec.ts | 15 ++ .../index.ts | 35 ++++ .../package-lock.json | 10 ++ .../package.json | 10 ++ .../java/presets/ConstraintsPreset.ts | 159 +++++++++--------- .../kotlin/presets/ConstraintsPreset.ts | 10 +- .../java/presets/ConstraintsPreset.spec.ts | 77 +++++++-- .../ConstraintsPreset.spec.ts.snap | 66 +++++++- .../kotlin/presets/ConstraintsPreset.spec.ts | 69 ++++++-- .../ConstraintsPreset.spec.ts.snap | 36 +++- 18 files changed, 535 insertions(+), 112 deletions(-) create mode 100644 examples/java-generate-jakarta-constraint-annotation/README.md create mode 100644 examples/java-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap create mode 100644 examples/java-generate-jakarta-constraint-annotation/index.spec.ts create mode 100644 examples/java-generate-jakarta-constraint-annotation/index.ts create mode 100644 examples/java-generate-jakarta-constraint-annotation/package-lock.json create mode 100644 examples/java-generate-jakarta-constraint-annotation/package.json create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/README.md create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/index.spec.ts create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/index.ts create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/package-lock.json create mode 100644 examples/kotlin-generate-jakarta-constraint-annotation/package.json diff --git a/examples/java-generate-jakarta-constraint-annotation/README.md b/examples/java-generate-jakarta-constraint-annotation/README.md new file mode 100644 index 0000000000..d956c0c557 --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/README.md @@ -0,0 +1,17 @@ +# Jakarta validation constraints annotations + +A basic example that shows how Java data models having `jakarta.validation.constraints` annotations can be generated. + +## How to run this example + +Run this example using: + +```sh +npm i && npm run start +``` + +If you are on Windows, use the `start:windows` script instead: + +```sh +npm i && npm run start:windows +``` diff --git a/examples/java-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap b/examples/java-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap new file mode 100644 index 0000000000..d036c4408d --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Should be able to generate models with jakarta.validation.constraints annotations and should log expected output to console 1`] = ` +Array [ + "public class JakartaAnnotation { + @NotNull + @Min(0) + private double minNumberProp; + @NotNull + @Max(99) + private double maxNumberProp; + @Size(min=2, max=3) + private Object[] arrayProp; + @Pattern(regexp=\\"^I_\\") + @Size(min=3) + private String stringProp; + private Map additionalProperties; + + public double getMinNumberProp() { return this.minNumberProp; } + public void setMinNumberProp(double minNumberProp) { this.minNumberProp = minNumberProp; } + + public double getMaxNumberProp() { return this.maxNumberProp; } + public void setMaxNumberProp(double maxNumberProp) { this.maxNumberProp = maxNumberProp; } + + public Object[] getArrayProp() { return this.arrayProp; } + public void setArrayProp(Object[] arrayProp) { this.arrayProp = arrayProp; } + + public String getStringProp() { return this.stringProp; } + public void setStringProp(String stringProp) { this.stringProp = stringProp; } + + public Map getAdditionalProperties() { return this.additionalProperties; } + public void setAdditionalProperties(Map additionalProperties) { this.additionalProperties = additionalProperties; } +}", +] +`; diff --git a/examples/java-generate-jakarta-constraint-annotation/index.spec.ts b/examples/java-generate-jakarta-constraint-annotation/index.spec.ts new file mode 100644 index 0000000000..1e5c1c4d4f --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/index.spec.ts @@ -0,0 +1,15 @@ +const spy = jest.spyOn(global.console, 'log').mockImplementation(() => { + return; +}); +import { generate } from './index'; + +describe('Should be able to generate models with jakarta.validation.constraints annotations', () => { + afterAll(() => { + jest.restoreAllMocks(); + }); + test('and should log expected output to console', async () => { + await generate(); + expect(spy.mock.calls.length).toEqual(1); + expect(spy.mock.calls[0]).toMatchSnapshot(); + }); +}); diff --git a/examples/java-generate-jakarta-constraint-annotation/index.ts b/examples/java-generate-jakarta-constraint-annotation/index.ts new file mode 100644 index 0000000000..b7325d32cf --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/index.ts @@ -0,0 +1,34 @@ +import { JavaGenerator, JAVA_CONSTRAINTS_PRESET } from '../../src'; + +const generator = new JavaGenerator({ + presets: [ + { + preset: JAVA_CONSTRAINTS_PRESET, + options: { + importFrom: 'jakarta' + } + } + ] +}); +const jsonSchemaDraft7 = { + $schema: 'http://json-schema.org/draft-07/schema#', + $id: 'JakartaAnnotation', + type: 'object', + properties: { + min_number_prop: { type: 'number', minimum: 0 }, + max_number_prop: { type: 'number', exclusiveMaximum: 100 }, + array_prop: { type: 'array', minItems: 2, maxItems: 3 }, + string_prop: { type: 'string', pattern: '^I_', minLength: 3 } + }, + required: ['min_number_prop', 'max_number_prop'] +}; + +export async function generate(): Promise { + const models = await generator.generate(jsonSchemaDraft7); + for (const model of models) { + console.log(model.result); + } +} +if (require.main === module) { + generate(); +} diff --git a/examples/java-generate-jakarta-constraint-annotation/package-lock.json b/examples/java-generate-jakarta-constraint-annotation/package-lock.json new file mode 100644 index 0000000000..1f23d26f33 --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/package-lock.json @@ -0,0 +1,10 @@ +{ + "name": "java-generate-jakarta-constraint-annotation", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "hasInstallScript": true + } + } +} diff --git a/examples/java-generate-jakarta-constraint-annotation/package.json b/examples/java-generate-jakarta-constraint-annotation/package.json new file mode 100644 index 0000000000..4144d6f73c --- /dev/null +++ b/examples/java-generate-jakarta-constraint-annotation/package.json @@ -0,0 +1,10 @@ +{ + "config" : { "example_name" : "java-generate-jakarta-constraint-annotation" }, + "scripts": { + "install": "cd ../.. && npm i", + "start": "../../node_modules/.bin/ts-node --cwd ../../ ./examples/$npm_package_config_example_name/index.ts", + "start:windows": "..\\..\\node_modules\\.bin\\ts-node --cwd ..\\..\\ .\\examples\\%npm_package_config_example_name%\\index.ts", + "test": "../../node_modules/.bin/jest --config=../../jest.config.js ./examples/$npm_package_config_example_name/index.spec.ts", + "test:windows": "..\\..\\node_modules\\.bin\\jest --config=..\\..\\jest.config.js examples/%npm_package_config_example_name%/index.spec.ts" + } +} diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/README.md b/examples/kotlin-generate-jakarta-constraint-annotation/README.md new file mode 100644 index 0000000000..7ada06fe52 --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/README.md @@ -0,0 +1,17 @@ +# Jakarta validation constraints annotations + +A basic example that shows how Kotlin data models having `jakarta.validation.constraints` annotations can be generated. + +## How to run this example + +Run this example using: + +```sh +npm i && npm run start +``` + +If you are on Windows, use the `start:windows` script instead: + +```sh +npm i && npm run start:windows +``` diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap b/examples/kotlin-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap new file mode 100644 index 0000000000..d13ab869e8 --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/__snapshots__/index.spec.ts.snap @@ -0,0 +1,22 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Should be able to generate models with jakarta.validation.constraints annotations and should log expected output to console 1`] = ` +Array [ + "data class JakartaAnnotation( + @get:NotNull + @get:Min(0) + val minNumberProp: Double, + @get:NotNull + @get:Max(99) + val maxNumberProp: Double, + @get:Min(101) + val minNumberPropExclusive: Double? = null, + @get:Size(min=2, max=3) + val arrayProp: List? = null, + @get:Pattern(regexp=\\"^I_\\") + @get:Size(min=3) + val stringProp: String? = null, + val additionalProperties: Map? = null, +)", +] +`; diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/index.spec.ts b/examples/kotlin-generate-jakarta-constraint-annotation/index.spec.ts new file mode 100644 index 0000000000..1e5c1c4d4f --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/index.spec.ts @@ -0,0 +1,15 @@ +const spy = jest.spyOn(global.console, 'log').mockImplementation(() => { + return; +}); +import { generate } from './index'; + +describe('Should be able to generate models with jakarta.validation.constraints annotations', () => { + afterAll(() => { + jest.restoreAllMocks(); + }); + test('and should log expected output to console', async () => { + await generate(); + expect(spy.mock.calls.length).toEqual(1); + expect(spy.mock.calls[0]).toMatchSnapshot(); + }); +}); diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/index.ts b/examples/kotlin-generate-jakarta-constraint-annotation/index.ts new file mode 100644 index 0000000000..70399898cc --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/index.ts @@ -0,0 +1,35 @@ +import { KotlinGenerator, KOTLIN_CONSTRAINTS_PRESET } from '../../src'; + +const generator = new KotlinGenerator({ + presets: [ + { + preset: KOTLIN_CONSTRAINTS_PRESET, + options: { + importFrom: 'jakarta' + } + } + ] +}); +const jsonSchemaDraft7 = { + $schema: 'http://json-schema.org/draft-07/schema#', + $id: 'JakartaAnnotation', + type: 'object', + properties: { + min_number_prop: { type: 'number', minimum: 0 }, + max_number_prop: { type: 'number', exclusiveMaximum: 100 }, + min_number_prop_exclusive: { type: 'number', exclusiveMinimum: 100 }, + array_prop: { type: 'array', minItems: 2, maxItems: 3 }, + string_prop: { type: 'string', pattern: '^I_', minLength: 3 } + }, + required: ['min_number_prop', 'max_number_prop'] +}; + +export async function generate(): Promise { + const models = await generator.generate(jsonSchemaDraft7); + for (const model of models) { + console.log(model.result); + } +} +if (require.main === module) { + generate(); +} diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/package-lock.json b/examples/kotlin-generate-jakarta-constraint-annotation/package-lock.json new file mode 100644 index 0000000000..51d900a025 --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/package-lock.json @@ -0,0 +1,10 @@ +{ + "name": "kotlin-generate-jakarta-constraint-annotation", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "hasInstallScript": true + } + } +} diff --git a/examples/kotlin-generate-jakarta-constraint-annotation/package.json b/examples/kotlin-generate-jakarta-constraint-annotation/package.json new file mode 100644 index 0000000000..de7e66f499 --- /dev/null +++ b/examples/kotlin-generate-jakarta-constraint-annotation/package.json @@ -0,0 +1,10 @@ +{ + "config" : { "example_name" : "kotlin-generate-jakarta-constraint-annotation" }, + "scripts": { + "install": "cd ../.. && npm i", + "start": "../../node_modules/.bin/ts-node --cwd ../../ ./examples/$npm_package_config_example_name/index.ts", + "start:windows": "..\\..\\node_modules\\.bin\\ts-node --cwd ..\\..\\ .\\examples\\%npm_package_config_example_name%\\index.ts", + "test": "../../node_modules/.bin/jest --config=../../jest.config.js ./examples/$npm_package_config_example_name/index.spec.ts", + "test:windows": "..\\..\\node_modules\\.bin\\jest --config=..\\..\\jest.config.js examples/%npm_package_config_example_name%/index.spec.ts" + } +} diff --git a/src/generators/java/presets/ConstraintsPreset.ts b/src/generators/java/presets/ConstraintsPreset.ts index 21745a3643..c15a7e200a 100644 --- a/src/generators/java/presets/ConstraintsPreset.ts +++ b/src/generators/java/presets/ConstraintsPreset.ts @@ -6,93 +6,102 @@ import { } from '../../../models'; import { JavaPreset } from '../JavaPreset'; +export interface JavaConstraintsPresetOptions { + useJakarta: false; +} /** * Preset which extends class's getters with annotations from `javax.validation.constraints` package * * @implements {JavaPreset} */ -export const JAVA_CONSTRAINTS_PRESET: JavaPreset = { - class: { - self({ renderer, content }) { - renderer.dependencyManager.addDependency( - 'import javax.validation.constraints.*;' - ); - return content; - }, - // eslint-disable-next-line sonarjs/cognitive-complexity - property({ renderer, property, content, model }) { - if (model.options.isExtended) { - return ''; - } - - const annotations: string[] = []; +export const JAVA_CONSTRAINTS_PRESET: JavaPreset = + { + class: { + self({ renderer, content, options }) { + options = options || { useJakarta: false }; + const importFrom = options.useJakarta ? 'jakarta' : 'javax'; + renderer.dependencyManager.addDependency( + `import ${importFrom}.validation.constraints.*;` + ); + return content; + }, + // eslint-disable-next-line sonarjs/cognitive-complexity + property({ renderer, property, content, model }) { + if (model.options.isExtended) { + return ''; + } - if (property.required) { - annotations.push(renderer.renderAnnotation('NotNull')); - } - const originalInput = property.property.originalInput; + const annotations: string[] = []; - // string - if (property.property instanceof ConstrainedStringModel) { - const pattern = originalInput['pattern']; - if (pattern !== undefined) { - annotations.push( - renderer.renderAnnotation('Pattern', { - regexp: renderer.renderStringLiteral(pattern) - }) - ); - } - const minLength = originalInput['minLength']; - const maxLength = originalInput['maxLength']; - if (minLength !== undefined || maxLength !== undefined) { - annotations.push( - renderer.renderAnnotation('Size', { - min: minLength, - max: maxLength - }) - ); + if (property.required) { + annotations.push(renderer.renderAnnotation('NotNull')); } - } + const originalInput = property.property.originalInput; - // number/integer - if ( - property.property instanceof ConstrainedFloatModel || - property.property instanceof ConstrainedIntegerModel - ) { - const minimum = originalInput['minimum']; - if (minimum !== undefined) { - annotations.push(renderer.renderAnnotation('Min', minimum)); + // string + if (property.property instanceof ConstrainedStringModel) { + const pattern = originalInput['pattern']; + if (pattern !== undefined) { + annotations.push( + renderer.renderAnnotation('Pattern', { + regexp: renderer.renderStringLiteral(pattern) + }) + ); + } + const minLength = originalInput['minLength']; + const maxLength = originalInput['maxLength']; + if (minLength !== undefined || maxLength !== undefined) { + annotations.push( + renderer.renderAnnotation('Size', { + min: minLength, + max: maxLength + }) + ); + } } - const exclusiveMinimum = originalInput['exclusiveMinimum']; - if (exclusiveMinimum !== undefined) { - annotations.push( - renderer.renderAnnotation('Min', exclusiveMinimum + 1) - ); - } - const maximum = originalInput['maximum']; - if (maximum !== undefined) { - annotations.push(renderer.renderAnnotation('Max', maximum)); - } - const exclusiveMaximum = originalInput['exclusiveMaximum']; - if (exclusiveMaximum !== undefined) { - annotations.push( - renderer.renderAnnotation('Max', exclusiveMaximum - 1) - ); + + // number/integer + if ( + property.property instanceof ConstrainedFloatModel || + property.property instanceof ConstrainedIntegerModel + ) { + const minimum = originalInput['minimum']; + if (minimum !== undefined) { + annotations.push(renderer.renderAnnotation('Min', minimum)); + } + const exclusiveMinimum = originalInput['exclusiveMinimum']; + if (exclusiveMinimum !== undefined) { + annotations.push( + renderer.renderAnnotation('Min', exclusiveMinimum + 1) + ); + } + const maximum = originalInput['maximum']; + if (maximum !== undefined) { + annotations.push(renderer.renderAnnotation('Max', maximum)); + } + const exclusiveMaximum = originalInput['exclusiveMaximum']; + if (exclusiveMaximum !== undefined) { + annotations.push( + renderer.renderAnnotation('Max', exclusiveMaximum - 1) + ); + } } - } - // array - if (property.property instanceof ConstrainedArrayModel) { - const minItems = originalInput['minItems']; - const maxItems = originalInput['maxItems']; - if (minItems !== undefined || maxItems !== undefined) { - annotations.push( - renderer.renderAnnotation('Size', { min: minItems, max: maxItems }) - ); + // array + if (property.property instanceof ConstrainedArrayModel) { + const minItems = originalInput['minItems']; + const maxItems = originalInput['maxItems']; + if (minItems !== undefined || maxItems !== undefined) { + annotations.push( + renderer.renderAnnotation('Size', { + min: minItems, + max: maxItems + }) + ); + } } - } - return renderer.renderBlock([...annotations, content]); + return renderer.renderBlock([...annotations, content]); + } } - } -}; + }; diff --git a/src/generators/kotlin/presets/ConstraintsPreset.ts b/src/generators/kotlin/presets/ConstraintsPreset.ts index 3ba7508cc3..447abadae6 100644 --- a/src/generators/kotlin/presets/ConstraintsPreset.ts +++ b/src/generators/kotlin/presets/ConstraintsPreset.ts @@ -8,11 +8,17 @@ import { import { KotlinPreset } from '../KotlinPreset'; import { ClassRenderer } from '../renderers/ClassRenderer'; +export interface KotlinConstraintsPresetOptions { + useJakarta: false; +} + export const KOTLIN_CONSTRAINTS_PRESET: KotlinPreset = { class: { - self({ renderer, content }) { + self({ renderer, content, options }) { + options = options || { useJakarta: false }; + const importFrom = options.useJakarta ? 'jakarta' : 'javax'; renderer.dependencyManager.addDependency( - 'javax.validation.constraints.*' + `${importFrom}.validation.constraints.*` ); return content; }, diff --git a/test/generators/java/presets/ConstraintsPreset.spec.ts b/test/generators/java/presets/ConstraintsPreset.spec.ts index 13a74fa289..76d4c051db 100644 --- a/test/generators/java/presets/ConstraintsPreset.spec.ts +++ b/test/generators/java/presets/ConstraintsPreset.spec.ts @@ -4,27 +4,46 @@ import { } from '../../../../src/generators'; describe('JAVA_CONSTRAINTS_PRESET', () => { - let generator: JavaGenerator; - beforeEach(() => { - generator = new JavaGenerator({ presets: [JAVA_CONSTRAINTS_PRESET] }); + const doc = { + $id: 'Clazz', + type: 'object', + properties: { + min_number_prop: { type: 'number', minimum: 0 }, + max_number_prop: { type: 'number', exclusiveMaximum: 100 }, + array_prop: { type: 'array', minItems: 2, maxItems: 3 }, + string_prop: { + type: 'string', + pattern: '^\\w+("\\.\\w+)*$', + minLength: 3 + } + }, + required: ['min_number_prop', 'max_number_prop'] + }; + + test('should render javax constraints annotations by default', async () => { + const generator = new JavaGenerator({ presets: [JAVA_CONSTRAINTS_PRESET] }); + const expectedDependencies = [ + 'import java.util.Map;', + 'import javax.validation.constraints.*;' + ]; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + expect(models[0].dependencies).toEqual(expectedDependencies); }); - test('should render constraints annotations', async () => { - const doc = { - $id: 'Clazz', - type: 'object', - properties: { - min_number_prop: { type: 'number', minimum: 0 }, - max_number_prop: { type: 'number', exclusiveMaximum: 100 }, - array_prop: { type: 'array', minItems: 2, maxItems: 3 }, - string_prop: { - type: 'string', - pattern: '^\\w+("\\.\\w+)*$', - minLength: 3 + test('should render javax constraints annotations when configured', async () => { + const generator = new JavaGenerator({ + presets: [ + { + preset: JAVA_CONSTRAINTS_PRESET, + options: { + useJakarta: false + } } - }, - required: ['min_number_prop', 'max_number_prop'] - }; + ] + }); const expectedDependencies = [ 'import java.util.Map;', 'import javax.validation.constraints.*;' @@ -36,6 +55,28 @@ describe('JAVA_CONSTRAINTS_PRESET', () => { expect(models[0].dependencies).toEqual(expectedDependencies); }); + test('should render jakarta constraints annotations from when configured', async () => { + const generator = new JavaGenerator({ + presets: [ + { + preset: JAVA_CONSTRAINTS_PRESET, + options: { + useJakarta: true + } + } + ] + }); + const expectedDependencies = [ + 'import java.util.Map;', + 'import jakarta.validation.constraints.*;' + ]; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + expect(models[0].dependencies).toEqual(expectedDependencies); + }); + test('should not render anything when isExtended is true', async () => { const extend = { $id: 'extend', diff --git a/test/generators/java/presets/__snapshots__/ConstraintsPreset.spec.ts.snap b/test/generators/java/presets/__snapshots__/ConstraintsPreset.spec.ts.snap index 4101fcd470..5fa0e9b3c7 100644 --- a/test/generators/java/presets/__snapshots__/ConstraintsPreset.spec.ts.snap +++ b/test/generators/java/presets/__snapshots__/ConstraintsPreset.spec.ts.snap @@ -22,7 +22,71 @@ Array [ ] `; -exports[`JAVA_CONSTRAINTS_PRESET should render constraints annotations 1`] = ` +exports[`JAVA_CONSTRAINTS_PRESET should render jakarta constraints annotations from when configured 1`] = ` +"public class Clazz { + @NotNull + @Min(0) + private double minNumberProp; + @NotNull + @Max(99) + private double maxNumberProp; + @Size(min=2, max=3) + private Object[] arrayProp; + @Pattern(regexp=\\"^\\\\\\\\w+(\\\\\\"\\\\\\\\.\\\\\\\\w+)*$\\") + @Size(min=3) + private String stringProp; + private Map additionalProperties; + + public double getMinNumberProp() { return this.minNumberProp; } + public void setMinNumberProp(double minNumberProp) { this.minNumberProp = minNumberProp; } + + public double getMaxNumberProp() { return this.maxNumberProp; } + public void setMaxNumberProp(double maxNumberProp) { this.maxNumberProp = maxNumberProp; } + + public Object[] getArrayProp() { return this.arrayProp; } + public void setArrayProp(Object[] arrayProp) { this.arrayProp = arrayProp; } + + public String getStringProp() { return this.stringProp; } + public void setStringProp(String stringProp) { this.stringProp = stringProp; } + + public Map getAdditionalProperties() { return this.additionalProperties; } + public void setAdditionalProperties(Map additionalProperties) { this.additionalProperties = additionalProperties; } +}" +`; + +exports[`JAVA_CONSTRAINTS_PRESET should render javax constraints annotations by default 1`] = ` +"public class Clazz { + @NotNull + @Min(0) + private double minNumberProp; + @NotNull + @Max(99) + private double maxNumberProp; + @Size(min=2, max=3) + private Object[] arrayProp; + @Pattern(regexp=\\"^\\\\\\\\w+(\\\\\\"\\\\\\\\.\\\\\\\\w+)*$\\") + @Size(min=3) + private String stringProp; + private Map additionalProperties; + + public double getMinNumberProp() { return this.minNumberProp; } + public void setMinNumberProp(double minNumberProp) { this.minNumberProp = minNumberProp; } + + public double getMaxNumberProp() { return this.maxNumberProp; } + public void setMaxNumberProp(double maxNumberProp) { this.maxNumberProp = maxNumberProp; } + + public Object[] getArrayProp() { return this.arrayProp; } + public void setArrayProp(Object[] arrayProp) { this.arrayProp = arrayProp; } + + public String getStringProp() { return this.stringProp; } + public void setStringProp(String stringProp) { this.stringProp = stringProp; } + + public Map getAdditionalProperties() { return this.additionalProperties; } + public void setAdditionalProperties(Map additionalProperties) { this.additionalProperties = additionalProperties; } +}" +`; + +exports[`JAVA_CONSTRAINTS_PRESET should render javax constraints annotations when configured 1`] = ` "public class Clazz { @NotNull @Min(0) diff --git a/test/generators/kotlin/presets/ConstraintsPreset.spec.ts b/test/generators/kotlin/presets/ConstraintsPreset.spec.ts index d320810e35..23e84ffcca 100644 --- a/test/generators/kotlin/presets/ConstraintsPreset.spec.ts +++ b/test/generators/kotlin/presets/ConstraintsPreset.spec.ts @@ -1,22 +1,41 @@ import { KotlinGenerator, KOTLIN_CONSTRAINTS_PRESET } from '../../../../src'; describe('KOTLIN_CONSTRAINTS_PRESET', () => { - let generator: KotlinGenerator; - beforeEach(() => { - generator = new KotlinGenerator({ presets: [KOTLIN_CONSTRAINTS_PRESET] }); + const doc = { + $id: 'Clazz', + type: 'object', + properties: { + min_number_prop: { type: 'number', minimum: 0 }, + max_number_prop: { type: 'number', exclusiveMaximum: 100 }, + array_prop: { type: 'array', minItems: 2, maxItems: 3 }, + string_prop: { type: 'string', pattern: '^I_', minLength: 3 } + }, + required: ['min_number_prop', 'max_number_prop'] + }; + + test('should render javax constraints annotations by default', async () => { + const generator = new KotlinGenerator({ + presets: [KOTLIN_CONSTRAINTS_PRESET] + }); + const expectedDependencies = ['import javax.validation.constraints.*']; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + expect(models[0].dependencies).toEqual(expectedDependencies); }); - test('should render constraints annotations', async () => { - const doc = { - $id: 'Clazz', - type: 'object', - properties: { - min_number_prop: { type: 'number', minimum: 0 }, - max_number_prop: { type: 'number', exclusiveMaximum: 100 }, - array_prop: { type: 'array', minItems: 2, maxItems: 3 }, - string_prop: { type: 'string', pattern: '^I_', minLength: 3 } - }, - required: ['min_number_prop', 'max_number_prop'] - }; + test('should render javax constraints annotations when configured', async () => { + const generator = new KotlinGenerator({ + presets: [ + { + preset: KOTLIN_CONSTRAINTS_PRESET, + options: { + useJakarta: false + } + } + ] + }); + const expectedDependencies = ['import javax.validation.constraints.*']; const models = await generator.generate(doc); @@ -24,4 +43,24 @@ describe('KOTLIN_CONSTRAINTS_PRESET', () => { expect(models[0].result).toMatchSnapshot(); expect(models[0].dependencies).toEqual(expectedDependencies); }); + + test('should render jakarta constraints annotations when configured', async () => { + const generator = new KotlinGenerator({ + presets: [ + { + preset: KOTLIN_CONSTRAINTS_PRESET, + options: { + useJakarta: true + } + } + ] + }); + + const expectedDependencies = ['import jakarta.validation.constraints.*']; + + const models = await generator.generate(doc); + expect(models).toHaveLength(1); + expect(models[0].result).toMatchSnapshot(); + expect(models[0].dependencies).toEqual(expectedDependencies); + }); }); diff --git a/test/generators/kotlin/presets/__snapshots__/ConstraintsPreset.spec.ts.snap b/test/generators/kotlin/presets/__snapshots__/ConstraintsPreset.spec.ts.snap index e47ccb4e5d..31c72a3c58 100644 --- a/test/generators/kotlin/presets/__snapshots__/ConstraintsPreset.spec.ts.snap +++ b/test/generators/kotlin/presets/__snapshots__/ConstraintsPreset.spec.ts.snap @@ -1,6 +1,40 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`KOTLIN_CONSTRAINTS_PRESET should render constraints annotations 1`] = ` +exports[`KOTLIN_CONSTRAINTS_PRESET should render jakarta constraints annotations when configured 1`] = ` +"data class Clazz( + @get:NotNull + @get:Min(0) + val minNumberProp: Double, + @get:NotNull + @get:Max(99) + val maxNumberProp: Double, + @get:Size(min=2, max=3) + val arrayProp: List? = null, + @get:Pattern(regexp=\\"^I_\\") + @get:Size(min=3) + val stringProp: String? = null, + val additionalProperties: Map? = null, +)" +`; + +exports[`KOTLIN_CONSTRAINTS_PRESET should render javax constraints annotations by default 1`] = ` +"data class Clazz( + @get:NotNull + @get:Min(0) + val minNumberProp: Double, + @get:NotNull + @get:Max(99) + val maxNumberProp: Double, + @get:Size(min=2, max=3) + val arrayProp: List? = null, + @get:Pattern(regexp=\\"^I_\\") + @get:Size(min=3) + val stringProp: String? = null, + val additionalProperties: Map? = null, +)" +`; + +exports[`KOTLIN_CONSTRAINTS_PRESET should render javax constraints annotations when configured 1`] = ` "data class Clazz( @get:NotNull @get:Min(0)