diff --git a/modules/openapi-generator-core/pom.xml b/modules/openapi-generator-core/pom.xml index a91ac2830f6..5b13385a765 100644 --- a/modules/openapi-generator-core/pom.xml +++ b/modules/openapi-generator-core/pom.xml @@ -15,4 +15,11 @@ openapi-generator-core openapi-generator-core https://github.com/openapitools/openapi-generator + + + org.testng + testng + test + + diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/GenericValidator.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/GenericValidator.java new file mode 100644 index 00000000000..2cac0876053 --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/GenericValidator.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +import java.util.List; + +/** + * A generic implementation of a validator instance which simply applies rules to an input instance. + * + * @param The type of object being evaluated. + */ +@SuppressWarnings({"WeakerAccess"}) +public class GenericValidator implements Validator { + private List rules; + + /** + * Constructs a new instance of {@link GenericValidator}. + * + * @param rules The rules to be evaluated during validation. + */ + public GenericValidator(List rules) { + this.rules = rules; + } + + /** + * Validates input, resulting in a instance of {@link ValidationResult} which provides details on all validations performed (success, error, warning). + * + * @param input The object instance to be validated. + * + * @return A {@link ValidationResult} which details the success, error, and warning validation results. + */ + @Override + public ValidationResult validate(TInput input) { + ValidationResult result = new ValidationResult(); + if (rules != null) { + rules.forEach(it -> { + boolean passes = it.evaluate(input); + if (passes) { + result.addResult(Validated.valid(it)); + } else { + result.addResult(Validated.invalid(it, it.getFailureMessage())); + } + }); + } + return result; + } +} diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Invalid.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Invalid.java new file mode 100644 index 00000000000..2f3745ebf01 --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Invalid.java @@ -0,0 +1,57 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +/** + * Represents a {@link Validated} state which is "Invalid" to some degree of {@link Severity}. + */ +@SuppressWarnings({"WeakerAccess"}) +public final class Invalid extends Validated { + private String message; + private ValidationRule rule; + + /** + * 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. + */ + Invalid(ValidationRule rule, String message) { + this.rule = rule; + this.message = message; + } + + @Override + String getMessage() { + return message; + } + + @Override + ValidationRule getRule() { + return rule; + } + + /** + * Get details about the severity of this invalid state. + * For instance, is this an {@link Severity#ERROR} or simply a {@link Severity#WARNING}. + * + * @return The {@link Severity} enum detailing this state's severity. + */ + public Severity getSeverity() { + return rule.getSeverity(); + } +} diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Severity.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Severity.java new file mode 100644 index 00000000000..7818dfd620a --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Severity.java @@ -0,0 +1,33 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +/** + * Defines different levels of severity to be used during validation. + */ +public enum Severity { + /** + * Lower severity indicating that the target state may be unpredictable, no longer supported, or known to have issues. + * Marking a type with this value should not result in application exceptions under normal operating circumstances. + */ + WARNING, + /** + * Higher severity indicating that the target state is not supported, or is known to cause problems with the application. + * Marking a type with this value should result in an application exception or error exit code under normal operating circumstances. + */ + ERROR +} \ No newline at end of file diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Valid.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Valid.java new file mode 100644 index 00000000000..d31443dca23 --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Valid.java @@ -0,0 +1,53 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +/** + * Represents a {@link Validated} state which is "valid" according to the defined rule. + */ +public final class Valid extends Validated { + private ValidationRule rule; + + /** + * Defines whether or not the validation resulted in a "valid" condition. + * + * @return true if the instance passed validation of the rule returned by {@link Validated#getRule()}. + */ + @Override + boolean isValid() { + return true; + } + + /** + * Constructs a new {@link Valid} instance. + * + * @param rule The rule which was evaluated and resulted in this state. + */ + Valid(ValidationRule rule) { + this.rule = rule; + } + + @Override + public String getMessage() { + return null; + } + + @Override + public ValidationRule getRule() { + return rule; + } +} diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Validated.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Validated.java new file mode 100644 index 00000000000..4800cd9ce75 --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Validated.java @@ -0,0 +1,68 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +/** + * Provides details about the state of a completed validation. + */ +public abstract class Validated { + /** + * Defines whether or not the validation resulted in a "valid" condition. + * + * @return true if the instance passed validation of the rule returned by {@link Validated#getRule()}. + */ + boolean isValid() { + return false; + } + + /** + * Gets the rule which was evaluated and resulted in this state. + * + * @return The instance of {@link ValidationRule} which was evaluated. + */ + abstract ValidationRule getRule(); + + /** + * Gets the message with details about this validated state. + * + * @return A string intended to be displayed to a user. + */ + abstract String getMessage(); + + /** + * 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. + * + * @return A {@link Validated} instance representing an invalid state according to the rule. + */ + public static Validated invalid(ValidationRule rule, String message) { + return new Invalid(rule, message); + } + + /** + * Creates an instance of an {@link Valid} validation state. + * + * @param rule The rule which was evaluated. + * + * @return A {@link Validated} instance representing a valid state according to the rule. + */ + public static Validated valid(ValidationRule rule) { + return new Valid(rule); + } +} diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/ValidationResult.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/ValidationResult.java new file mode 100644 index 00000000000..166ce2b2dff --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/ValidationResult.java @@ -0,0 +1,104 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Encapsulates details about the result of a validation test. + */ +@SuppressWarnings("WeakerAccess") +public final class ValidationResult { + private final List validations; + + /** + * Constructs a new {@link ValidationResult} instance, backed by the provided validations (useful for testing). + * + * @param validations A pre-defined set of validations to begin with. + */ + private ValidationResult(List validations) { + this.validations = Collections.synchronizedList(validations); + } + + /** + * Constructs a new {@link ValidationResult} instance. + */ + public ValidationResult() { + this(new ArrayList<>()); + } + + /** + * Gets all the validated states resulting from the evaluation. This includes all {@link Valid} and {@link Invalid} instances. + * + * @return All validated results. + */ + public List getAll() { + return validations; + } + + /** + * Gets a filtered list of {@link Valid} states. + * + * @return A list containing only {@link Valid} states. + */ + public List getValid(){ + return validations.stream().filter(Validated::isValid).map(it -> (Valid)it).collect(Collectors.toList()); + } + + /** + * Gets a filters list of {@link Invalid} states with the level of {@link Severity#ERROR} + * + * @return A list of all validation errors. + */ + public List getErrors(){ + return validations.stream() + .filter(it -> !it.isValid()) + .map(it -> (Invalid)it) + .filter(it -> it.getSeverity().equals(Severity.ERROR)) + .collect(Collectors.toList()); + } + + /** + * Gets a filtered list of {@link Invalid} states with the level of {@link Severity#WARNING} + * + * @return A list of all validation warnings. + */ + public List getWarnings(){ + return validations.stream() + .filter(it -> !it.isValid()) + .map(it -> (Invalid)it) + .filter(it -> it.getSeverity().equals(Severity.WARNING)) + .collect(Collectors.toList()); + } + + /** + * Adds a validation state to the final results. + * + * @param validated The {@link Valid} or {@link Invalid} instance to add to validations. + */ + public void addResult(Validated validated) { + synchronized (validations) { + ValidationRule rule = validated.getRule(); + if (rule != null && !rule.equals(ValidationRule.empty())) { + validations.add(validated); + } + } + } +} diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/ValidationRule.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/ValidationRule.java new file mode 100644 index 00000000000..b774e8653d4 --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/ValidationRule.java @@ -0,0 +1,152 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +import java.util.function.Function; + +/** + * Defines a rule to be evaluated against some target object. + */ +@SuppressWarnings("WeakerAccess") +public class ValidationRule { + private Severity severity; + private String description; + private String failureMessage; + private Function test; + + /** + * Constructs a new instance of {@link ValidationRule} + * + * @param severity The declared severity if this validation rule fails. + * @param description A description to help differentiate this rule from others (not intended to be user-facing). + * @param failureMessage The message to be displayed in the event of a test failure (intended to be user-facing). + * @param test The test condition to be applied as a part of this rule, when this function returns true, + * the evaluated instance will be considered "valid" according to this rule. + */ + ValidationRule(Severity severity, String description, String failureMessage, Function test) { + this.severity = severity; + this.description = description; + this.failureMessage = failureMessage; + this.test = test; + } + + /** + * Gets the message to be displayed in the event of a test failure (intended to be user-facing). + * + * @return A string message + */ + public String getFailureMessage() { + return failureMessage; + } + + /** + * Evalute an instance of an object against this rule. + * + * @param input The instance to be evaluated. + * + * @return true if the object state is valid according to this rule, otherwise false. + */ + public boolean evaluate(Object input) { + return test.apply(input); + } + + /** + * Get the level of severity which this rule considers a failure in evaluation. For example, if this is {@link Severity#WARNING} and + * a call to {@link ValidationRule#evaluate(Object)} returns false, a user should not expect an error to be thrown under + * normal operation. + * + * @return An enum defining how severe a failure to evaluate this rule should be considered by the caller. + */ + public Severity getSeverity() { + return severity; + } + + /** + * Gets a description to help differentiate this rule from others (not intended to be user-facing). + * + * @return A string description. + */ + public String getDescription() { + return description; + } + + /** + * Constructs an empty rule (useful for testing). + * + * @return An "empty" rule. + */ + static ValidationRule empty() { + return new ValidationRule(Severity.ERROR, "empty", "failure message", (i) -> false); + } + + /** + * Create an instance of a {@link ValidationRule} + * + * @param severity The declared severity if this validation rule fails. + * @param description A description to help differentiate this rule from others (not intended to be user-facing). + * @param failureMessage The message to be displayed in the event of a test failure (intended to be user-facing). + * @param fn The test condition to be applied as a part of this rule, when this function returns true, + * the evaluated instance will be considered "valid" according to this rule. + * @param The type of the object being evaluated. + * + * @return A new instance of a {@link ValidationRule} + */ + @SuppressWarnings("unchecked") + public static ValidationRule create(Severity severity, String description, String failureMessage, Function fn) { + return new ValidationRule(severity, description, failureMessage, (Function) fn); + } + + /** + * Create an instance of a {@link ValidationRule} which should result in an error should the evaluate of this rule fail. + * + * @param failureMessage The message to be displayed in the event of a test failure (intended to be user-facing). + * @param fn The test condition to be applied as a part of this rule, when this function returns true, + * the evaluated instance will be considered "valid" according to this rule. + * @param The type of the object being evaluated. + * + * @return A new instance of a {@link ValidationRule} + */ + @SuppressWarnings("unchecked") + public static ValidationRule error(String failureMessage, Function fn) { + return new ValidationRule(Severity.ERROR, null, failureMessage, (Function) fn); + } + + /** + * Create an instance of a {@link ValidationRule} which should result in a warning should the evaluate of this rule fail. + * + * @param description A description to help differentiate this rule from others (not intended to be user-facing). + * @param failureMessage The message to be displayed in the event of a test failure (intended to be user-facing). + * @param fn The test condition to be applied as a part of this rule, when this function returns true, + * the evaluated instance will be considered "valid" according to this rule. + * @param The type of the object being evaluated. + * + * @return A new instance of a {@link ValidationRule} + */ + @SuppressWarnings("unchecked") + public static ValidationRule warn(String description, String failureMessage, Function fn) { + return new ValidationRule(Severity.WARNING, description, failureMessage, (Function) fn); + } + + @Override + public String toString() { + return "ValidationRule{" + + "severity=" + severity + + ", description='" + description + '\'' + + ", failureMessage='" + failureMessage + '\'' + + '}'; + } +} diff --git a/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Validator.java b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Validator.java new file mode 100644 index 00000000000..a47e829fe6a --- /dev/null +++ b/modules/openapi-generator-core/src/main/java/org/openapitools/codegen/validation/Validator.java @@ -0,0 +1,34 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +/** + * Defines a contract allowing some input to be validated. + * + * @param The type of the input object. + */ +@FunctionalInterface +public interface Validator { + /** + * Validates input, resulting in a instance of {@link ValidationResult} which provides details on all validations performed (success, error, warning). + * + * @param input The object instance to be validated. + * + * @return A {@link ValidationResult} which details the success, error, and warning validation results. + */ + ValidationResult validate(TInput input); +} \ No newline at end of file diff --git a/modules/openapi-generator-core/src/test/java/org/openapitools/codegen/validation/GenericValidatorTest.java b/modules/openapi-generator-core/src/test/java/org/openapitools/codegen/validation/GenericValidatorTest.java new file mode 100644 index 00000000000..0a258d2a139 --- /dev/null +++ b/modules/openapi-generator-core/src/test/java/org/openapitools/codegen/validation/GenericValidatorTest.java @@ -0,0 +1,149 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +public class GenericValidatorTest { + class Person { + private int age; + private String name; + + Person(String name, int age) { + this.age = age; + this.name = name; + } + } + + private static boolean isValidAge(Person person) { + return person.age > 0; + } + + private static boolean isAdult(Person person) { + return person.age > 18; + } + + private static boolean isNameSet(Person person) { + return person.name != null && person.name.length() > 0; + } + + private static boolean isNameValid(Person person) { + String pattern = "^[A-Z][a-z]*$"; + return person.name.matches(pattern); + } + + private static boolean isNameNormalLength(Person person) { + return person.name.length() < 10; + } + + private List 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) + ); + + @Test + public void testGenericValidatorSuccesses(){ + Person person = new Person("Jim", 23); + GenericValidator validator = new GenericValidator<>(validationRules); + ValidationResult result = validator.validate(person); + List validated = result.getAll(); + List valid = result.getValid(); + List invalid = result.getErrors(); + + assertEquals(validated.size(), 5, "Expected 5 validations to run."); + assertEquals(valid.size(), 5, "Expected all validations to succeed"); + assertEquals(invalid.size(), 0, "Expected zero validations to fail."); + } + + @Test + public void testGenericValidatorSingleConditionFails(){ + Person person = new Person("Jim", 3); + GenericValidator validator = new GenericValidator<>(validationRules); + ValidationResult result = validator.validate(person); + List validated = result.getAll(); + List valid = result.getValid(); + List errors = result.getErrors(); + List warnings = result.getWarnings(); + + assertEquals(validated.size(), 5, "Expected 5 validations to run."); + assertEquals(valid.size(), 4, "Expected 4 validations to succeed"); + assertEquals(errors.size(), 1, "Expected 1 validation to fail."); + assertEquals(warnings.size(), 0, "Expected no warnings to be triggered."); + + Invalid failed = errors.get(0); + assertEquals(failed.getMessage(), "Only adults (18 years old and older)"); + } + + @Test + public void testGenericValidatorMultipleConditionsFail(){ + Person person = new Person("asdf", 3); + GenericValidator validator = new GenericValidator<>(validationRules); + ValidationResult result = validator.validate(person); + List validated = result.getAll(); + List valid = result.getValid(); + List errors = result.getErrors(); + List warnings = result.getWarnings(); + + assertEquals(validated.size(), 5, "Expected 5 validations to run."); + assertEquals(valid.size(), 3, "Expected 3 validations to succeed"); + assertEquals(errors.size(), 2, "Expected 2 validations to fail."); + assertEquals(warnings.size(), 0, "Expected no warnings to be triggered."); + + Optional nameValidation = errors.stream().filter(it -> it.getMessage().contains("formatted")).findFirst(); + Optional ageValidation = errors.stream().filter(it -> it.getMessage().contains("adults")).findFirst(); + + assertTrue(nameValidation.isPresent(), "Expected validation on name formatting to fail."); + assertTrue(ageValidation.isPresent(), "Expected validation on age requirements to fail."); + assertEquals(nameValidation.get().getMessage(), "Name isn't formatted correct"); + assertEquals(ageValidation.get().getMessage(), "Only adults (18 years old and older)"); + } + + @Test + public void testGenericValidatorErrorsAndWarnings(){ + Person person = new Person("0123456789asdfghjkl", 3); + GenericValidator validator = new GenericValidator<>(validationRules); + ValidationResult result = validator.validate(person); + List validated = result.getAll(); + List valid = result.getValid(); + List errors = result.getErrors(); + List warnings = result.getWarnings(); + + assertEquals(validated.size(), 5, "Expected 5 validations to run."); + assertEquals(valid.size(), 2, "Expected 2 validations to succeed"); + assertEquals(errors.size(), 2, "Expected 2 validations to fail."); + assertEquals(warnings.size(), 1, "Expected 1 warning to be triggered."); + + Optional nameValidation = errors.stream().filter(it -> it.getMessage().contains("formatted")).findFirst(); + Optional ageValidation = errors.stream().filter(it -> it.getMessage().contains("adults")).findFirst(); + Invalid nameLengthWarning = warnings.get(0); + + assertTrue(nameValidation.isPresent(), "Expected validation on name formatting to fail."); + assertTrue(ageValidation.isPresent(), "Expected validation on age requirements to fail."); + assertEquals(nameValidation.get().getMessage(), "Name isn't formatted correct"); + assertEquals(ageValidation.get().getMessage(), "Only adults (18 years old and older)"); + assertEquals(nameLengthWarning.getMessage(), "Name may be too long."); + } +} diff --git a/modules/openapi-generator-core/src/test/java/org/openapitools/codegen/validation/ValidatedTest.java b/modules/openapi-generator-core/src/test/java/org/openapitools/codegen/validation/ValidatedTest.java new file mode 100644 index 00000000000..8109461de57 --- /dev/null +++ b/modules/openapi-generator-core/src/test/java/org/openapitools/codegen/validation/ValidatedTest.java @@ -0,0 +1,35 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class ValidatedTest { + @Test + public void isValidTrueForValidType(){ + boolean isValid = Validated.valid(ValidationRule.empty()).isValid(); + assertTrue(isValid); + } + + @Test + public void isValidFalseForInvalidType(){ + boolean isValid = Validated.invalid(ValidationRule.empty(), "test").isValid(); + assertFalse(isValid); + } +} diff --git a/modules/openapi-generator-core/src/test/java/org/openapitools/codegen/validation/ValidationRuleTest.java b/modules/openapi-generator-core/src/test/java/org/openapitools/codegen/validation/ValidationRuleTest.java new file mode 100644 index 00000000000..afa6c02ff57 --- /dev/null +++ b/modules/openapi-generator-core/src/test/java/org/openapitools/codegen/validation/ValidationRuleTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2019 OpenAPI-Generator Contributors (https://openapi-generator.tech) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openapitools.codegen.validation; + +import org.testng.annotations.Test; + +import static org.testng.Assert.*; + +public class ValidationRuleTest { + class Sample { + private String name; + + public Sample(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + private static boolean checkName(Sample input) { + return input.getName() != null && input.getName().length() > 7; + } + + private static boolean checkPattern(Sample input) { + String pattern = "^[A-Z][a-z]*$"; + return input.getName() != null && input.getName().matches(pattern); + } + + @Test + public void createMethodUsingMethodReference(){ + Sample nil = new Sample(null); + Sample six = new Sample("123456"); + 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)); + } + + @Test + public void createMethodUsingLambda(){ + Sample nil = new Sample(null); + 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)); + } +} diff --git a/modules/openapi-generator/pom.xml b/modules/openapi-generator/pom.xml index fb876816e28..cbd6347dbcb 100644 --- a/modules/openapi-generator/pom.xml +++ b/modules/openapi-generator/pom.xml @@ -315,7 +315,7 @@ org.openapitools openapi-generator-core - 4.0.3-SNAPSHOT + ${project.parent.version} diff --git a/pom.xml b/pom.xml index ecb40eab0df..a63eb41b537 100644 --- a/pom.xml +++ b/pom.xml @@ -155,12 +155,22 @@ maven-surefire-plugin ${surefire-version} + true false none:none org.testng:testng -XX:+StartAttachListener -javaagent:"${settings.localRepository}/org/jmockit/jmockit/${jmockit-version}/jmockit-${jmockit-version}.jar" + + + + org.jmockit + jmockit + ${jmockit-version} + compile + + maven-dependency-plugin @@ -1286,12 +1296,12 @@ + modules/openapi-generator-core modules/openapi-generator modules/openapi-generator-cli modules/openapi-generator-maven-plugin modules/openapi-generator-gradle-plugin modules/openapi-generator-online - modules/openapi-generator-core target/site @@ -1373,8 +1383,8 @@ 1.14 4.1.2 6.14.3 - 2.22.1 - 1.43 + 3.0.0-M3 + 1.46 0.9.10