diff --git a/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ArrayIT.java b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ArrayIT.java new file mode 100644 index 0000000..6a3c08d --- /dev/null +++ b/integration-test/src/test/java/uk/gov/justice/generation/pojo/integration/test/ArrayIT.java @@ -0,0 +1,112 @@ +package uk.gov.justice.generation.pojo.integration.test; + +import static com.jayway.jsonassert.JsonAssert.with; +import static java.util.Arrays.asList; +import static org.apache.commons.io.FileUtils.cleanDirectory; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import uk.gov.justice.generation.io.files.loader.SchemaLoader; +import uk.gov.justice.generation.pojo.core.DefinitionBuilderVisitor; +import uk.gov.justice.generation.pojo.core.JsonSchemaWrapper; +import uk.gov.justice.generation.pojo.core.NameGenerator; +import uk.gov.justice.generation.pojo.generators.JavaGeneratorFactory; +import uk.gov.justice.generation.pojo.integration.utils.ClassCompiler; +import uk.gov.justice.generation.pojo.write.SourceWriter; +import uk.gov.justice.services.common.converter.jackson.ObjectMapperProducer; + +import java.io.File; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.everit.json.schema.Schema; +import org.junit.Before; +import org.junit.Test; + +public class ArrayIT { + + private final SourceWriter sourceWriter = new SourceWriter(); + private final ClassCompiler classCompiler = new ClassCompiler(); + + private final JavaGeneratorFactory javaGeneratorFactory = new JavaGeneratorFactory(); + private final NameGenerator rootFieldNameGenerator = new NameGenerator(); + private final SchemaLoader schemaLoader = new SchemaLoader(); + private final ObjectMapper objectMapper = new ObjectMapperProducer().objectMapper(); + + private File sourceOutputDirectory; + private File classesOutputDirectory; + + @Before + @SuppressWarnings("ResultOfMethodCallIgnored") + public void setup() throws Exception { + sourceOutputDirectory = new File("./target/test-generation/arrays"); + classesOutputDirectory = new File("./target/test-classes"); + + sourceOutputDirectory.mkdirs(); + classesOutputDirectory.mkdirs(); + + if (sourceOutputDirectory.exists()) { + cleanDirectory(sourceOutputDirectory); + } + } + + @Test + public void shouldAnArraySchemaDocumentWithAnArrayOfItemSchemas() throws Exception { + + final File jsonSchemaFile = new File("src/test/resources/schemas/example.recipe-added.json"); + final Schema schema = schemaLoader.loadFrom(jsonSchemaFile); + final String fieldName = rootFieldNameGenerator.rootFieldNameFrom(jsonSchemaFile); + + final DefinitionBuilderVisitor definitionBuilderVisitor = new DefinitionBuilderVisitor("uk.gov.justice.pojo.arrays"); + final JsonSchemaWrapper jsonSchemaWrapper = new JsonSchemaWrapper(schema); + + jsonSchemaWrapper.accept(fieldName, definitionBuilderVisitor); + + final List> newClasses = new ArrayList<>(); + + javaGeneratorFactory + .createClassGeneratorsFor(definitionBuilderVisitor.getDefinitions()) + .forEach(classGeneratable -> { + sourceWriter.write(classGeneratable, sourceOutputDirectory.toPath()); + final Class newClass = classCompiler.compile(classGeneratable, sourceOutputDirectory, classesOutputDirectory); + newClasses.add(newClass); + }); + + assertThat(newClasses.size(), is(2)); + assertThat(newClasses.get(0).getSimpleName(), is("Ingredients")); + assertThat(newClasses.get(1).getSimpleName(), is("RecipeAdded")); + + final Constructor ingredientsConstructor = newClasses.get(0).getConstructor( + Integer.class, + String.class); + final Constructor recipeAddedConstructor = newClasses.get(1).getConstructor( + String.class, + Boolean.class, + List.class, + String.class); + + final Object ingredient_1 = ingredientsConstructor.newInstance(1, "Eye of Newt"); + final Object ingredient_2 = ingredientsConstructor.newInstance(3, "Toe of Frog"); + + final Object regicidePie = recipeAddedConstructor.newInstance( + "Regicide Pie", + false, + asList(ingredient_1, ingredient_2), + "13" + ); + + final String json = objectMapper.writeValueAsString(regicidePie); + + with(json) + .assertThat("$.name", is("Regicide Pie")) + .assertThat("$.recipeId", is("13")) + .assertThat("$.glutenFree", is(false)) + .assertThat("$.ingredientsList[0].name", is("Eye of Newt")) + .assertThat("$.ingredientsList[0].quantity", is(1)) + .assertThat("$.ingredientsList[1].name", is("Toe of Frog")) + .assertThat("$.ingredientsList[1].quantity", is(3)) + ; + } +} diff --git a/integration-test/src/test/resources/schemas/example.recipe-added.json b/integration-test/src/test/resources/schemas/example.recipe-added.json new file mode 100644 index 0000000..cd1fad9 --- /dev/null +++ b/integration-test/src/test/resources/schemas/example.recipe-added.json @@ -0,0 +1,51 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "", + "type": "object", + "properties": { + "recipeId": { + "id": "/recipeId", + "type": "string", + "description": "Uniquely identifies the recipe", + "name": "id of recipe", + "title": "id of recipe" + }, + "name": { + "id": "/name", + "type": "string", + "description": "Name of the recipe", + "name": "Name of Cake", + "title": "Name of Cake" + }, + "glutenFree": { + "id": "/glutenFree", + "type": "boolean" + }, + "ingredients": { + "id": "/ingredients", + "type": "array", + "items": [ + { + "id": "ingredient", + "type": "object", + "properties": { + "name": { + "id": "name", + "type": "string" + }, + "quantity": { + "id": "quantity", + "type": "integer" + } + } + } + ], + "minItems": 1, + "description": "List ingredients and quantities for recipe" + } + }, + "required": [ + "name", + "ingredients" + ] +} \ No newline at end of file diff --git a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/core/JsonSchemaWrapperDelegate.java b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/core/JsonSchemaWrapperDelegate.java index 1c91fd4..139b164 100644 --- a/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/core/JsonSchemaWrapperDelegate.java +++ b/pojo-generator-core/src/main/java/uk/gov/justice/generation/pojo/core/JsonSchemaWrapperDelegate.java @@ -52,8 +52,19 @@ public void acceptArraySchema(final String fieldName, final Visitor visitor, fin final Schema allItemSchema = arraySchema.getAllItemSchema(); + if (allItemSchema != null) { + doAcceptArraySchema(fieldName, arraySchema, allItemSchema, visitor); + } else { + arraySchema + .getItemSchemas() + .forEach(schema -> doAcceptArraySchema(fieldName, arraySchema, schema, visitor)); + } + + } + + private void doAcceptArraySchema(final String fieldName, final ArraySchema arraySchema, final Schema schema, final Visitor visitor) { visitor.enter(fieldName, arraySchema); - visitChildSchema(fieldName, visitor, allItemSchema); + visitChildSchema(fieldName, visitor, schema); visitor.leave(arraySchema); } diff --git a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/core/CombinedSchemaPropertyExtractorTest.java b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/core/CombinedSchemaPropertyExtractorTest.java index 2002bba..9bd5fd0 100644 --- a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/core/CombinedSchemaPropertyExtractorTest.java +++ b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/core/CombinedSchemaPropertyExtractorTest.java @@ -9,7 +9,6 @@ import java.util.Map; -import com.fasterxml.jackson.module.jsonSchema.types.NumberSchema; import org.everit.json.schema.CombinedSchema; import org.everit.json.schema.EmptySchema; import org.everit.json.schema.ObjectSchema; diff --git a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/core/JsonSchemaWrapperDelegateTest.java b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/core/JsonSchemaWrapperDelegateTest.java index 381bdbf..29676f4 100644 --- a/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/core/JsonSchemaWrapperDelegateTest.java +++ b/pojo-generator-core/src/test/java/uk/gov/justice/generation/pojo/core/JsonSchemaWrapperDelegateTest.java @@ -1,5 +1,6 @@ package uk.gov.justice.generation.pojo.core; +import static java.util.Arrays.asList; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -111,7 +112,7 @@ public void shouldAcceptAnObjectSchema() throws Exception { } @Test - public void shouldAcceptAnArraySchema() throws Exception { + public void shouldAcceptAnArraySchemaWithAnAllItemSchema() throws Exception { final String fieldName = "fieldName"; final Visitor visitor = mock(Visitor.class); @@ -130,4 +131,29 @@ public void shouldAcceptAnArraySchema() throws Exception { inOrder.verify(jsonSchemaWrapper).accept(fieldName, visitor); inOrder.verify(visitor).leave(arraySchema); } + + @Test + public void shouldAcceptAnArraySchemaWithAListOfItemSchemas() throws Exception { + + final String fieldName = "fieldName"; + final Visitor visitor = mock(Visitor.class); + final ArraySchema arraySchema = mock(ArraySchema.class); + final Schema itemSchema_1 = mock(Schema.class); + final Schema itemSchema_2 = mock(Schema.class); + final JsonSchemaWrapper jsonSchemaWrapper_1 = mock(JsonSchemaWrapper.class); + final JsonSchemaWrapper jsonSchemaWrapper_2 = mock(JsonSchemaWrapper.class); + + when(arraySchema.getItemSchemas()).thenReturn(asList(itemSchema_1, itemSchema_2)); + when(jsonSchemaWrapperFactory.create(itemSchema_1)).thenReturn(jsonSchemaWrapper_1); + when(jsonSchemaWrapperFactory.create(itemSchema_2)).thenReturn(jsonSchemaWrapper_2); + + jsonSchemaWrapperDelegate.acceptArraySchema(fieldName, visitor, arraySchema); + + final InOrder inOrder = inOrder(visitor, jsonSchemaWrapper_1, jsonSchemaWrapper_2); + + inOrder.verify(visitor).enter(fieldName, arraySchema); + inOrder.verify(jsonSchemaWrapper_1).accept(fieldName, visitor); + inOrder.verify(jsonSchemaWrapper_2).accept(fieldName, visitor); + inOrder.verify(visitor).leave(arraySchema); + } }