Skip to content

Commit 5b434b4

Browse files
committed
validate schema against meta-schema
1 parent 72f5ed5 commit 5b434b4

File tree

5 files changed

+43
-12
lines changed

5 files changed

+43
-12
lines changed

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ or
5858
// ...
5959
ajv.addSchema(schema, 'mySchema');
6060
var valid = ajv.validate('mySchema', data);
61-
if (!valid) console.log(ajv.errors);
61+
if (!valid) console.log(ajv.errorsText());
6262
// ...
6363
```
6464

@@ -80,6 +80,8 @@ Generate validating function and cache the compiled schema for future use.
8080

8181
Validating function returns boolean and has properties `errors` with the errors from the last validation (`null` if there were no errors) and `schema` with the reference to the original schema.
8282

83+
Unless options `validateSchema` is false, the schema will be validated against meta-schema and if schema is invalid the errors will be logged. See [options](#options).
84+
8385

8486
##### .validate(Object schema|String key|String ref, data) -> Boolean
8587

@@ -120,13 +122,22 @@ Function should return validation result as `true` or `false`.
120122
Custom formats can be also added via `formats` option.
121123

122124

125+
##### .errorsText([Array<Object> errors [, Object options]]) -&gt; String
126+
127+
Returns the text with all errors in a String. Options can have these properties:
128+
129+
- separator: string used to separate errors, ", " is used by default.
130+
- dataVar: the variable name that dataPaths are prefixed with, "data" by default.
131+
132+
123133
## Options
124134

125135
- _allErrors_: check all rules collecting all errors. Default is to return after the first error.
126136
- _verbose_: include the reference to the part of the schema and validated data in errors (false by default).
127137
- _format_: formats validation mode ('fast' by default). Pass 'full' for more correct and slow validation or `false` not to validate formats at all. E.g., 25:00:00 and 2015/14/33 will be invalid time and date in 'full' mode but it will be valid in 'fast' mode.
128138
- _formats_: an object with custom formats. Keys and values will be passed to `addFormat` method.
129139
- _meta_: add [meta-schema](http://json-schema.org/documentation.html) so it can be used by other schemas (true by default).
140+
- _validateSchema: validate schema against meta-schema (true by default). `$schema` property in the schema can either be absent (draft-4 meta-schema will be used) or can be a reference to any previously added schema. If the validation fails, the errors will be logged.
130141
- _uniqueItems_: validate `uniqueItems` keyword (true by default).
131142
- _unicode_: calculate correct length of strings with unicode pairs (true by default). Pass `false` to use `.length` of strings that is faster, but gives "incorrect" lengths of strings with unicode pairs - each unicode pair is counted as two characters.
132143
- _beautify_: format the generated function with [js-beautify](https://github.com/beautify-web/js-beautify) (the validating function is generated without line-breaks). `npm install js-beautify` to use this option. `true` or js-beautify options can be passed.
@@ -141,6 +152,11 @@ npm test
141152

142153
## Changes history
143154

155+
##### 0.5.0
156+
157+
Schemas are validated against meta-schema before compilation
158+
159+
144160
##### 0.4.1
145161

146162
Custom formats support.

lib/ajv.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ function Ajv(opts) {
3333
this.addSchema = addSchema;
3434
this.getSchema = getSchema;
3535
this.addFormat = addFormat;
36+
this.errorsText = errorsText;
3637

3738
addInitialSchemas();
3839
addInitialFormats();
@@ -124,9 +125,9 @@ function Ajv(opts) {
124125
var id = resolve.normalizeId(schema.id);
125126
if (id) checkUnique(id);
126127

127-
// var ok = skipValidation || self.opts.validateSchema === false
128-
// || validateSchema(schema);
129-
// if (!ok) throw new Error('schema is invalid');
128+
var ok = skipValidation || self.opts.validateSchema === false
129+
|| validateSchema(schema);
130+
if (!ok) console.error('schema is invalid:\n', errorsText());
130131

131132
resolve.ids.call(self, schema);
132133

@@ -136,6 +137,20 @@ function Ajv(opts) {
136137
}
137138

138139

140+
function errorsText(errors, opts) {
141+
errors = errors || self.errors;
142+
if (!errors) return 'No errors';
143+
opts = opts || {};
144+
var separator = opts.separator || ', ';
145+
var dataVar = opts.dataVar || 'data';
146+
147+
var text = errors.reduce(function(txt, e) {
148+
return e ? txt + e.keyword + ' ' + dataVar + e.dataPath + ': ' + e.message + separator : txt;
149+
}, '');
150+
return text.slice(0, -separator.length);
151+
}
152+
153+
139154
function addFormat(name, format) {
140155
if (typeof format == 'string') format = new RegExp(format);
141156
self._formats[name] = format;

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ajv",
3-
"version": "0.4.15",
3+
"version": "0.5.0",
44
"description": "Another JSON schema Validator",
55
"main": "lib/ajv.js",
66
"scripts": {

spec/ajv.spec.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ describe('Ajv', function () {
3939
});
4040
})
4141

42-
it.skip('should throw if schema is invalid', function() {
43-
should.throw(function() {
44-
ajv.compile({ type: null });
45-
});
42+
it('should validate schema when it is compiled', function() {
43+
ajv.errors = null;
44+
ajv.compile({ type: null });
45+
ajv.errors.length .should.be.greaterThan(0);
4646
});
4747
});
4848

spec/json-schema.spec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ var DEBUG = false;
3131

3232

3333
var Ajv = require('../lib/ajv')
34-
, ajv = Ajv({ beautify: true, _debug: DEBUG })
35-
, fullAjv = Ajv({ allErrors: true, verbose: true, format: 'full', beautify: true, _debug: DEBUG });
34+
, ajv = Ajv({ beautify: DEBUG, _debug: DEBUG })
35+
, fullAjv = Ajv({ allErrors: true, verbose: true, format: 'full', beautify: DEBUG, _debug: DEBUG });
3636

3737
var remoteRefs = {
3838
'http://localhost:1234/integer.json': require('./JSON-Schema-Test-Suite/remotes/integer.json'),
@@ -64,7 +64,7 @@ function addTests(description, testsPath) {
6464
(skip ? describe.skip : describe) (file.name, function() {
6565
var testSets = require(file.path);
6666
testSets.forEach(function (testSet) {
67-
// if (testSet.description != 'restoring root after ref resolution (#12)') return;
67+
// if (testSet.description != 'change resolution scope') return;
6868
(testSet.skip ? describe.skip : describe)(testSet.description, function() {
6969
var validate, fullValidate;
7070
// it(testSet.description, function() {

0 commit comments

Comments
 (0)