Skip to content

Commit 7c0747f

Browse files
Philzenwelshm
authored andcommitted
[python-fastapi] Fix CLI crash when calling config-help & update docs (OpenAPITools#18816)
* Implement test for uniqueness of CliOptions across all generators * Refactor existing test to use @dataProvider and fluent assertion * Remove extraneous cliOption definition for disallowAdditionalPropertiesIfNotPresent This is already defined (matching exactly in all aspects) in DefaultCodegen. Resolves OpenAPITools#18810 * Avoid variable declaration & assignment when only used once * Add additional uniqueness tests for all DefaultCodegen List<> members Test uniqueness for lists of: - supportingFiles - supportedLibraries - supportedVendorExtensions * Disable AllGeneratorsTest.noDuplicateSupportingFiles for the time being Re-enable when OpenAPITools#18831 is fixed * Generate updated python-fastapi docs
1 parent 5203d12 commit 7c0747f

3 files changed

Lines changed: 79 additions & 37 deletions

File tree

docs/generators/python-fastapi.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
8686
<li>except</li>
8787
<li>exec</li>
8888
<li>false</li>
89+
<li>field</li>
8990
<li>finally</li>
9091
<li>float</li>
9192
<li>for</li>

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

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,17 @@ public PythonFastAPIServerCodegen() {
9090
super();
9191

9292
modifyFeatureSet(features -> features.includeSecurityFeatures(
93-
SecurityFeature.OAuth2_AuthorizationCode,
94-
SecurityFeature.OAuth2_Password
93+
SecurityFeature.OAuth2_AuthorizationCode,
94+
SecurityFeature.OAuth2_Password
9595
));
9696

97-
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
98-
.stability(Stability.BETA)
99-
.build();
97+
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata).stability(Stability.BETA).build();
10098

101-
SimpleModule simpleModule = new SimpleModule();
102-
simpleModule.addKeySerializer(String.class, new SnakeCaseKeySerializer());
103-
simpleModule.addSerializer(Boolean.class, new PythonBooleanSerializer());
104-
MAPPER.registerModule(simpleModule);
99+
MAPPER.registerModule(
100+
new SimpleModule()
101+
.addKeySerializer(String.class, new SnakeCaseKeySerializer())
102+
.addSerializer(Boolean.class, new PythonBooleanSerializer())
103+
);
105104

106105
/*
107106
* Additional Properties. These values can be passed to the templates and
@@ -139,19 +138,6 @@ public PythonFastAPIServerCodegen() {
139138
.defaultValue(DEFAULT_SOURCE_FOLDER));
140139
cliOptions.add(new CliOption(CodegenConstants.FASTAPI_IMPLEMENTATION_PACKAGE, "python package name for the implementation code (convention: snake_case).")
141140
.defaultValue(implPackage));
142-
143-
// option to change how we process + set the data in the 'additionalProperties' keyword.
144-
CliOption disallowAdditionalPropertiesIfNotPresentOpt = CliOption.newBoolean(
145-
CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT,
146-
CodegenConstants.DISALLOW_ADDITIONAL_PROPERTIES_IF_NOT_PRESENT_DESC).defaultValue(Boolean.TRUE.toString());
147-
Map<String, String> disallowAdditionalPropertiesIfNotPresentOpts = new HashMap<>();
148-
disallowAdditionalPropertiesIfNotPresentOpts.put("false",
149-
"The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.");
150-
disallowAdditionalPropertiesIfNotPresentOpts.put("true",
151-
"Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.");
152-
disallowAdditionalPropertiesIfNotPresentOpt.setEnum(disallowAdditionalPropertiesIfNotPresentOpts);
153-
cliOptions.add(disallowAdditionalPropertiesIfNotPresentOpt);
154-
this.setDisallowAdditionalPropertiesIfNotPresent(true);
155141
}
156142

157143
@Override

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

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,39 +17,94 @@
1717
package org.openapitools.codegen;
1818

1919
import org.openapitools.codegen.config.CodegenConfigurator;
20-
import org.testng.Assert;
20+
import org.testng.annotations.DataProvider;
2121
import org.testng.annotations.Test;
2222

2323
import java.io.File;
24-
import java.io.IOException;
2524
import java.nio.file.Files;
25+
import java.util.Iterator;
2626
import java.util.List;
27+
import java.util.Locale;
28+
import java.util.stream.Collectors;
29+
30+
import static org.assertj.core.api.Assertions.assertThat;
2731

2832
public class AllGeneratorsTest {
2933

30-
@Test
31-
public void testEachWithPetstore() throws IOException {
32-
for (final CodegenConfig codegenConfig : CodegenConfigLoader.getAll()) {
33-
final File output = Files.createTempDirectory("test").toFile();
34+
@DataProvider(name = "generators") Iterator<CodegenConfig> generators() {
35+
return CodegenConfigLoader.getAll().iterator();
36+
}
37+
38+
@Test(dataProvider = "generators")
39+
public void testEachWithPetstore(CodegenConfig codegenConfig) {
40+
try {
41+
File output = Files.createTempDirectory("test").toFile();
3442
output.deleteOnExit();
3543

3644
final CodegenConfigurator configurator = new CodegenConfigurator()
3745
.setGeneratorName(codegenConfig.getName())
3846
.setInputSpec("src/test/resources/3_0/petstore.yaml")
3947
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));
4048

41-
final ClientOptInput clientOptInput = configurator.toClientOptInput();
42-
List<File> files = List.of();
43-
try {
44-
DefaultGenerator generator = new DefaultGenerator();
45-
files = generator.opts(clientOptInput).generate();
46-
} catch (Exception e) {
47-
Assert.fail("Generator " + codegenConfig.getName() + " threw an exception (generating " + codegenConfig.getInputSpec() + "): " + e.getMessage(), e);
48-
}
49+
List<File> files = new DefaultGenerator().opts(configurator.toClientOptInput()).generate();
4950

5051
// Main intention of this test is to check that nothing crashes. Besides, we check here that
5152
// at least 1 file is generated, besides the common ".openapi-generator-ignore", "FILES" and "VERSION" files.
52-
Assert.assertTrue(files.size() >= 4);
53+
assertThat(files).hasSizeGreaterThanOrEqualTo(4);
54+
} catch (Exception e) {
55+
throw new RuntimeException(
56+
String.format(
57+
Locale.ROOT,
58+
"Generator %s threw an exception (generating %s): %s",
59+
codegenConfig.getName(), codegenConfig.getInputSpec(), e.getMessage()
60+
), e
61+
);
5362
}
5463
}
64+
65+
/**
66+
* Regression test for <a href="https://github.com/OpenAPITools/openapi-generator/issues/18810">#18810</a>
67+
*/
68+
@Test(dataProvider = "generators") void noDuplicateCliOptions(CodegenConfig codegenConfig) {
69+
final List<String> cliOptionKeys = codegenConfig.cliOptions()
70+
.stream().map(CliOption::getOpt).collect(Collectors.toList());
71+
72+
assertThat(cliOptionKeys).allSatisfy(
73+
opt -> assertThat(cliOptionKeys)
74+
.as("Generator '%s' defines CliOption '%s' more than once!", codegenConfig.getName(), opt)
75+
.containsOnlyOnce(opt)
76+
);
77+
}
78+
79+
@Test(dataProvider = "generators") void noDuplicateSupportedLibraries(CodegenConfig codegenConfig) {
80+
final var supportedLibraries = codegenConfig.supportedLibraries().keySet();
81+
82+
assertThat(supportedLibraries).allSatisfy(
83+
lib -> assertThat(supportedLibraries)
84+
.as("Generator '%s' defines '%s' more than once in supportedLibraries!", codegenConfig.getName(), lib)
85+
.containsOnlyOnce(lib)
86+
);
87+
}
88+
89+
@Test(dataProvider = "generators", enabled = false) // re-enable when https://github.com/OpenAPITools/openapi-generator/issues/18831 is fixed
90+
void noDuplicateSupportingFiles(CodegenConfig codegenConfig) {
91+
final List<String> supportingFiles = codegenConfig.supportingFiles()
92+
.stream().map(SupportingFile::toString).collect(Collectors.toList());
93+
94+
assertThat(supportingFiles).allSatisfy(
95+
file -> assertThat(supportingFiles)
96+
.as("Generator '%s' defines '%s' more than once in supportingFiles!", codegenConfig.getName(), file)
97+
.containsOnlyOnce(file)
98+
);
99+
}
100+
101+
@Test(dataProvider = "generators") void noDuplicateSupportedVendorExtensions(CodegenConfig codegenConfig) {
102+
final List<VendorExtension> supportedVendorExtensions = codegenConfig.getSupportedVendorExtensions();
103+
104+
assertThat(supportedVendorExtensions).allSatisfy(
105+
extension -> assertThat(supportedVendorExtensions)
106+
.as("Generator '%s' defines '%s' more than once in supportedVendorExtensions!", codegenConfig.getName(), extension)
107+
.containsOnlyOnce(extension)
108+
);
109+
}
55110
}

0 commit comments

Comments
 (0)