Skip to content

Commit

Permalink
refactor(state): Add draft-06 meta schema to tests; Add uriKeys varia…
Browse files Browse the repository at this point in the history
…ble to contain id/$id changes; Fix boolean schema descend resolution #41
  • Loading branch information
korzio committed Sep 21, 2017
1 parent ad70e8e commit 01b3731
Show file tree
Hide file tree
Showing 5 changed files with 233 additions and 10 deletions.
7 changes: 7 additions & 0 deletions lib/utils/environment.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const properties = require('./properties');
const keywords = require('./keywords');
const validators = require('../validators');
const formats = require('./formats');
const { uriKeys } = require('./');

const contains = require('../validators/contains');
const constant = require('../validators/const');
Expand Down Expand Up @@ -58,11 +59,17 @@ const environmentConfig = {
propertyNames
});

// TODO optimize uri-reference regex... too long
Object.assign(formats, {
'json-pointer': '!/^$|^\\/(?:~(?=[01])|[^~])*$/i.test(%s)', // add empty valid string,
'uri-reference': '!/^(?:[A-Za-z][A-Za-z0-9+\\-.]*:(?:\\/\\/(?:(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:]|%[0-9A-Fa-f]{2})*@)?(?:\\[(?:(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|::(?:[0-9A-Fa-f]{1,4}:){5}|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)|[Vv][0-9A-Fa-f]+\\.[A-Za-z0-9\\-._~!$&\'()*+,;=:]+)\\]|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[A-Za-z0-9\\-._~!$&\'()*+,;=]|%[0-9A-Fa-f]{2})*)(?::[0-9]*)?(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*|\\/(?:(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)?|(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*|)(?:\\?(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*)?(?:\\#(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*)?|(?:\\/\\/(?:(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:]|%[0-9A-Fa-f]{2})*@)?(?:\\[(?:(?:(?:(?:[0-9A-Fa-f]{1,4}:){6}|::(?:[0-9A-Fa-f]{1,4}:){5}|(?:[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,1}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){3}|(?:(?:[0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})?::(?:[0-9A-Fa-f]{1,4}:){2}|(?:(?:[0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}:|(?:(?:[0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})?::)(?:[0-9A-Fa-f]{1,4}:[0-9A-Fa-f]{1,4}|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(?:(?:[0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})?::[0-9A-Fa-f]{1,4}|(?:(?:[0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})?::)|[Vv][0-9A-Fa-f]+\\.[A-Za-z0-9\\-._~!$&\'()*+,;=:]+)\\]|(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[A-Za-z0-9\\-._~!$&\'()*+,;=]|%[0-9A-Fa-f]{2})*)(?::[0-9]*)?(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*|\\/(?:(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})+(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*)?|(?:[A-Za-z0-9\\-._~!$&\'()*+,;=@]|%[0-9A-Fa-f]{2})+(?:\\/(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@]|%[0-9A-Fa-f]{2})*)*|)(?:\\?(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*)?(?:\\#(?:[A-Za-z0-9\\-._~!$&\'()*+,;=:@\\/?]|%[0-9A-Fa-f]{2})*)?)$/i.test(%s)',
'uri-template': '!/^(?:(?:[^\\x00-\\x20"\'<>%\\\\^`{|}]|%[0-9a-f]{2})|\\{[+#.\\/;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?:\\:[1-9][0-9]{0,3}|\\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?:\\:[1-9][0-9]{0,3}|\\*)?)*\\})*$/i.test(%s)',
});

if (uriKeys.indexOf('id') !== -1) {
uriKeys.splice(uriKeys.indexOf('id'), 1, '$id');
uriKeys.id = '$id';
}
},
};

Expand Down
3 changes: 3 additions & 0 deletions lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ function makeSchema(instance) {
};
}

const uriKeys = Object.assign(['id', '$ref'], { id: 'id' });

module.exports = {
cleanId,
asExpression,
Expand All @@ -198,4 +200,5 @@ module.exports = {
head,
fragment,
normalize,
uriKeys,
};
21 changes: 11 additions & 10 deletions lib/utils/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ const {
cleanId,
fragment,
transformSchema,
uriKeys,
isSchema,
} = require('./');

function State(schema = {}, env) {
Expand Down Expand Up @@ -116,7 +118,6 @@ State.prototype = Object.assign(Object.create(Array.prototype), {
}

const reversed = this.slice().reverse();
const uriKeys = ['id', '$ref'];

// find last full URI schema
let lastFullURIReference;
Expand Down Expand Up @@ -173,14 +174,14 @@ State.prototype = Object.assign(Object.create(Array.prototype), {
let parentSchema = this
.slice()
.reverse()
.find(({ id }) => !!id)
.find(({ [uriKeys.id]: id }) => !!id)
|| this[0];

// Same procedure as no path
if (path) {
// TODO make separate function ...byId
// TODO preprocess ids like it was before (concat...), then check in env separately...
const resolvedId = cleanId(makePath([parentSchema.id, path]));
const resolvedId = cleanId(makePath([parentSchema[uriKeys.id], path]));
// TODO refactor reverse, slice on every call
parentSchema = (
hasProperty(this.env.resolved, resolvedId) &&
Expand All @@ -189,7 +190,7 @@ State.prototype = Object.assign(Object.create(Array.prototype), {
this
.slice()
.reverse()
.find(({ id }) => cleanId(id) === resolvedId) ||
.find(({ [uriKeys.id]: id }) => cleanId(id) === resolvedId) ||
parentSchema;
}

Expand Down Expand Up @@ -231,24 +232,24 @@ State.prototype = Object.assign(Object.create(Array.prototype), {
const currentSchema = parts
.map(normalize)
.reduce((schema, part, index) => {
const subSchema = schema[part] || (
schema.definitions &&
schema.definitions[part]
);
let subSchema = schema[part];
if (!isSchema(subSchema)) {
subSchema = schema.definitions && schema.definitions[part];
}

if (
// last will be pushed on visit
// @see /draft4/refRemote.json:http://localhost:1234/scope_change_defs2.json
index !== parts.length - 1 &&
hasProperty(subSchema, 'id')
hasProperty(subSchema, uriKeys.id)
) {
this.push(subSchema);
}

return subSchema;
}, parentSchema);

return currentSchema || parentSchema;
return isSchema(currentSchema) ? currentSchema : parentSchema;
},
/**
* @name resolve
Expand Down
1 change: 1 addition & 0 deletions test/json-schema-test-suite.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const refs = {
'http://localhost:1234/subSchemas.json': require('json-schema-test-suite/remotes/subSchemas.json'),
'http://localhost:1234/folder/folderInteger.json': require('json-schema-test-suite/remotes/folder/folderInteger.json'),
'http://json-schema.org/draft-04/schema': require('./resources/draft-04-schema.json'),
'http://json-schema.org/draft-06/schema': require('./resources/draft-06-schema.json'),
};

const factory = function djvTestSuiteAdapter(version) {
Expand Down
211 changes: 211 additions & 0 deletions test/resources/draft-06-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
{
"$schema": "http://json-schema.org/draft-06/schema#",
"$id": "http://json-schema.org/draft-06/schema#",
"title": "Core schema meta-schema",
"definitions": {
"schemaArray": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "#"
}
},
"nonNegativeInteger": {
"type": "integer",
"minimum": 0
},
"nonNegativeIntegerDefault0": {
"allOf": [
{
"$ref": "#/definitions/nonNegativeInteger"
},
{
"default": 0
}
]
},
"simpleTypes": {
"enum": [
"array",
"boolean",
"integer",
"null",
"number",
"object",
"string"
]
},
"stringArray": {
"type": "array",
"items": {
"type": "string"
},
"uniqueItems": true,
"default": []
}
},
"type": [
"object",
"boolean"
],
"properties": {
"$id": {
"type": "string",
"format": "uri-reference"
},
"$schema": {
"type": "string",
"format": "uri"
},
"$ref": {
"type": "string",
"format": "uri-reference"
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"default": {},
"multipleOf": {
"type": "number",
"exclusiveMinimum": 0
},
"maximum": {
"type": "number"
},
"exclusiveMaximum": {
"type": "number"
},
"minimum": {
"type": "number"
},
"exclusiveMinimum": {
"type": "number"
},
"maxLength": {
"$ref": "#/definitions/nonNegativeInteger"
},
"minLength": {
"$ref": "#/definitions/nonNegativeIntegerDefault0"
},
"pattern": {
"type": "string",
"format": "regex"
},
"additionalItems": {
"$ref": "#"
},
"items": {
"anyOf": [
{
"$ref": "#"
},
{
"$ref": "#/definitions/schemaArray"
}
],
"default": {}
},
"maxItems": {
"$ref": "#/definitions/nonNegativeInteger"
},
"minItems": {
"$ref": "#/definitions/nonNegativeIntegerDefault0"
},
"uniqueItems": {
"type": "boolean",
"default": false
},
"contains": {
"$ref": "#"
},
"maxProperties": {
"$ref": "#/definitions/nonNegativeInteger"
},
"minProperties": {
"$ref": "#/definitions/nonNegativeIntegerDefault0"
},
"required": {
"$ref": "#/definitions/stringArray"
},
"additionalProperties": {
"$ref": "#"
},
"definitions": {
"type": "object",
"additionalProperties": {
"$ref": "#"
},
"default": {}
},
"properties": {
"type": "object",
"additionalProperties": {
"$ref": "#"
},
"default": {}
},
"patternProperties": {
"type": "object",
"additionalProperties": {
"$ref": "#"
},
"default": {}
},
"dependencies": {
"type": "object",
"additionalProperties": {
"anyOf": [
{
"$ref": "#"
},
{
"$ref": "#/definitions/stringArray"
}
]
}
},
"propertyNames": {
"$ref": "#"
},
"const": {},
"enum": {
"type": "array",
"minItems": 1,
"uniqueItems": true
},
"type": {
"anyOf": [
{
"$ref": "#/definitions/simpleTypes"
},
{
"type": "array",
"items": {
"$ref": "#/definitions/simpleTypes"
},
"minItems": 1,
"uniqueItems": true
}
]
},
"format": {
"type": "string"
},
"allOf": {
"$ref": "#/definitions/schemaArray"
},
"anyOf": {
"$ref": "#/definitions/schemaArray"
},
"oneOf": {
"$ref": "#/definitions/schemaArray"
},
"not": {
"$ref": "#"
}
},
"default": {}
}

0 comments on commit 01b3731

Please sign in to comment.