Skip to content

Commit

Permalink
Allow noline schemas and custom file extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
trickl committed Oct 14, 2019
1 parent 4e5ec8d commit 380daf4
Show file tree
Hide file tree
Showing 7 changed files with 126 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
import com.trickl.assertj.core.api.json.JsonContainer;
import java.io.BufferedWriter;
import java.io.FileWriter;
Expand All @@ -28,6 +29,10 @@
public abstract class AbstractJsonObjectAssert<S extends AbstractJsonObjectAssert<S>>
extends AbstractAssert<S, JsonObject> {

private static final String DEFAULT_JSON_DATA_FILE_EXT = ".example.json";

private static final String DEFAULT_SCHEMA_FILE_EXT = ".schema.json";

private ObjectMapper objectMapper = new ObjectMapper();

private Path schemaResourcePath = null;
Expand All @@ -40,6 +45,12 @@ public abstract class AbstractJsonObjectAssert<S extends AbstractJsonObjectAsser

private String projectDir = null;

private boolean noInlineSchemas = false;

private String jsonDataFileExtension = DEFAULT_JSON_DATA_FILE_EXT;

private String schemaFileExtension = DEFAULT_SCHEMA_FILE_EXT;

public AbstractJsonObjectAssert(JsonObject actual, Class<?> selfType) {
super(actual, selfType);
}
Expand All @@ -52,7 +63,7 @@ public AbstractJsonObjectAssert(JsonObject actual, Class<?> selfType) {
public S serializesAsExpected() {
if (serializationResourcePath == null) {
serializationResourcePath =
classAsResourcePathConvention(actual.getObject().getClass(), ".example.json");
classAsResourcePathConvention(actual.getObject().getClass(), jsonDataFileExtension);
}

Path actualPath = null;
Expand All @@ -77,7 +88,7 @@ public S serializesAsExpected() {
public S deserializesAsExpected() {
if (deserializationResourceUrl == null) {
deserializationResourceUrl =
classAsResourceUrlConvention(actual.getObject().getClass(), ".example.json");
classAsResourceUrlConvention(actual.getObject().getClass(), jsonDataFileExtension);
}

assertThat(deserialize(deserializationResourceUrl, actual.getObject().getClass()))
Expand All @@ -93,7 +104,7 @@ public S deserializesAsExpected() {
public S deserializesWithoutError() {
if (deserializationResourceUrl == null) {
deserializationResourceUrl =
classAsResourceUrlConvention(actual.getObject().getClass(), ".example.json");
classAsResourceUrlConvention(actual.getObject().getClass(), jsonDataFileExtension);
}

assertThat(deserialize(deserializationResourceUrl, actual.getObject().getClass()))
Expand All @@ -109,7 +120,8 @@ public S deserializesWithoutError() {
public S schemaAsExpected() {
if (schemaResourcePath == null) {
schemaResourcePath =
classAsResourcePathConvention(actual.getObject().getClass(), ".schema.json");
classAsResourcePathConvention(actual.getObject().getClass(),
schemaFileExtension);
}

Path actualPath = null;
Expand Down Expand Up @@ -172,27 +184,47 @@ public S doNotCreateExpectedIfAbsent() {
return myself;
}

private <T> T deserialize(URL value, Class<T> clazz) {
public S withNoInlineSchemas() {
noInlineSchemas = true;
return myself;
}

public S withJsonDataFileExtension(String extension) {
jsonDataFileExtension = extension;
return myself;
}

public S withSchemaFileExtension(String extension) {
schemaFileExtension = extension;
return myself;
}

protected <T> T deserialize(URL value, Class<T> clazz) {
try {
return objectMapper.readValue(value, (Class<T>) clazz);
} catch (IOException e) {
throw new UncheckedIOException("Unable to deserialize JSON", e);
}
}

private String serialize(Object obj) {
protected String serialize(Object obj) {
try {
return objectMapper.writeValueAsString(obj);
} catch (IOException e) {
throw new UncheckedIOException("Unable to serialize JSON", e);
}
}

private String schema(Object obj) {
protected String schema(Object obj) {
try {
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(objectMapper);
JsonSchema schema = schemaGen.generateSchema(actual.getObject().getClass());
return objectMapper.writeValueAsString(schema);
SchemaFactoryWrapper visitor = new SchemaFactoryWrapper();
if (noInlineSchemas) {
visitor.setVisitorContext(new NoInlineSchemaVisitorContext());
}
objectMapper.acceptJsonFormatVisitor(actual.getObject().getClass(), visitor);
JsonSchema schema = visitor.finalSchema();
return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);

} catch (IOException e) {
throw new UncheckedIOException("Unable to generate JSON schema", e);
}
Expand All @@ -206,12 +238,12 @@ private JsonContainer safeJson(Path path) {
}
}

private URL classAsResourceUrlConvention(Class<?> clazz, String extension) {
protected URL classAsResourceUrlConvention(Class<?> clazz, String extension) {
String resourceName = clazz.getSimpleName() + extension;
return clazz.getResource(resourceName);
}

private Path classAsResourcePathConvention(Class<?> clazz, String extension) {
protected Path classAsResourcePathConvention(Class<?> clazz, String extension) {
String projectDirectory = projectDir;
if (projectDirectory == null) {
projectDirectory = getProjectDirectoryFromLocalClazz(clazz);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.trickl.assertj.core.api.json.serialize;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.module.jsonSchema.factories.VisitorContext;

public class NoInlineSchemaVisitorContext extends VisitorContext {
@Override
public String getSeenSchemaUri(JavaType javaType) {
if (javaType != null && !javaType.isPrimitive()) {
return javaTypeToUrn(javaType);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import java.util.Map;

import com.trickl.assertj.examples.Example;
import com.trickl.assertj.examples.NestedExample;

import org.junit.Test;

/**
Expand Down Expand Up @@ -68,4 +70,20 @@ public void should_pass_on_schema_match() {
assertThat(example)
.schemaAsExpected();
}

@Test
public void should_respect_no_inlining() {
NestedExample nested = new NestedExample();
assertThat(nested)
.withNoInlineSchemas()
.schemaAsExpected();
}

@Test
public void should_respect_allow_inlining() {
NestedExample nested = new NestedExample();
assertThat(nested)
.withSchemaFileExtension(".schema2.json")
.schemaAsExpected();
}
}
6 changes: 3 additions & 3 deletions src/test/java/com/trickl/assertj/examples/Example.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

@Data
public class Example {
@JsonProperty("my-field")
@JsonPropertyDescription("Description of my field")
private String myField;
@JsonProperty("my-field")
@JsonPropertyDescription("Description of my field")
private String myField;
}
13 changes: 13 additions & 0 deletions src/test/java/com/trickl/assertj/examples/NestedExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.trickl.assertj.examples;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

@Data
public class NestedExample {
@JsonProperty("first-example")
private Example firstExample;

@JsonProperty("second-example")
private Example secondExample;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"id": "urn:jsonschema:com:trickl:assertj:examples:NestedExample",
"type": "object",
"properties": {
"second-example": {
"type": "object",
"$ref": "urn:jsonschema:com:trickl:assertj:examples:Example"
},
"first-example": {
"type": "object",
"$ref": "urn:jsonschema:com:trickl:assertj:examples:Example"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"id": "urn:jsonschema:com:trickl:assertj:examples:NestedExample",
"type": "object",
"properties": {
"second-example": {
"type": "object",
"$ref": "urn:jsonschema:com:trickl:assertj:examples:Example"
},
"first-example": {
"id": "urn:jsonschema:com:trickl:assertj:examples:Example",
"type": "object",
"properties": {
"my-field": {
"description": "Description of my field",
"type": "string"
}
}
}
}
}

0 comments on commit 380daf4

Please sign in to comment.