Skip to content

Commit

Permalink
Parameterise example JSON tests to cover example YAML too
Browse files Browse the repository at this point in the history
  • Loading branch information
joelittlejohn committed Feb 16, 2023
1 parent 15e4229 commit d17503d
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 346 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,8 @@ public JType generate(JCodeModel codeModel, String className, String packageName
JPackage jpackage = codeModel._package(packageName);

JsonNode schemaNode = null;
if (ruleFactory.getGenerationConfig().getSourceType() == SourceType.JSON) {
if (ruleFactory.getGenerationConfig().getSourceType() == SourceType.JSON
|| ruleFactory.getGenerationConfig().getSourceType() == SourceType.YAML) {
JsonNode jsonNode = objectMapper().readTree(json);
schemaNode = schemaGenerator.schemaFromExample(jsonNode);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,75 +27,100 @@
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;

import org.jsonschema2pojo.integration.util.Jsonschema2PojoRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

@RunWith(Parameterized.class)
public class JsonTypesIT {

@Parameters(name="{0}")
public static List<Object[]> data() {
return Arrays.asList(new Object[][] {
{ "json", new ObjectMapper()},
{ "yaml", new ObjectMapper(new YAMLFactory()) }
});
}

@Rule
public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule();

@Rule
public ExpectedException thrown = ExpectedException.none();

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
private final String format;
private final ObjectMapper objectMapper;

public JsonTypesIT(final String format, final ObjectMapper objectMapper) {
this.format = format;
this.objectMapper = objectMapper;
}

private String filePath(String baseName) {
return "/" + format + "/" + baseName + "." + format;
}

@Test
public void simpleTypesInExampleAreMappedToCorrectJavaTypes() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/simpleTypes.json", "com.example",
config("sourceType", "json"));
final String filePath = filePath("simpleTypes");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example", config("sourceType", format));

Class<?> generatedType = resultsClassLoader.loadClass("com.example.SimpleTypes");

Object deserialisedValue = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/simpleTypes.json"), generatedType);
Object deserializedValue = objectMapper.readValue(this.getClass().getResourceAsStream(filePath), generatedType);

assertThat((String) generatedType.getMethod("getA").invoke(deserialisedValue), is("abc"));
assertThat((Integer) generatedType.getMethod("getB").invoke(deserialisedValue), is(123));
assertThat((String) generatedType.getMethod("getA").invoke(deserializedValue), is("abc"));
assertThat((Integer) generatedType.getMethod("getB").invoke(deserializedValue), is(123));
assertThat(generatedType.getMethod("getB").getReturnType().getName(), is("java.lang.Integer"));
assertThat((Double) generatedType.getMethod("getC").invoke(deserialisedValue), is(12999999999999999999999.99d));
assertThat((Boolean) generatedType.getMethod("getD").invoke(deserialisedValue), is(true));
assertThat(generatedType.getMethod("getE").invoke(deserialisedValue), is(nullValue()));
assertThat(generatedType.getMethod("getF").invoke(deserialisedValue), is(21474836470L));
assertThat((Double) generatedType.getMethod("getC").invoke(deserializedValue), is(12999999999999999999999.99d));
assertThat((Boolean) generatedType.getMethod("getD").invoke(deserializedValue), is(true));
assertThat(generatedType.getMethod("getE").invoke(deserializedValue), is(nullValue()));
assertThat(generatedType.getMethod("getF").invoke(deserializedValue), is(21474836470L));

}

@Test
public void integerIsMappedToBigInteger() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/simpleTypes.json", "com.example", config("sourceType", "json", "useBigIntegers", true));
final String filePath = filePath("simpleTypes");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example", config("sourceType", format, "useBigIntegers", true));

Class<?> generatedType = resultsClassLoader.loadClass("com.example.SimpleTypes");

Object deserialisedValue = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/simpleTypes.json"), generatedType);
Object deserializedValue = objectMapper.readValue(this.getClass().getResourceAsStream(filePath), generatedType);

assertThat((BigInteger) generatedType.getMethod("getB").invoke(deserialisedValue), is(new BigInteger("123")));
assertThat((BigInteger) generatedType.getMethod("getB").invoke(deserializedValue), is(new BigInteger("123")));
}

@Test
public void numberIsMappedToBigDecimal() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/simpleTypes.json", "com.example", config("sourceType", "json", "useBigDecimals", true));
final String filePath = filePath("simpleTypes");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example", config("sourceType", format, "useBigDecimals", true));

Class<?> generatedType = resultsClassLoader.loadClass("com.example.SimpleTypes");

Object deserialisedValue = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/simpleTypes.json"), generatedType);
Object deserializedValue = objectMapper.readValue(this.getClass().getResourceAsStream(filePath), generatedType);

assertThat((BigDecimal) generatedType.getMethod("getC").invoke(deserialisedValue), is(new BigDecimal("12999999999999999999999.99")));
assertThat((BigDecimal) generatedType.getMethod("getC").invoke(deserializedValue), is(new BigDecimal("12999999999999999999999.99")));
}

@Test(expected = ClassNotFoundException.class)
public void simpleTypeAtRootProducesNoJavaTypes() throws ClassNotFoundException {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/simpleTypeAsRoot.json", "com.example",
config("sourceType", "json"));
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath("simpleTypeAsRoot"), "com.example", config("sourceType", format));

resultsClassLoader.loadClass("com.example.SimpleTypeAsRoot");

Expand All @@ -105,11 +130,11 @@ public void simpleTypeAtRootProducesNoJavaTypes() throws ClassNotFoundException
@SuppressWarnings("unchecked")
public void complexTypesProduceObjects() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/complexObject.json", "com.example",
config("sourceType", "json"));
final String filePath = filePath("complexObject");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example", config("sourceType", format));

Class<?> complexObjectClass = resultsClassLoader.loadClass("com.example.ComplexObject");
Object complexObject = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/complexObject.json"), complexObjectClass);
Object complexObject = objectMapper.readValue(this.getClass().getResourceAsStream(filePath), complexObjectClass);

Object a = complexObjectClass.getMethod("getA").invoke(complexObject);
Object aa = a.getClass().getMethod("getAa").invoke(a);
Expand All @@ -130,21 +155,21 @@ public void complexTypesProduceObjects() throws Exception {
@SuppressWarnings("rawtypes")
public void arrayTypePropertiesProduceLists() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/array.json", "com.example",
config("sourceType", "json"));
final String filePath = filePath("array");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example", config("sourceType", format));

Class<?> arrayType = resultsClassLoader.loadClass("com.example.Array");
Class<?> itemType = resultsClassLoader.loadClass("com.example.A");

Object deserialisedValue = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/array.json"), arrayType);
Object deserializedValue = objectMapper.readValue(this.getClass().getResourceAsStream(filePath), arrayType);

List<?> valueA = (List) arrayType.getMethod("getA").invoke(deserialisedValue);
List<?> valueA = (List) arrayType.getMethod("getA").invoke(deserializedValue);
assertThat(((ParameterizedType) arrayType.getMethod("getA").getGenericReturnType()).getActualTypeArguments()[0], is(equalTo((Type) itemType)));
assertThat((Integer) itemType.getMethod("get0").invoke(valueA.get(0)), is(0));
assertThat((Integer) itemType.getMethod("get1").invoke(valueA.get(1)), is(1));
assertThat((Integer) itemType.getMethod("get2").invoke(valueA.get(2)), is(2));

Object valueB = arrayType.getMethod("getB").invoke(deserialisedValue);
Object valueB = arrayType.getMethod("getB").invoke(deserializedValue);
assertThat(valueB, is(instanceOf(List.class)));
assertThat(((ParameterizedType) arrayType.getMethod("getB").getGenericReturnType()).getActualTypeArguments()[0], is(equalTo((Type) Integer.class)));

Expand All @@ -153,12 +178,13 @@ public void arrayTypePropertiesProduceLists() throws Exception {
@Test
public void arrayItemsAreRecursivelyMerged() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/complexPropertiesInArrayItem.json", "com.example", config("sourceType", "json"));
final String filePath = filePath("complexPropertiesInArrayItem");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example", config("sourceType", format));
Class<?> genType = resultsClassLoader.loadClass("com.example.ComplexPropertiesInArrayItem");
Class<?> listItemType = resultsClassLoader.loadClass("com.example.List");
Class<?> objItemType = resultsClassLoader.loadClass("com.example.Obj");

Object[] items = (Object[]) OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/complexPropertiesInArrayItem.json"), Array.newInstance(genType, 0).getClass());
Object[] items = (Object[]) objectMapper.readValue(this.getClass().getResourceAsStream(filePath), Array.newInstance(genType, 0).getClass());
{
Object item = items[0];

Expand Down Expand Up @@ -188,7 +214,8 @@ public void arrayItemsAreRecursivelyMerged() throws Exception {
@Test
public void arrayItemsAreNotRecursivelyMerged() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/simplePropertiesInArrayItem.json", "com.example", config("sourceType", "json"));
final String filePath = filePath("simplePropertiesInArrayItem");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example", config("sourceType", format));
Class<?> genType = resultsClassLoader.loadClass("com.example.SimplePropertiesInArrayItem");

// Different array items use different types for the same property;
Expand All @@ -197,39 +224,38 @@ public void arrayItemsAreNotRecursivelyMerged() throws Exception {

thrown.expect(InvalidFormatException.class);
thrown.expectMessage(startsWith("Cannot deserialize value of type `java.lang.Integer` from String \"what\": not a valid `java.lang.Integer` value"));
OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/simplePropertiesInArrayItem.json"), Array.newInstance(genType, 0).getClass());
objectMapper.readValue(this.getClass().getResourceAsStream(filePath), Array.newInstance(genType, 0).getClass());
}

@Test(expected = ClassNotFoundException.class)
public void arrayAtRootProducesNoJavaTypes() throws Exception {
public void arrayAtRootWithSimpleTypeProducesNoJavaTypes() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/arrayAsRoot.json", "com.example",
config("sourceType", "json"));
final String filePath = filePath("arrayAsRoot");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example", config("sourceType", format));

resultsClassLoader.loadClass("com.example.ArrayAsRoot");

}

@Test
@SuppressWarnings("rawtypes")
public void propertiesWithSameNameOnDifferentObjects() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/propertiesSameName", "com.example",
config("sourceType", "json"));
final String filePath = "/" + format + "/propertiesSameName";
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example", config("sourceType", format));

Class<?> aType = resultsClassLoader.loadClass("com.example.A");
Class<?> bType = resultsClassLoader.loadClass("com.example.B");
Class<?> aFieldsType = resultsClassLoader.loadClass("com.example.Fields");
Class<?> bFieldsType = resultsClassLoader.loadClass("com.example.Fields__1");

Object deserialisedValueA = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/propertiesSameName/a.json"), aType);
Object deserialisedValueB = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/propertiesSameName/b.json"), bType);
Object deserializedValueA = objectMapper.readValue(this.getClass().getResourceAsStream(filePath("propertiesSameName/a")), aType);
Object deserializedValueB = objectMapper.readValue(this.getClass().getResourceAsStream(filePath("propertiesSameName/b")), bType);

Object aFields = aType.getMethod("getFields").invoke(deserialisedValueA);
Object aFields = aType.getMethod("getFields").invoke(deserializedValueA);
Object onlyOnA = aFieldsType.getMethod("getOnlyOnA").invoke(aFields);
assertThat(onlyOnA, is("aaa"));

Object bFields = bType.getMethod("getFields").invoke(deserialisedValueB);
Object bFields = bType.getMethod("getFields").invoke(deserializedValueB);
Object onlyOnB = bFieldsType.getMethod("getOnlyOnB").invoke(bFields);
assertThat(onlyOnB, is("bbb"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,54 @@
import static org.jsonschema2pojo.integration.util.CodeGenerationHelper.*;
import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.List;

import org.jsonschema2pojo.integration.util.Jsonschema2PojoRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;

@RunWith(Parameterized.class)
public class RealJsonExamplesIT {

@Rule public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule();
@Parameterized.Parameters(name="{0}")
public static List<Object[]> data() {
return Arrays.asList(new Object[][] {
{ "json", new ObjectMapper()},
{ "yaml", new ObjectMapper(new YAMLFactory()) }
});
}

@Rule
public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule();

private final String format;
private final ObjectMapper objectMapper;

private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
public RealJsonExamplesIT(final String format, final ObjectMapper objectMapper) {
this.format = format;
this.objectMapper = objectMapper;
}

private String filePath(String baseName) {
return "/" + format + "/" + baseName + "." + format;
}

@Test
public void getUserDataProducesValidTypes() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/examples/GetUserData.json", "com.example",
config("sourceType", "json",
"useLongIntegers", true));
final String filePath = filePath("examples/GetUserData");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example",
config("sourceType", format, "useLongIntegers", true));

Class<?> userDataType = resultsClassLoader.loadClass("com.example.GetUserData");

Object userData = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/examples/GetUserData.json"), userDataType);
Object userData = objectMapper.readValue(this.getClass().getResourceAsStream(filePath), userDataType);
Object result = userDataType.getMethod("getResult").invoke(userData);
Object data = result.getClass().getMethod("getData").invoke(result);
Object userUIPref = data.getClass().getMethod("getUserUIPref").invoke(data);
Expand All @@ -60,13 +84,14 @@ public void getUserDataProducesValidTypes() throws Exception {
@Test
public void torrentProducesValidTypes() throws Exception {

ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/json/examples/torrent.json", "com.example",
config("sourceType", "json",
final String filePath = filePath("examples/torrent");
ClassLoader resultsClassLoader = schemaRule.generateAndCompile(filePath, "com.example",
config("sourceType", format,
"propertyWordDelimiters", "_"));

Class<?> torrentType = resultsClassLoader.loadClass("com.example.Torrent");

Object torrent = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/json/examples/torrent.json"), torrentType);
Object torrent = objectMapper.readValue(this.getClass().getResourceAsStream(filePath), torrentType);

Object props = torrentType.getMethod("getProps").invoke(torrent);
Object prop0 = ((List<?>) props).get(0);
Expand Down
Loading

0 comments on commit d17503d

Please sign in to comment.