From 84f055a7875fd9d2b900391bb6f70792d9eb43ff Mon Sep 17 00:00:00 2001 From: Mattias-Sehlstedt <60173714+Mattias-Sehlstedt@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:25:53 +0200 Subject: [PATCH 1/2] Add test to illustrate example of how to handle x-parent without REF_AS_PARENT_IN_ALLOF normalization --- .../codegen/OpenAPINormalizerTest.java | 2 +- .../codegen/java/JavaClientCodegenTest.java | 72 ++++++++++++++++--- .../resources/3_0/allOf_extension_parent.yaml | 19 ++++- 3 files changed, 82 insertions(+), 11 deletions(-) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index f401296ef7a8..01ad5609aa7f 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -66,7 +66,7 @@ public void testOpenAPINormalizerRefAsParentInAllOf() { assertEquals(schema5.getExtensions().get(X_PARENT), "abstract"); // Verify that all allOf refs gets marked as parents - SchemaschemaWithTwoParents = openAPI.getComponents().getSchemas().get("SchemaWithTwoParents"); + SchemaschemaWithTwoParents = openAPI.getComponents().getSchemas().get("SchemaWithTwoAllOfRefs"); assertNull(schemaWithTwoParents.getExtensions()); SchemapersonA = openAPI.getComponents().getSchemas().get("PersonA"); assertEquals(personA.getExtensions().get(X_PARENT), true); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java index 45e9f4492e63..ac6c08a65201 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java @@ -22,7 +22,7 @@ import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.expr.Expression; import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.visitor.*; +import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import com.google.common.collect.ImmutableMap; import io.swagger.parser.OpenAPIParser; import io.swagger.v3.oas.models.OpenAPI; @@ -40,7 +40,6 @@ import org.openapitools.codegen.java.assertions.JavaFileAssert; import org.openapitools.codegen.languages.AbstractJavaCodegen; import org.openapitools.codegen.languages.JavaClientCodegen; -import org.openapitools.codegen.languages.RubyClientCodegen; import org.openapitools.codegen.languages.features.BeanValidationFeatures; import org.openapitools.codegen.languages.features.CXFServerFeatures; import org.openapitools.codegen.meta.features.SecurityFeature; @@ -49,7 +48,6 @@ import org.openapitools.codegen.testutils.ConfigAssert; import org.testng.Assert; import org.testng.annotations.DataProvider; -import org.testng.annotations.Parameters; import org.testng.annotations.Test; import java.io.File; @@ -1791,13 +1789,71 @@ public void testJdkHttpClientWithAndWithoutParentExtension() { List files = generator.opts(configurator.toClientOptInput()).generate(); validateJavaSourceFiles(files); - assertThat(files).hasSize(42); + assertThat(files).hasSize(48); assertThat(output.resolve("src/main/java/xyz/abcdef/model/Child.java")) .content().contains("public class Child extends Person {"); assertThat(output.resolve("src/main/java/xyz/abcdef/model/Adult.java")) .content().contains("public class Adult extends Person {"); - assertThat(output.resolve("src/main/java/xyz/abcdef/model/SchemaWithTwoParents.java")) - .content().contains("public class SchemaWithTwoParents {"); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/SchemaWithTwoAllOfRefs.java")) + .content().contains("public class SchemaWithTwoAllOfRefs {"); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/AnotherChild.java")) + .content().contains("public class AnotherChild {"); + } + + @Test + public void allOfWithSeveralRefsAndRefAsParentInAllOfNormalizationIsTrue() { + final Path output = newTempFolder(); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName(JAVA_GENERATOR) + .addAdditionalProperty(CodegenConstants.API_PACKAGE, "xyz.abcdef.api") + .addAdditionalProperty(CodegenConstants.MODEL_PACKAGE, "xyz.abcdef.model") + .addAdditionalProperty(CodegenConstants.INVOKER_PACKAGE, "xyz.abcdef.invoker") + .addOpenapiNormalizer("REF_AS_PARENT_IN_ALLOF", "true") + .setInputSpec("src/test/resources/3_0/allOf_extension_parent.yaml") + .setOutputDir(output.toString().replace("\\", "/")); + + DefaultGenerator generator = new DefaultGenerator(); + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true"); + List files = generator.opts(configurator.toClientOptInput()).generate(); + + validateJavaSourceFiles(files); + assertThat(files).hasSize(48); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/Child.java")) + .content().contains("public class Child extends Person {"); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/Adult.java")) + .content().contains("public class Adult extends Person {"); + // The class does not extend a parent since the REF_AS_PARENT_IN_ALLOF normalizer will assign it two parents + assertThat(output.resolve("src/main/java/xyz/abcdef/model/SchemaWithTwoAllOfRefsOneIsMarkedAsParent.java")) + .content().contains("public class SchemaWithTwoAllOfRefsOneIsMarkedAsParent {"); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/AnotherChild.java")) + .content().contains("public class AnotherChild extends AnotherPerson {"); + } + + @Test + public void allOfWithSeveralRefsButOnlyOneIsMarkedAsParent() { + final Path output = newTempFolder(); + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName(JAVA_GENERATOR) + .addAdditionalProperty(CodegenConstants.API_PACKAGE, "xyz.abcdef.api") + .addAdditionalProperty(CodegenConstants.MODEL_PACKAGE, "xyz.abcdef.model") + .addAdditionalProperty(CodegenConstants.INVOKER_PACKAGE, "xyz.abcdef.invoker") + .setInputSpec("src/test/resources/3_0/allOf_extension_parent.yaml") + .setOutputDir(output.toString().replace("\\", "/")); + + DefaultGenerator generator = new DefaultGenerator(); + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true"); + List files = generator.opts(configurator.toClientOptInput()).generate(); + + validateJavaSourceFiles(files); + assertThat(files).hasSize(48); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/Child.java")) + .content().contains("public class Child extends Person {"); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/Adult.java")) + .content().contains("public class Adult extends Person {"); + assertThat(output.resolve("src/main/java/xyz/abcdef/model/SchemaWithTwoAllOfRefsOneIsMarkedAsParent.java")) + .content().contains("public class SchemaWithTwoAllOfRefsOneIsMarkedAsParent extends PersonAExplicitParent {"); assertThat(output.resolve("src/main/java/xyz/abcdef/model/AnotherChild.java")) .content().contains("public class AnotherChild {"); } @@ -3986,7 +4042,7 @@ public void oneOfWithInnerModelTest() { } @Test - public void testOneOfClassWithAnnotation() throws IOException { + public void testOneOfClassWithAnnotation() { final Map files = generateFromContract("src/test/resources/3_0/java/oneOf-with-annotations.yaml", RESTCLIENT); JavaFileAssert.assertThat(files.get("Fruit.java")) .isNormalClass() @@ -3994,7 +4050,7 @@ public void testOneOfClassWithAnnotation() throws IOException { } @Test - public void testOneOfInterfaceWithAnnotation() throws IOException { + public void testOneOfInterfaceWithAnnotation() { final Map files = generateFromContract("src/test/resources/3_0/java/oneOf-with-annotations.yaml", RESTCLIENT, Map.of(USE_ONE_OF_INTERFACES, "true")); JavaFileAssert.assertThat(files.get("Fruit.java")) diff --git a/modules/openapi-generator/src/test/resources/3_0/allOf_extension_parent.yaml b/modules/openapi-generator/src/test/resources/3_0/allOf_extension_parent.yaml index 5f8336b6c1d1..63b83e72574c 100644 --- a/modules/openapi-generator/src/test/resources/3_0/allOf_extension_parent.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/allOf_extension_parent.yaml @@ -42,8 +42,13 @@ components: properties: lastName: type: string + PersonAExplicitParent: + type: object + x-parent: "abstract" + properties: + lastName: + type: string PersonB: - description: type: object properties: firstName: @@ -76,7 +81,7 @@ components: type: integer format: int32 - $ref: '#/components/schemas/AnotherPerson' - SchemaWithTwoParents: + SchemaWithTwoAllOfRefs: description: A schema that has two allOfs with refs allOf: - type: object @@ -86,6 +91,16 @@ components: format: int32 - $ref: '#/components/schemas/PersonA' - $ref: '#/components/schemas/PersonB' + SchemaWithTwoAllOfRefsOneIsMarkedAsParent: + description: A schema that has two allOfs with refs, but one of the allOfs is explicitly marked with x-parent + allOf: + - type: object + properties: + age: + type: integer + format: int32 + - $ref: '#/components/schemas/PersonAExplicitParent' + - $ref: '#/components/schemas/PersonB' AnotherPerson: description: person object without x-parent extension type: object From 1b4da774e58de20aa19354a43f27ca2e53027ed1 Mon Sep 17 00:00:00 2001 From: Mattias-Sehlstedt <60173714+Mattias-Sehlstedt@users.noreply.github.com> Date: Wed, 1 Oct 2025 21:05:25 +0200 Subject: [PATCH 2/2] Minor change to retrigger build --- .../org/openapitools/codegen/OpenAPINormalizerTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java index 01ad5609aa7f..ae32471a9a87 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/OpenAPINormalizerTest.java @@ -79,10 +79,10 @@ public void testOpenAPINormalizerRefAsParentInAllOfAndRefactorAllOfWithPropertie // to test the both REF_AS_PARENT_IN_ALLOF and REFACTOR_ALLOF_WITH_PROPERTIES_ONLY OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/allOf_extension_parent.yaml"); - Schema schema = openAPI.getComponents().getSchemas().get("Child"); + Schema schema = openAPI.getComponents().getSchemas().get("Child"); assertNull(schema.getExtensions()); - Schema schema2 = openAPI.getComponents().getSchemas().get("Ancestor"); + Schema schema2 = openAPI.getComponents().getSchemas().get("Ancestor"); assertNull(schema2.getExtensions()); Map options = new HashMap<>(); @@ -91,10 +91,10 @@ public void testOpenAPINormalizerRefAsParentInAllOfAndRefactorAllOfWithPropertie OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options); openAPINormalizer.normalize(); - Schema schema3 = openAPI.getComponents().getSchemas().get("Ancestor"); + Schema schema3 = openAPI.getComponents().getSchemas().get("Ancestor"); assertEquals(schema3.getExtensions().get(X_PARENT), true); - Schema schema4 = openAPI.getComponents().getSchemas().get("Child"); + Schema schema4 = openAPI.getComponents().getSchemas().get("Child"); assertNull(schema4.getExtensions()); }