mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-09 16:56:09 +00:00
Merge remote-tracking branch 'origin/master' into 5.0.x
This commit is contained in:
@@ -16,6 +16,18 @@
|
||||
<name>openapi-generator-core</name>
|
||||
<url>https://github.com/openapitools/openapi-generator</url>
|
||||
|
||||
<build>
|
||||
<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>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
@@ -34,6 +46,31 @@
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<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>
|
||||
|
||||
<properties>
|
||||
<slf4j-version>1.7.12</slf4j-version>
|
||||
<guava-version>26.0-jre</guava-version>
|
||||
|
||||
@@ -21,6 +21,9 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -406,15 +409,29 @@ public class WorkflowSettings {
|
||||
*/
|
||||
public Builder withTemplateDir(String templateDir) {
|
||||
if (templateDir != null) {
|
||||
URI uri = null;
|
||||
File f = new File(templateDir);
|
||||
|
||||
// check to see if the folder exists
|
||||
if (!(f.exists() && f.isDirectory())) {
|
||||
if (f.exists() && f.isDirectory()) {
|
||||
uri = f.toURI();
|
||||
this.templateDir = Paths.get(uri).toAbsolutePath().toString();
|
||||
} else {
|
||||
URL url = this.getClass().getClassLoader().getResource(templateDir);
|
||||
if (url != null) {
|
||||
try {
|
||||
uri = url.toURI();
|
||||
this.templateDir = templateDir;
|
||||
} catch (URISyntaxException e) {
|
||||
LOGGER.warn("The requested template was found on the classpath, but resulted in a syntax error.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uri == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Template directory " + templateDir + " does not exist.");
|
||||
}
|
||||
|
||||
this.templateDir = Paths.get(f.toURI()).toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
|
||||
package org.openapitools.codegen.meta;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.openapitools.codegen.meta.features.*;
|
||||
import org.openapitools.codegen.meta.features.annotations.AnnotationType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -178,6 +180,167 @@ public class FeatureSet {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a flattened or "normalized" view of the featureSet. This is for simplifying user-facing display only.
|
||||
*/
|
||||
public static class FeatureSetFlattened {
|
||||
String featureCategory;
|
||||
String featureName;
|
||||
boolean isSupported;
|
||||
|
||||
List<AnnotationType> source = new ArrayList<>(3);
|
||||
|
||||
public String getFeatureCategory() {
|
||||
return featureCategory;
|
||||
}
|
||||
|
||||
public String getFeatureName() {
|
||||
return featureName;
|
||||
}
|
||||
|
||||
public boolean isSupported() {
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
public List<AnnotationType> getSource() {
|
||||
return ImmutableList.copyOf(source);
|
||||
}
|
||||
}
|
||||
|
||||
public List<FeatureSetFlattened> flatten() {
|
||||
// TODO: Look at making this method function more generically.
|
||||
List<FeatureSetFlattened> states = new ArrayList<>();
|
||||
EnumSet.allOf(ClientModificationFeature.class).forEach(feat -> {
|
||||
FeatureSetFlattened state = new FeatureSetFlattened();
|
||||
state.featureCategory = ClientModificationFeature.class.getSimpleName();
|
||||
state.featureName = feat.name();
|
||||
state.isSupported = this.clientModificationFeatures.contains(feat);
|
||||
|
||||
try {
|
||||
for (Annotation an : ClientModificationFeature.class.getField(feat.name()).getAnnotations()) {
|
||||
state.source.add(AnnotationType.fromAnnotation(an.annotationType()));
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
states.add(state);
|
||||
});
|
||||
EnumSet.allOf(DataTypeFeature.class).forEach(feat -> {
|
||||
FeatureSetFlattened state = new FeatureSetFlattened();
|
||||
state.featureCategory = DataTypeFeature.class.getSimpleName();
|
||||
state.featureName = feat.name();
|
||||
state.isSupported = this.dataTypeFeatures.contains(feat);
|
||||
|
||||
try {
|
||||
for (Annotation an : DataTypeFeature.class.getField(feat.name()).getAnnotations()) {
|
||||
state.source.add(AnnotationType.fromAnnotation(an.annotationType()));
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
states.add(state);
|
||||
});
|
||||
EnumSet.allOf(DocumentationFeature.class).forEach(feat -> {
|
||||
FeatureSetFlattened state = new FeatureSetFlattened();
|
||||
state.featureCategory = DocumentationFeature.class.getSimpleName();
|
||||
state.featureName = feat.name();
|
||||
state.isSupported = this.documentationFeatures.contains(feat);
|
||||
|
||||
try {
|
||||
for (Annotation an : DocumentationFeature.class.getField(feat.name()).getAnnotations()) {
|
||||
state.source.add(AnnotationType.fromAnnotation(an.annotationType()));
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
states.add(state);
|
||||
});
|
||||
EnumSet.allOf(SchemaSupportFeature.class).forEach(feat -> {
|
||||
FeatureSetFlattened state = new FeatureSetFlattened();
|
||||
state.featureCategory = SchemaSupportFeature.class.getSimpleName();
|
||||
state.featureName = feat.name();
|
||||
state.isSupported = this.schemaSupportFeatures.contains(feat);
|
||||
|
||||
try {
|
||||
for (Annotation an : SchemaSupportFeature.class.getField(feat.name()).getAnnotations()) {
|
||||
state.source.add(AnnotationType.fromAnnotation(an.annotationType()));
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
states.add(state);
|
||||
});
|
||||
EnumSet.allOf(GlobalFeature.class).forEach(feat -> {
|
||||
FeatureSetFlattened state = new FeatureSetFlattened();
|
||||
state.featureCategory = GlobalFeature.class.getSimpleName();
|
||||
state.featureName = feat.name();
|
||||
state.isSupported = this.globalFeatures.contains(feat);
|
||||
|
||||
try {
|
||||
for (Annotation an : GlobalFeature.class.getField(feat.name()).getAnnotations()) {
|
||||
state.source.add(AnnotationType.fromAnnotation(an.annotationType()));
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
states.add(state);
|
||||
});
|
||||
EnumSet.allOf(ParameterFeature.class).forEach(feat -> {
|
||||
FeatureSetFlattened state = new FeatureSetFlattened();
|
||||
state.featureCategory = ParameterFeature.class.getSimpleName();
|
||||
state.featureName = feat.name();
|
||||
state.isSupported = this.parameterFeatures.contains(feat);
|
||||
|
||||
try {
|
||||
for (Annotation an : ParameterFeature.class.getField(feat.name()).getAnnotations()) {
|
||||
state.source.add(AnnotationType.fromAnnotation(an.annotationType()));
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
states.add(state);
|
||||
});
|
||||
EnumSet.allOf(SecurityFeature.class).forEach(feat -> {
|
||||
FeatureSetFlattened state = new FeatureSetFlattened();
|
||||
state.featureCategory = SecurityFeature.class.getSimpleName();
|
||||
state.featureName = feat.name();
|
||||
state.isSupported = this.securityFeatures.contains(feat);
|
||||
|
||||
try {
|
||||
for (Annotation an : SecurityFeature.class.getField(feat.name()).getAnnotations()) {
|
||||
state.source.add(AnnotationType.fromAnnotation(an.annotationType()));
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
states.add(state);
|
||||
});
|
||||
EnumSet.allOf(WireFormatFeature.class).forEach(feat -> {
|
||||
FeatureSetFlattened state = new FeatureSetFlattened();
|
||||
state.featureCategory = WireFormatFeature.class.getSimpleName();
|
||||
state.featureName = feat.name();
|
||||
state.isSupported = this.wireFormatFeatures.contains(feat);
|
||||
|
||||
try {
|
||||
for (Annotation an : WireFormatFeature.class.getField(feat.name()).getAnnotations()) {
|
||||
state.source.add(AnnotationType.fromAnnotation(an.annotationType()));
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
states.add(state);
|
||||
});
|
||||
|
||||
return states;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@code FeatureSet} builder static inner class.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package org.openapitools.codegen.meta.features.annotations;
|
||||
|
||||
public enum AnnotationType {
|
||||
OAS2, OAS3, ToolingExtension;
|
||||
|
||||
public static AnnotationType fromAnnotation(Class<?> input) {
|
||||
if(input == OAS2.class) return AnnotationType.OAS2;
|
||||
if(input == OAS3.class) return AnnotationType.OAS3;
|
||||
if(input == ToolingExtension.class) return AnnotationType.ToolingExtension;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,8 @@ import java.util.List;
|
||||
*
|
||||
* @param <TInput> The type of object being evaluated.
|
||||
*/
|
||||
@SuppressWarnings({"WeakerAccess"})
|
||||
public class GenericValidator<TInput> implements Validator<TInput> {
|
||||
private List<ValidationRule> rules;
|
||||
protected List<ValidationRule> rules;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@link GenericValidator}.
|
||||
@@ -48,11 +47,11 @@ public class GenericValidator<TInput> implements Validator<TInput> {
|
||||
ValidationResult result = new ValidationResult();
|
||||
if (rules != null) {
|
||||
rules.forEach(it -> {
|
||||
boolean passes = it.evaluate(input);
|
||||
if (passes) {
|
||||
ValidationRule.Result attempt = it.evaluate(input);
|
||||
if (attempt.passed()) {
|
||||
result.addResult(Validated.valid(it));
|
||||
} else {
|
||||
result.addResult(Validated.invalid(it, it.getFailureMessage()));
|
||||
result.addResult(Validated.invalid(it, it.getFailureMessage(), attempt.getDetails()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ package org.openapitools.codegen.validation;
|
||||
public final class Invalid extends Validated {
|
||||
private String message;
|
||||
private ValidationRule rule;
|
||||
private String details;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Invalid} instance.
|
||||
@@ -35,13 +36,29 @@ public final class Invalid extends Validated {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link Invalid} instance.
|
||||
*
|
||||
* @param rule The rule which was evaluated and resulted in this state.
|
||||
* @param message The message to be displayed for this invalid state.
|
||||
* @param details Additional contextual details related to the invalid state.
|
||||
*/
|
||||
public Invalid(ValidationRule rule, String message, String details) {
|
||||
this(rule, message);
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public String getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getMessage() {
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
ValidationRule getRule() {
|
||||
public ValidationRule getRule() {
|
||||
return rule;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,18 @@ public abstract class Validated {
|
||||
public static Validated invalid(ValidationRule rule, String message) {
|
||||
return new Invalid(rule, message);
|
||||
}
|
||||
/**
|
||||
* Creates an instance of an {@link Invalid} validation state.
|
||||
*
|
||||
* @param rule The rule which was evaluated.
|
||||
* @param message The message to display to a user.
|
||||
* @param details Additional contextual details related to the invalid state.
|
||||
*
|
||||
* @return A {@link Validated} instance representing an invalid state according to the rule.
|
||||
*/
|
||||
public static Validated invalid(ValidationRule rule, String message, String details) {
|
||||
return new Invalid(rule, message, details);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance of an {@link Valid} validation state.
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* Encapsulates details about the result of a validation test.
|
||||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public final class ValidationResult {
|
||||
private final List<Validated> validations;
|
||||
|
||||
@@ -96,9 +95,16 @@ public final class ValidationResult {
|
||||
public void addResult(Validated validated) {
|
||||
synchronized (validations) {
|
||||
ValidationRule rule = validated.getRule();
|
||||
if (rule != null && !rule.equals(ValidationRule.empty())) {
|
||||
if (rule != null && !rule.equals(ValidationRule.empty()) && !validations.contains(validated)) {
|
||||
validations.add(validated);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ValidationResult consume(ValidationResult other) {
|
||||
synchronized (validations) {
|
||||
validations.addAll(other.validations);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class ValidationRule {
|
||||
private Severity severity;
|
||||
private String description;
|
||||
private String failureMessage;
|
||||
private Function<Object, Boolean> test;
|
||||
private Function<Object, Result> test;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@link ValidationRule}
|
||||
@@ -37,7 +37,7 @@ public class ValidationRule {
|
||||
* @param test The test condition to be applied as a part of this rule, when this function returns <code>true</code>,
|
||||
* the evaluated instance will be considered "valid" according to this rule.
|
||||
*/
|
||||
ValidationRule(Severity severity, String description, String failureMessage, Function<Object, Boolean> test) {
|
||||
ValidationRule(Severity severity, String description, String failureMessage, Function<Object, Result> test) {
|
||||
this.severity = severity;
|
||||
this.description = description;
|
||||
this.failureMessage = failureMessage;
|
||||
@@ -60,7 +60,7 @@ public class ValidationRule {
|
||||
*
|
||||
* @return <code>true</code> if the object state is valid according to this rule, otherwise <code>false</code>.
|
||||
*/
|
||||
public boolean evaluate(Object input) {
|
||||
public Result evaluate(Object input) {
|
||||
return test.apply(input);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class ValidationRule {
|
||||
* @return An "empty" rule.
|
||||
*/
|
||||
static ValidationRule empty() {
|
||||
return new ValidationRule(Severity.ERROR, "empty", "failure message", (i) -> false);
|
||||
return new ValidationRule(Severity.ERROR, "empty", "failure message", (i) -> Fail.empty() );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,8 +106,8 @@ public class ValidationRule {
|
||||
* @return A new instance of a {@link ValidationRule}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> ValidationRule create(Severity severity, String description, String failureMessage, Function<T, Boolean> fn) {
|
||||
return new ValidationRule(severity, description, failureMessage, (Function<Object, Boolean>) fn);
|
||||
public static <T> ValidationRule create(Severity severity, String description, String failureMessage, Function<T, Result> fn) {
|
||||
return new ValidationRule(severity, description, failureMessage, (Function<Object, Result>) fn);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,8 +121,8 @@ public class ValidationRule {
|
||||
* @return A new instance of a {@link ValidationRule}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> ValidationRule error(String failureMessage, Function<T, Boolean> fn) {
|
||||
return new ValidationRule(Severity.ERROR, null, failureMessage, (Function<Object, Boolean>) fn);
|
||||
public static <T> ValidationRule error(String failureMessage, Function<T, Result> fn) {
|
||||
return new ValidationRule(Severity.ERROR, null, failureMessage, (Function<Object, Result>) fn);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,8 +137,8 @@ public class ValidationRule {
|
||||
* @return A new instance of a {@link ValidationRule}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> ValidationRule warn(String description, String failureMessage, Function<T, Boolean> fn) {
|
||||
return new ValidationRule(Severity.WARNING, description, failureMessage, (Function<Object, Boolean>) fn);
|
||||
public static <T> ValidationRule warn(String description, String failureMessage, Function<T, Result> fn) {
|
||||
return new ValidationRule(Severity.WARNING, description, failureMessage, (Function<Object, Result>) fn);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -149,4 +149,69 @@ public class ValidationRule {
|
||||
", failureMessage='" + failureMessage + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public static abstract class Result {
|
||||
protected String details = null;
|
||||
protected Throwable throwable = null;
|
||||
|
||||
public String getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public void setDetails(String details) {
|
||||
assert this.details == null;
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public abstract boolean passed();
|
||||
public final boolean failed() { return !passed(); }
|
||||
|
||||
public Throwable getThrowable() {
|
||||
return throwable;
|
||||
}
|
||||
|
||||
public boolean thrown() { return this.throwable == null; }
|
||||
}
|
||||
|
||||
public static final class Pass extends Result {
|
||||
public static Result empty() { return new Pass(); }
|
||||
|
||||
public Pass() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Pass(String details) {
|
||||
this();
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passed() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Fail extends Result {
|
||||
public static Result empty() { return new Fail(); }
|
||||
|
||||
public Fail() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Fail(String details) {
|
||||
this();
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public Fail(String details, Throwable throwable) {
|
||||
this();
|
||||
this.throwable = throwable;
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean passed() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package org.openapitools.codegen.meta;
|
||||
|
||||
import org.openapitools.codegen.meta.features.*;
|
||||
import org.openapitools.codegen.meta.features.annotations.AnnotationType;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
public class FeatureSetTest {
|
||||
|
||||
@Test
|
||||
public void flattOnUnspecified() {
|
||||
List<FeatureSet.FeatureSetFlattened> flattened = FeatureSet.UNSPECIFIED.flatten();
|
||||
// There are 73 features at the time of writing this test. This makes sure we get a "Full" flat representation.
|
||||
int knownFeatureCount = 73;
|
||||
int checkedCount = 0;
|
||||
assertTrue(flattened.size() >= knownFeatureCount);
|
||||
|
||||
for (FeatureSet.FeatureSetFlattened f : flattened) {
|
||||
checkedCount += 1;
|
||||
assertFalse(f.isSupported);
|
||||
}
|
||||
|
||||
assertTrue(checkedCount >= knownFeatureCount);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flattenOnMultipleFeatures() {
|
||||
FeatureSet featureSet = FeatureSet.newBuilder()
|
||||
.includeClientModificationFeatures(ClientModificationFeature.BasePath)
|
||||
.includeDataTypeFeatures(DataTypeFeature.Int32, DataTypeFeature.Array)
|
||||
.includeGlobalFeatures(GlobalFeature.Consumes, GlobalFeature.Examples)
|
||||
.includeParameterFeatures(ParameterFeature.Body, ParameterFeature.Query)
|
||||
.includeSecurityFeatures(SecurityFeature.BearerToken, SecurityFeature.BasicAuth, SecurityFeature.OAuth2_Implicit)
|
||||
.includeDocumentationFeatures(DocumentationFeature.Model)
|
||||
.includeSchemaSupportFeatures(SchemaSupportFeature.Composite)
|
||||
.build();
|
||||
|
||||
List<FeatureSet.FeatureSetFlattened> flattened = featureSet.flatten();
|
||||
List<FeatureSet.FeatureSetFlattened> supported = new ArrayList<>();
|
||||
flattened.forEach(f -> {
|
||||
if (f.isSupported) {
|
||||
supported.add(f);
|
||||
}
|
||||
});
|
||||
|
||||
// note that the order of these checks is deterministic, but unrelated to feature inclusion order in this test.
|
||||
assertEquals(supported.size(), 12);
|
||||
|
||||
Set<AnnotationType> toolingOnly = new HashSet<AnnotationType>() {{
|
||||
add(AnnotationType.ToolingExtension);
|
||||
}};
|
||||
Set<AnnotationType> oas2Only = new HashSet<AnnotationType>() {{
|
||||
add(AnnotationType.OAS2);
|
||||
}};
|
||||
Set<AnnotationType> oas3Only = new HashSet<AnnotationType>() {{
|
||||
add(AnnotationType.OAS3);
|
||||
}};
|
||||
Set<AnnotationType> bothSpecs = new HashSet<AnnotationType>() {{
|
||||
add(AnnotationType.OAS2);
|
||||
add(AnnotationType.OAS3);
|
||||
}};
|
||||
|
||||
assertEquals(supported.get(0).featureCategory, ClientModificationFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(0).featureName, ClientModificationFeature.BasePath.name());
|
||||
assertEquals(new HashSet<>(supported.get(0).source), toolingOnly);
|
||||
|
||||
assertEquals(supported.get(1).featureCategory, DataTypeFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(1).featureName, DataTypeFeature.Int32.name());
|
||||
assertEquals(new HashSet<>(supported.get(1).source), bothSpecs);
|
||||
|
||||
assertEquals(supported.get(2).featureCategory, DataTypeFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(2).featureName, DataTypeFeature.Array.name());
|
||||
assertEquals(new HashSet<>(supported.get(2).source), bothSpecs);
|
||||
|
||||
assertEquals(supported.get(3).featureCategory, DocumentationFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(3).featureName, DocumentationFeature.Model.name());
|
||||
assertEquals(new HashSet<>(supported.get(3).source), toolingOnly);
|
||||
|
||||
assertEquals(supported.get(4).featureCategory, SchemaSupportFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(4).featureName, SchemaSupportFeature.Composite.name());
|
||||
assertEquals(new HashSet<>(supported.get(4).source), bothSpecs);
|
||||
|
||||
assertEquals(supported.get(5).featureCategory, GlobalFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(5).featureName, GlobalFeature.Consumes.name());
|
||||
assertEquals(new HashSet<>(supported.get(5).source), oas2Only);
|
||||
|
||||
assertEquals(supported.get(6).featureCategory, GlobalFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(6).featureName, GlobalFeature.Examples.name());
|
||||
assertEquals(new HashSet<>(supported.get(6).source), bothSpecs);
|
||||
|
||||
assertEquals(supported.get(7).featureCategory, ParameterFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(7).featureName, ParameterFeature.Query.name());
|
||||
assertEquals(new HashSet<>(supported.get(7).source), bothSpecs);
|
||||
|
||||
assertEquals(supported.get(8).featureCategory, ParameterFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(8).featureName, ParameterFeature.Body.name());
|
||||
assertEquals(new HashSet<>(supported.get(8).source), oas2Only);
|
||||
|
||||
assertEquals(supported.get(9).featureCategory, SecurityFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(9).featureName, SecurityFeature.BasicAuth.name());
|
||||
assertEquals(new HashSet<>(supported.get(9).source), bothSpecs);
|
||||
|
||||
assertEquals(supported.get(10).featureCategory, SecurityFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(10).featureName, SecurityFeature.BearerToken.name());
|
||||
assertEquals(new HashSet<>(supported.get(10).source), oas3Only);
|
||||
|
||||
assertEquals(supported.get(11).featureCategory, SecurityFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(11).featureName, SecurityFeature.OAuth2_Implicit.name());
|
||||
assertEquals(new HashSet<>(supported.get(11).source), bothSpecs);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flattenOnSingleFeatures() {
|
||||
FeatureSet featureSet = FeatureSet.newBuilder().includeClientModificationFeatures(ClientModificationFeature.BasePath).build();
|
||||
List<FeatureSet.FeatureSetFlattened> flattened = featureSet.flatten();
|
||||
List<FeatureSet.FeatureSetFlattened> supported = new ArrayList<>();
|
||||
flattened.forEach(f -> {
|
||||
if (f.isSupported) {
|
||||
supported.add(f);
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(supported.size(), 1);
|
||||
assertEquals(supported.get(0).featureCategory, ClientModificationFeature.class.getSimpleName());
|
||||
assertEquals(supported.get(0).featureName, ClientModificationFeature.BasePath.name());
|
||||
assertEquals(new HashSet<>(supported.get(0).source), new HashSet<AnnotationType>() {{
|
||||
add(AnnotationType.ToolingExtension);
|
||||
}});
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class GenericValidatorTest {
|
||||
class Person {
|
||||
static class Person {
|
||||
private int age;
|
||||
private String name;
|
||||
|
||||
@@ -35,33 +35,33 @@ public class GenericValidatorTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isValidAge(Person person) {
|
||||
return person.age > 0;
|
||||
private static ValidationRule.Result checkAge(Person person) {
|
||||
return person.age > 0 ? ValidationRule.Pass.empty() : ValidationRule.Fail.empty();
|
||||
}
|
||||
|
||||
private static boolean isAdult(Person person) {
|
||||
return person.age > 18;
|
||||
private static ValidationRule.Result checkAdult(Person person) {
|
||||
return person.age > 18 ? ValidationRule.Pass.empty() : ValidationRule.Fail.empty();
|
||||
}
|
||||
|
||||
private static boolean isNameSet(Person person) {
|
||||
return person.name != null && person.name.length() > 0;
|
||||
private static ValidationRule.Result checkName(Person person) {
|
||||
return (person.name != null && person.name.length() > 0) ? ValidationRule.Pass.empty() : ValidationRule.Fail.empty();
|
||||
}
|
||||
|
||||
private static boolean isNameValid(Person person) {
|
||||
private static ValidationRule.Result checkNamePattern(Person person) {
|
||||
String pattern = "^[A-Z][a-z]*$";
|
||||
return person.name.matches(pattern);
|
||||
return person.name.matches(pattern) ? ValidationRule.Pass.empty() : ValidationRule.Fail.empty();
|
||||
}
|
||||
|
||||
private static boolean isNameNormalLength(Person person) {
|
||||
return person.name.length() < 10;
|
||||
private static ValidationRule.Result checkNameNormalLength(Person person) {
|
||||
return person.name.length() < 10? ValidationRule.Pass.empty() : ValidationRule.Fail.empty();
|
||||
}
|
||||
|
||||
private List<ValidationRule> validationRules = Arrays.asList(
|
||||
ValidationRule.error("Age must be positive and more than zero", GenericValidatorTest::isValidAge),
|
||||
ValidationRule.error("Only adults (18 years old and older)", GenericValidatorTest::isAdult),
|
||||
ValidationRule.error("Name isn't set!", GenericValidatorTest::isNameSet),
|
||||
ValidationRule.error("Name isn't formatted correct", GenericValidatorTest::isNameValid),
|
||||
ValidationRule.warn("Name too long?", "Name may be too long.", GenericValidatorTest::isNameNormalLength)
|
||||
ValidationRule.error("Age must be positive and more than zero", GenericValidatorTest::checkAge),
|
||||
ValidationRule.error("Only adults (18 years old and older)", GenericValidatorTest::checkAdult),
|
||||
ValidationRule.error("Name isn't set!", GenericValidatorTest::checkName),
|
||||
ValidationRule.error("Name isn't formatted correct", GenericValidatorTest::checkNamePattern),
|
||||
ValidationRule.warn("Name too long?", "Name may be too long.", GenericValidatorTest::checkNameNormalLength)
|
||||
);
|
||||
|
||||
@Test
|
||||
|
||||
@@ -33,13 +33,13 @@ public class ValidationRuleTest {
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean checkName(Sample input) {
|
||||
return input.getName() != null && input.getName().length() > 7;
|
||||
private static ValidationRule.Result checkName(Sample input) {
|
||||
return (input.getName() != null && input.getName().length() > 7) ? ValidationRule.Pass.empty() : ValidationRule.Fail.empty();
|
||||
}
|
||||
|
||||
private static boolean checkPattern(Sample input) {
|
||||
private static ValidationRule.Result checkPattern(Sample input) {
|
||||
String pattern = "^[A-Z][a-z]*$";
|
||||
return input.getName() != null && input.getName().matches(pattern);
|
||||
return (input.getName() != null && input.getName().matches(pattern)) ? ValidationRule.Pass.empty() : ValidationRule.Fail.empty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -49,10 +49,10 @@ public class ValidationRuleTest {
|
||||
Sample seven = new Sample("1234567");
|
||||
Sample eight = new Sample("12345678");
|
||||
ValidationRule result = ValidationRule.error("test", ValidationRuleTest::checkName);
|
||||
assertFalse(result.evaluate(nil));
|
||||
assertFalse(result.evaluate(six));
|
||||
assertFalse(result.evaluate(seven));
|
||||
assertTrue(result.evaluate(eight));
|
||||
assertFalse(result.evaluate(nil).passed());
|
||||
assertFalse(result.evaluate(six).passed());
|
||||
assertFalse(result.evaluate(seven).passed());
|
||||
assertTrue(result.evaluate(eight).passed());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -61,8 +61,8 @@ public class ValidationRuleTest {
|
||||
Sample lowercase = new Sample("jim");
|
||||
Sample titlecase = new Sample("Jim");
|
||||
ValidationRule result = ValidationRule.error("test", i -> checkPattern((Sample)i));
|
||||
assertFalse(result.evaluate(nil));
|
||||
assertFalse(result.evaluate(lowercase));
|
||||
assertTrue(result.evaluate(titlecase));
|
||||
assertFalse(result.evaluate(nil).passed());
|
||||
assertFalse(result.evaluate(lowercase).passed());
|
||||
assertTrue(result.evaluate(titlecase).passed());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user