diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/data_class_opt_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/data_class_opt_var.mustache index deae3ebd5dc..2ce65fd1d16 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/data_class_opt_var.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/data_class_opt_var.mustache @@ -18,4 +18,4 @@ {{#deprecated}} @Deprecated(message = "This property is deprecated.") {{/deprecated}} - {{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") {{/multiplatform}}{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInCamelCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInCamelCase}}}{{/isArray}}{{/isEnum}}? = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}} \ No newline at end of file + {{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") {{/multiplatform}}{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}{{#uniqueItems}}kotlin.collections.Set{{/uniqueItems}}{{^uniqueItems}}kotlin.collections.List{{/uniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInCamelCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInCamelCase}}}{{/isArray}}{{/isEnum}}? = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/data_class_req_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/data_class_req_var.mustache index 2c44be195c8..d7a2fcf31bd 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/data_class_req_var.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/data_class_req_var.mustache @@ -18,4 +18,4 @@ {{#deprecated}} @Deprecated(message = "This property is deprecated.") {{/deprecated}} - {{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") @Required {{/multiplatform}}{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInCamelCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInCamelCase}}}{{/isArray}}{{/isEnum}}{{#isNullable}}?{{/isNullable}} \ No newline at end of file + {{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") @Required {{/multiplatform}}{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}{{#isUniqueItems}}kotlin.collections.Set{{/isUniqueItems}}{{^isUniqueItems}}kotlin.collections.List{{/isUniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInCamelCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInCamelCase}}}{{/isArray}}{{/isEnum}}{{#isNullable}}?{{/isNullable}} \ No newline at end of file diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinModelCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinModelCodegenTest.java index 19829496e23..af675c8913d 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinModelCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinModelCodegenTest.java @@ -52,12 +52,17 @@ public class KotlinModelCodegenTest { } private void checkModel(AbstractKotlinCodegen codegen, boolean mutable, String... props) throws IOException { + String outputPath = generateModels(codegen, "src/test/resources/3_0/generic.yaml", mutable); + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/models/Animal.kt"), props); + } + + private String generateModels(AbstractKotlinCodegen codegen, String fileName, boolean mutable) throws IOException { File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); output.deleteOnExit(); String outputPath = output.getAbsolutePath().replace('\\', '/'); OpenAPI openAPI = new OpenAPIParser() - .readLocation("src/test/resources/3_0/generic.yaml", null, new ParseOptions()).getOpenAPI(); + .readLocation(fileName, null, new ParseOptions()).getOpenAPI(); codegen.setOutputDir(output.getAbsolutePath()); codegen.additionalProperties().put(CodegenConstants.MODEL_PACKAGE, "models"); @@ -77,6 +82,34 @@ public class KotlinModelCodegenTest { generator.opts(input).generate(); - assertFileContains(Paths.get(outputPath + "/src/main/kotlin/models/Animal.kt"), props); + return outputPath; + } + + @Test(dataProvider = "generators") + public void valuesArrayWithUniqueItems(AbstractKotlinCodegen codegen) throws IOException { + String outputPath = generateModels(codegen, "src/test/resources/3_0/issue_9848.yaml", false); + + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/models/NonUniqueArray.kt"), + codegen instanceof KotlinVertxServerCodegen || codegen instanceof KotlinServerDeprecatedCodegen + ? "val array: kotlin.Array" + : "val array: kotlin.collections.List" + ); + + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/models/UniqueArray.kt"), + "val array: kotlin.collections.Set"); + } + + @Test(dataProvider = "generators") + public void mutableArrayWithUniqueItems(AbstractKotlinCodegen codegen) throws IOException { + String outputPath = generateModels(codegen, "src/test/resources/3_0/issue_9848.yaml", true); + + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/models/NonUniqueArray.kt"), + codegen instanceof KotlinVertxServerCodegen || codegen instanceof KotlinServerDeprecatedCodegen + ? "var array: kotlin.Array" + : "var array: kotlin.collections.List" + ); + + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/models/UniqueArray.kt"), + "var array: kotlin.collections.Set"); } } diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_9848.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_9848.yaml new file mode 100644 index 00000000000..5fc12434df5 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_9848.yaml @@ -0,0 +1,50 @@ +openapi: 3.0.1 +info: + title: OpenAPI Petstore + description: "sample spec" + license: + name: Apache-2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html + version: 1.0.0 +servers: + - url: http://petstore.swagger.io:80/v2 +tags: + - name: isX + description: an api that ensures that isX properties are present on Schema classes +paths: + /uniqueTypes: + get: + responses: + '200': + description: 'unique array' + content: + application/json: + schema: + $ref: '#/components/schemas/uniqueArray' + /nonUniqueTypes: + get: + responses: + '200': + description: 'non-unique array' + content: + application/json: + schema: + $ref: '#/components/schemas/nonUniqueArray' +components: + schemas: + uniqueArray: + type: object + properties: + array: + type: array + items: + type: string + uniqueItems: true + nonUniqueArray: + type: object + properties: + array: + type: array + items: + type: string + uniqueItems: false