Skip to content

Commit

Permalink
[Kotlin] Correct isInherited flag for Kotlin generators (#4254)
Browse files Browse the repository at this point in the history
* Correct isInherited flag for Kotlin generators

* Update Kotlin Client inheritance test to check variables
  • Loading branch information
mtraynham authored and jimschubert committed Jan 5, 2020
1 parent 79d11d7 commit 38185d8
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@

import java.io.File;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.openapitools.codegen.utils.StringUtils.*;

Expand Down Expand Up @@ -771,7 +773,22 @@ protected boolean needToImport(String type) {
public CodegenModel fromModel(String name, Schema schema) {
CodegenModel m = super.fromModel(name, schema);
m.optionalVars = m.optionalVars.stream().distinct().collect(Collectors.toList());
m.allVars.stream().filter(p -> !m.vars.contains(p)).forEach(p -> p.isInherited = true);
// Update allVars/requiredVars/optionalVars with isInherited
// Each of these lists contains elements that are similar, but they are all cloned
// via CodegenModel.removeAllDuplicatedProperty and therefore need to be updated
// separately.
// First find only the parent vars via baseName matching
Map<String, CodegenProperty> allVarsMap = m.allVars.stream()
.collect(Collectors.toMap(CodegenProperty::getBaseName, Function.identity()));
allVarsMap.keySet()
.removeAll(m.vars.stream().map(CodegenProperty::getBaseName).collect(Collectors.toSet()));
// Update the allVars
allVarsMap.values().forEach(p -> p.isInherited = true);
// Update any other vars (requiredVars, optionalVars)
Stream.of(m.requiredVars, m.optionalVars)
.flatMap(List::stream)
.filter(p -> allVarsMap.containsKey(p.baseName))
.forEach(p -> p.isInherited = true);
return m;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,18 +617,6 @@ public void execute(Template.Fragment fragment, Writer writer) throws IOExceptio
}
}

// Can't figure out the logic in DefaultCodegen but optional vars are getting duplicated when there's
// inheritance involved. Also, isInherited doesn't seem to be getting set properly ¯\_(ツ)_/¯
@Override
public CodegenModel fromModel(String name, Schema schema) {
CodegenModel m = super.fromModel(name, schema);

m.optionalVars = m.optionalVars.stream().distinct().collect(Collectors.toList());
m.allVars.stream().filter(p -> !m.vars.contains(p)).forEach(p -> p.isInherited = true);

return m;
}

/**
* Output the proper model name (capitalized).
* In case the name belongs to the TypeSystem it won't be renamed.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
package org.openapitools.codegen.kotlin;

import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.ObjectSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.CodegenModel;
import org.openapitools.codegen.CodegenProperty;
import org.openapitools.codegen.CodegenType;
import org.openapitools.codegen.DefaultCodegen;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.languages.AbstractKotlinCodegen;
import org.testng.Assert;
import org.testng.annotations.Test;

import java.io.File;
import java.util.HashSet;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.openapitools.codegen.CodegenConstants.ENUM_PROPERTY_NAMING_TYPE.*;
import static org.testng.Assert.*;
Expand Down Expand Up @@ -197,4 +210,45 @@ public void processOptsBooleanFalseFromNumeric() {
codegen.processOpts();
Assert.assertFalse((boolean) codegen.additionalProperties().get(CodegenConstants.SERIALIZABLE_MODEL));
}
}

@Test
public void handleInheritance() {
Schema parent = new ObjectSchema()
.addProperties("a", new StringSchema())
.addProperties("b", new StringSchema())
.addRequiredItem("a")
.name("Parent");
Schema child = new ComposedSchema()
.addAllOfItem(new Schema().$ref("Parent"))
.addAllOfItem(new ObjectSchema()
.addProperties("c", new StringSchema())
.addProperties("d", new StringSchema())
.addRequiredItem("c"))
.name("Child");
OpenAPI openAPI = TestUtils.createOpenAPI();
openAPI.getComponents().addSchemas(parent.getName(), parent);
openAPI.getComponents().addSchemas(child.getName(), child);

final DefaultCodegen codegen = new P_AbstractKotlinCodegen();
codegen.setOpenAPI(openAPI);

final CodegenModel pm = codegen
.fromModel("Child", child);
Map<String, CodegenProperty> allVarsMap = pm.allVars.stream()
.collect(Collectors.toMap(CodegenProperty::getBaseName, Function.identity()));
for (CodegenProperty p : pm.requiredVars) {
Assert.assertEquals(allVarsMap.get(p.baseName).isInherited, p.isInherited);
}
Assert.assertEqualsNoOrder(
pm.requiredVars.stream().map(CodegenProperty::getBaseName).toArray(),
new String[] {"a", "c"}
);
for (CodegenProperty p : pm.optionalVars) {
Assert.assertEquals(allVarsMap.get(p.baseName).isInherited, p.isInherited);
}
Assert.assertEqualsNoOrder(
pm.optionalVars.stream().map(CodegenProperty::getBaseName).toArray(),
new String[] {"b", "d"}
);
}
}

0 comments on commit 38185d8

Please sign in to comment.