/**
* Copyright © 2010-2014 Nokia
*
* 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.jsonschema2pojo.integration.config;
import static java.util.Arrays.*;
import static org.hamcrest.Matchers.*;
import static org.jsonschema2pojo.integration.util.CodeGenerationHelper.*;
import static org.junit.Assert.*;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import org.hamcrest.Matcher;
import org.jsonschema2pojo.integration.util.FileSearchMatcher;
import org.jsonschema2pojo.integration.util.Jsonschema2PojoRule;
import org.junit.Rule;
import org.junit.Test;
@SuppressWarnings("rawtypes")
public class IncludeJsr303AnnotationsIT {
@Rule public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule();
private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();;
@Test
public void jsrAnnotationsAreNotIncludedByDefault() throws ClassNotFoundException {
File outputDirectory = schemaRule.generate("/schema/jsr303/all.json", "com.example");
assertThat(outputDirectory, not(containsText("javax.validation")));
}
@Test
public void jsrAnnotationsAreNotIncludedWhenSwitchedOff() throws ClassNotFoundException {
File outputDirectory = schemaRule.generate("/schema/jsr303/all.json", "com.example",
config("includeJsr303Annotations", false));
assertThat(outputDirectory, not(containsText("javax.validation")));
}
@Test
public void jsr303DecimalMinValidationIsAddedForSchemaRuleMinimum() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/minimum.json", "com.example",
config("includeJsr303Annotations", true));
Class generatedType = resultsClassLoader.loadClass("com.example.Minimum");
Object validInstance = createInstanceWithPropertyValue(generatedType, "minimum", 2.0d);
assertNumberOfConstraintViolationsOn(validInstance, is(0));
Object invalidInstance = createInstanceWithPropertyValue(generatedType, "minimum", 0.9d);
assertNumberOfConstraintViolationsOn(invalidInstance, is(1));
}
@Test
public void jsr303DecimalMaxValidationIsAddedForSchemaRuleMaximum() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/maximum.json", "com.example",
config("includeJsr303Annotations", true));
Class generatedType = resultsClassLoader.loadClass("com.example.Maximum");
Object validInstance = createInstanceWithPropertyValue(generatedType, "maximum", 8.9d);
assertNumberOfConstraintViolationsOn(validInstance, is(0));
Object invalidInstance = createInstanceWithPropertyValue(generatedType, "maximum", 10.9d);
assertNumberOfConstraintViolationsOn(invalidInstance, is(1));
}
@Test
public void jsr303SizeValidationIsAddedForSchemaRuleMinItems() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/minItems.json", "com.example",
config("includeJsr303Annotations", true));
Class generatedType = resultsClassLoader.loadClass("com.example.MinItems");
Object validInstance = createInstanceWithPropertyValue(generatedType, "minItems", asList(1, 2, 3, 4, 5, 6));
assertNumberOfConstraintViolationsOn(validInstance, is(0));
Object invalidInstance = createInstanceWithPropertyValue(generatedType, "minItems", asList(1, 2, 3));
assertNumberOfConstraintViolationsOn(invalidInstance, is(1));
}
@Test
public void jsr303SizeValidationIsAddedForSchemaRuleMaxItems() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/maxItems.json", "com.example",
config("includeJsr303Annotations", true));
Class generatedType = resultsClassLoader.loadClass("com.example.MaxItems");
Object validInstance = createInstanceWithPropertyValue(generatedType, "maxItems", asList(1, 2, 3));
assertNumberOfConstraintViolationsOn(validInstance, is(0));
Object invalidInstance = createInstanceWithPropertyValue(generatedType, "maxItems", asList(1, 2, 3, 4, 5, 6));
assertNumberOfConstraintViolationsOn(invalidInstance, is(1));
}
@Test
public void jsr303SizeValidationIsAddedForSchemaRuleMinItemsAndMaxItems() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/minAndMaxItems.json", "com.example",
config("includeJsr303Annotations", true));
Class generatedType = resultsClassLoader.loadClass("com.example.MinAndMaxItems");
Object validInstance = createInstanceWithPropertyValue(generatedType, "minAndMaxItems", asList(1, 2, 3));
assertNumberOfConstraintViolationsOn(validInstance, is(0));
Object invalidInstance1 = createInstanceWithPropertyValue(generatedType, "minAndMaxItems", asList(1));
assertNumberOfConstraintViolationsOn(invalidInstance1, is(1));
Object invalidInstance2 = createInstanceWithPropertyValue(generatedType, "minAndMaxItems", asList(1, 2, 3, 4, 5));
assertNumberOfConstraintViolationsOn(invalidInstance2, is(1));
}
@Test
public void jsr303PatternValidationIsAddedForSchemaRulePattern() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/pattern.json", "com.example",
config("includeJsr303Annotations", true));
Class generatedType = resultsClassLoader.loadClass("com.example.Pattern");
Object validInstance = createInstanceWithPropertyValue(generatedType, "pattern", "abc123");
assertNumberOfConstraintViolationsOn(validInstance, is(0));
Object invalidInstance = createInstanceWithPropertyValue(generatedType, "pattern", "123abc");
assertNumberOfConstraintViolationsOn(invalidInstance, is(1));
}
@Test
public void jsr303NotNullValidationIsAddedForSchemaRuleRequired() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/required.json", "com.example",
config("includeJsr303Annotations", true));
Class generatedType = resultsClassLoader.loadClass("com.example.Required");
Object validInstance = createInstanceWithPropertyValue(generatedType, "required", "abc");
assertNumberOfConstraintViolationsOn(validInstance, is(0));
Object invalidInstance = createInstanceWithPropertyValue(generatedType, "required", null);
assertNumberOfConstraintViolationsOn(invalidInstance, is(1));
}
@Test
public void jsr303SizeValidationIsAddedForSchemaRuleMinLength() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/minLength.json", "com.example",
config("includeJsr303Annotations", true));
Class generatedType = resultsClassLoader.loadClass("com.example.MinLength");
Object validInstance = createInstanceWithPropertyValue(generatedType, "minLength", "Long enough");
assertNumberOfConstraintViolationsOn(validInstance, is(0));
Object invalidInstance = createInstanceWithPropertyValue(generatedType, "minLength", "Too short");
assertNumberOfConstraintViolationsOn(invalidInstance, is(1));
}
@Test
public void jsr303SizeValidationIsAddedForSchemaRuleMaxLength() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/maxLength.json", "com.example",
config("includeJsr303Annotations", true));
Class generatedType = resultsClassLoader.loadClass("com.example.MaxLength");
Object validInstance = createInstanceWithPropertyValue(generatedType, "maxLength", "Short");
assertNumberOfConstraintViolationsOn(validInstance, is(0));
Object invalidInstance = createInstanceWithPropertyValue(generatedType, "maxLength", "Tooooo long");
assertNumberOfConstraintViolationsOn(invalidInstance, is(1));
}
@Test
public void jsr303ValidAnnotationIsAddedForObject() throws ClassNotFoundException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validObject.json", "com.example",
config("includeJsr303Annotations", true));
Class validObjectType = resultsClassLoader.loadClass("com.example.ValidObject");
Class objectFieldType = resultsClassLoader.loadClass("com.example.Objectfield");
Object invalidObjectFieldInstance = createInstanceWithPropertyValue(objectFieldType, "childprimitivefield", "Too long");
Object validObjectInstance = createInstanceWithPropertyValue(validObjectType, "objectfield", invalidObjectFieldInstance);
assertNumberOfConstraintViolationsOn(validObjectInstance, is(1));
Object validObjectFieldInstance = createInstanceWithPropertyValue(objectFieldType, "childprimitivefield", "OK");
validObjectInstance = createInstanceWithPropertyValue(validObjectType, "objectfield", validObjectFieldInstance);
assertNumberOfConstraintViolationsOn(validObjectInstance, is(0));
}
@Test
public void jsr303ValidAnnotationIsAddedForArray() throws ClassNotFoundException, NoSuchFieldException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validArray.json", "com.example",
config("includeJsr303Annotations", true));
Class validArrayType = resultsClassLoader.loadClass("com.example.ValidArray");
Class objectArrayType = resultsClassLoader.loadClass("com.example.Objectarray");
List<Object> objectArrayList = new ArrayList<Object>();
Object objectArrayInstance = createInstanceWithPropertyValue(objectArrayType, "arrayitem", "OK");
objectArrayList.add(objectArrayInstance);
Object validArrayInstance = createInstanceWithPropertyValue(validArrayType, "objectarray", objectArrayList);
assertNumberOfConstraintViolationsOn(validArrayInstance, is(0));
Object invalidObjectArrayInstance = createInstanceWithPropertyValue(objectArrayType, "arrayitem", "Too long");
objectArrayList.add(invalidObjectArrayInstance);
validArrayInstance = createInstanceWithPropertyValue(validArrayType, "objectarray", objectArrayList);
assertNumberOfConstraintViolationsOn(validArrayInstance, is(1));
}
@Test
public void jsr303ValidAnnotationIsAddedForArrayWithRef() throws ClassNotFoundException, NoSuchFieldException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validArray.json", "com.example",
config("includeJsr303Annotations", true));
Class validArrayType = resultsClassLoader.loadClass("com.example.ValidArray");
Class refarrayType = resultsClassLoader.loadClass("com.example.Refarray");
List<Object> objectArrayList = new ArrayList<Object>();
Object objectArrayInstance = createInstanceWithPropertyValue(refarrayType, "arrayitem", "OK");
objectArrayList.add(objectArrayInstance);
Object validArrayInstance = createInstanceWithPropertyValue(validArrayType, "refarray", objectArrayList);
assertNumberOfConstraintViolationsOn(validArrayInstance, is(0));
Object invalidObjectArrayInstance = createInstanceWithPropertyValue(refarrayType, "arrayitem", "Too long");
objectArrayList.add(invalidObjectArrayInstance);
validArrayInstance = createInstanceWithPropertyValue(validArrayType, "refarray", objectArrayList);
assertNumberOfConstraintViolationsOn(validArrayInstance, is(1));
}
@SuppressWarnings("unchecked")
@Test
public void jsr303AnnotionsValidatedForAdditionalProperties() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/jsr303/validAdditionalProperties.json", "com.example", config("includeJsr303Annotations", true));
Class parentType = resultsClassLoader.loadClass("com.example.ValidAdditionalProperties");
Object parent = parentType.newInstance();
Class subPropertyType = resultsClassLoader.loadClass("com.example.ValidAdditionalPropertiesProperty");
Object validSubPropertyInstance = createInstanceWithPropertyValue(subPropertyType, "maximum", 9.0D);
Object invalidSubPropertyInstance = createInstanceWithPropertyValue(subPropertyType, "maximum", 11.0D);
Method setter = parentType.getMethod("setAdditionalProperty", String.class, subPropertyType);
setter.invoke(parent, "maximum", validSubPropertyInstance);
assertNumberOfConstraintViolationsOn(parent, is(0));
setter.invoke(parent, "maximum", invalidSubPropertyInstance);
assertNumberOfConstraintViolationsOn(parent, is(1));
}
private static void assertNumberOfConstraintViolationsOn(Object instance, Matcher<Integer> matcher) {
Set<ConstraintViolation<Object>> violationsForValidInstance = validator.validate(instance);
assertThat(violationsForValidInstance.size(), matcher);
}
private static Object createInstanceWithPropertyValue(Class type, String propertyName, Object propertyValue) {
try {
Object instance = type.newInstance();
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(propertyName, type);
propertyDescriptor.getWriteMethod().invoke(instance, propertyValue);
return instance;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static Matcher<File> containsText(String searchText) {
return new FileSearchMatcher(searchText);
}
}