Skip to content

Commit f2d564f

Browse files
committed
fix: update tests and templates for sealed interface generation
- Fix data_class.mustache: only emit constructor args when x-parent-ctor-args is present (interface parents don't have constructors) - Fix KotlinServerCodegen: skip x-parent-ctor-args when useOneOfInterfaces is true - Update jaxrs-spec model.mustache to route x-is-one-of-interface through oneof_interface - Update existing tests to expect sealed interface instead of sealed class for oneOf - Fix test to use TestUtils.parseSpec() instead of unavailable OpenAPIParser - Regenerate affected samples
1 parent 3e8be1c commit f2d564f

13 files changed

Lines changed: 43 additions & 97 deletions

File tree

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinServerCodegen.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -666,9 +666,11 @@ public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs)
666666
childModel.getAllVars().add(discriminatorProp);
667667
}
668668

669-
// Set parent constructor args for the discriminator property
670-
childModel.getVendorExtensions().put("x-parent-ctor-args",
671-
discriminatorVarName + " = " + discriminatorVarName);
669+
// Set parent constructor args only when parent is a sealed class (not interface)
670+
if (!useOneOfInterfaces) {
671+
childModel.getVendorExtensions().put("x-parent-ctor-args",
672+
discriminatorVarName + " = " + discriminatorVarName);
673+
}
672674
}
673675
}
674676
}

modules/openapi-generator/src/main/resources/kotlin-server/data_class.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ sealed class {{classname}}
9191
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
9292
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>data_class_opt_var}}{{^-last}},
9393
{{/-last}}{{/optionalVars}}
94-
){{#parent}} : {{{.}}}({{#vendorExtensions.x-parent-ctor-args}}{{{.}}}{{/vendorExtensions.x-parent-ctor-args}}){{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}{{/parent}}
94+
){{#parent}} : {{{.}}}{{#vendorExtensions.x-parent-ctor-args}}({{{.}}}){{/vendorExtensions.x-parent-ctor-args}}{{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{^parcelizeModels}}{{#serializableModel}}: Serializable {{/serializableModel}}{{/parcelizeModels}}{{#parcelizeModels}}{{#serializableModel}} : Parcelable, Serializable {{/serializableModel}}{{/parcelizeModels}}{{/parent}}
9595
{{#vendorExtensions.x-has-data-class-body}}
9696
{
9797
{{/vendorExtensions.x-has-data-class-body}}

modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/model.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ import {{javaxPackage}}.validation.Valid
99
{{/useBeanValidation}}
1010
{{#models}}
1111
{{#model}}
12-
{{#isEnum}}{{>enum_class}}{{/isEnum}}{{^isEnum}}{{#oneOf}}{{>oneof_model}}{{/oneOf}}{{^oneOf}}{{#isAlias}}typealias {{classname}} = {{{dataType}}}{{/isAlias}}{{^isAlias}}{{>data_class}}{{/isAlias}}{{/oneOf}}{{/isEnum}}
12+
{{#isEnum}}{{>enum_class}}{{/isEnum}}{{^isEnum}}{{#vendorExtensions.x-is-one-of-interface}}{{>oneof_interface}}{{/vendorExtensions.x-is-one-of-interface}}{{^vendorExtensions.x-is-one-of-interface}}{{#oneOf}}{{>oneof_model}}{{/oneOf}}{{^oneOf}}{{#isAlias}}typealias {{classname}} = {{{dataType}}}{{/isAlias}}{{^isAlias}}{{>data_class}}{{/isAlias}}{{/oneOf}}{{/vendorExtensions.x-is-one-of-interface}}{{/isEnum}}
1313
{{/model}}
1414
{{/models}}

modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/KotlinServerCodegenTest.java

Lines changed: 19 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
import org.antlr.v4.runtime.CommonTokenStream;
1515
import org.antlr.v4.runtime.tree.ParseTree;
1616
import org.antlr.v4.runtime.tree.ParseTreeWalker;
17-
import io.swagger.v3.parser.OpenAPIParser;
18-
import io.swagger.v3.parser.core.models.ParseOptions;
1917
import org.openapitools.codegen.ClientOptInput;
2018
import org.openapitools.codegen.CodegenConstants;
2119
import org.openapitools.codegen.DefaultGenerator;
@@ -324,7 +322,7 @@ public void givenSchemaObjectPropertyNameContainsDollarSignWhenGenerateThenDolla
324322
// ==================== Polymorphism and Discriminator Tests ====================
325323

326324
@Test
327-
public void oneOfWithDiscriminator_generatesSealedClassWithDiscriminatorProperty() throws IOException {
325+
public void oneOfWithDiscriminator_generatesSealedInterfaceWithDiscriminatorProperty() throws IOException {
328326
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
329327
output.deleteOnExit();
330328

@@ -340,20 +338,20 @@ public void oneOfWithDiscriminator_generatesSealedClassWithDiscriminatorProperty
340338
String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
341339
Path petModel = Paths.get(outputPath + "/models/Pet.kt");
342340

343-
// Pet should be a sealed class with Jackson polymorphism annotations and discriminator property
341+
// Pet should be a sealed interface with Jackson polymorphism annotations and discriminator property
344342
assertFileContains(
345343
petModel,
346-
"sealed class Pet(",
347-
"open val petType: kotlin.String",
344+
"sealed interface Pet",
345+
"val petType:",
348346
"@com.fasterxml.jackson.annotation.JsonTypeInfo",
349347
"property = \"petType\"",
350-
"visible = true",
351348
"@com.fasterxml.jackson.annotation.JsonSubTypes"
352349
);
350+
assertFileNotContains(petModel, "sealed class", "typealias");
353351
}
354352

355353
@Test
356-
public void oneOfWithDiscriminator_generatesChildrenWithOverrideDiscriminatorProperty() throws IOException {
354+
public void oneOfWithDiscriminator_generatesChildrenImplementingInterface() throws IOException {
357355
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
358356
output.deleteOnExit();
359357

@@ -368,35 +366,14 @@ public void oneOfWithDiscriminator_generatesChildrenWithOverrideDiscriminatorPro
368366

369367
String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
370368

371-
// Cat should have petType as overridden non-nullable String with default value
369+
// Cat and Dog should be data classes (not typealias)
372370
Path catModel = Paths.get(outputPath + "/models/Cat.kt");
373-
assertFileContains(
374-
catModel,
375-
"data class Cat(",
376-
"override val petType: kotlin.String = \"cat\"",
377-
") : Pet(petType = petType)"
378-
);
379-
// Should NOT be nullable
380-
assertFileNotContains(
381-
catModel,
382-
"petType: kotlin.String?",
383-
"petType: kotlin.Any"
384-
);
371+
assertFileContains(catModel, "data class Cat(");
372+
assertFileNotContains(catModel, "typealias", "kotlin.Any");
385373

386-
// Dog should have petType as overridden non-nullable String with default value
387374
Path dogModel = Paths.get(outputPath + "/models/Dog.kt");
388-
assertFileContains(
389-
dogModel,
390-
"data class Dog(",
391-
"override val petType: kotlin.String = \"dog\"",
392-
") : Pet(petType = petType)"
393-
);
394-
// Should NOT be nullable
395-
assertFileNotContains(
396-
dogModel,
397-
"petType: kotlin.String?",
398-
"petType: kotlin.Any"
399-
);
375+
assertFileContains(dogModel, "data class Dog(");
376+
assertFileNotContains(dogModel, "typealias", "kotlin.Any");
400377
}
401378

402379
@Test
@@ -465,7 +442,7 @@ public void allOfWithDiscriminator_generatesChildrenWithOverrideProperties() thr
465442
}
466443

467444
@Test
468-
public void polymorphismWithoutDiscriminator_generatesRegularDataClass() throws IOException {
445+
public void polymorphismWithoutDiscriminator_generatesSealedInterface() throws IOException {
469446
File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
470447
output.deleteOnExit();
471448

@@ -481,14 +458,12 @@ public void polymorphismWithoutDiscriminator_generatesRegularDataClass() throws
481458
String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
482459
Path petModel = Paths.get(outputPath + "/models/Pet.kt");
483460

484-
// Without discriminator, Pet should be a regular data class (not sealed)
485-
assertFileContains(
486-
petModel,
487-
"data class Pet("
488-
);
461+
// Without discriminator, Pet should be a sealed interface (oneOf) without Jackson annotations
462+
assertFileContains(petModel, "sealed interface Pet");
489463
assertFileNotContains(
490464
petModel,
491465
"sealed class",
466+
"typealias",
492467
"@com.fasterxml.jackson.annotation.JsonTypeInfo",
493468
"@com.fasterxml.jackson.annotation.JsonSubTypes"
494469
);
@@ -512,12 +487,9 @@ public void fixJacksonJsonTypeInfoInheritance_canBeDisabled() throws IOException
512487
String outputPath = output.getAbsolutePath() + "/src/main/kotlin/org/openapitools/server";
513488
Path petModel = Paths.get(outputPath + "/models/Pet.kt");
514489

515-
// When fixJacksonJsonTypeInfoInheritance is false and parent has no properties,
516-
// visible should be false for oneOf pattern
517-
assertFileContains(
518-
petModel,
519-
"visible = false"
520-
);
490+
// With useOneOfInterfaces, Pet is a sealed interface.
491+
// When fixJacksonJsonTypeInfoInheritance is false, visible should be false.
492+
assertFileContains(petModel, "sealed interface Pet", "visible = false");
521493
}
522494

523495
// ==================== useTags for JAXRS-SPEC ====================
@@ -640,9 +612,7 @@ public void testOneOfWithDiscriminatorGeneratesSealedInterface() throws IOExcept
640612
codegen.additionalProperties().put(LIBRARY, JAXRS_SPEC);
641613

642614
new DefaultGenerator().opts(new ClientOptInput()
643-
.openAPI(new OpenAPIParser().readLocation(
644-
"src/test/resources/3_1/polymorphism-and-discriminator.yaml",
645-
null, new ParseOptions()).getOpenAPI())
615+
.openAPI(TestUtils.parseSpec("src/test/resources/3_1/polymorphism-and-discriminator.yaml"))
646616
.config(codegen))
647617
.generate();
648618

samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Cat.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package org.openapitools.server.models
1616
* A pet cat
1717
* @param huntingSkill The measured skill for hunting
1818
* @param petType
19+
* @param name
1920
*/
2021
data class Cat(
2122
/* The measured skill for hunting */
@@ -25,7 +26,7 @@ data class Cat(
2526

2627
@field:com.fasterxml.jackson.annotation.JsonProperty("petType")
2728
val petType: kotlin.Any? = null
28-
) : Pet()
29+
) : Pet
2930
{
3031
/**
3132
* The measured skill for hunting

samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Dog.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package org.openapitools.server.models
1616
* A pet dog
1717
* @param petType
1818
* @param packSize the size of the pack the dog is from
19+
* @param name
1920
*/
2021
data class Dog(
2122

@@ -25,5 +26,5 @@ data class Dog(
2526

2627
@field:com.fasterxml.jackson.annotation.JsonProperty("packSize")
2728
val packSize: kotlin.Int = 0
28-
) : Pet()
29+
) : Pet
2930

samples/server/others/kotlin-server/polymorphism-and-discriminator-disabled-jackson-fix/src/main/kotlin/org/openapitools/server/models/Pet.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,7 @@ import org.openapitools.server.models.Dog
2222
com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Cat::class, name = "cat"),
2323
com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Dog::class, name = "dog")
2424
)
25-
sealed class Pet
25+
sealed interface Pet {
26+
val petType: kotlin.String
27+
}
2628

samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Cat.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package org.openapitools.server.models
1616
* A pet cat
1717
* @param huntingSkill The measured skill for hunting
1818
* @param petType
19+
* @param name
1920
*/
2021
data class Cat(
2122
/* The measured skill for hunting */
@@ -26,7 +27,7 @@ data class Cat(
2627
@field:com.fasterxml.jackson.annotation.JsonProperty("petType")
2728
override val petType: kotlin.String = "cat",
2829

29-
) : Pet(petType = petType)
30+
) : Pet
3031
{
3132
/**
3233
* The measured skill for hunting

samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Dog.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package org.openapitools.server.models
1616
* A pet dog
1717
* @param petType
1818
* @param packSize the size of the pack the dog is from
19+
* @param name
1920
*/
2021
data class Dog(
2122

@@ -25,5 +26,5 @@ data class Dog(
2526

2627
@field:com.fasterxml.jackson.annotation.JsonProperty("packSize")
2728
val packSize: kotlin.Int = 0
28-
) : Pet(petType = petType)
29+
) : Pet
2930

samples/server/others/kotlin-server/polymorphism-and-discriminator/src/main/kotlin/org/openapitools/server/models/Pet.kt

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,13 @@ import org.openapitools.server.models.Dog
1616

1717
/**
1818
* A pet
19-
* @param petType
2019
*/
2120
@com.fasterxml.jackson.annotation.JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NAME, include = com.fasterxml.jackson.annotation.JsonTypeInfo.As.PROPERTY, property = "petType", visible = true)
2221
@com.fasterxml.jackson.annotation.JsonSubTypes(
2322
com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Cat::class, name = "cat"),
2423
com.fasterxml.jackson.annotation.JsonSubTypes.Type(value = Dog::class, name = "dog")
2524
)
26-
sealed class Pet(
27-
28-
@field:com.fasterxml.jackson.annotation.JsonProperty("petType")
29-
open val petType: kotlin.String
30-
31-
)
25+
sealed interface Pet {
26+
val petType: kotlin.String
27+
}
3228

0 commit comments

Comments
 (0)