I have this following example schema:
{
"id": "http://schema.acme.com/widgets",
"$schema": "http://json-schema.org/draft-06/schema#",
"definitions": {
"bentWidget": {
"type": "object",
"required": ["angle", "baseWidget"],
"properties": {
"angle": {
"type": "number",
"minimum": 0,
"maximum": 90
},
"baseWidget": {
"$ref": "#/definitions/baseWidget"
}
}
},
"highPowerWidget": {
"type": "object",
"required": ["power", "baseWidget"],
"properties": {
"power": {
"type": "number",
"minimum": 101,
"maximum": 200
},
"baseWidget": {
"$ref": "#/definitions/baseWidget"
}
}
},
"color": {
"description": "the color of a widget",
"type": "string"
},
"baseWidget": {
"description": "The base type for a widget",
"type": "object",
"required": [
"title",
"version",
"colors"
],
"properties": {
"title": {
"type": "string",
"maximum": 100,
"minimum": 1,
"pattern": "^[a-zA-Z]+((_[a-zA-Z]+)*|([a-zA-Z]+_)*|_)"
},
"flanged": {
"type": "boolean"
},
"version": {
"type": "string",
"maximum": 64,
"minimum": 1
},
"colors": {
"type": "array",
"items": {
"$ref": "#/definitions/color"
}
}
}
}
},
"anyOf": [
{ "$ref": "#/definitions/baseWidget" },
{ "$ref": "#/definitions/bentWidget" },
{ "$ref": "#/definitions/highPowerWidget" }
]
}
and I want to test it, so I write this out to a file:
{
"type": "highPowerWidget",
"title": "foobar",
"version": "foo"
}
and then I run ajv on it from a shell
$ ajv -s widgetSchema.json -d widget-highPower.json
widget-highPower.json valid
And it tells me that it is valid, which is incorrect, a highPowerWidget must have a power property, and the "inherited" version and colors property.
I was able to test my individual schemas by removing the anyOf section and putting in something like this:
"properties": {
"testObject": {
"type": "object",
"oneOf": [
{ "$ref": "#/definitions/baseWidget" },
{ "$ref": "#/definitions/bentWidget" },
{ "$ref": "#/definitions/highPowerWidget" }
]
}
},
"required": [ "testObject" ]
and validating this JSON:
{
"testObject": {
"type" : "highPowerWidget",
"title" : "title",
"version" : "baz",
"colors" : [ "red", "green", "blue"],
"flanged" : true
}
}
But this seems wrong for two reasons.
I think I have a basic misunderstanding of how I can write, or at least test, my schemas. My goal is to have an array of objects that all validate, and a set of files which all fail. This way I can unit test my schema.
Your schema is valid. As written this would be a valid highPowerWidget:
{
"power": 150,
"baseWidget":{
"title": "SuperHighPower",
"flanged":true,
"version": "version 1",
"colors":["blue"]
}
}
I think the misunderstanding is that JSONSchema doesn't support OO style inheritance.
Instead this schema is essentially asking for a "baseWidget" property on either the highPowerWidget or bentWidget. Here's a sandbox plnkr for AJV you can test it with.
EDIT: Just thought about it and you could accomplish this removing the baseWidget property from bentWidget and highPowerWidget and instead add "allOf":[{"$ref":"#/definitions/baseWidget"}]
to each of the subwidgets. That would require them to pass baseWidget's schema. So your schema would be:
{
"id": "http://schema.acme.com/widgets",
"$schema": "http://json-schema.org/draft-06/schema#",
"definitions": {
"bentWidget": {
"type": "object",
"required": ["angle"],
"properties": {
"angle": {
"type": "number",
"minimum": 0,
"maximum": 90
}
},
allOf: [{
"$ref": "#/definitions/baseWidget"
}]
},
"highPowerWidget": {
"type": "object",
"required": ["power"],
"properties": {
"power": {
"type": "number",
"minimum": 101,
"maximum": 200
}
},
allOf: [{
"$ref": "#/definitions/baseWidget"
}]
},
"color": {
"description": "the color of a widget",
"type": "string"
},
"baseWidget": {
"description": "The base type for a widget",
"type": "object",
"required": [
"title",
"version",
"colors"
],
"properties": {
"title": {
"type": "string",
"maximum": 100,
"minimum": 1,
"pattern": "^[a-zA-Z]+((_[a-zA-Z]+)*|([a-zA-Z]+_)*|_)"
},
"flanged": {
"type": "boolean"
},
"version": {
"type": "string",
"maximum": 64,
"minimum": 1
},
"colors": {
"type": "array",
"items": {
"$ref": "#/definitions/color"
}
}
}
}
},
"anyOf": [{
"$ref": "#/definitions/baseWidget"
}, {
"$ref": "#/definitions/bentWidget"
}, {
"$ref": "#/definitions/highPowerWidget"
}]
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With