From 0021032091a88e057f341431f27eb77d47700fcd Mon Sep 17 00:00:00 2001 From: Evgeny Poberezkin Date: Sun, 31 May 2015 10:46:44 +0100 Subject: [PATCH] removed dataType parameter --- lib/compile/index.js | 63 +++++++++++++++++++++++---- lib/compile/rules/$ref.dot.js | 4 +- lib/compile/rules/allOf.dot.js | 4 +- lib/compile/rules/anyOf.dot.js | 4 +- lib/compile/rules/dependencies.dot.js | 4 +- lib/compile/rules/enum.dot.js | 9 +--- lib/compile/rules/items.dot.js | 8 ++-- lib/compile/rules/not.dot.js | 4 +- lib/compile/rules/oneOf.dot.js | 4 +- lib/compile/rules/properties.dot.js | 5 +-- lib/compile/rules/type.dot.js | 43 +++--------------- lib/compile/rules/uniqueItems.dot.js | 2 +- lib/compile/validate.dot.js | 7 ++- package.json | 2 +- spec/json-schema.spec.js | 7 +-- 15 files changed, 88 insertions(+), 82 deletions(-) diff --git a/lib/compile/index.js b/lib/compile/index.js index 272605c..570db36 100644 --- a/lib/compile/index.js +++ b/lib/compile/index.js @@ -22,8 +22,10 @@ function compile(schema) { RULES: RULES, validate: validateTemplate, copy: copy, + toHash: toHash, resolveRef: resolveRef, - getDataType: getDataType, + checkDataType: checkDataType, + checkDataTypes: checkDataTypes, escapeQuotes: escapeQuotes, stableStringify: stableStringify, opts: this.opts @@ -54,13 +56,6 @@ function compile(schema) { */ -function getDataType(data) { - if (data === null) return 'null'; - if (Array.isArray(data)) return 'array'; - return typeof data; -} - - function copy(o, to) { to = to || {}; for (var key in o) to[key] = o[key]; @@ -68,6 +63,58 @@ function copy(o, to) { } +function getDataType(data) { + if (data === null) return 'null'; + if (Array.isArray(data)) return 'array'; + return typeof data; +} + + +function checkDataType(dataType) { + switch (dataType) { + case 'null': return 'data === null'; + case 'array': return 'Array.isArray(data)'; + case 'object': return '(data && typeof data == "object" && !Array.isArray(data))'; + // case 'object': return 'Object.prototype.toString.call(data).slice(8,-1) == "Object"'; + case 'integer': return '(typeof data == "number" && !(data % 1))' + default: return 'typeof data == "' + dataType + '"'; + } +} + + +function checkDataTypes(dataTypes) { + switch (dataTypes.length) { + case 0: return 'true'; + case 1: return checkDataType(dataTypes[0]); + default: + var code = '' + var types = toHash(dataTypes); + if (types.array && types.object) { + code = types.null ? '(': '(data && ' + code += 'typeof data == "object")'; + delete types.null; + delete types.array; + delete types.object; + } + if (types.number) delete types.integer; + for (var t in types) + code += (code ? '||' : '' ) + checkDataType(t); + + return code; + } +} + + +function toHash(arr, func) { + var hash = {}; + arr.forEach(function (item) { + if (func) item = func(item); + hash[item] = true; + }); + return hash; +} + + function escapeQuotes(str) { return str.replace(/"/g, '\\"'); } diff --git a/lib/compile/rules/$ref.dot.js b/lib/compile/rules/$ref.dot.js index 8af0bdf..c2d00dd 100644 --- a/lib/compile/rules/$ref.dot.js +++ b/lib/compile/rules/$ref.dot.js @@ -1,8 +1,8 @@ -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; {{? it.resolveRef(it.schema) }} - var result = validateRef('{{= it.schema }}', data, dataType, dataPath); + var result = validateRef('{{= it.schema }}', data, dataPath); if (!result.valid) validate.errors.push.apply(validate.errors, result.errors); return result.valid; diff --git a/lib/compile/rules/allOf.dot.js b/lib/compile/rules/allOf.dot.js index bf8bd01..b7cc62e 100644 --- a/lib/compile/rules/allOf.dot.js +++ b/lib/compile/rules/allOf.dot.js @@ -1,4 +1,4 @@ -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; {{? it.opts.allErrors }} var errs = validate.errors.length; {{?}} @@ -11,7 +11,7 @@ function (data, dataType, dataPath) { }} {{? !it.opts.allErrors }} var valid = {{?}} - ({{= it.validate($it) }})(data, dataType, dataPath); + ({{= it.validate($it) }})(data, dataPath); {{? !it.opts.allErrors }} if (!valid) return false; {{?}} {{~}} diff --git a/lib/compile/rules/anyOf.dot.js b/lib/compile/rules/anyOf.dot.js index 2dd14f3..bb71052 100644 --- a/lib/compile/rules/anyOf.dot.js +++ b/lib/compile/rules/anyOf.dot.js @@ -1,4 +1,4 @@ -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; var errs = validate.errors.length; @@ -10,7 +10,7 @@ function (data, dataType, dataPath) { $it.schemaPath = it.schemaPath + '[' + $i + ']'; }} - var valid = ({{= it.validate($it) }})(data, dataType, dataPath); + var valid = ({{= it.validate($it) }})(data, dataPath); if (valid) { validate.errors.length = errs; diff --git a/lib/compile/rules/dependencies.dot.js b/lib/compile/rules/dependencies.dot.js index 6bb3591..8917602 100644 --- a/lib/compile/rules/dependencies.dot.js +++ b/lib/compile/rules/dependencies.dot.js @@ -1,4 +1,4 @@ -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; {{? it.opts.allErrors }} var errs = validate.errors.length; {{?}} @@ -41,7 +41,7 @@ function (data, dataType, dataPath) { }} {{? !it.opts.allErrors }} var valid = {{?}} - ({{= it.validate($it) }})(data, dataType, dataPath); + ({{= it.validate($it) }})(data, dataPath); {{? !it.opts.allErrors }} if (!valid) return false; {{?}} } diff --git a/lib/compile/rules/enum.dot.js b/lib/compile/rules/enum.dot.js index da2257c..fa30558 100644 --- a/lib/compile/rules/enum.dot.js +++ b/lib/compile/rules/enum.dot.js @@ -1,13 +1,8 @@ -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; /* TODO change to inline */ - {{ - var $itemsHash = {}; - it.schema.forEach(function ($item) { - $itemsHash[it.stableStringify($item)] = true; - }); - }} + {{ var $itemsHash = it.toHash(it.schema, it.stableStringify); }} var itemsHash = {{= JSON.stringify($itemsHash) }}; var valid = itemsHash[stableStringify(data)]; diff --git a/lib/compile/rules/items.dot.js b/lib/compile/rules/items.dot.js index a88c605..a9ef0e0 100644 --- a/lib/compile/rules/items.dot.js +++ b/lib/compile/rules/items.dot.js @@ -1,17 +1,16 @@ {{## def.validateItems:startFrom: for (var i = {{= startFrom }}; i < data.length; i++) { var _data = data[i] - , _dataType = getDataType(_data) , _dataPath = dataPath + '[' + i + ']'; {{? !it.opts.allErrors }} var valid = {{?}} - validateItems(_data, _dataType, _dataPath); + validateItems(_data, _dataPath); {{? !it.opts.allErrors }} if (!valid) return false; {{?}} } #}} -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; {{? it.opts.allErrors }} var errs = validate.errors.length; {{?}} @@ -41,11 +40,10 @@ function (data, dataType, dataPath) { }} var _data = data[{{= $index }}] - , _dataType = getDataType(_data) , _dataPath = dataPath + '[{{= $index }}]'; {{? !it.opts.allErrors }} var valid = {{?}} - ({{= it.validate($it) }})(_data, _dataType, _dataPath); + ({{= it.validate($it) }})(_data, _dataPath); {{? !it.opts.allErrors }} if (!valid) return false; {{?}} } diff --git a/lib/compile/rules/not.dot.js b/lib/compile/rules/not.dot.js index 65916cc..271c6f2 100644 --- a/lib/compile/rules/not.dot.js +++ b/lib/compile/rules/not.dot.js @@ -1,9 +1,9 @@ -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; var errs = validate.errors.length; - var valid = ({{= it.validate(it) }})(data, dataType, dataPath); + var valid = ({{= it.validate(it) }})(data, dataPath); valid = !valid; if (valid) validate.errors.length = errs; diff --git a/lib/compile/rules/oneOf.dot.js b/lib/compile/rules/oneOf.dot.js index bbf02af..0ec962d 100644 --- a/lib/compile/rules/oneOf.dot.js +++ b/lib/compile/rules/oneOf.dot.js @@ -1,4 +1,4 @@ -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; var foundValid = false @@ -11,7 +11,7 @@ function (data, dataType, dataPath) { $it.schemaPath = it.schemaPath + '[' + $i + ']'; }} - var valid = ({{= it.validate($it) }})(data, dataType, dataPath); + var valid = ({{= it.validate($it) }})(data, dataPath); if (valid) { if (foundValid) { diff --git a/lib/compile/rules/properties.dot.js b/lib/compile/rules/properties.dot.js index 80855eb..15645e6 100644 --- a/lib/compile/rules/properties.dot.js +++ b/lib/compile/rules/properties.dot.js @@ -1,15 +1,14 @@ {{## def.validateProperty:useKey: var _data = data[{{= useKey }}] - , _dataType = getDataType(_data) , _dataPath = dataPath + '.' + {{= useKey }}; {{? !it.opts.allErrors }} var valid = {{?}} - ({{= it.validate($it) }})(_data, _dataType, _dataPath); + ({{= it.validate($it) }})(_data, _dataPath); {{? !it.opts.allErrors }} if (!valid) return false; {{?}} #}} -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; var errs = validate.errors.length; diff --git a/lib/compile/rules/type.dot.js b/lib/compile/rules/type.dot.js index 229c21f..1780f47 100644 --- a/lib/compile/rules/type.dot.js +++ b/lib/compile/rules/type.dot.js @@ -1,48 +1,15 @@ -{{## def.isInteger: - dataType == 'number' && !(data % 1) -#}} +{{ var $isArray = Array.isArray(it.schema.type); }} - -{{ - var $schema = it.schema.type; - var $isArray = Array.isArray($schema); - if ($isArray && $schema.length == 1) { - $schema = $schema[0]; - $isArray = false; - } -}} - -var valid; {{? $isArray }} - {{? $schema.indexOf('integer') >= 0 }} - valid = {{~ $schema:$t }} - {{? $t != 'integer' }} - {{? $notFirst }} || {{?}} - {{ var $notFirst = true; }} - dataType == '{{=$t}}' - {{?}} - {{~}}; - if (!valid) { - valid = {{# def.isInteger }}; - } - {{??}} - valid = {{~ $schema:$t:$i }} - {{? $i }} || {{?}} - dataType == '{{=$t}}' - {{~}}; - {{?}} + var valid = {{= it.checkDataTypes(it.schema.type) }}; {{??}} - valid = {{? $schema == 'integer' }} - {{# def.isInteger }}; - {{??}} - dataType == '{{= $schema }}'; - {{?}} + var valid = {{= it.checkDataType(it.schema.type) }}; {{?}} if (!valid) validate.errors.push({ keyword: 'type', dataPath: dataPath, - message: 'should be {{? $isArray }}{{= $schema.join(",") }}{{??}}{{= $schema }}{{?}}' - {{? it.opts.verbose }}, schema: {{? $isArray }}validate.schema{{= it.schemaPath + '.type' }}{{??}}'{{= $schema }}'{{?}}, data: data{{?}} + message: 'should be {{? $isArray }}{{= it.schema.type.join(",") }}{{??}}{{= it.schema.type }}{{?}}' + {{? it.opts.verbose }}, schema: {{? $isArray }}validate.schema{{= it.schemaPath + '.type' }}{{??}}'{{= it.schema.type }}'{{?}}, data: data{{?}} }); diff --git a/lib/compile/rules/uniqueItems.dot.js b/lib/compile/rules/uniqueItems.dot.js index 97239cd..9f495cd 100644 --- a/lib/compile/rules/uniqueItems.dot.js +++ b/lib/compile/rules/uniqueItems.dot.js @@ -1,4 +1,4 @@ -function (data, dataType, dataPath) { +function (data, dataPath) { 'use strict'; /* TODO change to inline ??? with break in the loop */ diff --git a/lib/compile/validate.dot.js b/lib/compile/validate.dot.js index abfc849..600ca3d 100644 --- a/lib/compile/validate.dot.js +++ b/lib/compile/validate.dot.js @@ -9,12 +9,11 @@ * copy, getDataType etc. are defined in the parent scope in index.js */ }} -function (data{{? !it.isRoot }}, dataType, dataPath{{?}}) { +function (data{{? !it.isRoot }}, dataPath{{?}}) { 'use strict'; {{? it.isRoot }} {{ it.isRoot = false; }} - var dataType = getDataType(data); var dataPath = ''; var errs = validate.errors.length = 0; {{??}} @@ -23,7 +22,7 @@ function (data{{? !it.isRoot }}, dataType, dataPath{{?}}) { {{~ it.RULES:$rulesGroup }} {{? $shouldUseGroup($rulesGroup) }} - {{? $rulesGroup.type }} if (dataType == '{{= $rulesGroup.type }}') { {{?}} + {{? $rulesGroup.type }} if ({{= it.checkDataType($rulesGroup.type) }}) { {{?}} {{~ $rulesGroup.rules:$rule }} {{? $shouldUseRule($rule) }} {{? $rule.inline }} @@ -37,7 +36,7 @@ function (data{{? !it.isRoot }}, dataType, dataPath{{?}}) { $it.parentSchemaPath = it.schemaPath; }} {{? !it.opts.allErrors }} var valid = {{?}} - ({{= $rule.code($it) }})(data, dataType, dataPath); + ({{= $rule.code($it) }})(data, dataPath); {{?}} {{? !it.opts.allErrors }} if (!valid) return false; {{?}} diff --git a/package.json b/package.json index 7f4c6af..ed3d89d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ajv", - "version": "0.1.3", + "version": "0.1.4", "description": "Another JSON schema Validator", "main": "lib/ajv.js", "scripts": { diff --git a/spec/json-schema.spec.js b/spec/json-schema.spec.js index 549dff1..b01d176 100644 --- a/spec/json-schema.spec.js +++ b/spec/json-schema.spec.js @@ -7,7 +7,8 @@ var fs = require('fs') var ONLY_RULES, SKIP_RULES; // ONLY_RULES = [ -// 'type', 'not', 'allOf', 'anyOf', 'oneOf', 'enum', +// 'type', +// 'not', 'allOf', 'anyOf', 'oneOf', 'enum', // 'maximum', 'minimum', 'multipleOf', // 'maxLength', 'minLength', 'pattern', // 'properties', 'patternProperties', 'additionalProperties', @@ -51,14 +52,14 @@ describe('JSON-Schema tests', function () { describe(file.name, function() { var testSets = require(file.path); testSets.forEach(function (testSet) { - // if (testSet.description != 'not') return; + // if (testSet.description != 'multiple types can be specified in an array') return; describe(testSet.description, function() { // it(testSet.description, function() { var validate = ajv.compile(testSet.schema); var fullValidate = fullAjv.compile(testSet.schema); testSet.tests.forEach(function (test) { - // if (test.description != 'a float is not an integer') return; + // if (test.description != 'an integer is valid') return; it(test.description, function() { var valid = validate(test.data); // console.log('result', result);