Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import static org.openapitools.codegen.CodegenConstants.*;
import static org.openapitools.codegen.utils.EnumUtils.ANY_OF;
import static org.openapitools.codegen.utils.EnumUtils.ONE_OF;
import static org.openapitools.codegen.utils.ModelUtils.isOneOfOfConsts;
import static org.openapitools.codegen.utils.ModelUtils.simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema;
import static org.openapitools.codegen.utils.StringUtils.getUniqueString;

Expand Down Expand Up @@ -1705,18 +1706,24 @@ protected Schema processSimplifyOneOf(Schema schema) {
}

schema = simplifyOneOfAnyOfWithOnlyOneNonNullSubSchema(openAPI, schema, oneOfSchemas);
if (ModelUtils.isIntegerSchema(schema) || ModelUtils.isNumberSchema(schema) || ModelUtils.isStringSchema(schema)) {
if (schema.getSpecVersion().equals(SpecVersion.V30)) {
schema.setOneOf(null);
} //else {
// TODO convert oneOf const/deprecated to enum
// }
}
clearOneOf(schema);
}

return schema;
}

/**
* Removes the {@code oneOf} from the schema if it is considered to not contain information that the generator can
* currently act upon. The schema is left untouched if all the {@code oneOf} branches contain an OAS 3.1 {@code const}.
* This since that structure can potentially be used for enum interpretation.
*/
private void clearOneOf(Schema schema) {
if (ModelUtils.isIntegerSchema(schema) || ModelUtils.isNumberSchema(schema) || ModelUtils.isStringSchema(schema)) {
if (!isOneOfOfConsts(schema)) {
schema.setOneOf(null);
}
}
}

/**
* Ensure inheritance is correctly defined for OneOf and Discriminators.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2802,6 +2802,19 @@ public static boolean containsEnums(OpenAPI openAPI) {
return schemaMap.values().stream().anyMatch(ModelUtils::isEnumSchema);
}

/**
* Whether all branches in the oneOf contains a {@code const}. Returns false for OAS 3.0 since that does not support
* {@code const}.
* @param schema The Schema
* @return true if all {@code oneOf} branches contains a {@code const}.
*/
public static boolean isOneOfOfConsts(Schema<?> schema) {
if (hasOneOf(schema) && !schema.getSpecVersion().equals(SpecVersion.V30)) {
return schema.getOneOf().stream().allMatch(oneOf -> oneOf.getConst() != null);
}
return false;
}

@FunctionalInterface
private interface OpenAPISchemaVisitor {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@

public class OpenAPINormalizerTest {

private static final String SIMPLIFY_ONE_OF_ANY_OF = "SIMPLIFY_ONEOF_ANYOF";
private static final String SIMPLIFY_ONEOF_ANYOF_ENUM = "SIMPLIFY_ONEOF_ANYOF_ENUM";
private static final String REF_AS_PARENT_IN_ALLOF = "REF_AS_PARENT_IN_ALLOF";
private static final String X_PARENT = "x-parent";
private static final String X_INTERNAL = "x-internal";
Expand Down Expand Up @@ -201,7 +203,7 @@ public void testSimplifyOneOfAnyOfEnum() throws Exception {

// Test with rule enabled (default)
Map<String, String> options = new HashMap<>();
options.put("SIMPLIFY_ONEOF_ANYOF_ENUM", "true");
options.put(SIMPLIFY_ONEOF_ANYOF_ENUM, "true");
OpenAPINormalizer normalizer = new OpenAPINormalizer(openAPI, options);
normalizer.normalize();

Expand Down Expand Up @@ -239,7 +241,7 @@ public void testSimplifyOneOfAnyOfEnum() throws Exception {
// Test with rule disabled
OpenAPI openAPI2 = TestUtils.parseSpec("src/test/resources/3_0/simplifyOneOfWithEnums_test.yaml");
Map<String, String> options2 = new HashMap<>();
options2.put("SIMPLIFY_ONEOF_ANYOF_ENUM", "false");
options2.put(SIMPLIFY_ONEOF_ANYOF_ENUM, "false");
OpenAPINormalizer normalizer2 = new OpenAPINormalizer(openAPI2, options2);
normalizer2.normalize();

Expand Down Expand Up @@ -303,7 +305,7 @@ public void testOpenAPINormalizerSimplifyOneOfAnyOf() {
assertEquals(schema19.getAnyOf().size(), 1);

Map<String, String> options = new HashMap<>();
options.put("SIMPLIFY_ONEOF_ANYOF", "true");
options.put(SIMPLIFY_ONE_OF_ANY_OF, "true");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
openAPINormalizer.normalize();

Expand Down Expand Up @@ -361,7 +363,7 @@ public void testOpenAPINormalizerSimplifyOneOfWithSingleRef() {
assertEquals(((Schema) oneOfWithSingleRef.getProperties().get("number")).getOneOf().size(), 1);

Map<String, String> options = new HashMap<>();
options.put("SIMPLIFY_ONEOF_ANYOF", "true");
options.put(SIMPLIFY_ONE_OF_ANY_OF, "true");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
openAPINormalizer.normalize();

Expand Down Expand Up @@ -502,7 +504,7 @@ public void testOpenAPINormalizerConvertEnumNullToNullable() {
assertNull(schema.getNullable());

Map<String, String> options = new HashMap<>();
options.put("SIMPLIFY_ONEOF_ANYOF", "true");
options.put(SIMPLIFY_ONE_OF_ANY_OF, "true");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
openAPINormalizer.normalize();

Expand Down Expand Up @@ -1530,7 +1532,7 @@ public void testOpenAPINormalizerSimplifyOneOfAnyOf31Spec() {

// start the normalization
Map<String, String> options = new HashMap<>();
options.put("SIMPLIFY_ONEOF_ANYOF", "true");
options.put(SIMPLIFY_ONE_OF_ANY_OF, "true");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
openAPINormalizer.normalize();

Expand Down Expand Up @@ -1604,6 +1606,40 @@ public void testOpenAPINormalizerSimplifyOneOfAnyOf31Spec() {
assertEquals(((Schema) schema24.getProperties().get("anyof_nullable_number")).getTypes().size(), 1);
}

@Test
public void testOneOfWithStringsWithDifferentPatternsAreCollapsedWithSimplifyOneOfAnyOf() {
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/simplifyOneOfAnyOf_test.yaml");

Schema stringPatternsWithOneOf = openAPI.getComponents().getSchemas().get("StringPatternsWithOneOf");
assertEquals(stringPatternsWithOneOf.getOneOf().size(), 2);

// start the normalization
Map<String, String> options = new HashMap<>();
options.put(SIMPLIFY_ONE_OF_ANY_OF, "true");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
openAPINormalizer.normalize();

Schema normalizedStringPatternsWithOneOf = openAPI.getComponents().getSchemas().get("StringPatternsWithOneOf");
assertNull(normalizedStringPatternsWithOneOf.getOneOf());
}

@Test
public void testOneOfWithConstsIsUntouchedBySimplifyOneOfAnyOf() {
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/simplifyOneOfAnyOf_test.yaml");

Schema integerWithOneOfConsts = openAPI.getComponents().getSchemas().get("TypeIntegerWithOneOf");
assertEquals(integerWithOneOfConsts.getOneOf().size(), 3);

// start the normalization
Map<String, String> options = new HashMap<>();
options.put(SIMPLIFY_ONEOF_ANYOF_ENUM, "false");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
openAPINormalizer.normalize();

Schema normalizedIntegerWithOneOfConsts = openAPI.getComponents().getSchemas().get("TypeIntegerWithOneOf");
assertEquals(normalizedIntegerWithOneOfConsts.getOneOf().size(), 3);
}

@Test
public void testOpenAPINormalizerSimplifyOneOfWithSingleRef31Spec() {
OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_1/simplifyOneOfAnyOf_test.yaml");
Expand All @@ -1612,7 +1648,7 @@ public void testOpenAPINormalizerSimplifyOneOfWithSingleRef31Spec() {
assertEquals(((Schema) oneOfWithSingleRef.getProperties().get("number")).getOneOf().size(), 1);

Map<String, String> options = new HashMap<>();
options.put("SIMPLIFY_ONEOF_ANYOF", "true");
options.put(SIMPLIFY_ONE_OF_ANY_OF, "true");
OpenAPINormalizer openAPINormalizer = new OpenAPINormalizer(openAPI, options);
openAPINormalizer.normalize();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,13 @@ components:
OneOfNullAndRef3:
oneOf:
- $ref: '#/components/schemas/Parent'
- type: "null"
- type: "null"
StringPatternsWithOneOf:
type: string
oneOf:
- type: string
description: Numeric identifier
pattern: '^\d{1,35}$'
- type: string
description: UUID identifier
pattern: '^[0-9a-f-]{36}$'
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ components:
allOf:
- $ref: "#/components/schemas/Parent"
nullable: true
StringPatternsWithOneOf:
type: string
ParentWithPluralOneOfProperty_number:
oneOf:
- $ref: "#/components/schemas/Number"
Expand Down
Loading