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

[kotlin] Enum should match spec #18062

Merged
merged 5 commits into from
Mar 9, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/generators/kotlin-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|apiSuffix|suffix for api classes| |Api|
|artifactId|Generated artifact id (name of jar).| |kotlin-server|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original|
|featureAutoHead|Automatically provide responses to HEAD requests for existing routes that have the GET verb defined.| |true|
|featureCORS|Ktor by default provides an interceptor for implementing proper support for Cross-Origin Resource Sharing (CORS). See enable-cors.org.| |false|
|featureCompression|Adds ability to compress outgoing content using gzip, deflate or custom encoder and thus reduce size of the response.| |true|
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/kotlin-spring.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|configPackage|configuration package for generated code| |org.openapitools.configuration|
|delegatePattern|Whether to generate the server files using the delegate pattern| |false|
|documentationProvider|Select the OpenAPI documentation provider.|<dl><dt>**none**</dt><dd>Do not publish an OpenAPI specification.</dd><dt>**source**</dt><dd>Publish the original input OpenAPI specification.</dd><dt>**springfox**</dt><dd>Generate an OpenAPI 2 (fka Swagger RESTful API Documentation Specification) specification using SpringFox 2.x. Deprecated (for removal); use springdoc instead.</dd><dt>**springdoc**</dt><dd>Generate an OpenAPI 3 specification using SpringDoc.</dd></dl>|springdoc|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original|
|exceptionHandler|generate default global exception handlers (not compatible with reactive. enabling reactive will disable exceptionHandler )| |true|
|gradleBuildFile|generate a gradle build file using the Kotlin DSL| |true|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/kotlin-vertx.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|apiSuffix|suffix for api classes| |Api|
|artifactId|Generated artifact id (name of jar).| |null|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|modelMutable|Create mutable models| |false|
|packageName|Generated artifact package name.| |org.openapitools|
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/kotlin.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|artifactVersion|Generated artifact's package version.| |1.0.0|
|collectionType|Option. Collection type to use|<dl><dt>**array**</dt><dd>kotlin.Array</dd><dt>**list**</dt><dd>kotlin.collections.List</dd></dl>|list|
|dateLibrary|Option. Date library to use|<dl><dt>**threetenbp-localdatetime**</dt><dd>Threetenbp - Backport of JSR310 (jvm only, for legacy app only)</dd><dt>**kotlinx-datetime**</dt><dd>kotlinx-datetime (preferred for multiplatform)</dd><dt>**string**</dt><dd>String</dd><dt>**java8-localdatetime**</dt><dd>Java 8 native JSR310 (jvm only, for legacy app only)</dd><dt>**java8**</dt><dd>Java 8 native JSR310 (jvm only, preferred for jdk 1.8+)</dd><dt>**threetenbp**</dt><dd>Threetenbp - Backport of JSR310 (jvm only, preferred for jdk &lt; 1.8)</dd></dl>|java8|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original|
|generateRoomModels|Generate Android Room database models in addition to API models (JVM Volley library only)| |false|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|idea|Add IntellJ Idea plugin and mark Kotlin main and test folders as source folders.| |false|
Expand Down
2 changes: 1 addition & 1 deletion docs/generators/ktorm-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
|artifactId|Generated artifact id (name of jar).| |ktorm|
|artifactVersion|Generated artifact's package version.| |1.0.0|
|defaultDatabaseName|Default database name for all queries| |sqlite.db|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |camelCase|
|enumPropertyNaming|Naming convention for enum properties: 'camelCase', 'PascalCase', 'snake_case', 'UPPERCASE', and 'original'| |original|
|groupId|Generated artifact package's organization (i.e. maven groupId).| |org.openapitools|
|identifierNamingConvention|Naming convention of Ktorm identifiers(table names and column names). This is not related to database name which is defined by defaultDatabaseName option|<dl><dt>**original**</dt><dd>Do not transform original names</dd><dt>**snake_case**</dt><dd>Use snake_case names</dd></dl>|original|
|importModelPackageName|Package name of the imported models| |org.openapitools.database.models|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co

protected boolean nonPublicApi = false;

protected CodegenConstants.ENUM_PROPERTY_NAMING_TYPE enumPropertyNaming = CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.camelCase;
protected CodegenConstants.ENUM_PROPERTY_NAMING_TYPE enumPropertyNaming = CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.original;

// model classes cannot use the same property names defined in HashMap
// ref: https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-hash-map/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,38 @@

{{unescapedDescription}}


{{^allowableValues}}
[.fields-{{classname}}]
[cols="2,1,2,4,1"]
[cols="2,1,1,2,4,1"]
|===
| Field Name| Required| Type| Description| Format
| Field Name| Required| Nullable | Type| Description | Format

{{#vars}}
| {{baseName}}
| {{#required}}X{{/required}}
| {{dataType}} {{#isContainer}} of <<{{complexType}}>>{{/isContainer}}
| {{#isNullable}}X{{/isNullable}}
| {{#isModel}}<<{{ dataType }}>>{{/isModel}} {{^container}}{{^allowableValues}} {{^isModel}}{{ dataType }}{{/isModel}}{{/allowableValues}}{{#allowableValues}}{{^allowableValues.empty}}<<{{ dataType }}>>{{/allowableValues.empty}}{{/allowableValues}} {{/container}} {{#isContainer}} of <<{{complexType}}>>{{/isContainer}}
| {{description}}
| {{{dataFormat}}} {{#isEnum}}_Enum:_ {{#_enum}}{{this}}, {{/_enum}}{{/isEnum}}
| {{{dataFormat}}} {{#isEnum}}_Enum:_ {{#_enum}}{{this}}, {{/_enum}}{{/isEnum}} {{^isEnum}}{{^container}}{{^allowableValues.empty}} {{#allowableValues.values}}{{this}}, {{/allowableValues.values}} {{/allowableValues.empty}}{{/container}}{{/isEnum}}

{{/vars}}
|===
{{/allowableValues}}

{{#allowableValues}}

[.fields-{{classname}}]
[cols="1"]
|===
| Enum Values

{{#allowableValues.values}}
| {{this}}
{{/allowableValues.values}}

|===
{{/allowableValues}}

{{/model}}
{{/models}}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
import org.testng.annotations.Test;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -278,9 +281,70 @@ public void testEnumPropertyWithDefaultValue() {
// Assert the enum default value is properly generated
CodegenProperty cp1 = cm1.vars.get(0);
Assert.assertEquals(cp1.getEnumName(), "PropertyName");
Assert.assertEquals(cp1.getDefaultValue(), "PropertyName.vALUE");
Assert.assertEquals(cp1.getDefaultValue(), "PropertyName.VALUE");
}

@Test(description = "Issue #3804")
public void testEnumPropertyWithCapitalization() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/kotlin/issue3804-enum-enum-capitalization.yaml");
final AbstractKotlinCodegen codegen = new P_AbstractKotlinCodegen();

Schema test1 = openAPI.getComponents().getSchemas().get("ModelWithEnumPropertyHavingDefault");
CodegenModel cm1 = codegen.fromModel("ModelWithEnumPropertyHavingDefault", test1);

// We need to postProcess the model for enums to be processed
codegen.postProcessModels(createCodegenModelWrapper(cm1));

// Assert the enums are generated without changing capitalization
CodegenProperty cp0 = cm1.vars.get(0);
Assert.assertEquals(cp0.getEnumName(), "PropertyName");
Assert.assertEquals(((HashMap)((ArrayList) cp0.getAllowableValues().get("enumVars")).get(0)).get("name"), "VALUE");
CodegenProperty cp1 = cm1.vars.get(1);
Assert.assertEquals(cp1.getEnumName(), "PropertyName2");
Assert.assertEquals(((HashMap)((ArrayList) cp1.getAllowableValues().get("enumVars")).get(0)).get("name"), "Value");
CodegenProperty cp2 = cm1.vars.get(2);
Assert.assertEquals(cp2.getEnumName(), "PropertyName3");
Assert.assertEquals(((HashMap)((ArrayList) cp2.getAllowableValues().get("enumVars")).get(0)).get("name"), "nonkeywordvalue");
}

@Test(description = "Issue #3804")
public void testEnumPropertyDefaultWithCapitalization() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/kotlin/issue3804-enum-enum-capitalization.yaml");
final AbstractKotlinCodegen codegen = new P_AbstractKotlinCodegen();

Schema test1 = openAPI.getComponents().getSchemas().get("ModelWithEnumPropertyHavingDefault");
CodegenModel cm1 = codegen.fromModel("ModelWithEnumPropertyHavingDefault", test1);

// We need to postProcess the model for enums to be processed
codegen.postProcessModels(createCodegenModelWrapper(cm1));

// Assert the enum default value is properly generated
CodegenProperty cp0 = cm1.vars.get(0);
Assert.assertEquals(cp0.getDefaultValue(), "PropertyName.VALUE");
CodegenProperty cp1 = cm1.vars.get(1);
Assert.assertEquals(cp1.getDefaultValue(), "PropertyName2.Value");
CodegenProperty cp2 = cm1.vars.get(2);
Assert.assertEquals(cp2.getDefaultValue(), "PropertyName3.nonkeywordvalue");
}

@Test(description = "Issue #3804")
public void testEnumPropertyWithKeyword() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/kotlin/issue3804-enum-enum-capitalization.yaml");
final AbstractKotlinCodegen codegen = new P_AbstractKotlinCodegen();

Schema test1 = openAPI.getComponents().getSchemas().get("ModelWithEnumPropertyHavingDefault");
CodegenModel cm1 = codegen.fromModel("ModelWithEnumPropertyHavingDefault", test1);

// We need to postProcess the model for enums to be processed
codegen.postProcessModels(createCodegenModelWrapper(cm1));

// Assert the enum default value is properly generated
CodegenProperty cp3 = cm1.vars.get(3);
Assert.assertEquals(cp3.getEnumName(), "PropertyName4");
Assert.assertEquals(cp3.getDefaultValue(), "PropertyName4.`value`");
}


@Test(description = "Issue #10792")
public void handleInheritanceWithObjectTypeShouldNotBeAMap() {
Schema parent = new ObjectSchema()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1399,9 +1399,21 @@
"items": {
"$ref": "#/components/schemas/TaskWeek"
}
},
"pricingModelType":{
"$ref": "#/components/schemas/PricingModelType"
}
},
"description": "week, holds all work and working assignments."
},
"PricingModelType": {
"type": "string",
"enum": [
"Unsupported",
"Flex",
"Community",
"Freedom"
]
}
},
"securitySchemes": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
openapi: 3.0.0
info:
title: 'Issue 10591 Enum default value'
version: latest
paths:
'/':
get:
operationId: operation
responses:
'200':
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/ModelWithEnumPropertyHavingDefault'
components:
schemas:
ModelWithEnumPropertyHavingDefault:
required:
- propertyName
properties:
propertyName:
type: string
default: VALUE
enum:
- VALUE
propertyName2:
type: string
default: Value
enum:
- Value
propertyName3:
type: string
default: nonkeywordvalue
enum:
- nonkeywordvalue
propertyName4:
type: string
default: value
enum:
- value
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

* `unclassified` (value: `"unclassified"`)

* `unknownDefaultOpenApi` (value: `"unknown_default_open_api"`)
* `unknown_default_open_api` (value: `"unknown_default_open_api"`)



Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ data class DefaultValue (
/**
*
*
* Values: success,failure,unclassified,unknownDefaultOpenApi
* Values: success,failure,unclassified,unknown_default_open_api
*/
enum class ArrayStringEnumDefault(val value: kotlin.String) {
@JsonProperty(value = "success") success("success"),
@JsonProperty(value = "failure") failure("failure"),
@JsonProperty(value = "unclassified") unclassified("unclassified"),
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknownDefaultOpenApi("unknown_default_open_api");
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknown_default_open_api("unknown_default_open_api");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ data class Pet (
/**
* pet status in the store
*
* Values: available,pending,sold,unknownDefaultOpenApi
* Values: available,pending,sold,unknown_default_open_api
*/
enum class Status(val value: kotlin.String) {
@JsonProperty(value = "available") available("available"),
@JsonProperty(value = "pending") pending("pending"),
@JsonProperty(value = "sold") sold("sold"),
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknownDefaultOpenApi("unknown_default_open_api");
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknown_default_open_api("unknown_default_open_api");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ data class Query (
/**
*
*
* Values: sUCCESS,fAILURE,sKIPPED,unknownDefaultOpenApi
* Values: SUCCESS,FAILURE,SKIPPED,unknown_default_open_api
*/
enum class Outcomes(val value: kotlin.String) {
@JsonProperty(value = "SUCCESS") sUCCESS("SUCCESS"),
@JsonProperty(value = "FAILURE") fAILURE("FAILURE"),
@JsonProperty(value = "SKIPPED") sKIPPED("SKIPPED"),
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknownDefaultOpenApi("unknown_default_open_api");
@JsonProperty(value = "SUCCESS") SUCCESS("SUCCESS"),
@JsonProperty(value = "FAILURE") FAILURE("FAILURE"),
@JsonProperty(value = "SKIPPED") SKIPPED("SKIPPED"),
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknown_default_open_api("unknown_default_open_api");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
/**
*
*
* Values: success,failure,unclassified,unknownDefaultOpenApi
* Values: success,failure,unclassified,unknown_default_open_api
*/

enum class StringEnumRef(val value: kotlin.String) {
Expand All @@ -36,7 +36,7 @@ enum class StringEnumRef(val value: kotlin.String) {
unclassified("unclassified"),

@JsonProperty(value = "unknown_default_open_api")
unknownDefaultOpenApi("unknown_default_open_api");
unknown_default_open_api("unknown_default_open_api");

/**
* Override [toString()] to avoid using the enum variable name as the value, and instead use
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

* `unclassified` (value: `"unclassified"`)

* `unknownDefaultOpenApi` (value: `"unknown_default_open_api"`)
* `unknown_default_open_api` (value: `"unknown_default_open_api"`)



Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ data class DefaultValue (
/**
*
*
* Values: success,failure,unclassified,unknownDefaultOpenApi
* Values: success,failure,unclassified,unknown_default_open_api
*/
enum class ArrayStringEnumDefault(val value: kotlin.String) {
@JsonProperty(value = "success") success("success"),
@JsonProperty(value = "failure") failure("failure"),
@JsonProperty(value = "unclassified") unclassified("unclassified"),
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknownDefaultOpenApi("unknown_default_open_api");
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknown_default_open_api("unknown_default_open_api");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ data class Pet (
/**
* pet status in the store
*
* Values: available,pending,sold,unknownDefaultOpenApi
* Values: available,pending,sold,unknown_default_open_api
*/
enum class Status(val value: kotlin.String) {
@JsonProperty(value = "available") available("available"),
@JsonProperty(value = "pending") pending("pending"),
@JsonProperty(value = "sold") sold("sold"),
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknownDefaultOpenApi("unknown_default_open_api");
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknown_default_open_api("unknown_default_open_api");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ data class Query (
/**
*
*
* Values: sUCCESS,fAILURE,sKIPPED,unknownDefaultOpenApi
* Values: SUCCESS,FAILURE,SKIPPED,unknown_default_open_api
*/
enum class Outcomes(val value: kotlin.String) {
@JsonProperty(value = "SUCCESS") sUCCESS("SUCCESS"),
@JsonProperty(value = "FAILURE") fAILURE("FAILURE"),
@JsonProperty(value = "SKIPPED") sKIPPED("SKIPPED"),
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknownDefaultOpenApi("unknown_default_open_api");
@JsonProperty(value = "SUCCESS") SUCCESS("SUCCESS"),
@JsonProperty(value = "FAILURE") FAILURE("FAILURE"),
@JsonProperty(value = "SKIPPED") SKIPPED("SKIPPED"),
@JsonProperty(value = "unknown_default_open_api") @JsonEnumDefaultValue unknown_default_open_api("unknown_default_open_api");
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
/**
*
*
* Values: success,failure,unclassified,unknownDefaultOpenApi
* Values: success,failure,unclassified,unknown_default_open_api
*/

enum class StringEnumRef(val value: kotlin.String) {
Expand All @@ -36,7 +36,7 @@ enum class StringEnumRef(val value: kotlin.String) {
unclassified("unclassified"),

@JsonProperty(value = "unknown_default_open_api")
unknownDefaultOpenApi("unknown_default_open_api");
unknown_default_open_api("unknown_default_open_api");

/**
* Override [toString()] to avoid using the enum variable name as the value, and instead use
Expand Down