You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
JSV does not properly handle $ref referral from a schema to another, regardless of whether that schemas has been registered with the environment already. It apparently falls back to an open schema, and does not enforce the referred schema.
Using $ref to refer to another schema is an important tool to reuse, factor, and scale the use of schemas.
A secondary issue is that JSV does not define what happens when a referral cannot be found. I don't think JSV should require all references to resolve when a schema is created (perhaps there is a circular or resolution issue there), but when if the validator cannot find a referral when doing a validation, it should be an error.
For my particular interest, I plan to hook into JSV to tell it what to do when a referral cannot be found (perhaps look in a library, filesystem, module, or the internet); however I cannot do that if JSV does not enforce the referred schemas.
I have attached a series of tests below to illustrate (requires qunit.js, following the qunit test format included with JSV).
var env;
//calls ok(true) if no error is thrown
function okNoError(func, msg) {
try {
func();
ok(true, msg);
} catch (e) {
ok(false, msg + ': ' + e);
}
}
function setupEnv () {
env = env || require('../lib/jsv').JSV.createEnvironment("json-schema-draft-03");
// AddressBook example from http://relaxng.org/compact-tutorial-20030326.html
env.createSchema({
"type": "object",
"id": "http://example.com/addressbook.json",
"description": "AddressBook example from http://relaxng.org/compact-tutorial-20030326.html",
"properties": {
"cards": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 2,
"maxItems": 2,
"$schema":"http://json-schema.org/draft-03/schema#"
},
"required": true
}
},
"$schema":"http://json-schema.org/draft-03/schema#"
},
undefined,
"http://example.com/addressbook.json");
// Similar example, using $ref to factor part of the schema.
env.createSchema({
"type": "object",
"id": "http://example.com/addressbook_ref.json",
"description": "Similar example, using $ref to factor part of the schema.",
"properties": {
"cards": {
"type": "array",
"items": {
"$ref": "./subdir/card.json"
},
"required": true
}
},
"$schema":"http://json-schema.org/draft-03/schema#"
},
undefined,
"http://example.com/addressbook_ref.json");
// Similar example, using extends to factor part of the schema.
env.createSchema({
"type": "object",
"id": "http://example.com/addressbook_extends.json",
"description": "Similar example, using extends to factor part of the schema.",
"properties": {
"cards": {
"type": "array",
"items": {
"extends": {
"$ref": "./subdir/card.json"
}
},
"required": true
}
},
"$schema":"http://json-schema.org/draft-03/schema#"
},
undefined,
"http://example.com/addressbook_extends.json");
// The referral target schema, with a canonical id.
env.createSchema({
"type": "array",
"id": "http://example.com/subdir/card.json",
"description": "Referral target",
"items": {
"type": "string"
},
"minItems": 2,
"maxItems": 2,
"$schema":"http://json-schema.org/draft-03/schema#"
},
undefined,
"http://example.com/subdir/card.json");
}
//
//
// Tests
//
//
module("Reference Tests");
test("Self Identifying Schemas", function () {
setupEnv();
// While createSchema takes a URI argument, for V3 schemas the validator should be able
// to use the canonical id field to find it, if it has been registered.
// http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.27
env.createSchema({ "id": "http://example.com/foo.json",
"$schema":"http://json-schema.org/draft-03/schema#"
});
ok(env.findSchema("http://example.com/foo.json"), "found schema by id");
});
test("Forward Referral", function () {
setupEnv();
// A schema with a reference in it should be accepted, even if the destination schema
// hasn't been registered yet.
okNoError(function () {
env.createSchema({
"type": "object",
"id": "http://example.com/addressbook.json",
"properties": {
"cards": {
"type": "array",
"items": {
"$ref": "http://example.com/subdir/card.json"
},
"required": true
}
},
"$schema":"http://json-schema.org/draft-03/schema#"
});
}, "Can make schema with forward reference");
});
The bug was due to the way I implemented referencing into the draft 3 core schema (Hyper Schema wasn't affected by this bug). I have fixed the issue, and included your tests into the test suite. Code is up on GitHub.
JSV does not properly handle $ref referral from a schema to another, regardless of whether that schemas has been registered with the environment already. It apparently falls back to an open schema, and does not enforce the referred schema.
Using $ref to refer to another schema is an important tool to reuse, factor, and scale the use of schemas.
A secondary issue is that JSV does not define what happens when a referral cannot be found. I don't think JSV should require all references to resolve when a schema is created (perhaps there is a circular or resolution issue there), but when if the validator cannot find a referral when doing a validation, it should be an error.
For my particular interest, I plan to hook into JSV to tell it what to do when a referral cannot be found (perhaps look in a library, filesystem, module, or the internet); however I cannot do that if JSV does not enforce the referred schemas.
I have attached a series of tests below to illustrate (requires qunit.js, following the qunit test format included with JSV).
var env;
//calls ok(true) if no error is thrown
function okNoError(func, msg) {
try {
func();
ok(true, msg);
} catch (e) {
ok(false, msg + ': ' + e);
}
}
function setupEnv () {
env = env || require('../lib/jsv').JSV.createEnvironment("json-schema-draft-03");
}
//
//
// Tests
//
//
module("Reference Tests");
test("Self Identifying Schemas", function () {
test("Forward Referral", function () {
test("Validate Schema", function () {
test("Simple Referral", function () {
function validateAddressbook (test_name, schema_uri) {
var schema = { "$ref": schema_uri };
}
validateAddressbook("Explicit Schema", "http://example.com/addressbook.json");
validateAddressbook("Referring Schema", "http://example.com/addressbook_ref.json");
validateAddressbook("Extends Schema", "http://example.com/addressbook_extends.json");
The text was updated successfully, but these errors were encountered: