forked from loafle/openapi-generator-original
		
	[csharp][java] Fix enum discriminator default value (#19614)
* Fix enum discriminator default value * Remove system out call * Add case when discriminator type is ref * Use correct schema * Handle different use cases of mappings * Add missing enum type Lizzy * Make it more robust * Add missing test for Sedan * Refactor some code to make it cleaner * Initialize discriminator enum field * Don't override existing default value * Fix issue with finding discriminators * Move setIsEnum back to its original location * Be smarter about figuring out the model name * Fix final warnings * Add javadocs to introduced methods
This commit is contained in:
		
							parent
							
								
									1fa07bf46c
								
							
						
					
					
						commit
						c75fbb312e
					
				| @ -3098,6 +3098,7 @@ public class DefaultCodegen implements CodegenConfig { | |||||||
|             listOLists.add(m.requiredVars); |             listOLists.add(m.requiredVars); | ||||||
|             listOLists.add(m.vars); |             listOLists.add(m.vars); | ||||||
|             listOLists.add(m.allVars); |             listOLists.add(m.allVars); | ||||||
|  |             listOLists.add(m.readWriteVars); | ||||||
|             for (List<CodegenProperty> theseVars : listOLists) { |             for (List<CodegenProperty> theseVars : listOLists) { | ||||||
|                 for (CodegenProperty requiredVar : theseVars) { |                 for (CodegenProperty requiredVar : theseVars) { | ||||||
|                     if (discPropName.equals(requiredVar.baseName)) { |                     if (discPropName.equals(requiredVar.baseName)) { | ||||||
| @ -3131,6 +3132,63 @@ public class DefaultCodegen implements CodegenConfig { | |||||||
|         return m; |         return m; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Sets the default value for an enum discriminator property in the provided {@link CodegenModel}. | ||||||
|  |      * <p> | ||||||
|  |      * If the model's discriminator is defined, this method identifies the discriminator properties among the model's | ||||||
|  |      * variables and assigns the default value to reflect the corresponding enum value for the model type. | ||||||
|  |      * </p> | ||||||
|  |      * <p> | ||||||
|  |      * Example: If the discriminator is for type `Animal`, and the model is `Cat`, the default value | ||||||
|  |      * will be set to `Animal.Cat` for the properties that have the same name as the discriminator. | ||||||
|  |      * </p> | ||||||
|  |      * | ||||||
|  |      * @param model the {@link CodegenModel} whose discriminator property default value is to be set | ||||||
|  |      */ | ||||||
|  |     protected static void setEnumDiscriminatorDefaultValue(CodegenModel model) { | ||||||
|  |         if (model.discriminator == null) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         String discPropName = model.discriminator.getPropertyBaseName(); | ||||||
|  |         Stream.of(model.requiredVars, model.vars, model.allVars, model.readWriteVars) | ||||||
|  |                 .flatMap(List::stream) | ||||||
|  |                 .filter(v -> discPropName.equals(v.baseName)) | ||||||
|  |                 .forEach(v -> v.defaultValue = getEnumValueForProperty(model.schemaName, model.discriminator, v)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Retrieves the appropriate default value for an enum discriminator property based on the model name. | ||||||
|  |      * <p> | ||||||
|  |      * If the discriminator has a mapping defined, it attempts to find a mapping for the model name. | ||||||
|  |      * Otherwise, it defaults to one of the allowable enum value associated with the property. | ||||||
|  |      * If no suitable value is found, the original default value of the property is returned. | ||||||
|  |      * </p> | ||||||
|  |      * | ||||||
|  |      * @param modelName     the name of the model to determine the default value for | ||||||
|  |      * @param discriminator the {@link CodegenDiscriminator} containing the mapping and enum details | ||||||
|  |      * @param var           the {@link CodegenProperty} representing the discriminator property | ||||||
|  |      * @return the default value for the enum discriminator property, or its original default value if none is found | ||||||
|  |      */ | ||||||
|  |     protected static String getEnumValueForProperty( | ||||||
|  |             String modelName, CodegenDiscriminator discriminator, CodegenProperty var) { | ||||||
|  |         if (!discriminator.getIsEnum() && !var.isEnum) { | ||||||
|  |             return var.defaultValue; | ||||||
|  |         } | ||||||
|  |         Map<String, String> mapping = Optional.ofNullable(discriminator.getMapping()).orElseGet(Collections::emptyMap); | ||||||
|  |         for (Map.Entry<String, String> e : mapping.entrySet()) { | ||||||
|  |             String schemaName = e.getValue().indexOf('/') < 0 ? e.getValue() : ModelUtils.getSimpleRef(e.getValue()); | ||||||
|  |             if (modelName.equals(schemaName)) { | ||||||
|  |                 return e.getKey(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         Object values = var.allowableValues.get("values"); | ||||||
|  |         if (!(values instanceof List<?>)) { | ||||||
|  |             return var.defaultValue; | ||||||
|  |         } | ||||||
|  |         List<?> valueList = (List<?>) values; | ||||||
|  |         return valueList.stream().filter(o -> o.equals(modelName)).map(o -> (String) o).findAny().orElse(var.defaultValue); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     protected void SortModelPropertiesByRequiredFlag(CodegenModel model) { |     protected void SortModelPropertiesByRequiredFlag(CodegenModel model) { | ||||||
|         Comparator<CodegenProperty> comparator = new Comparator<CodegenProperty>() { |         Comparator<CodegenProperty> comparator = new Comparator<CodegenProperty>() { | ||||||
|             @Override |             @Override | ||||||
| @ -3201,15 +3259,19 @@ public class DefaultCodegen implements CodegenConfig { | |||||||
|      * @param visitedSchemas     A set of visited schema names |      * @param visitedSchemas     A set of visited schema names | ||||||
|      */ |      */ | ||||||
|     private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc, String discPropName, Set<String> visitedSchemas) { |     private CodegenProperty discriminatorFound(String composedSchemaName, Schema sc, String discPropName, Set<String> visitedSchemas) { | ||||||
|         if (visitedSchemas.contains(composedSchemaName)) { // recursive schema definition found |         Schema refSchema = ModelUtils.getReferencedSchema(openAPI, sc); | ||||||
|  |         String schemaName = Optional.ofNullable(composedSchemaName) | ||||||
|  |                 .or(() -> Optional.ofNullable(refSchema.getName())) | ||||||
|  |                 .or(() -> Optional.ofNullable(sc.get$ref()).map(ModelUtils::getSimpleRef)) | ||||||
|  |                 .orElseGet(sc::toString); | ||||||
|  |         if (visitedSchemas.contains(schemaName)) { // recursive schema definition found | ||||||
|             return null; |             return null; | ||||||
|         } else { |         } else { | ||||||
|             visitedSchemas.add(composedSchemaName); |             visitedSchemas.add(schemaName); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Schema refSchema = ModelUtils.getReferencedSchema(openAPI, sc); |  | ||||||
|         if (refSchema.getProperties() != null && refSchema.getProperties().get(discPropName) != null) { |         if (refSchema.getProperties() != null && refSchema.getProperties().get(discPropName) != null) { | ||||||
|             Schema discSchema = (Schema) refSchema.getProperties().get(discPropName); |             Schema discSchema = ModelUtils.getReferencedSchema(openAPI, (Schema)refSchema.getProperties().get(discPropName)); | ||||||
|             CodegenProperty cp = new CodegenProperty(); |             CodegenProperty cp = new CodegenProperty(); | ||||||
|             if (ModelUtils.isStringSchema(discSchema)) { |             if (ModelUtils.isStringSchema(discSchema)) { | ||||||
|                 cp.isString = true; |                 cp.isString = true; | ||||||
| @ -3218,6 +3280,7 @@ public class DefaultCodegen implements CodegenConfig { | |||||||
|             if (refSchema.getRequired() != null && refSchema.getRequired().contains(discPropName)) { |             if (refSchema.getRequired() != null && refSchema.getRequired().contains(discPropName)) { | ||||||
|                 cp.setRequired(true); |                 cp.setRequired(true); | ||||||
|             } |             } | ||||||
|  |             cp.setIsEnum(discSchema.getEnum() != null && !discSchema.getEnum().isEmpty()); | ||||||
|             return cp; |             return cp; | ||||||
|         } |         } | ||||||
|         if (ModelUtils.isComposedSchema(refSchema)) { |         if (ModelUtils.isComposedSchema(refSchema)) { | ||||||
| @ -3225,7 +3288,8 @@ public class DefaultCodegen implements CodegenConfig { | |||||||
|             if (composedSchema.getAllOf() != null) { |             if (composedSchema.getAllOf() != null) { | ||||||
|                 // If our discriminator is in one of the allOf schemas break when we find it |                 // If our discriminator is in one of the allOf schemas break when we find it | ||||||
|                 for (Object allOf : composedSchema.getAllOf()) { |                 for (Object allOf : composedSchema.getAllOf()) { | ||||||
|                     CodegenProperty cp = discriminatorFound(composedSchemaName, (Schema) allOf, discPropName, visitedSchemas); |                     Schema allOfSchema = (Schema) allOf; | ||||||
|  |                     CodegenProperty cp = discriminatorFound(allOfSchema.getName(), allOfSchema, discPropName, visitedSchemas); | ||||||
|                     if (cp != null) { |                     if (cp != null) { | ||||||
|                         return cp; |                         return cp; | ||||||
|                     } |                     } | ||||||
| @ -3235,8 +3299,11 @@ public class DefaultCodegen implements CodegenConfig { | |||||||
|                 // All oneOf definitions must contain the discriminator |                 // All oneOf definitions must contain the discriminator | ||||||
|                 CodegenProperty cp = new CodegenProperty(); |                 CodegenProperty cp = new CodegenProperty(); | ||||||
|                 for (Object oneOf : composedSchema.getOneOf()) { |                 for (Object oneOf : composedSchema.getOneOf()) { | ||||||
|                     String modelName = ModelUtils.getSimpleRef(((Schema) oneOf).get$ref()); |                     Schema oneOfSchema = (Schema) oneOf; | ||||||
|                     CodegenProperty thisCp = discriminatorFound(composedSchemaName, (Schema) oneOf, discPropName, visitedSchemas); |                     String modelName = ModelUtils.getSimpleRef((oneOfSchema).get$ref()); | ||||||
|  |                     // Must use a copied set as the oneOf schemas can point to the same discriminator. | ||||||
|  |                     Set<String> visitedSchemasCopy = new TreeSet<>(visitedSchemas); | ||||||
|  |                     CodegenProperty thisCp = discriminatorFound(oneOfSchema.getName(), oneOfSchema, discPropName, visitedSchemasCopy); | ||||||
|                     if (thisCp == null) { |                     if (thisCp == null) { | ||||||
|                         once(LOGGER).warn( |                         once(LOGGER).warn( | ||||||
|                                 "'{}' defines discriminator '{}', but the referenced OneOf schema '{}' is missing {}", |                                 "'{}' defines discriminator '{}', but the referenced OneOf schema '{}' is missing {}", | ||||||
| @ -3258,8 +3325,11 @@ public class DefaultCodegen implements CodegenConfig { | |||||||
|                 // All anyOf definitions must contain the discriminator because a min of one must be selected |                 // All anyOf definitions must contain the discriminator because a min of one must be selected | ||||||
|                 CodegenProperty cp = new CodegenProperty(); |                 CodegenProperty cp = new CodegenProperty(); | ||||||
|                 for (Object anyOf : composedSchema.getAnyOf()) { |                 for (Object anyOf : composedSchema.getAnyOf()) { | ||||||
|                     String modelName = ModelUtils.getSimpleRef(((Schema) anyOf).get$ref()); |                     Schema anyOfSchema = (Schema) anyOf; | ||||||
|                     CodegenProperty thisCp = discriminatorFound(composedSchemaName, (Schema) anyOf, discPropName, visitedSchemas); |                     String modelName = ModelUtils.getSimpleRef(anyOfSchema.get$ref()); | ||||||
|  |                     // Must use a copied set as the anyOf schemas can point to the same discriminator. | ||||||
|  |                     Set<String> visitedSchemasCopy = new TreeSet<>(visitedSchemas); | ||||||
|  |                     CodegenProperty thisCp = discriminatorFound(anyOfSchema.getName(), anyOfSchema, discPropName, visitedSchemasCopy); | ||||||
|                     if (thisCp == null) { |                     if (thisCp == null) { | ||||||
|                         once(LOGGER).warn( |                         once(LOGGER).warn( | ||||||
|                                 "'{}' defines discriminator '{}', but the referenced AnyOf schema '{}' is missing {}", |                                 "'{}' defines discriminator '{}', but the referenced AnyOf schema '{}' is missing {}", | ||||||
| @ -3542,13 +3612,11 @@ public class DefaultCodegen implements CodegenConfig { | |||||||
|         discriminator.setPropertyType(propertyType); |         discriminator.setPropertyType(propertyType); | ||||||
| 
 | 
 | ||||||
|         // check to see if the discriminator property is an enum string |         // check to see if the discriminator property is an enum string | ||||||
|         if (schema.getProperties() != null && |         boolean isEnum = Optional | ||||||
|                 schema.getProperties().get(discriminatorPropertyName) instanceof StringSchema) { |                 .ofNullable(discriminatorFound(schemaName, schema, discriminatorPropertyName, new TreeSet<>())) | ||||||
|             StringSchema s = (StringSchema) schema.getProperties().get(discriminatorPropertyName); |                 .map(CodegenProperty::getIsEnum) | ||||||
|             if (s.getEnum() != null && !s.getEnum().isEmpty()) { // it's an enum string |                 .orElse(false); | ||||||
|                 discriminator.setIsEnum(true); |         discriminator.setIsEnum(isEnum); | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         discriminator.setMapping(sourceDiscriminator.getMapping()); |         discriminator.setMapping(sourceDiscriminator.getMapping()); | ||||||
|         List<MappedModel> uniqueDescendants = new ArrayList<>(); |         List<MappedModel> uniqueDescendants = new ArrayList<>(); | ||||||
|  | |||||||
| @ -1713,6 +1713,7 @@ public abstract class AbstractJavaCodegen extends DefaultCodegen implements Code | |||||||
| 
 | 
 | ||||||
|         // additional import for different cases |         // additional import for different cases | ||||||
|         addAdditionalImports(codegenModel, codegenModel.getComposedSchemas()); |         addAdditionalImports(codegenModel, codegenModel.getComposedSchemas()); | ||||||
|  |         setEnumDiscriminatorDefaultValue(codegenModel); | ||||||
|         return codegenModel; |         return codegenModel; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -432,6 +432,7 @@ public class CSharpClientCodegen extends AbstractCSharpCodegen { | |||||||
|     public CodegenModel fromModel(String name, Schema model) { |     public CodegenModel fromModel(String name, Schema model) { | ||||||
|         Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI); |         Map<String, Schema> allDefinitions = ModelUtils.getSchemas(this.openAPI); | ||||||
|         CodegenModel codegenModel = super.fromModel(name, model); |         CodegenModel codegenModel = super.fromModel(name, model); | ||||||
|  |         setEnumDiscriminatorDefaultValue(codegenModel); | ||||||
|         if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) { |         if (allDefinitions != null && codegenModel != null && codegenModel.parent != null) { | ||||||
|             final Schema<?> parentModel = allDefinitions.get(toModelName(codegenModel.parent)); |             final Schema<?> parentModel = allDefinitions.get(toModelName(codegenModel.parent)); | ||||||
|             if (parentModel != null) { |             if (parentModel != null) { | ||||||
|  | |||||||
| @ -1611,6 +1611,12 @@ public class ModelUtils { | |||||||
|      * @return the name of the parent model |      * @return the name of the parent model | ||||||
|      */ |      */ | ||||||
|     public static List<String> getAllParentsName(Schema composedSchema, Map<String, Schema> allSchemas, boolean includeAncestors) { |     public static List<String> getAllParentsName(Schema composedSchema, Map<String, Schema> allSchemas, boolean includeAncestors) { | ||||||
|  |         return getAllParentsName(composedSchema, allSchemas, includeAncestors, new HashSet<>()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Use a set of seen names to avoid infinite recursion | ||||||
|  |     private static List<String> getAllParentsName( | ||||||
|  |             Schema composedSchema, Map<String, Schema> allSchemas, boolean includeAncestors, Set<String> seenNames) { | ||||||
|         List<Schema> interfaces = getInterfaces(composedSchema); |         List<Schema> interfaces = getInterfaces(composedSchema); | ||||||
|         List<String> names = new ArrayList<String>(); |         List<String> names = new ArrayList<String>(); | ||||||
| 
 | 
 | ||||||
| @ -1619,6 +1625,10 @@ public class ModelUtils { | |||||||
|                 // get the actual schema |                 // get the actual schema | ||||||
|                 if (StringUtils.isNotEmpty(schema.get$ref())) { |                 if (StringUtils.isNotEmpty(schema.get$ref())) { | ||||||
|                     String parentName = getSimpleRef(schema.get$ref()); |                     String parentName = getSimpleRef(schema.get$ref()); | ||||||
|  |                     if (seenNames.contains(parentName)) { | ||||||
|  |                         continue; | ||||||
|  |                     } | ||||||
|  |                     seenNames.add(parentName); | ||||||
|                     Schema s = allSchemas.get(parentName); |                     Schema s = allSchemas.get(parentName); | ||||||
|                     if (s == null) { |                     if (s == null) { | ||||||
|                         LOGGER.error("Failed to obtain schema from {}", parentName); |                         LOGGER.error("Failed to obtain schema from {}", parentName); | ||||||
| @ -1627,7 +1637,7 @@ public class ModelUtils { | |||||||
|                         // discriminator.propertyName is used or x-parent is used |                         // discriminator.propertyName is used or x-parent is used | ||||||
|                         names.add(parentName); |                         names.add(parentName); | ||||||
|                         if (includeAncestors && isComposedSchema(s)) { |                         if (includeAncestors && isComposedSchema(s)) { | ||||||
|                             names.addAll(getAllParentsName(s, allSchemas, true)); |                             names.addAll(getAllParentsName(s, allSchemas, true, seenNames)); | ||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         // not a parent since discriminator.propertyName is not set |                         // not a parent since discriminator.propertyName is not set | ||||||
|  | |||||||
| @ -81,6 +81,11 @@ public class {{classname}} {{#parent}}extends {{{.}}} {{/parent}}{{#vendorExtens | |||||||
|     {{/parcelableModel}} |     {{/parcelableModel}} | ||||||
|     {{/parent}} |     {{/parent}} | ||||||
|     {{#discriminator}} |     {{#discriminator}} | ||||||
|  |     {{#discriminator.isEnum}} | ||||||
|  | {{#readWriteVars}}{{#isDiscriminator}}{{#defaultValue}} | ||||||
|  |     this.{{name}} = {{defaultValue}}; | ||||||
|  | {{/defaultValue}}{{/isDiscriminator}}{{/readWriteVars}} | ||||||
|  |     {{/discriminator.isEnum}} | ||||||
|     {{^discriminator.isEnum}} |     {{^discriminator.isEnum}} | ||||||
|     this.{{{discriminatorName}}} = this.getClass().getSimpleName(); |     this.{{{discriminatorName}}} = this.getClass().getSimpleName(); | ||||||
|     {{/discriminator.isEnum}} |     {{/discriminator.isEnum}} | ||||||
|  | |||||||
| @ -140,4 +140,46 @@ public class CSharpClientCodegenTest { | |||||||
|         assertFileContains(modelFile.toPath(), |         assertFileContains(modelFile.toPath(), | ||||||
|                 " Dictionary<string, ResponseResultsValue> results = default(Dictionary<string, ResponseResultsValue>"); |                 " Dictionary<string, ResponseResultsValue> results = default(Dictionary<string, ResponseResultsValue>"); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testEnumDiscriminatorDefaultValueIsNotString() throws IOException { | ||||||
|  |         File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); | ||||||
|  |         output.deleteOnExit(); | ||||||
|  |         final OpenAPI openAPI = TestUtils.parseFlattenSpec( | ||||||
|  |                 "src/test/resources/3_0/enum_discriminator_inheritance.yaml"); | ||||||
|  |         final DefaultGenerator defaultGenerator = new DefaultGenerator(); | ||||||
|  |         final ClientOptInput clientOptInput = new ClientOptInput(); | ||||||
|  |         clientOptInput.openAPI(openAPI); | ||||||
|  |         CSharpClientCodegen cSharpClientCodegen = new CSharpClientCodegen(); | ||||||
|  |         cSharpClientCodegen.setOutputDir(output.getAbsolutePath()); | ||||||
|  |         cSharpClientCodegen.setAutosetConstants(true); | ||||||
|  |         clientOptInput.config(cSharpClientCodegen); | ||||||
|  |         defaultGenerator.opts(clientOptInput); | ||||||
|  | 
 | ||||||
|  |         Map<String, File> files = defaultGenerator.generate().stream() | ||||||
|  |                 .collect(Collectors.toMap(File::getPath, Function.identity())); | ||||||
|  | 
 | ||||||
|  |         Map<String, String> expectedContents = Map.of( | ||||||
|  |                 "Cat", "PetTypeEnum petType = PetTypeEnum.Catty", | ||||||
|  |                 "Dog", "PetTypeEnum petType = PetTypeEnum.Dog", | ||||||
|  |                 "Gecko", "PetTypeEnum petType = PetTypeEnum.Gecko", | ||||||
|  |                 "Chameleon", "PetTypeEnum petType = PetTypeEnum.Camo", | ||||||
|  |                 "MiniVan", "CarType carType = CarType.MiniVan", | ||||||
|  |                 "CargoVan", "CarType carType = CarType.CargoVan", | ||||||
|  |                 "SUV", "CarType carType = CarType.SUV", | ||||||
|  |                 "Truck", "CarType carType = CarType.Truck", | ||||||
|  |                 "Sedan", "CarType carType = CarType.Sedan" | ||||||
|  | 
 | ||||||
|  |         ); | ||||||
|  |         for (Map.Entry<String, String> e : expectedContents.entrySet()) { | ||||||
|  |             String modelName = e.getKey(); | ||||||
|  |             String expectedContent = e.getValue(); | ||||||
|  |             File file = files.get(Paths | ||||||
|  |                     .get(output.getAbsolutePath(), "src", "Org.OpenAPITools", "Model", modelName + ".cs") | ||||||
|  |                     .toString() | ||||||
|  |             ); | ||||||
|  |             assertNotNull(file, "Could not find file for model: " + modelName); | ||||||
|  |             assertFileContains(file.toPath(), expectedContent); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -2408,6 +2408,39 @@ public class JavaClientCodegenTest { | |||||||
|         assertNull(files.get("pom.xml")); |         assertNull(files.get("pom.xml")); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @Test | ||||||
|  |     public void testEnumDiscriminatorDefaultValueIsNotString() { | ||||||
|  |         final Path output = newTempFolder(); | ||||||
|  |         final OpenAPI openAPI = TestUtils.parseFlattenSpec( | ||||||
|  |                 "src/test/resources/3_0/enum_discriminator_inheritance.yaml"); | ||||||
|  |         JavaClientCodegen codegen = new JavaClientCodegen(); | ||||||
|  |         codegen.setOutputDir(output.toString()); | ||||||
|  | 
 | ||||||
|  |         Map<String, File> files = new DefaultGenerator().opts(new ClientOptInput().openAPI(openAPI).config(codegen)) | ||||||
|  |                 .generate().stream().collect(Collectors.toMap(File::getName, Function.identity())); | ||||||
|  | 
 | ||||||
|  |         Map<String, String> expectedContents = Map.of( | ||||||
|  |                 "Cat", "this.petType = PetTypeEnum.CATTY", | ||||||
|  |                 "Dog", "this.petType = PetTypeEnum.DOG", | ||||||
|  |                 "Gecko", "this.petType = PetTypeEnum.GECKO", | ||||||
|  |                 "Chameleon", "this.petType = PetTypeEnum.CAMO", | ||||||
|  |                 "MiniVan", "this.carType = CarType.MINI_VAN", | ||||||
|  |                 "CargoVan", "this.carType = CarType.CARGO_VAN", | ||||||
|  |                 "SUV", "this.carType = CarType.SUV", | ||||||
|  |                 "Truck", "this.carType = CarType.TRUCK", | ||||||
|  |                 "Sedan", "this.carType = CarType.SEDAN" | ||||||
|  | 
 | ||||||
|  |         ); | ||||||
|  |         for (Map.Entry<String, String> e : expectedContents.entrySet()) { | ||||||
|  |             String modelName = e.getKey(); | ||||||
|  |             String expectedContent = e.getValue(); | ||||||
|  |             File entityFile = files.get(modelName + ".java"); | ||||||
|  |             assertNotNull(entityFile); | ||||||
|  |             assertThat(entityFile).content().doesNotContain("Type = this.getClass().getSimpleName();"); | ||||||
|  |             assertThat(entityFile).content().contains(expectedContent); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void testRestTemplateHandleURIEnum() { |     public void testRestTemplateHandleURIEnum() { | ||||||
|         String[] expectedInnerEnumLines = new String[]{ |         String[] expectedInnerEnumLines = new String[]{ | ||||||
|  | |||||||
| @ -0,0 +1,132 @@ | |||||||
|  | openapi: 3.0.3 | ||||||
|  | info: | ||||||
|  |   title: Test schema with enum discriminator | ||||||
|  |   version: v1 | ||||||
|  | paths: | ||||||
|  |   "/animal": | ||||||
|  |     get: | ||||||
|  |       operationId: animalGet | ||||||
|  |       responses: | ||||||
|  |         '200': | ||||||
|  |           description: OK | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 "$ref": "#/components/schemas/Animal" | ||||||
|  | components: | ||||||
|  |   schemas: | ||||||
|  |     Animal: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         # Inline enum type | ||||||
|  |         petType: | ||||||
|  |           type: string | ||||||
|  |           enum: | ||||||
|  |             - Dog | ||||||
|  |             - Catty | ||||||
|  |             - Gecko | ||||||
|  |             - Camo | ||||||
|  |       discriminator: | ||||||
|  |         propertyName: petType | ||||||
|  |         # Mapping with implicit (Dog, Gecko), explicit ref (Catty -> Cat), and explicit schema name (Camo -> Chameleon) | ||||||
|  |         mapping: | ||||||
|  |           Catty: '#/components/schemas/Cat' | ||||||
|  |           Camo: 'Chameleon' | ||||||
|  |       required: | ||||||
|  |         - petType | ||||||
|  |     Cat: | ||||||
|  |       type: object | ||||||
|  |       allOf: | ||||||
|  |         - $ref: '#/components/schemas/Animal' | ||||||
|  |       properties: | ||||||
|  |         meow: | ||||||
|  |           type: string | ||||||
|  |     Dog: | ||||||
|  |       type: object | ||||||
|  |       allOf: | ||||||
|  |         - $ref: '#/components/schemas/Animal' | ||||||
|  |       properties: | ||||||
|  |         bark: | ||||||
|  |           type: string | ||||||
|  |     Lizard: | ||||||
|  |       oneOf: | ||||||
|  |         - $ref: '#/components/schemas/Gecko' | ||||||
|  |         - $ref: '#/components/schemas/Chameleon' | ||||||
|  |     Gecko: | ||||||
|  |       type: object | ||||||
|  |       allOf: | ||||||
|  |         - $ref: '#/components/schemas/Animal' | ||||||
|  |       properties: | ||||||
|  |         lovesRocks: | ||||||
|  |           type: string | ||||||
|  |     Chameleon: | ||||||
|  |       type: object | ||||||
|  |       allOf: | ||||||
|  |         - $ref: '#/components/schemas/Animal' | ||||||
|  |       properties: | ||||||
|  |         currentColor: | ||||||
|  |           type: string | ||||||
|  |     # Car inheritance tree: Car -> Truck -> SUV | ||||||
|  |     #                       Car -> Van -> MiniVan | ||||||
|  |     #                       Car -> Van -> CargoVan | ||||||
|  |     #                       Car -> Sedan | ||||||
|  |     Car: | ||||||
|  |       type: object | ||||||
|  |       required: | ||||||
|  |         - carType | ||||||
|  |       # Discriminator carType not defined in Car properties, but in child properties | ||||||
|  |       discriminator: | ||||||
|  |         propertyName: carType | ||||||
|  |     CarType: | ||||||
|  |       type: string | ||||||
|  |       enum: | ||||||
|  |         - Truck | ||||||
|  |         - SUV | ||||||
|  |         - Sedan | ||||||
|  |         - MiniVan | ||||||
|  |         - CargoVan | ||||||
|  |     Truck: | ||||||
|  |       type: object | ||||||
|  |       allOf: | ||||||
|  |         - $ref: '#/components/schemas/Car' | ||||||
|  |       properties: | ||||||
|  |         carType: | ||||||
|  |           $ref: '#/components/schemas/CarType' | ||||||
|  |       required: | ||||||
|  |         - carType | ||||||
|  |     SUV: | ||||||
|  |       type: object | ||||||
|  |       # SUV gets its discriminator property from Truck | ||||||
|  |       allOf: | ||||||
|  |         - $ref: '#/components/schemas/Truck' | ||||||
|  |     Sedan: | ||||||
|  |       type: object | ||||||
|  |       allOf: | ||||||
|  |         - $ref: '#/components/schemas/Car' | ||||||
|  |       required: | ||||||
|  |         - carType | ||||||
|  |       properties: | ||||||
|  |         carType: | ||||||
|  |           $ref: '#/components/schemas/CarType' | ||||||
|  |     Van: | ||||||
|  |       oneOf: | ||||||
|  |         - $ref: '#/components/schemas/MiniVan' | ||||||
|  |         - $ref: '#/components/schemas/CargoVan' | ||||||
|  |     MiniVan: | ||||||
|  |       type: object | ||||||
|  |       allOf: | ||||||
|  |         - $ref: '#/components/schemas/Car' | ||||||
|  |       properties: | ||||||
|  |         carType: | ||||||
|  |           $ref: '#/components/schemas/CarType' | ||||||
|  |       required: | ||||||
|  |         - carType | ||||||
|  |     CargoVan: | ||||||
|  |       type: object | ||||||
|  |       allOf: | ||||||
|  |         - $ref: '#/components/schemas/Car' | ||||||
|  |       properties: | ||||||
|  |         carType: | ||||||
|  |           $ref: '#/components/schemas/CarType' | ||||||
|  |       required: | ||||||
|  |         - carType | ||||||
| @ -108,6 +108,7 @@ public class EnumStringDiscriminator { | |||||||
|   protected EnumStrTypeEnum enumStrType; |   protected EnumStrTypeEnum enumStrType; | ||||||
| 
 | 
 | ||||||
|   public EnumStringDiscriminator() { |   public EnumStringDiscriminator() { | ||||||
|  | 
 | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   public EnumStringDiscriminator enumStrType(@javax.annotation.Nonnull EnumStrTypeEnum enumStrType) { |   public EnumStringDiscriminator enumStrType(@javax.annotation.Nonnull EnumStrTypeEnum enumStrType) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user