Merge remote-tracking branch 'origin/master' into 5.0.x

This commit is contained in:
William Cheng
2020-02-04 15:31:10 +08:00
1179 changed files with 58478 additions and 9334 deletions

View File

@@ -26,6 +26,13 @@
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<configuration>
<configLocation>${project.parent.basedir}${file.separator}google_checkstyle.xml</configLocation>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
@@ -58,6 +65,16 @@
<transformer
implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
@@ -73,6 +90,31 @@
</plugins>
</build>
<profiles>
<profile>
<id>static-analysis</id>
<build>
<plugins>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<configuration>
<excludeFilterFile>${project.parent.basedir}${file.separator}spotbugs-exclude.xml</excludeFilterFile>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
</plugin>
<plugin>
<groupId>se.bjurr.violations</groupId>
<artifactId>violations-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
@@ -102,6 +144,11 @@
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.codehaus.janino</groupId>
<artifactId>janino</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
@@ -109,9 +156,9 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<!-- <version>${jmockit-version}</version> -->
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito-version}</version>
<scope>test</scope>
</dependency>
</dependencies>

View File

@@ -24,15 +24,15 @@ import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConfig;
import org.openapitools.codegen.CodegenConfigLoader;
import org.openapitools.codegen.GeneratorNotFoundException;
import org.openapitools.codegen.meta.FeatureSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -78,6 +78,9 @@ public class ConfigHelp implements Runnable {
@Option(name = {"--instantiation-types"}, title = "instantiation types", description = "displays types used to instantiate simple type/alias names")
private Boolean instantiationTypes;
@Option(name = {"--feature-set"}, title = "feature set", description = "displays feature set as supported by the generator")
private Boolean featureSets;
@Option(name = {
"--markdown-header"}, title = "markdown header", description = "When format=markdown, include this option to write out markdown headers (e.g. for docusaurus).")
private Boolean markdownHeader;
@@ -99,6 +102,7 @@ public class ConfigHelp implements Runnable {
reservedWords = Boolean.TRUE;
languageSpecificPrimitives = Boolean.TRUE;
importMappings = Boolean.TRUE;
featureSets = Boolean.TRUE;
}
try {
@@ -199,17 +203,12 @@ public class ConfigHelp implements Runnable {
sb.append("|");
// default
sb.append(escapeHtml4(langCliOption.getDefault())).append("|");
sb.append(newline);
sb.append(escapeHtml4(langCliOption.getDefault())).append("|").append(newline);
});
if (Boolean.TRUE.equals(importMappings)) {
sb.append(newline);
sb.append("## IMPORT MAPPING");
sb.append(newline);
sb.append(newline);
sb.append(newline).append("## IMPORT MAPPING").append(newline).append(newline);
sb.append("| Type/Alias | Imports |").append(newline);
sb.append("| ---------- | ------- |").append(newline);
@@ -227,10 +226,7 @@ public class ConfigHelp implements Runnable {
}
if (Boolean.TRUE.equals(instantiationTypes)) {
sb.append(newline);
sb.append("## INSTANTIATION TYPES");
sb.append(newline);
sb.append(newline);
sb.append(newline).append("## INSTANTIATION TYPES").append(newline).append(newline);
sb.append("| Type/Alias | Instantiated By |").append(newline);
sb.append("| ---------- | --------------- |").append(newline);
@@ -248,31 +244,51 @@ public class ConfigHelp implements Runnable {
}
if (Boolean.TRUE.equals(languageSpecificPrimitives)) {
sb.append(newline);
sb.append("## LANGUAGE PRIMITIVES");
sb.append(newline);
sb.append(newline);
sb.append(newline).append("## LANGUAGE PRIMITIVES").append(newline).append(newline);
sb.append("<ul data-columns=\"2\" style=\"list-style-type: disc;-webkit-columns:2;-moz-columns:2;columns:2;-moz-column-fill:auto;column-fill:auto\">");
config.languageSpecificPrimitives()
.stream()
.sorted(String::compareTo)
.forEach(s -> sb.append("<li>").append(escapeHtml4(s)).append("</li>").append(newline));
sb.append("</ul>");
sb.append(newline);
sb.append("</ul>").append(newline);
}
if (Boolean.TRUE.equals(reservedWords)) {
sb.append(newline);
sb.append("## RESERVED WORDS");
sb.append(newline);
sb.append(newline);
sb.append(newline).append("## RESERVED WORDS").append(newline).append(newline);
sb.append("<ul data-columns=\"2\" style=\"list-style-type: disc;-webkit-columns:2;-moz-columns:2;columns:2;-moz-column-fill:auto;column-fill:auto\">");
config.reservedWords()
.stream()
.sorted(String::compareTo)
.forEach(s -> sb.append("<li>").append(escapeHtml4(s)).append("</li>").append(newline));
sb.append("</ul>");
sb.append(newline);
sb.append("</ul>").append(newline);
}
if (Boolean.TRUE.equals(featureSets)) {
sb.append(newline).append("## FEATURE SET").append(newline).append(newline);
List<FeatureSet.FeatureSetFlattened> flattened = config.getFeatureSet().flatten();
flattened.sort(Comparator.comparing(FeatureSet.FeatureSetFlattened::getFeatureCategory));
AtomicReference<String> lastCategory = new AtomicReference<>();
flattened.forEach(featureSet -> {
if (!featureSet.getFeatureCategory().equals(lastCategory.get())) {
lastCategory.set(featureSet.getFeatureCategory());
String[] header = StringUtils.splitByCharacterTypeCamelCase(featureSet.getFeatureCategory());
sb.append(newline).append("### ").append(StringUtils.join(header, " ")).append(newline);
sb.append("| Name | Supported | Defined By |").append(newline);
sb.append("| ---- | --------- | ---------- |").append(newline);
}
// Appends a ✓ or ✗ for support
sb.append("|").append(featureSet.getFeatureName())
.append("|").append(featureSet.isSupported() ? "" : "")
.append("|").append(StringUtils.join(featureSet.getSource(), ","))
.append(newline);
});
}
}
@@ -305,14 +321,12 @@ public class ConfigHelp implements Runnable {
}
private void generatePlainTextHelp(StringBuilder sb, CodegenConfig config) {
sb.append(newline);
sb.append("CONFIG OPTIONS");
sb.append(newline).append("CONFIG OPTIONS");
if (Boolean.TRUE.equals(namedHeader)) {
sb.append(" for ").append(generatorName).append(newline);
}
sb.append(newline);
sb.append(newline);
sb.append(newline).append(newline);
String optIndent = "\t";
String optNestedIndent = "\t ";
@@ -324,19 +338,14 @@ public class ConfigHelp implements Runnable {
}, TreeMap::new));
langCliOptions.forEach((key, langCliOption) -> {
sb.append(optIndent).append(key);
sb.append(newline);
sb.append(optIndent).append(key).append(newline);
sb.append(optNestedIndent).append(langCliOption.getOptionHelp()
.replaceAll("\n", System.lineSeparator() + optNestedIndent));
sb.append(newline);
sb.append(newline);
sb.append(newline).append(newline);
});
if (Boolean.TRUE.equals(importMappings)) {
sb.append(newline);
sb.append("IMPORT MAPPING");
sb.append(newline);
sb.append(newline);
sb.append(newline).append("IMPORT MAPPING").append(newline).append(newline);
Map<String, String> map = config.importMapping()
.entrySet()
.stream()
@@ -348,10 +357,7 @@ public class ConfigHelp implements Runnable {
}
if (Boolean.TRUE.equals(instantiationTypes)) {
sb.append(newline);
sb.append("INSTANTIATION TYPES");
sb.append(newline);
sb.append(newline);
sb.append(newline).append("INSTANTIATION TYPES").append(newline).append(newline);
Map<String, String> map = config.instantiationTypes()
.entrySet()
.stream()
@@ -363,24 +369,53 @@ public class ConfigHelp implements Runnable {
}
if (Boolean.TRUE.equals(languageSpecificPrimitives)) {
sb.append(newline);
sb.append("LANGUAGE PRIMITIVES");
sb.append(newline);
sb.append(newline);
sb.append(newline).append("LANGUAGE PRIMITIVES").append(newline).append(newline);
String[] arr = config.languageSpecificPrimitives().stream().sorted().toArray(String[]::new);
writePlainTextFromArray(sb, arr, optIndent);
sb.append(newline);
}
if (Boolean.TRUE.equals(reservedWords)) {
sb.append(newline);
sb.append("RESERVED WORDS");
sb.append(newline);
sb.append(newline);
sb.append(newline).append("RESERVED WORDS").append(newline).append(newline);
String[] arr = config.reservedWords().stream().sorted().toArray(String[]::new);
writePlainTextFromArray(sb, arr, optIndent);
sb.append(newline);
}
if (Boolean.TRUE.equals(featureSets)) {
sb.append(newline).append("FEATURE SET").append(newline);
List<FeatureSet.FeatureSetFlattened> flattened = config.getFeatureSet().flatten();
flattened.sort(Comparator.comparing(FeatureSet.FeatureSetFlattened::getFeatureCategory));
AtomicReference<String> lastCategory = new AtomicReference<>();
String nameKey = "Name";
String supportedKey = "Supported";
String definedByKey = "Defined By";
int maxNameLength = flattened.stream().map(FeatureSet.FeatureSetFlattened::getFeatureName).mapToInt(String::length).max().orElse(nameKey.length());
int maxSupportedLength = supportedKey.length();
int definedInLength = 20;
String format = "%-" + maxNameLength + "s\t%-" + maxSupportedLength + "s\t%-" + definedInLength + "s";
flattened.forEach(featureSet -> {
if (!featureSet.getFeatureCategory().equals(lastCategory.get())) {
lastCategory.set(featureSet.getFeatureCategory());
sb.append(newline).append(newline).append(" ").append(featureSet.getFeatureCategory()).append(":");
sb.append(newline).append(newline);
sb.append(optIndent).append(String.format(Locale.ROOT, format, nameKey, supportedKey, definedByKey)).append(newline);
sb.append(optIndent).append(String.format(Locale.ROOT, format,
StringUtils.repeat("-", maxNameLength),
StringUtils.repeat("-", maxSupportedLength),
StringUtils.repeat("-", definedInLength)));
}
String mark = featureSet.isSupported() ? "" : "x";
String centeredMark = StringUtils.center(mark, maxSupportedLength);
String definedByCsv = StringUtils.join(featureSet.getSource(), ",");
sb.append(newline).append(optIndent).append(String.format(Locale.ROOT, format, featureSet.getFeatureName(), centeredMark, definedByCsv));
});
}
}
private void writePlainTextFromMap(

View File

@@ -28,22 +28,17 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.GeneratorNotFoundException;
import org.openapitools.codegen.*;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* User: lanwen Date: 24.03.15 Time: 20:22
*/
@Command(name = "generate", description = "Generate code with the specified generator.")
public class Generate implements Runnable {
// private static final Logger LOGGER = LoggerFactory.getLogger(Generate.class);
CodegenConfigurator configurator;
Generator generator;
@Option(name = {"-v", "--verbose"}, description = "verbose mode")
private Boolean verbose;
@@ -257,13 +252,18 @@ public class Generate implements Runnable {
.ifPresent(FilterAttachable::clearAllFilters);
}
// attempt to read from config file
CodegenConfigurator configurator = CodegenConfigurator.fromFile(configFile);
// if a config file wasn't specified or we were unable to read it
// this initial check allows for field-level package private injection (for unit testing)
if (configurator == null) {
// createa a fresh configurator
configurator = new CodegenConfigurator();
if (configFile != null && configFile.length() > 0) {
// attempt to load from configFile
configurator = CodegenConfigurator.fromFile(configFile);
}
// if a config file wasn't specified, or we were unable to read it
if (configurator == null) {
// create a fresh configurator
configurator = new CodegenConfigurator();
}
}
// now override with any specified parameters
@@ -413,7 +413,14 @@ public class Generate implements Runnable {
try {
final ClientOptInput clientOptInput = configurator.toClientOptInput();
new DefaultGenerator().opts(clientOptInput).generate();
// this null check allows us to inject for unit testing.
if (generator == null) {
generator = new DefaultGenerator();
}
generator.opts(clientOptInput);
generator.generate();
} catch (GeneratorNotFoundException e) {
System.err.println(e.getMessage());
System.err.println("[error] Check the spelling of the generator's name and try again.");

View File

@@ -123,27 +123,12 @@ public class GenerateBatch implements Runnable {
}
}
LOGGER.info(String.format(Locale.ROOT, "Batch generation using up to %d threads.\nIncludes: %s\nRoot: %s", numThreads, includesDir.getAbsolutePath(), rootDir.toAbsolutePath().toString()));
// Create a module which loads our config files, but supports a special "!include" key which can point to an existing config file.
// This allows us to create a sort of meta-config which holds configs which are otherwise required at CLI time (via generate task).
// That is, this allows us to create a wrapper config for generatorName, inputSpec, outputDir, etc.
SimpleModule module = new SimpleModule("GenerateBatch");
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config,
BeanDescription bd, JsonDeserializer<?> original) {
JsonDeserializer<?> result;
if (bd.getBeanClass() == DynamicSettings.class) {
result = new DynamicSettingsRefSupport(original, includesDir);
} else {
result = original;
}
return result;
}
});
SimpleModule module = getCustomDeserializationModel(includesDir);
List<CodegenConfigurator> configurators = configs.stream().map(config -> CodegenConfigurator.fromFile(config, module)).collect(Collectors.toList());
// it doesn't make sense to interleave INFO level logs, so limit these to only ERROR.
@@ -169,6 +154,8 @@ public class GenerateBatch implements Runnable {
System.out.println("COMPLETE.");
} catch (InterruptedException e) {
e.printStackTrace();
// re-interrupt
Thread.currentThread().interrupt();
}
}
@@ -227,6 +214,28 @@ public class GenerateBatch implements Runnable {
}
}
static SimpleModule getCustomDeserializationModel(final File includesDir) {
// Create a module which loads our config files, but supports a special "!include" key which can point to an existing config file.
// This allows us to create a sort of meta-config which holds configs which are otherwise required at CLI time (via generate task).
// That is, this allows us to create a wrapper config for generatorName, inputSpec, outputDir, etc.
SimpleModule module = new SimpleModule("GenerateBatch");
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config,
BeanDescription bd, JsonDeserializer<?> original) {
JsonDeserializer<?> result;
if (bd.getBeanClass() == DynamicSettings.class) {
result = new DynamicSettingsRefSupport(original, includesDir);
} else {
result = original;
}
return result;
}
});
return module;
}
static class DynamicSettingsRefSupport extends DelegatingDeserializer {
private static final String INCLUDE = "!include";
private File scanDir;
@@ -255,11 +264,13 @@ public class GenerateBatch implements Runnable {
// load the file into the tree node and continue parsing as normal
((ObjectNode) node).remove(INCLUDE);
JsonParser includeParser = codec.getFactory().createParser(includeFile);
TreeNode includeNode = includeParser.readValueAsTree();
TreeNode includeNode;
try (JsonParser includeParser = codec.getFactory().createParser(includeFile)) {
includeNode = includeParser.readValueAsTree();
}
ObjectReader reader = codec.readerForUpdating(node);
TreeNode updated = reader.readValue(includeFile);
TreeNode updated = reader.readValue(includeNode.traverse());
JsonParser updatedParser = updated.traverse();
updatedParser.nextToken();
return super.deserialize(updatedParser, ctx);

View File

@@ -22,14 +22,14 @@ import io.airlift.airline.Option;
import io.swagger.parser.OpenAPIParser;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.parser.core.models.SwaggerParseResult;
import org.openapitools.codegen.utils.ModelUtils;
import org.apache.commons.lang3.text.WordUtils;
import org.openapitools.codegen.validation.ValidationResult;
import org.openapitools.codegen.validations.oas.OpenApiEvaluator;
import org.openapitools.codegen.validations.oas.RuleConfiguration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@Command(name = "validate", description = "Validate specification")
@@ -54,42 +54,28 @@ public class Validate implements Runnable {
StringBuilder sb = new StringBuilder();
OpenAPI specification = result.getOpenAPI();
if (Boolean.TRUE.equals(recommend)) {
if (specification != null) {
// Add information about unused models to the warnings set.
List<String> unusedModels = ModelUtils.getUnusedSchemas(specification);
if (unusedModels != null) {
unusedModels.forEach(name -> warnings.add("Unused model: " + name));
}
RuleConfiguration ruleConfiguration = new RuleConfiguration();
ruleConfiguration.setEnableRecommendations(recommend != null ? recommend : false);
// check for loosely defined oneOf extension requirements.
// This is a recommendation because the 3.0.x spec is not clear enough on usage of oneOf.
// see https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.section.9.2.1.3 and the OAS section on 'Composition and Inheritance'.
Map<String, Schema> schemas = ModelUtils.getSchemas(specification);
schemas.forEach((key, schema) -> {
if (schema instanceof ComposedSchema) {
final ComposedSchema composed = (ComposedSchema) schema;
if (composed.getOneOf() != null && composed.getOneOf().size() > 0) {
if (composed.getProperties() != null && composed.getProperties().size() >= 1 && composed.getProperties().get("discriminator") == null) {
warnings.add("Schema (oneOf) should not contain properties: " + key);
}
}
}
});
}
}
OpenApiEvaluator evaluator = new OpenApiEvaluator(ruleConfiguration);
ValidationResult validationResult = evaluator.validate(specification);
// TODO: We could also provide description here along with getMessage. getMessage is either a "generic" message or specific (e.g. Model 'Cat' has issues).
// This would require that we parse the messageList coming from swagger-parser into a better structure.
validationResult.getWarnings().forEach(invalid -> warnings.add(invalid.getMessage()));
validationResult.getErrors().forEach(invalid -> errors.add(invalid.getMessage()));
if (!errors.isEmpty()) {
sb.append("Errors:").append(System.lineSeparator());
errors.forEach(msg ->
sb.append("\t-").append(msg).append(System.lineSeparator())
sb.append("\t- ").append(WordUtils.wrap(msg, 90).replace(System.lineSeparator(), System.lineSeparator() + "\t ")).append(System.lineSeparator())
);
}
if (!warnings.isEmpty()) {
sb.append("Warnings: ").append(System.lineSeparator());
warnings.forEach(msg ->
sb.append("\t-").append(msg).append(System.lineSeparator())
sb.append("\t- ").append(WordUtils.wrap(msg, 90).replace(System.lineSeparator(), System.lineSeparator() + "\t ")).append(System.lineSeparator())
);
}

View File

@@ -1,9 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Prevent startup messages from Logback -->
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
<!-- For those without color (the default) -->
<property name="noColorPattern"
value="[%thread] %-5level %logger{36} - %msg%n" />
<!-- For those with color (with -Dcolor set) -->
<property name="colorPattern"
value="[%thread] %highlight(%-5level) %logger{36} - %msg%n" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>[%thread] %-5level %logger{36} - %msg%n</pattern>
<pattern>${noColorPattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
@@ -14,21 +25,80 @@
<appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>[%thread] %-5level %logger{36} - %msg%n</pattern>
<pattern>${noColorPattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<appender name="STDOUT_COLOR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.out</target>
<withJansi>true</withJansi>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${colorPattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>NEUTRAL</onMismatch>
</filter>
</appender>
<appender name="STDERR_COLOR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<withJansi>true</withJansi>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${colorPattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<appender name="ONCELOGGER_COLOR" class="ch.qos.logback.core.ConsoleAppender">
<target>System.err</target>
<withJansi>true</withJansi>
<evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator">
<marker>ONCE</marker>
</evaluator>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>[%thread] %highlight(%-5level) %logger{36} - %red(%msg)%n</pattern>
</encoder>
</appender>
<logger name="io.swagger" level="warn">
<appender-ref ref="STDOUT"/>
<appender-ref ref="STDERR"/>
<!-- Colorize by passing -Dcolor -->
<if condition='isDefined("color")'>
<then>
<appender-ref ref="STDOUT_COLOR"/>
<appender-ref ref="STDERR_COLOR"/>
</then>
<else>
<appender-ref ref="STDOUT"/>
<appender-ref ref="STDERR"/>
</else>
</if>
</logger>
<logger name="org.openapitools" level="${log.level:-info}">
<appender-ref ref="STDOUT"/>
<appender-ref ref="STDERR"/>
<!-- Colorize by passing -Dcolor -->
<if condition='isDefined("color")'>
<then>
<appender-ref ref="STDOUT_COLOR"/>
<appender-ref ref="STDERR_COLOR"/>
</then>
<else>
<appender-ref ref="STDOUT"/>
<appender-ref ref="STDERR"/>
</else>
</if>
</logger>
<root level="error">
<appender-ref ref="STDERR"/>
<!-- Colorize by passing -Dcolor -->
<if condition='isDefined("color")'>
<then>
<appender-ref ref="STDERR_COLOR"/>
</then>
<else>
<appender-ref ref="STDERR"/>
</else>
</if>
</root>
</configuration>

View File

@@ -0,0 +1,102 @@
package org.openapitools.codegen.cmd;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.config.Context;
import org.openapitools.codegen.config.GeneratorSettings;
import org.openapitools.codegen.config.WorkflowSettings;
import org.testng.ITestContext;
import org.testng.TestRunner;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import static org.testng.Assert.*;
@SuppressWarnings("RedundantThrows")
public class GenerateBatchTest {
private static final String SPEC_FILE = "batch/specs/petstore.yaml";
private static final String JAXRS_DATELIB_J8_JSON = "jaxrs-datelib-j8.json";
private static final String JAXRS_DATELIB_J8_YAML = "jaxrs-datelib-j8.yaml";
private static final String JAXRS_DATELIB_J8_YAML_INCLUDE_JSON = "jaxrs-datelib-j8-yaml-include.json";
private static final String JAXRS_DATELIB_J8_JSON_INCLUDE_YAML = "jaxrs-datelib-j8-json-include.yaml";
Path workingDirectory;
@BeforeTest
public void setUp(ITestContext ctx) throws IOException {
workingDirectory = Paths.get("src", "test", "resources", "batch");
}
@DataProvider(name = "customIncludeDeserializerFiles")
public Object[][] customIncludeDeserializerFiles() {
return new Object[][] {
{JAXRS_DATELIB_J8_JSON},
{JAXRS_DATELIB_J8_YAML},
{JAXRS_DATELIB_J8_JSON_INCLUDE_YAML}
};
}
@Test(dataProvider = "customIncludeDeserializerFiles")
public void testDeserializerWithJsonInclude(String file) throws IOException {
String config = getTargetResourceAsFile(file).toString();
SimpleModule module = GenerateBatch.getCustomDeserializationModel(getIncludesDir());
CodegenConfigurator loaded = CodegenConfigurator.fromFile(config, module);
Map<String, Object> expectedAdditionalProperties = new HashMap<>();
expectedAdditionalProperties.put("serverPort", "8082");
expectedAdditionalProperties.put("dateLibrary", "java8");
expectedAdditionalProperties.put("hideGenerationTimestamp", true);
expectedAdditionalProperties.put("serializableModel", true);
expectedAdditionalProperties.put("withXml", true);
expectedAdditionalProperties.put("java8", true);
expectedAdditionalProperties.put("useBeanValidation", true);
assertNotNull(loaded);
Context<?> context = loaded.toContext();
WorkflowSettings workflowSettings = context.getWorkflowSettings();
GeneratorSettings generatorSettings = context.getGeneratorSettings();
assertNotNull(workflowSettings);
assertNotNull(generatorSettings);
assertEquals(generatorSettings.getGeneratorName(), "jaxrs-jersey");
assertEquals(workflowSettings.getOutputDir(), "outputDir");
assertEquals(workflowSettings.getInputSpec(), SPEC_FILE);
assertTrue(generatorSettings.getAdditionalProperties().size() >= 7);
Set<Map.Entry<String, Object>> actualSet = generatorSettings.getAdditionalProperties().entrySet();
assertTrue(actualSet.containsAll(expectedAdditionalProperties.entrySet()));
}
@SuppressWarnings("unused")
@Test(
expectedExceptions = { RuntimeException.class },
expectedExceptionsMessageRegExp = "Unable to deserialize config file: .*"
)
public void testInvalidDeserializerWithIncludeOption() {
// JSON is valid YAML, but not the other way around, so we can't load a YAML include from a JSON config
// to do so would require additional work.
String config = getTargetResourceAsFile(JAXRS_DATELIB_J8_YAML_INCLUDE_JSON).toString();
SimpleModule module = GenerateBatch.getCustomDeserializationModel(getIncludesDir());
CodegenConfigurator loaded = CodegenConfigurator.fromFile(config, module);
fail("Expected an exception when trying to load a YAML include from a JSON file");
}
private File getIncludesDir() {
// The includes directory would be "batch" under resources here, as everything is relative to this directory.
return workingDirectory.toFile();
}
private File getTargetResourceAsFile(String relative) {
return workingDirectory.resolve(relative).toAbsolutePath().toFile();
}
}

View File

@@ -17,536 +17,417 @@
package org.openapitools.codegen.cmd;
import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.OpenAPIGenerator;
import org.openapitools.codegen.config.CodegenConfigurator;
import mockit.Expectations;
import mockit.FullVerifications;
import mockit.Injectable;
import mockit.Mocked;
import mockit.Verifications;
import io.airlift.airline.Cli;
import org.apache.commons.lang3.ArrayUtils;
import org.mockito.MockSettings;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.Generator;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import static org.mockito.Answers.CALLS_REAL_METHODS;
import static org.mockito.Mockito.*;
import static org.testng.Assert.fail;
@SuppressWarnings("unused")
public class GenerateTest {
@Mocked
CodegenConfigurator configurator;
protected MockSettings mockSettings = withSettings().useConstructor().defaultAnswer(CALLS_REAL_METHODS);
private Generator generator;
private CodegenConfigurator configurator;
private Path outputDirectory;
@Injectable
ClientOptInput clientOptInput;
@AfterMethod
public void afterEachTest() {
outputDirectory.toFile().deleteOnExit();
}
@Mocked
DefaultGenerator generator;
@BeforeMethod
public void beforeEachTest() throws IOException {
outputDirectory = Files.createTempDirectory("GenerateTest");
generator = mock(DefaultGenerator.class);
when(generator.generate()).thenReturn(new ArrayList<>());
@Test
public void testVerbose() throws Exception {
setupAndRunGenericTest("-v");
new FullVerifications() {
{
configurator.setVerbose(true);
times = 1;
}
};
setupAndRunGenericTest("--verbose");
new FullVerifications() {
{
configurator.setVerbose(true);
times = 1;
}
};
configurator = mock(CodegenConfigurator.class, mockSettings);
}
@Test
public void testRequiredArgs_ShortArgs() throws Exception {
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", false, null, "-p", "foo=bar");
new FullVerifications() {
{
configurator.addAdditionalProperty("foo", "bar");
times = 1;
}
};
}
@Test
public void testRequiredArgs_LongArgs() throws Exception {
setupAndRunTest("--input-spec", "src/test/resources/swagger.yaml", "--generator-name", "java", "--output",
"src/main/java", false, null);
new FullVerifications() {
{
}
};
}
@Test
public void testTemplateDir() throws Exception {
final String templateDir = "src/main/resources/customTemplates";
setupAndRunGenericTest("--template-dir", templateDir);
new FullVerifications() {
{
configurator.setTemplateDir(templateDir);
times = 1;
}
};
setupAndRunGenericTest("-t", templateDir);
new FullVerifications() {
{
configurator.setTemplateDir(templateDir);
times = 1;
}
};
}
@Test
public void testAuth() throws Exception {
final String auth = "hello:world";
setupAndRunGenericTest("--auth", auth);
new FullVerifications() {
{
configurator.setAuth(auth);
times = 1;
}
};
setupAndRunGenericTest("-a", auth);
new FullVerifications() {
{
configurator.setAuth(auth);
times = 1;
}
};
setupAndRunGenericTest();
new FullVerifications() {
{
configurator.setAuth(anyString);
times = 0;
}
};
}
@Test
public void testConfigJson() throws Exception {
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
"config.json", "-c", "config.json");
new FullVerifications() {
{
}
};
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
"config.json", "--config", "config.json");
new FullVerifications() {
{
}
};
}
@Test
public void testConfigYaml() throws Exception {
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
"config.yaml", "-c", "config.yaml");
new FullVerifications() {
{
}
};
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
"config.yaml", "--config", "config.yaml");
new FullVerifications() {
{
}
};
}
@Test
public void testSkipOverwrite() throws Exception {
setupAndRunGenericTest("-s");
new FullVerifications() {
{
configurator.setSkipOverwrite(true);
times = 1;
}
};
setupAndRunGenericTest("--skip-overwrite");
new FullVerifications() {
{
configurator.setSkipOverwrite(true);
times = 1;
}
};
}
@Test
public void testStrictSpec() throws Exception {
setupAndRunGenericTest("--strict-spec", "true");
new FullVerifications() {
{
configurator.setStrictSpecBehavior(true);
times = 1;
}
};
setupAndRunGenericTest("--strict-spec", "false");
new FullVerifications() {
{
configurator.setStrictSpecBehavior(false);
times = 1;
}
};
}
@Test
public void testPackageName() throws Exception {
final String value = "io.foo.bar.baz";
setupAndRunGenericTest("--package-name", value);
new FullVerifications() {
{
configurator.setPackageName(value);
times = 1;
}
};
}
@Test
public void testApiPackage() throws Exception {
final String value = "io.foo.bar.api";
setupAndRunGenericTest("--api-package", value);
new FullVerifications() {
{
configurator.setApiPackage(value);
times = 1;
}
};
}
@Test
public void testModelPackage() throws Exception {
final String value = "io.foo.bar.api";
setupAndRunGenericTest("--model-package", value);
new FullVerifications() {
{
configurator.setModelPackage(value);
times = 1;
}
};
}
@Test
public void testInstantiationTypes() throws Exception {
setupAndRunGenericTest("--instantiation-types", "hello=world,key=,foo=bar,key2");
new FullVerifications() {
{
configurator.addInstantiationType("hello", "world");
times = 1;
configurator.addInstantiationType("foo", "bar");
times = 1;
configurator.addInstantiationType("key", "");
times = 1;
configurator.addInstantiationType("key2", "");
times = 1;
}
};
setupAndRunGenericTest("--instantiation-types", "hello=world", "--instantiation-types",
"key=", "--instantiation-types", "foo=bar", "--instantiation-types", "key2");
new FullVerifications() {
{
configurator.addInstantiationType("hello", "world");
times = 1;
configurator.addInstantiationType("foo", "bar");
times = 1;
configurator.addInstantiationType("key", "");
times = 1;
configurator.addInstantiationType("key2", "");
times = 1;
}
};
}
@Test
public void testTypeMappings() throws Exception {
setupAndRunGenericTest("--type-mappings", "hello=world,key=,foo=bar,key2");
new FullVerifications() {
{
configurator.addTypeMapping("hello", "world");
times = 1;
configurator.addTypeMapping("foo", "bar");
times = 1;
configurator.addTypeMapping("key", "");
times = 1;
configurator.addTypeMapping("key2", "");
times = 1;
}
};
setupAndRunGenericTest("--type-mappings", "hello=world", "--type-mappings", "key=",
"--type-mappings", "foo=bar", "--type-mappings", "key2");
new FullVerifications() {
{
configurator.addTypeMapping("hello", "world");
times = 1;
configurator.addTypeMapping("foo", "bar");
times = 1;
configurator.addTypeMapping("key", "");
times = 1;
configurator.addTypeMapping("key2", "");
times = 1;
}
};
}
@Test
public void testAdditionalProperties() throws Exception {
public void testAdditionalPropertiesLong() {
setupAndRunGenericTest("--additional-properties", "hello=world,key=,foo=bar,key2");
verify(configurator).addAdditionalProperty("hello", "world");
verify(configurator).addAdditionalProperty("foo", "bar");
verify(configurator).addAdditionalProperty("key", "");
verify(configurator).addAdditionalProperty("key2", "");
}
new FullVerifications() {
{
configurator.addAdditionalProperty("hello", "world");
times = 1;
configurator.addAdditionalProperty("foo", "bar");
times = 1;
configurator.addAdditionalProperty("key", "");
times = 1;
configurator.addAdditionalProperty("key2", "");
times = 1;
}
};
@Test
public void testAdditionalPropertiesLongMultiple() {
setupAndRunGenericTest("--additional-properties", "hello=world", "--additional-properties",
"key=", "--additional-properties", "foo=bar", "--additional-properties", "key2");
new FullVerifications() {
{
configurator.addAdditionalProperty("hello", "world");
times = 1;
configurator.addAdditionalProperty("foo", "bar");
times = 1;
configurator.addAdditionalProperty("key", "");
times = 1;
configurator.addAdditionalProperty("key2", "");
times = 1;
}
};
verify(configurator).addAdditionalProperty("hello", "world");
verify(configurator).addAdditionalProperty("foo", "bar");
verify(configurator).addAdditionalProperty("key", "");
verify(configurator).addAdditionalProperty("key2", "");
}
@Test
public void testLanguageSpecificPrimitives() throws Exception {
setupAndRunGenericTest("--language-specific-primitives", "foo,,bar",
"--language-specific-primitives", "hello,world");
new FullVerifications() {
{
configurator.addLanguageSpecificPrimitive("foo");
times = 1;
configurator.addLanguageSpecificPrimitive("bar");
times = 1;
configurator.addLanguageSpecificPrimitive("hello");
times = 1;
configurator.addLanguageSpecificPrimitive("world");
times = 1;
}
};
}
@Test
public void testImportMappings() throws Exception {
setupAndRunGenericTest("--import-mappings", "hello=world,key=,foo=bar,key2");
new FullVerifications() {
{
configurator.addImportMapping("hello", "world");
times = 1;
configurator.addImportMapping("foo", "bar");
times = 1;
configurator.addImportMapping("key", "");
times = 1;
configurator.addImportMapping("key2", "");
times = 1;
}
};
setupAndRunGenericTest("--import-mappings", "hello=world", "--import-mappings", "key=",
"--import-mappings", "foo=bar", "--import-mappings", "key2");
new FullVerifications() {
{
configurator.addImportMapping("hello", "world");
times = 1;
configurator.addImportMapping("foo", "bar");
times = 1;
configurator.addImportMapping("key", "");
times = 1;
configurator.addImportMapping("key2", "");
times = 1;
}
};
}
@Test
public void testInvokerPackage() throws Exception {
public void testApiPackage() {
final String value = "io.foo.bar.api";
setupAndRunGenericTest("--invoker-package", value);
new FullVerifications() {
{
configurator.setInvokerPackage(value);
times = 1;
}
};
setupAndRunGenericTest("--api-package", value);
verify(configurator).setApiPackage(value);
}
@Test
public void testGroupId() throws Exception {
final String value = "io.foo.bar.api";
setupAndRunGenericTest("--group-id", value);
new FullVerifications() {
{
configurator.setGroupId(value);
times = 1;
}
};
}
@Test
public void testArtifactId() throws Exception {
public void testArtifactId() {
final String value = "awesome-api";
setupAndRunGenericTest("--artifact-id", value);
new FullVerifications() {
{
configurator.setArtifactId(value);
times = 1;
}
};
}
@Test
public void testArtifactVersion() throws Exception {
final String value = "1.2.3";
setupAndRunGenericTest("--artifact-version", value);
new FullVerifications() {
{
configurator.setArtifactVersion(value);
times = 1;
}
};
}
@Test
public void testLibrary() throws Exception {
final String value = "library1";
setupAndRunGenericTest("--library", value);
new FullVerifications() {
{
configurator.setLibrary(value);
times = 1;
}
};
}
private void setupAndRunTest(String specFlag, final String spec, String langFlag,
final String lang, String outputDirFlag, final String outputDir,
boolean configuratorFromFile, final String configFile, String... additionalParameters) {
final String[] commonArgs =
{"generate", langFlag, lang, outputDirFlag, outputDir, specFlag, spec};
String[] argsToUse = ArrayUtils.addAll(commonArgs, additionalParameters);
if (configuratorFromFile) {
new Expectations() {
{
CodegenConfigurator.fromFile(configFile);
times = 1;
result = configurator;
}
};
} else {
new Expectations() {
{
CodegenConfigurator.fromFile(anyString);
result = null;
new CodegenConfigurator();
times = 1;
result = configurator;
}
};
}
new Expectations() {
{
configurator.toClientOptInput();
times = 1;
result = clientOptInput;
new DefaultGenerator();
times = 1;
result = generator;
generator.opts(clientOptInput);
times = 1;
result = generator;
generator.generate();
times = 1;
}
};
OpenAPIGenerator.main(argsToUse);
new Verifications() {
{
configurator.setGeneratorName(lang);
times = 1;
configurator.setInputSpec(spec);
times = 1;
configurator.setOutputDir(outputDir);
}
};
verify(configurator).setArtifactId(value);
}
private void setupAndRunGenericTest(String... additionalParameters) {
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", false, null,
additionalParameters);
}
@SuppressWarnings("SameParameterValue")
private void setupAndRunTest(String specFlag, final String spec, String langFlag,
final String lang, String outputDirFlag, final String outputDir,
boolean configuratorFromFile, final String configFile, String... additionalParameters) {
final String[] commonArgs =
{"generate", langFlag, lang, outputDirFlag, outputDir, specFlag, spec};
String[] argsToUse = ArrayUtils.addAll(commonArgs, additionalParameters);
Cli.CliBuilder<Runnable> builder =
Cli.<Runnable>builder("openapi-generator-cli")
.withCommands(Generate.class);
Generate generate = (Generate) builder.build().parse(argsToUse);
generate.configurator = configurator;
generate.generator = generator;
try {
generate.run();
} finally {
verify(configurator).setInputSpec(spec);
verify(configurator).setGeneratorName(lang);
verify(configurator).setOutputDir(outputDir);
}
}
@Test
public void testArtifactVersion() {
final String value = "1.2.3";
setupAndRunGenericTest("--artifact-version", value);
verify(configurator).setArtifactVersion(value);
}
@Test
public void testAuthLong() {
final String auth = "hello:world";
setupAndRunGenericTest("--auth", auth);
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verify(configurator).setAuth(auth);
verifyNoMoreInteractions(configurator);
}
@Test
public void testAuthShort() {
final String auth = "hello:world";
setupAndRunGenericTest("-a", auth);
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verify(configurator).setAuth(auth);
verifyNoMoreInteractions(configurator);
}
@Test
public void testAuthUnspecified() {
setupAndRunGenericTest();
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verify(configurator, never()).setAuth(anyString());
verifyNoMoreInteractions(configurator);
}
@Test
public void testConfigJsonLong() {
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
"config.json", "--config", "config.json");
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
@Test
public void testConfigJsonShort() {
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
"config.json", "-c", "config.json");
// on top of those in setupAndRunTest
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
@Test
public void testConfigYamlLong() {
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
"config.yaml", "--config", "config.yaml");
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
@Test
public void testConfigYamlShort() {
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", true,
"config.yaml", "-c", "config.yaml");
// on top of those in setupAndRunTest
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
@Test
public void testGroupId() {
final String value = "io.foo.bar.api";
setupAndRunGenericTest("--group-id", value);
verify(configurator).setGroupId(value);
}
@Test
public void testImportMappingsLong() {
setupAndRunGenericTest("--import-mappings", "hello=world,key=,foo=bar,key2");
verify(configurator).addImportMapping("hello", "world");
verify(configurator).addImportMapping("foo", "bar");
verify(configurator).addImportMapping("key", "");
verify(configurator).addImportMapping("key2", "");
}
@Test
public void testImportMappingsLongMultiple() {
setupAndRunGenericTest("--import-mappings", "hello=world", "--import-mappings", "key=",
"--import-mappings", "foo=bar", "--import-mappings", "key2");
verify(configurator).addImportMapping("hello", "world");
verify(configurator).addImportMapping("foo", "bar");
verify(configurator).addImportMapping("key", "");
verify(configurator).addImportMapping("key2", "");
}
@Test
public void testInstantiationTypesLong() {
setupAndRunGenericTest("--instantiation-types", "hello=world,key=,foo=bar,key2");
verify(configurator).addInstantiationType("hello", "world");
verify(configurator).addInstantiationType("foo", "bar");
verify(configurator).addInstantiationType("key", "");
verify(configurator).addInstantiationType("key2", "");
}
@Test
public void testInstantiationTypesLongMultiple() {
setupAndRunGenericTest("--instantiation-types", "hello=world", "--instantiation-types",
"key=", "--instantiation-types", "foo=bar", "--instantiation-types", "key2");
verify(configurator).addInstantiationType("hello", "world");
verify(configurator).addInstantiationType("foo", "bar");
verify(configurator).addInstantiationType("key", "");
verify(configurator).addInstantiationType("key2", "");
}
@Test
public void testInvokerPackage() {
final String value = "io.foo.bar.api";
setupAndRunGenericTest("--invoker-package", value);
verify(configurator).setInvokerPackage(value);
}
@Test
public void testLanguageSpecificPrimitives() {
setupAndRunGenericTest("--language-specific-primitives", "foo,,bar",
"--language-specific-primitives", "hello,world");
verify(configurator).addLanguageSpecificPrimitive("foo");
verify(configurator).addLanguageSpecificPrimitive("bar");
verify(configurator).addLanguageSpecificPrimitive("hello");
verify(configurator).addLanguageSpecificPrimitive("world");
}
@Test
public void testLibrary() {
final String value = "feign";
setupAndRunGenericTest("--library", value);
verify(configurator).setLibrary(value);
}
@Test
public void testModelPackage() {
final String value = "io.foo.bar.api";
setupAndRunGenericTest("--model-package", value);
verify(configurator).setModelPackage(value);
}
@Test
public void testPackageName() {
final String value = "io.foo.bar.baz";
setupAndRunGenericTest("--package-name", value);
verify(configurator).setPackageName(value);
}
@Test
public void testRequiredArgs_LongArgs() {
setupAndRunTest("--input-spec", "src/test/resources/swagger.yaml", "--generator-name", "java", "--output",
"src/main/java", false, null);
// on top of those in setupAndRunTest:
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
@Test
public void testRequiredArgs_ShortArgs() {
setupAndRunTest("-i", "src/test/resources/swagger.yaml", "-g", "java", "-o", "src/main/java", false, null, "-p", "foo=bar");
verify(configurator).addAdditionalProperty("foo", "bar");
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
@Test
public void testSkipOverwriteLong() {
setupAndRunGenericTest("--skip-overwrite");
verify(configurator).setSkipOverwrite(true);
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
@Test
public void testSkipOverwriteShort() {
setupAndRunGenericTest("-s");
verify(configurator).setSkipOverwrite(true);
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
@Test
public void testStrictSpecFalse() {
setupAndRunGenericTest("--strict-spec", "false");
verify(configurator).setStrictSpecBehavior(false);
}
@Test
public void testStrictSpecTrue() {
setupAndRunGenericTest("--strict-spec", "true");
verify(configurator).setStrictSpecBehavior(true);
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@Test
public void testTemplateDirLong() {
final String templateDir = "src/main/resources/customTemplates";
File f = outputDirectory.resolve(templateDir).toFile();
try {
f.mkdirs();
setupAndRunGenericTest("--template-dir", f.getAbsolutePath());
verify(configurator).setTemplateDir(f.getAbsolutePath());
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
} finally {
if(!f.delete()) {
System.out.println("Directory didn't delete. You can ignore this.");
}
}
}
@Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Template directory src/main/resources/customTemplates does not exist.")
public void testTemplateDirMustExist() {
final String templateDir = "src/main/resources/customTemplates";
setupAndRunGenericTest("-t", templateDir);
fail("Expected exception was not thrown.");
}
@SuppressWarnings("ResultOfMethodCallIgnored")
@Test
public void testTemplateDirShort() {
final String templateDir = "src/main/resources/customTemplates";
File f = outputDirectory.resolve(templateDir).toFile();
try {
f.mkdirs();
setupAndRunGenericTest("-t", f.getAbsolutePath());
} finally {
verify(configurator).setTemplateDir(f.getAbsolutePath());
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
if(!f.delete()) {
System.out.println("Directory didn't delete. You can ignore this.");
}
}
}
@Test
public void testTypeMappingsLong() {
setupAndRunGenericTest("--type-mappings", "hello=world,key=,foo=bar,key2");
verify(configurator).addTypeMapping("hello", "world");
verify(configurator).addTypeMapping("foo", "bar");
verify(configurator).addTypeMapping("key", "");
verify(configurator).addTypeMapping("key2", "");
}
@Test
public void testTypeMappingsLongMultiple() {
setupAndRunGenericTest("--type-mappings", "hello=world", "--type-mappings", "key=",
"--type-mappings", "foo=bar", "--type-mappings", "key2");
verify(configurator).addTypeMapping("hello", "world");
verify(configurator).addTypeMapping("foo", "bar");
verify(configurator).addTypeMapping("key", "");
verify(configurator).addTypeMapping("key2", "");
}
@Test
public void testVerboseLong() {
setupAndRunGenericTest("--verbose");
verify(configurator).setVerbose(true);
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
@Test
public void testVerboseShort() {
setupAndRunGenericTest("-v");
verify(configurator).setVerbose(true);
verify(configurator).toClientOptInput();
verify(configurator).toContext();
verifyNoMoreInteractions(configurator);
}
}

View File

@@ -0,0 +1,7 @@
{
"serializableModel": true,
"withXml": true,
"dateLibrary": "java8",
"java8": true,
"useBeanValidation": true
}

View File

@@ -0,0 +1,6 @@
---
serializableModel: true
withXml: true
dateLibrary: java8
java8: true
useBeanValidation: true

View File

@@ -0,0 +1,8 @@
---
"!include": common/jaxrs-datelib-j8.json
generatorName: jaxrs-jersey
inputSpec: batch/specs/petstore.yaml
outputDir: outputDir
additionalProperties:
hideGenerationTimestamp: true
serverPort: '8082'

View File

@@ -0,0 +1,10 @@
{
"!include": "common/jaxrs-datelib-j8.yaml",
"generatorName": "jaxrs-jersey",
"inputSpec": "batch/specs/petstore.yaml",
"outputDir": "outputDir",
"additionalProperties": {
"hideGenerationTimestamp": true,
"serverPort": "8082"
}
}

View File

@@ -0,0 +1,10 @@
{
"!include": "common/jaxrs-datelib-j8.json",
"generatorName": "jaxrs-jersey",
"inputSpec": "batch/specs/petstore.yaml",
"outputDir": "outputDir",
"additionalProperties": {
"hideGenerationTimestamp": true,
"serverPort": "8082"
}
}

View File

@@ -0,0 +1,8 @@
---
"!include": common/jaxrs-datelib-j8.yaml
generatorName: jaxrs-jersey
inputSpec: batch/specs/petstore.yaml
outputDir: outputDir
additionalProperties:
hideGenerationTimestamp: true
serverPort: '8082'

View File

@@ -0,0 +1,111 @@
openapi: "3.0.0"
info:
version: 1.0.0
title: Swagger Petstore
license:
name: MIT
servers:
- url: http://petstore.swagger.io/v1
paths:
/pets:
get:
summary: List all pets
operationId: listPets
tags:
- pets
parameters:
- name: limit
in: query
description: How many items to return at one time (max 100)
required: false
schema:
type: integer
format: int32
responses:
'200':
description: A paged array of pets
headers:
x-next:
description: A link to the next page of responses
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/Pets"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
post:
summary: Create a pet
operationId: createPets
tags:
- pets
responses:
'201':
description: Null response
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
/pets/{petId}:
get:
summary: Info for a specific pet
operationId: showPetById
tags:
- pets
parameters:
- name: petId
in: path
required: true
description: The id of the pet to retrieve
schema:
type: string
responses:
'200':
description: Expected response to a valid request
content:
application/json:
schema:
$ref: "#/components/schemas/Pet"
default:
description: unexpected error
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
schemas:
Pet:
type: object
required:
- id
- name
properties:
id:
type: integer
format: int64
name:
type: string
tag:
type: string
Pets:
type: array
items:
$ref: "#/components/schemas/Pet"
Error:
type: object
required:
- code
- message
properties:
code:
type: integer
format: int32
message:
type: string