/** * 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; import static org.hamcrest.Matchers.*; import static org.jsonschema2pojo.integration.util.CodeGenerationHelper.*; import static org.junit.Assert.*; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.jsonschema2pojo.integration.util.Jsonschema2PojoRule; import org.junit.Rule; import org.junit.Test; public class ExtendsIT { @Rule public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule(); @Test @SuppressWarnings("rawtypes") public void extendsWithEmbeddedSchemaGeneratesParentType() throws ClassNotFoundException { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/extendsEmbeddedSchema.json", "com.example"); Class subtype = resultsClassLoader.loadClass("com.example.ExtendsEmbeddedSchema"); Class supertype = resultsClassLoader.loadClass("com.example.ExtendsEmbeddedSchemaParent"); assertThat(subtype.getSuperclass(), is(equalTo(supertype))); } @Test @SuppressWarnings("rawtypes") public void extendsWithRefToAnotherSchema() throws ClassNotFoundException { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfA.json", "com.example"); Class subtype = resultsClassLoader.loadClass("com.example.SubtypeOfA"); Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfAParent"); assertThat(subtype.getSuperclass(), is(equalTo(supertype))); } @Test @SuppressWarnings("rawtypes") public void extendsWithRefToAnotherSchemaThatIsAlreadyASubtype() throws ClassNotFoundException { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfSubtypeOfA.json", "com.example"); Class subtype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfA"); Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfAParent"); assertThat(subtype.getSuperclass(), is(equalTo(supertype))); } @Test(expected = ClassNotFoundException.class) public void extendsStringCausesNoNewTypeToBeGenerated() throws ClassNotFoundException { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/extendsString.json", "com.example"); resultsClassLoader.loadClass("com.example.ExtendsString"); } @Test @SuppressWarnings("rawtypes") public void extendsEquals() throws Exception { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfSubtypeOfA.json", "com.example2"); Class generatedType = resultsClassLoader.loadClass("com.example2.SubtypeOfSubtypeOfA"); Object instance = generatedType.newInstance(); Object instance2 = generatedType.newInstance(); new PropertyDescriptor("parent", generatedType).getWriteMethod().invoke(instance, "1"); new PropertyDescriptor("child", generatedType).getWriteMethod().invoke(instance, "2"); new PropertyDescriptor("parent", generatedType).getWriteMethod().invoke(instance2, "not-equal"); new PropertyDescriptor("child", generatedType).getWriteMethod().invoke(instance2, "2"); assertFalse(instance.equals(instance2)); } @Test @SuppressWarnings("rawtypes") public void extendsSchemaWithinDefinitions() throws Exception { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/extendsSchemaWithinDefinitions.json", "com.example"); Class subtype = resultsClassLoader.loadClass("com.example.Child"); assertNotNull("no propertyOfChild field", subtype.getDeclaredField("propertyOfChild")); Class supertype = resultsClassLoader.loadClass("com.example.ChildParent"); assertNotNull("no propertyOfParent field", supertype.getDeclaredField("propertyOfParent")); assertThat(subtype.getSuperclass(), is(equalTo(supertype))); } @Test @SuppressWarnings({ "rawtypes", "unchecked" }) public void constructorHasParentsProperties() throws Exception { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfB.json", "com.example", config("includeConstructors", true)); Class type = resultsClassLoader.loadClass("com.example.SubtypeOfB"); Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfBParent"); assertThat(type.getSuperclass(), is(equalTo(supertype))); assertNotNull("Parent constructor is missing", supertype.getConstructor(String.class)); assertNotNull("Constructor is missing", type.getConstructor(String.class, String.class)); Object typeInstance = type.getConstructor(String.class, String.class).newInstance("String1", "String2"); Field chieldField = type.getDeclaredField("childProperty"); chieldField.setAccessible(true); String childProp = (String)chieldField.get(typeInstance); Field parentField = supertype.getDeclaredField("parentProperty"); parentField.setAccessible(true); String parentProp = (String)parentField.get(typeInstance); assertThat(childProp, is(equalTo("String1"))); assertThat(parentProp, is(equalTo("String2"))); } @Test @SuppressWarnings({ "rawtypes", "unchecked" }) public void constructorHasParentsParentProperties() throws Exception { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfSubtypeOfB.json", "com.example", config("includeConstructors", true)); Class type = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfB"); Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfBParent"); Class superSupertype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfBParentParent"); assertThat(type.getSuperclass(), is(equalTo(supertype))); assertNotNull("Parent Parent constructor is missing", superSupertype.getDeclaredConstructor(String.class)); assertNotNull("Parent Constructor is missing", supertype.getDeclaredConstructor(String.class, String.class)); assertNotNull("Constructor is missing", type.getDeclaredConstructor(String.class, String.class, String.class)); Object typeInstance = type.getConstructor(String.class, String.class, String.class).newInstance("String1", "String2", "String3"); Field chieldChildField = type.getDeclaredField("childChildProperty"); chieldChildField.setAccessible(true); String childChildProp = (String)chieldChildField.get(typeInstance); Field chieldField = supertype.getDeclaredField("childProperty"); chieldField.setAccessible(true); String childProp = (String)chieldField.get(typeInstance); Field parentField = superSupertype.getDeclaredField("parentProperty"); parentField.setAccessible(true); String parentProp = (String)parentField.get(typeInstance); assertThat(childChildProp, is(equalTo("String1"))); assertThat(childProp, is(equalTo("String2"))); assertThat(parentProp, is(equalTo("String3"))); } @Test @SuppressWarnings({ "rawtypes", "unchecked" }) public void constructorHasParentsParentPropertiesInCorrectOrder() throws Exception { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfSubtypeOfBDifferentType.json", "com.example", config("includeConstructors", true)); Class type = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfBDifferentType"); Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfBDifferentTypeParent"); Class superSupertype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfBDifferentTypeParentParent"); assertThat(type.getSuperclass(), is(equalTo(supertype))); assertNotNull("Parent Parent constructor is missing", superSupertype.getDeclaredConstructor(String.class)); assertNotNull("Parent Constructor is missing", supertype.getDeclaredConstructor(String.class, String.class)); assertNotNull("Constructor is missing", type.getDeclaredConstructor(Integer.class, String.class, String.class)); Object typeInstance = type.getConstructor(Integer.class, String.class, String.class).newInstance(5, "String2", "String3"); Field chieldChildField = type.getDeclaredField("childChildProperty"); chieldChildField.setAccessible(true); int childChildProp = (Integer)chieldChildField.get(typeInstance); Field chieldField = supertype.getDeclaredField("childProperty"); chieldField.setAccessible(true); String childProp = (String)chieldField.get(typeInstance); Field parentField = superSupertype.getDeclaredField("parentProperty"); parentField.setAccessible(true); String parentProp = (String)parentField.get(typeInstance); assertThat(childChildProp, is(equalTo(5))); assertThat(childProp, is(equalTo("String2"))); assertThat(parentProp, is(equalTo("String3"))); } @Test @SuppressWarnings({ "rawtypes", "unchecked" }) public void constructorDoesNotDuplicateArgsFromDuplicatedParentProperties() throws Exception { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfSubtypeOfC.json", "com.example", config("includeConstructors", true)); Class type = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfC"); Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfCParent"); Class superSupertype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfCParentParent"); assertNotNull("Parent Parent constructor is missing", superSupertype.getDeclaredConstructor(String.class, Integer.class)); assertNotNull("Parent Constructor is missing", supertype.getDeclaredConstructor(String.class, Boolean.class, Integer.class)); assertNotNull("Constructor is missing", type.getDeclaredConstructor(String.class, Integer.class, Boolean.class, Integer.class)); Object typeInstance = type.getConstructor(String.class, Integer.class, Boolean.class, Integer.class).newInstance("String1", 5, true, 6); Field chieldChildField = type.getDeclaredField("duplicatedProp"); chieldChildField.setAccessible(true); String childChildProp = (String)chieldChildField.get(typeInstance); Field chieldField = supertype.getDeclaredField("duplicatedProp"); chieldField.setAccessible(true); String childProp = (String)chieldField.get(typeInstance); Field parentField = superSupertype.getDeclaredField("duplicatedProp"); parentField.setAccessible(true); String parentProp = (String)parentField.get(typeInstance); assertThat(childChildProp, is(equalTo("String1"))); assertThat(childProp, is(equalTo("String1"))); assertThat(parentProp, is(equalTo("String1"))); } @Test @SuppressWarnings("rawtypes") public void extendsBuilderMethods() throws Exception { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfSubtypeOfA.json", "com.example", config("generateBuilders", true)); Class subtype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfA"); Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfSubtypeOfAParent"); checkBuilderMethod(subtype, supertype, "withParent"); } @Test @SuppressWarnings("rawtypes") public void builderMethodsOnChildWithProperties() throws Exception { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfB.json", "com.example", config("generateBuilders", true)); Class type = resultsClassLoader.loadClass("com.example.SubtypeOfB"); Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfBParent"); checkBuilderMethod(type, supertype, "withParentProperty"); } @Test @SuppressWarnings("rawtypes") public void builderMethodsOnChildWithNoProperties() throws Exception { ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema/extends/subtypeOfBWithNoProperties.json", "com.example", config("generateBuilders", true)); Class type = resultsClassLoader.loadClass("com.example.SubtypeOfBWithNoProperties"); Class supertype = resultsClassLoader.loadClass("com.example.SubtypeOfBWithNoPropertiesParent"); checkBuilderMethod(type, supertype, "withParentProperty"); } @SuppressWarnings({ "rawtypes", "unchecked" }) static void checkBuilderMethod(Class type, Class supertype, String builderMethodName) throws Exception { assertThat(type.getSuperclass(), is(equalTo(supertype))); Method builderMethod = supertype.getDeclaredMethod(builderMethodName, String.class); assertNotNull("Builder method not found on super type: " + builderMethodName, builderMethod); assertThat(builderMethod.getReturnType(), is(equalTo(supertype))); Method builderMethodOverride = type.getDeclaredMethod(builderMethodName, String.class); assertNotNull("Builder method not overridden on type: " + builderMethodName, builderMethodOverride); assertThat(builderMethodOverride.getReturnType(), is(equalTo(type))); } }