Loading src/main/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGenerator.scala +6 −2 Original line number Diff line number Diff line Loading @@ -11,6 +11,10 @@ import com.fasterxml.jackson.databind._ import com.fasterxml.jackson.databind.node.{ArrayNode, JsonNodeFactory, ObjectNode} import org.slf4j.LoggerFactory object JsonSchemaGenerator { val JSON_SCHEMA_DRAFT_4_URL = "http://json-schema.org/draft-04/schema#" } class JsonSchemaGenerator(rootObjectMapper: ObjectMapper, debug:Boolean = false) { import scala.collection.JavaConversions._ Loading Loading @@ -356,7 +360,7 @@ class JsonSchemaGenerator(rootObjectMapper: ObjectMapper, debug:Boolean = false) // Check if we should set this property as required val rawClass = prop.getType.getRawClass val requiredProperty:Boolean = if ( rawClass.isPrimitive && rawClass.isAssignableFrom(classOf[Boolean])) { val requiredProperty:Boolean = if ( rawClass.isPrimitive ) { // primitive boolean MUST have a value true } else if(prop.getAnnotation(classOf[NotNull]) != null) { Loading Loading @@ -410,7 +414,7 @@ class JsonSchemaGenerator(rootObjectMapper: ObjectMapper, debug:Boolean = false) val rootNode = JsonNodeFactory.instance.objectNode() // Specify that this is a v4 json schema rootNode.put("$schema", "http://json-schema.org/draft-04/schema#") rootNode.put("$schema", JsonSchemaGenerator.JSON_SCHEMA_DRAFT_4_URL) //rootNode.put("id", "http://my.site/myschema#") val definitionsHandler = new DefinitionsHandler Loading src/test/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGeneratorTest.scala +141 −21 Original line number Diff line number Diff line Loading @@ -2,12 +2,14 @@ package com.kjetland.jackson.jsonSchema import com.fasterxml.jackson.annotation.JsonValue import com.fasterxml.jackson.databind.module.SimpleModule import com.fasterxml.jackson.databind.node.ArrayNode import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper} import com.github.fge.jsonschema.main.JsonSchemaFactory import com.kjetland.jackson.jsonSchema.testData._ import org.scalatest.{FunSuite, Matchers} import scala.collection.JavaConversions._ class JsonSchemaGeneratorTest extends FunSuite with Matchers with TestData { class JsonSchemaGeneratorTest extends FunSuite with Matchers { val objectMapper = new ObjectMapper() val simpleModule = new SimpleModule() Loading @@ -17,15 +19,20 @@ class JsonSchemaGeneratorTest extends FunSuite with Matchers with TestData { val jsonSchemaGenerator = new JsonSchemaGenerator(objectMapper) val testData = new TestData{} def asPrettyJson(node:JsonNode):String = { objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(node) } // Asserts that we're able to go from object => json => equal object def assertToFromJson(o:Any): JsonNode = { assertToFromJson(o, o.getClass) } // Asserts that we're able to go from object => json => equal object // deserType might be a class which o extends (polymorphism) def assertToFromJson(o:Any, deserType:Class[_]): JsonNode = { val json = objectMapper.writeValueAsString(o) println(s"json: $json") Loading @@ -47,58 +54,165 @@ class JsonSchemaGeneratorTest extends FunSuite with Matchers with TestData { } } def generateAndValidateSchema(clazz:Class[_], jsonToTestAgainstSchema:Option[JsonNode] = None):String = { // Generates schema, validates the schema using external schema validator and // Optionally tries to validate json against the schema. def generateAndValidateSchema(clazz:Class[_], jsonToTestAgainstSchema:Option[JsonNode] = None):JsonNode = { val schema = jsonSchemaGenerator.generateJsonSchema(clazz) println("--------------------------------------------") println(asPrettyJson(schema)) assert( JsonSchemaGenerator.JSON_SCHEMA_DRAFT_4_URL == schema.at("/$schema").asText()) useSchema(schema, jsonToTestAgainstSchema) asPrettyJson(schema) schema } def assertJsonSubTypesInfo(node:JsonNode, typeParamName:String, typeName:String): Unit ={ /* "properties" : { "type" : { "type" : "string", "enum" : [ "child1" ], "default" : "child1" }, }, "title" : "child1", "required" : [ "type" ] */ assert( node.at(s"/properties/$typeParamName/type").asText() == "string" ) assert( node.at(s"/properties/$typeParamName/enum/0").asText() == typeName) assert( node.at(s"/properties/$typeParamName/default").asText() == typeName) assert( node.at(s"/title").asText() == typeName) assert( getRequiredList(node).contains(typeParamName)) } def getArrayNodeAsListOfStrings(node:JsonNode):List[String] = { node.asInstanceOf[ArrayNode].iterator().toList.map(_.asText()) } def getRequiredList(node:JsonNode):List[String] = { getArrayNodeAsListOfStrings(node.at(s"/required")) } test("regular object") { val jsonNode = assertToFromJson(child1) def getNodeViaArrayOfRefs(root:JsonNode, pathToArrayOfRefs:String, definitionName:String):JsonNode = { val nodeWhereArrayOfRefsIs:ArrayNode = root.at(pathToArrayOfRefs).asInstanceOf[ArrayNode] val arrayItemNodes = nodeWhereArrayOfRefsIs.iterator().toList val ref = arrayItemNodes.map(_.get("$ref").asText()).find( _.endsWith(s"/$definitionName")).get // use ref to look the node up val fixedRef = ref.substring(1) // Removing starting # root.at(fixedRef) } test("Generate scheme for plain class not using @JsonTypeInfo") { val jsonNode = assertToFromJson(testData.classNotExtendingAnything) val schema = generateAndValidateSchema((testData.classNotExtendingAnything).getClass, Some(jsonNode)) val schemaAsJson = generateAndValidateSchema(child1.getClass, Some(jsonNode)) assert( false == schema.at("/additionalProperties").asBoolean()) assert( schema.at("/properties/someString/type").asText() == "string") } test("polymorphism") { val jsonNode = assertToFromJson(pojoWithParent) test("Generating schema for concrete class which happens to extend class using @JsonTypeInfo") { val jsonNode = assertToFromJson(testData.child1) val schemaAsJson = generateAndValidateSchema(pojoWithParent.getClass, Some(jsonNode)) val schema = generateAndValidateSchema(testData.child1.getClass, Some(jsonNode)) assert( false == schema.at("/additionalProperties").asBoolean()) assert( schema.at("/properties/parentString/type").asText() == "string") assertJsonSubTypesInfo(schema, "type", "child1") } test("polymorphism - first Level") { val jsonNode = assertToFromJson(child1) assertToFromJson(child1, classOf[Parent]) test("Generate schema for regular class which has a property of class annotated with @JsonTypeInfo") { val jsonNode = assertToFromJson(testData.pojoWithParent) val schema = generateAndValidateSchema(testData.pojoWithParent.getClass, Some(jsonNode)) assert( false == schema.at("/additionalProperties").asBoolean()) assert( schema.at("/properties/pojoValue/type").asText() == "boolean") assertChild1(schema, "/properties/child/oneOf") assertChild2(schema, "/properties/child/oneOf") } def assertChild1(node:JsonNode, path:String): Unit ={ val child1 = getNodeViaArrayOfRefs(node, path, "Child1") assertJsonSubTypesInfo(child1, "type", "child1") assert( child1.at("/properties/parentString/type").asText() == "string" ) assert( child1.at("/properties/child1String/type").asText() == "string" ) } def assertChild2(node:JsonNode, path:String): Unit ={ val child2 = getNodeViaArrayOfRefs(node, path, "Child2") assertJsonSubTypesInfo(child2, "type", "child2") assert( child2.at("/properties/parentString/type").asText() == "string" ) assert( child2.at("/properties/child2int/type").asText() == "integer" ) } test("Generate schema for super class annotated with @JsonTypeInfo") { val jsonNode = assertToFromJson(testData.child1) assertToFromJson(testData.child1, classOf[Parent]) val schema = generateAndValidateSchema(classOf[Parent], Some(jsonNode)) assertChild1(schema, "/oneOf") assertChild2(schema, "/oneOf") val schemaAsJson = generateAndValidateSchema(classOf[Parent], Some(jsonNode)) } test("primitives") { val jsonNode = assertToFromJson(manyPrimitives) val schemaAsJson = generateAndValidateSchema(manyPrimitives.getClass, Some(jsonNode)) val jsonNode = assertToFromJson(testData.manyPrimitives) val schema = generateAndValidateSchema(testData.manyPrimitives.getClass, Some(jsonNode)) assert( schema.at("/properties/_string/type").asText() == "string" ) assert( schema.at("/properties/_integer/type").asText() == "integer" ) assert( !getRequiredList(schema).contains("_integer")) // Should allow null by default assert( schema.at("/properties/_int/type").asText() == "integer" ) assert( getRequiredList(schema).contains("_int")) // Must have a value assert( schema.at("/properties/_booleanObject/type").asText() == "boolean" ) assert( !getRequiredList(schema).contains("_booleanObject")) // Should allow null by default assert( schema.at("/properties/_booleanPrimitive/type").asText() == "boolean" ) assert( getRequiredList(schema).contains("_booleanPrimitive")) // Must be required since it must have true or false - not null assert( schema.at("/properties/_booleanObjectWithNotNull/type").asText() == "boolean" ) assert( getRequiredList(schema).contains("_booleanObjectWithNotNull")) assert( schema.at("/properties/_doubleObject/type").asText() == "number" ) assert( !getRequiredList(schema).contains("_doubleObject")) // Should allow null by default assert( schema.at("/properties/_doublePrimitive/type").asText() == "number" ) assert( getRequiredList(schema).contains("_doublePrimitive")) // Must be required since it must have a value - not null assert( schema.at("/properties/myEnum/type").asText() == "string") assert( getArrayNodeAsListOfStrings(schema.at("/properties/myEnum/enum")) == List("A", "B", "C") ) } test("custom serializer not overriding JsonSerializer.acceptJsonFormatVisitor") { val jsonNode = assertToFromJson(pojoWithCustomSerializer) val schemaAsJson = generateAndValidateSchema(pojoWithCustomSerializer.getClass, Some(jsonNode)) val jsonNode = assertToFromJson(testData.pojoWithCustomSerializer) val schema = generateAndValidateSchema(testData.pojoWithCustomSerializer.getClass, Some(jsonNode)) } test("pojoWithArrays") { val jsonNode = assertToFromJson(pojoWithArrays) val schemaAsJson = generateAndValidateSchema(pojoWithArrays.getClass, Some(jsonNode)) val jsonNode = assertToFromJson(testData.pojoWithArrays) val schema = generateAndValidateSchema(testData.pojoWithArrays.getClass, Some(jsonNode)) } test("recursivePojo") { val jsonNode = assertToFromJson(recursivePojo) val schemaAsJson = generateAndValidateSchema(recursivePojo.getClass, Some(jsonNode)) val jsonNode = assertToFromJson(testData.recursivePojo) val schema = generateAndValidateSchema(testData.recursivePojo.getClass, Some(jsonNode)) } Loading Loading @@ -128,6 +242,12 @@ trait TestData { p } val classNotExtendingAnything = { val o = new ClassNotExtendingAnything o.someString = "Something" o } val manyPrimitives = new ManyPrimitives("s1", 1, 2, true, false, true, 0.1, 0.2, MyEnum.B) val pojoWithCustomSerializer = { Loading src/test/scala/com/kjetland/jackson/jsonSchema/testData/ClassNotExtendingAnything.java 0 → 100644 +22 −0 Original line number Diff line number Diff line package com.kjetland.jackson.jsonSchema.testData; public class ClassNotExtendingAnything { public String someString; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ClassNotExtendingAnything child1 = (ClassNotExtendingAnything) o; return someString != null ? someString.equals(child1.someString) : child1.someString == null; } @Override public int hashCode() { return someString != null ? someString.hashCode() : 0; } } src/test/scala/com/kjetland/jackson/jsonSchema/testData/ManyPrimitives.java +21 −21 Original line number Diff line number Diff line Loading @@ -6,27 +6,27 @@ public class ManyPrimitives { public String _string; public Integer _integer; public int _int; public Boolean _boolean; public boolean _boolean2; public Boolean _booleanObject; public boolean _booleanPrimitive; @NotNull public Boolean _boolean3; public Double _double; public double _double2; public Boolean _booleanObjectWithNotNull; public Double _doubleObject; public double _doublePrimitive; public MyEnum myEnum; public ManyPrimitives() { } public ManyPrimitives(String _string, Integer _integer, int _int, Boolean _boolean, boolean _boolean2, Boolean _boolean3, Double _double, double _double2, MyEnum myEnum) { public ManyPrimitives(String _string, Integer _integer, int _int, Boolean _booleanObject, boolean _booleanPrimitive, Boolean _booleanObjectWithNotNull, Double _doubleObject, double _doublePrimitive, MyEnum myEnum) { this._string = _string; this._integer = _integer; this._int = _int; this._boolean = _boolean; this._boolean2 = _boolean2; this._boolean3 = _boolean3; this._double = _double; this._double2 = _double2; this._booleanObject = _booleanObject; this._booleanPrimitive = _booleanPrimitive; this._booleanObjectWithNotNull = _booleanObjectWithNotNull; this._doubleObject = _doubleObject; this._doublePrimitive = _doublePrimitive; this.myEnum = myEnum; } Loading @@ -38,13 +38,13 @@ public class ManyPrimitives { ManyPrimitives that = (ManyPrimitives) o; if (_int != that._int) return false; if (_boolean2 != that._boolean2) return false; if (Double.compare(that._double2, _double2) != 0) return false; if (_booleanPrimitive != that._booleanPrimitive) return false; if (Double.compare(that._doublePrimitive, _doublePrimitive) != 0) return false; if (_string != null ? !_string.equals(that._string) : that._string != null) return false; if (_integer != null ? !_integer.equals(that._integer) : that._integer != null) return false; if (_boolean != null ? !_boolean.equals(that._boolean) : that._boolean != null) return false; if (_boolean3 != null ? !_boolean3.equals(that._boolean3) : that._boolean3 != null) return false; if (_double != null ? !_double.equals(that._double) : that._double != null) return false; if (_booleanObject != null ? !_booleanObject.equals(that._booleanObject) : that._booleanObject != null) return false; if (_booleanObjectWithNotNull != null ? !_booleanObjectWithNotNull.equals(that._booleanObjectWithNotNull) : that._booleanObjectWithNotNull != null) return false; if (_doubleObject != null ? !_doubleObject.equals(that._doubleObject) : that._doubleObject != null) return false; return myEnum == that.myEnum; } Loading @@ -56,11 +56,11 @@ public class ManyPrimitives { result = _string != null ? _string.hashCode() : 0; result = 31 * result + (_integer != null ? _integer.hashCode() : 0); result = 31 * result + _int; result = 31 * result + (_boolean != null ? _boolean.hashCode() : 0); result = 31 * result + (_boolean2 ? 1 : 0); result = 31 * result + (_boolean3 != null ? _boolean3.hashCode() : 0); result = 31 * result + (_double != null ? _double.hashCode() : 0); temp = Double.doubleToLongBits(_double2); result = 31 * result + (_booleanObject != null ? _booleanObject.hashCode() : 0); result = 31 * result + (_booleanPrimitive ? 1 : 0); result = 31 * result + (_booleanObjectWithNotNull != null ? _booleanObjectWithNotNull.hashCode() : 0); result = 31 * result + (_doubleObject != null ? _doubleObject.hashCode() : 0); temp = Double.doubleToLongBits(_doublePrimitive); result = 31 * result + (int) (temp ^ (temp >>> 32)); result = 31 * result + (myEnum != null ? myEnum.hashCode() : 0); return result; Loading Loading
src/main/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGenerator.scala +6 −2 Original line number Diff line number Diff line Loading @@ -11,6 +11,10 @@ import com.fasterxml.jackson.databind._ import com.fasterxml.jackson.databind.node.{ArrayNode, JsonNodeFactory, ObjectNode} import org.slf4j.LoggerFactory object JsonSchemaGenerator { val JSON_SCHEMA_DRAFT_4_URL = "http://json-schema.org/draft-04/schema#" } class JsonSchemaGenerator(rootObjectMapper: ObjectMapper, debug:Boolean = false) { import scala.collection.JavaConversions._ Loading Loading @@ -356,7 +360,7 @@ class JsonSchemaGenerator(rootObjectMapper: ObjectMapper, debug:Boolean = false) // Check if we should set this property as required val rawClass = prop.getType.getRawClass val requiredProperty:Boolean = if ( rawClass.isPrimitive && rawClass.isAssignableFrom(classOf[Boolean])) { val requiredProperty:Boolean = if ( rawClass.isPrimitive ) { // primitive boolean MUST have a value true } else if(prop.getAnnotation(classOf[NotNull]) != null) { Loading Loading @@ -410,7 +414,7 @@ class JsonSchemaGenerator(rootObjectMapper: ObjectMapper, debug:Boolean = false) val rootNode = JsonNodeFactory.instance.objectNode() // Specify that this is a v4 json schema rootNode.put("$schema", "http://json-schema.org/draft-04/schema#") rootNode.put("$schema", JsonSchemaGenerator.JSON_SCHEMA_DRAFT_4_URL) //rootNode.put("id", "http://my.site/myschema#") val definitionsHandler = new DefinitionsHandler Loading
src/test/scala/com/kjetland/jackson/jsonSchema/JsonSchemaGeneratorTest.scala +141 −21 Original line number Diff line number Diff line Loading @@ -2,12 +2,14 @@ package com.kjetland.jackson.jsonSchema import com.fasterxml.jackson.annotation.JsonValue import com.fasterxml.jackson.databind.module.SimpleModule import com.fasterxml.jackson.databind.node.ArrayNode import com.fasterxml.jackson.databind.{JsonNode, ObjectMapper} import com.github.fge.jsonschema.main.JsonSchemaFactory import com.kjetland.jackson.jsonSchema.testData._ import org.scalatest.{FunSuite, Matchers} import scala.collection.JavaConversions._ class JsonSchemaGeneratorTest extends FunSuite with Matchers with TestData { class JsonSchemaGeneratorTest extends FunSuite with Matchers { val objectMapper = new ObjectMapper() val simpleModule = new SimpleModule() Loading @@ -17,15 +19,20 @@ class JsonSchemaGeneratorTest extends FunSuite with Matchers with TestData { val jsonSchemaGenerator = new JsonSchemaGenerator(objectMapper) val testData = new TestData{} def asPrettyJson(node:JsonNode):String = { objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(node) } // Asserts that we're able to go from object => json => equal object def assertToFromJson(o:Any): JsonNode = { assertToFromJson(o, o.getClass) } // Asserts that we're able to go from object => json => equal object // deserType might be a class which o extends (polymorphism) def assertToFromJson(o:Any, deserType:Class[_]): JsonNode = { val json = objectMapper.writeValueAsString(o) println(s"json: $json") Loading @@ -47,58 +54,165 @@ class JsonSchemaGeneratorTest extends FunSuite with Matchers with TestData { } } def generateAndValidateSchema(clazz:Class[_], jsonToTestAgainstSchema:Option[JsonNode] = None):String = { // Generates schema, validates the schema using external schema validator and // Optionally tries to validate json against the schema. def generateAndValidateSchema(clazz:Class[_], jsonToTestAgainstSchema:Option[JsonNode] = None):JsonNode = { val schema = jsonSchemaGenerator.generateJsonSchema(clazz) println("--------------------------------------------") println(asPrettyJson(schema)) assert( JsonSchemaGenerator.JSON_SCHEMA_DRAFT_4_URL == schema.at("/$schema").asText()) useSchema(schema, jsonToTestAgainstSchema) asPrettyJson(schema) schema } def assertJsonSubTypesInfo(node:JsonNode, typeParamName:String, typeName:String): Unit ={ /* "properties" : { "type" : { "type" : "string", "enum" : [ "child1" ], "default" : "child1" }, }, "title" : "child1", "required" : [ "type" ] */ assert( node.at(s"/properties/$typeParamName/type").asText() == "string" ) assert( node.at(s"/properties/$typeParamName/enum/0").asText() == typeName) assert( node.at(s"/properties/$typeParamName/default").asText() == typeName) assert( node.at(s"/title").asText() == typeName) assert( getRequiredList(node).contains(typeParamName)) } def getArrayNodeAsListOfStrings(node:JsonNode):List[String] = { node.asInstanceOf[ArrayNode].iterator().toList.map(_.asText()) } def getRequiredList(node:JsonNode):List[String] = { getArrayNodeAsListOfStrings(node.at(s"/required")) } test("regular object") { val jsonNode = assertToFromJson(child1) def getNodeViaArrayOfRefs(root:JsonNode, pathToArrayOfRefs:String, definitionName:String):JsonNode = { val nodeWhereArrayOfRefsIs:ArrayNode = root.at(pathToArrayOfRefs).asInstanceOf[ArrayNode] val arrayItemNodes = nodeWhereArrayOfRefsIs.iterator().toList val ref = arrayItemNodes.map(_.get("$ref").asText()).find( _.endsWith(s"/$definitionName")).get // use ref to look the node up val fixedRef = ref.substring(1) // Removing starting # root.at(fixedRef) } test("Generate scheme for plain class not using @JsonTypeInfo") { val jsonNode = assertToFromJson(testData.classNotExtendingAnything) val schema = generateAndValidateSchema((testData.classNotExtendingAnything).getClass, Some(jsonNode)) val schemaAsJson = generateAndValidateSchema(child1.getClass, Some(jsonNode)) assert( false == schema.at("/additionalProperties").asBoolean()) assert( schema.at("/properties/someString/type").asText() == "string") } test("polymorphism") { val jsonNode = assertToFromJson(pojoWithParent) test("Generating schema for concrete class which happens to extend class using @JsonTypeInfo") { val jsonNode = assertToFromJson(testData.child1) val schemaAsJson = generateAndValidateSchema(pojoWithParent.getClass, Some(jsonNode)) val schema = generateAndValidateSchema(testData.child1.getClass, Some(jsonNode)) assert( false == schema.at("/additionalProperties").asBoolean()) assert( schema.at("/properties/parentString/type").asText() == "string") assertJsonSubTypesInfo(schema, "type", "child1") } test("polymorphism - first Level") { val jsonNode = assertToFromJson(child1) assertToFromJson(child1, classOf[Parent]) test("Generate schema for regular class which has a property of class annotated with @JsonTypeInfo") { val jsonNode = assertToFromJson(testData.pojoWithParent) val schema = generateAndValidateSchema(testData.pojoWithParent.getClass, Some(jsonNode)) assert( false == schema.at("/additionalProperties").asBoolean()) assert( schema.at("/properties/pojoValue/type").asText() == "boolean") assertChild1(schema, "/properties/child/oneOf") assertChild2(schema, "/properties/child/oneOf") } def assertChild1(node:JsonNode, path:String): Unit ={ val child1 = getNodeViaArrayOfRefs(node, path, "Child1") assertJsonSubTypesInfo(child1, "type", "child1") assert( child1.at("/properties/parentString/type").asText() == "string" ) assert( child1.at("/properties/child1String/type").asText() == "string" ) } def assertChild2(node:JsonNode, path:String): Unit ={ val child2 = getNodeViaArrayOfRefs(node, path, "Child2") assertJsonSubTypesInfo(child2, "type", "child2") assert( child2.at("/properties/parentString/type").asText() == "string" ) assert( child2.at("/properties/child2int/type").asText() == "integer" ) } test("Generate schema for super class annotated with @JsonTypeInfo") { val jsonNode = assertToFromJson(testData.child1) assertToFromJson(testData.child1, classOf[Parent]) val schema = generateAndValidateSchema(classOf[Parent], Some(jsonNode)) assertChild1(schema, "/oneOf") assertChild2(schema, "/oneOf") val schemaAsJson = generateAndValidateSchema(classOf[Parent], Some(jsonNode)) } test("primitives") { val jsonNode = assertToFromJson(manyPrimitives) val schemaAsJson = generateAndValidateSchema(manyPrimitives.getClass, Some(jsonNode)) val jsonNode = assertToFromJson(testData.manyPrimitives) val schema = generateAndValidateSchema(testData.manyPrimitives.getClass, Some(jsonNode)) assert( schema.at("/properties/_string/type").asText() == "string" ) assert( schema.at("/properties/_integer/type").asText() == "integer" ) assert( !getRequiredList(schema).contains("_integer")) // Should allow null by default assert( schema.at("/properties/_int/type").asText() == "integer" ) assert( getRequiredList(schema).contains("_int")) // Must have a value assert( schema.at("/properties/_booleanObject/type").asText() == "boolean" ) assert( !getRequiredList(schema).contains("_booleanObject")) // Should allow null by default assert( schema.at("/properties/_booleanPrimitive/type").asText() == "boolean" ) assert( getRequiredList(schema).contains("_booleanPrimitive")) // Must be required since it must have true or false - not null assert( schema.at("/properties/_booleanObjectWithNotNull/type").asText() == "boolean" ) assert( getRequiredList(schema).contains("_booleanObjectWithNotNull")) assert( schema.at("/properties/_doubleObject/type").asText() == "number" ) assert( !getRequiredList(schema).contains("_doubleObject")) // Should allow null by default assert( schema.at("/properties/_doublePrimitive/type").asText() == "number" ) assert( getRequiredList(schema).contains("_doublePrimitive")) // Must be required since it must have a value - not null assert( schema.at("/properties/myEnum/type").asText() == "string") assert( getArrayNodeAsListOfStrings(schema.at("/properties/myEnum/enum")) == List("A", "B", "C") ) } test("custom serializer not overriding JsonSerializer.acceptJsonFormatVisitor") { val jsonNode = assertToFromJson(pojoWithCustomSerializer) val schemaAsJson = generateAndValidateSchema(pojoWithCustomSerializer.getClass, Some(jsonNode)) val jsonNode = assertToFromJson(testData.pojoWithCustomSerializer) val schema = generateAndValidateSchema(testData.pojoWithCustomSerializer.getClass, Some(jsonNode)) } test("pojoWithArrays") { val jsonNode = assertToFromJson(pojoWithArrays) val schemaAsJson = generateAndValidateSchema(pojoWithArrays.getClass, Some(jsonNode)) val jsonNode = assertToFromJson(testData.pojoWithArrays) val schema = generateAndValidateSchema(testData.pojoWithArrays.getClass, Some(jsonNode)) } test("recursivePojo") { val jsonNode = assertToFromJson(recursivePojo) val schemaAsJson = generateAndValidateSchema(recursivePojo.getClass, Some(jsonNode)) val jsonNode = assertToFromJson(testData.recursivePojo) val schema = generateAndValidateSchema(testData.recursivePojo.getClass, Some(jsonNode)) } Loading Loading @@ -128,6 +242,12 @@ trait TestData { p } val classNotExtendingAnything = { val o = new ClassNotExtendingAnything o.someString = "Something" o } val manyPrimitives = new ManyPrimitives("s1", 1, 2, true, false, true, 0.1, 0.2, MyEnum.B) val pojoWithCustomSerializer = { Loading
src/test/scala/com/kjetland/jackson/jsonSchema/testData/ClassNotExtendingAnything.java 0 → 100644 +22 −0 Original line number Diff line number Diff line package com.kjetland.jackson.jsonSchema.testData; public class ClassNotExtendingAnything { public String someString; @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ClassNotExtendingAnything child1 = (ClassNotExtendingAnything) o; return someString != null ? someString.equals(child1.someString) : child1.someString == null; } @Override public int hashCode() { return someString != null ? someString.hashCode() : 0; } }
src/test/scala/com/kjetland/jackson/jsonSchema/testData/ManyPrimitives.java +21 −21 Original line number Diff line number Diff line Loading @@ -6,27 +6,27 @@ public class ManyPrimitives { public String _string; public Integer _integer; public int _int; public Boolean _boolean; public boolean _boolean2; public Boolean _booleanObject; public boolean _booleanPrimitive; @NotNull public Boolean _boolean3; public Double _double; public double _double2; public Boolean _booleanObjectWithNotNull; public Double _doubleObject; public double _doublePrimitive; public MyEnum myEnum; public ManyPrimitives() { } public ManyPrimitives(String _string, Integer _integer, int _int, Boolean _boolean, boolean _boolean2, Boolean _boolean3, Double _double, double _double2, MyEnum myEnum) { public ManyPrimitives(String _string, Integer _integer, int _int, Boolean _booleanObject, boolean _booleanPrimitive, Boolean _booleanObjectWithNotNull, Double _doubleObject, double _doublePrimitive, MyEnum myEnum) { this._string = _string; this._integer = _integer; this._int = _int; this._boolean = _boolean; this._boolean2 = _boolean2; this._boolean3 = _boolean3; this._double = _double; this._double2 = _double2; this._booleanObject = _booleanObject; this._booleanPrimitive = _booleanPrimitive; this._booleanObjectWithNotNull = _booleanObjectWithNotNull; this._doubleObject = _doubleObject; this._doublePrimitive = _doublePrimitive; this.myEnum = myEnum; } Loading @@ -38,13 +38,13 @@ public class ManyPrimitives { ManyPrimitives that = (ManyPrimitives) o; if (_int != that._int) return false; if (_boolean2 != that._boolean2) return false; if (Double.compare(that._double2, _double2) != 0) return false; if (_booleanPrimitive != that._booleanPrimitive) return false; if (Double.compare(that._doublePrimitive, _doublePrimitive) != 0) return false; if (_string != null ? !_string.equals(that._string) : that._string != null) return false; if (_integer != null ? !_integer.equals(that._integer) : that._integer != null) return false; if (_boolean != null ? !_boolean.equals(that._boolean) : that._boolean != null) return false; if (_boolean3 != null ? !_boolean3.equals(that._boolean3) : that._boolean3 != null) return false; if (_double != null ? !_double.equals(that._double) : that._double != null) return false; if (_booleanObject != null ? !_booleanObject.equals(that._booleanObject) : that._booleanObject != null) return false; if (_booleanObjectWithNotNull != null ? !_booleanObjectWithNotNull.equals(that._booleanObjectWithNotNull) : that._booleanObjectWithNotNull != null) return false; if (_doubleObject != null ? !_doubleObject.equals(that._doubleObject) : that._doubleObject != null) return false; return myEnum == that.myEnum; } Loading @@ -56,11 +56,11 @@ public class ManyPrimitives { result = _string != null ? _string.hashCode() : 0; result = 31 * result + (_integer != null ? _integer.hashCode() : 0); result = 31 * result + _int; result = 31 * result + (_boolean != null ? _boolean.hashCode() : 0); result = 31 * result + (_boolean2 ? 1 : 0); result = 31 * result + (_boolean3 != null ? _boolean3.hashCode() : 0); result = 31 * result + (_double != null ? _double.hashCode() : 0); temp = Double.doubleToLongBits(_double2); result = 31 * result + (_booleanObject != null ? _booleanObject.hashCode() : 0); result = 31 * result + (_booleanPrimitive ? 1 : 0); result = 31 * result + (_booleanObjectWithNotNull != null ? _booleanObjectWithNotNull.hashCode() : 0); result = 31 * result + (_doubleObject != null ? _doubleObject.hashCode() : 0); temp = Double.doubleToLongBits(_doublePrimitive); result = 31 * result + (int) (temp ^ (temp >>> 32)); result = 31 * result + (myEnum != null ? myEnum.hashCode() : 0); return result; Loading