kriszyp / json-schema

JSON Schema specifications, reference schemas, and a CommonJS implementation
http://json-schema.org/
Other
520 stars 168 forks source link

validate.js is unable to validate core schema #17

Open laurie71 opened 13 years ago

laurie71 commented 13 years ago

validating the core schema [validate(schema)] causes validate to choke on the '$schema' instance property; [validate(schema,schema)], which should be equivalent, adds an extra 'null' entry to the result. Deleting the $schema property before validating results in a single 'null' in result.errors.

Here's my test script reproducing the problem:

var schema = require('document/document').tmp['http://json-schema.org/draft-03/schema'];

var v = require('document/validate');
var sys = require('sys');
var result;

sys.debug('----- SCHEMA ----- \n'+sys.inspect(schema));
sys.debug('\n\n');

sys.debug('----- VALIDATE: -----');

result = v.validate(schema);
sys.debug('result = v.validate(schema);'); // should validate
sys.debug('----- RESULT 1 ----- \n'+sys.inspect(result));

result = v.validate(schema, schema); // should be equiv. to 1.
sys.debug('result = v.validate(schema, schema);');
sys.debug('----- RESULT 2 ----- \n'+sys.inspect(result));

delete schema['$schema'];
result = v.validate(schema); // no schema to validate against
sys.debug('result = v.validate(schema);');
sys.debug('----- RESULT 3 ----- \n'+sys.inspect(result));

result = v.validate(schema, schema); // should validate
sys.debug('result = v.validate(schema, schema);');
sys.debug('----- RESULT 4 ----- \n'+sys.inspect(result));

and here's the result of running it:

DEBUG: ----- SCHEMA ----- 
{ '$schema': 'http://json-schema.org/draft-03/schema#'
, id: 'http://json-schema.org/draft-03/schema#'
, type: 'object'
, properties: 
   { type: 
      { type: [Object]
      , items: [Object]
      , uniqueItems: true
      , default: 'any'
      }
   , properties: 
      { type: 'object'
      , additionalProperties: [Object]
      , default: {}
      }
   , patternProperties: 
      { type: 'object'
      , additionalProperties: [Object]
      , default: {}
      }
   , additionalProperties: { type: [Object], default: {} }
   , items: { type: [Object], items: [Object], default: {} }
   , additionalItems: { type: [Object], default: {} }
   , required: { type: 'boolean', default: false }
   , dependencies: 
      { type: 'object'
      , additionalProperties: [Object]
      , default: {}
      }
   , minimum: { type: 'number' }
   , maximum: { type: 'number' }
   , exclusiveMinimum: { type: 'boolean', default: false }
   , exclusiveMaximum: { type: 'boolean', default: false }
   , minItems: { type: 'integer', minimum: 0, default: 0 }
   , maxItems: { type: 'integer', minimum: 0 }
   , uniqueItems: { type: 'boolean', default: false }
   , pattern: { type: 'string', format: 'regex' }
   , minLength: { type: 'integer', minimum: 0, default: 0 }
   , maxLength: { type: 'integer' }
   , enum: { type: 'array', minItems: 1, uniqueItems: true }
   , default: { type: 'any' }
   , title: { type: 'string' }
   , description: { type: 'string' }
   , format: { type: 'string' }
   , divisibleBy: 
      { type: 'number'
      , minimum: 0
      , exclusiveMinimum: true
      , default: 1
      }
   , disallow: { type: [Object], items: [Object], uniqueItems: true }
   , extends: { type: [Object], items: [Object], default: {} }
   , id: { type: 'string', format: 'uri' }
   , '$ref': { type: 'string', format: 'uri' }
   , '$schema': { type: 'string', format: 'uri' }
   }
, dependencies: 
   { exclusiveMinimum: 'minimum'
   , exclusiveMaximum: 'maximum'
   }
, default: {}
}
DEBUG: 

DEBUG: ----- VALIDATE: -----
DEBUG: result = v.validate(schema);
DEBUG: ----- RESULT 1 ----- 
{ valid: false
, errors: 
   [ { property: ''
     , message: 'Invalid schema/property definition http://json-schema.org/draft-03/schema#'
     }
   ]
}
DEBUG: result = v.validate(schema, schema);
DEBUG: ----- RESULT 2 ----- 
{ valid: false
, errors: 
   [ null
   , { property: ''
     , message: 'Invalid schema/property definition http://json-schema.org/draft-03/schema#'
     }
   ]
}
DEBUG: result = v.validate(schema);
DEBUG: ----- RESULT 3 ----- 
{ valid: true, errors: [] }
DEBUG: result = v.validate(schema, schema);
DEBUG: ----- RESULT 4 ----- 
{ valid: false, errors: [ null ] }
laurie71 commented 13 years ago

Note: this is using my patch for required vs. optional; without that, there are lots more errors about missing required properties ;-)

c2c533c4f237 commented 13 years ago

What is your patch - you just switch that one line?

laurie71 commented 13 years ago

Hmm, seems I accidentally deleted my fork, which has deleted the pull request too. I'll see if I still have a working copy that I can push back up.

laurie71 commented 13 years ago

OK, resubmitted the commit that the test case above assumes. Sorry about that.

laurie71 commented 13 years ago

I added vows tests on my fork, showing this problem; see https://github.com/laurie71/json-schema/commit/0a52e1e737d4adeab0cb45739062f327dfd65257

The tests are run with 'vows test/*.js'

neonstalwart commented 13 years ago

i think i just came across this same problem. the draft-03 schema restricts a $schema property to only be a string and the validator expects that if the $schema property exists on an instance then it is an object (a schema to be used to validate this instance). so if you try to validate an instance that has the draft-03 schema as it's $schema property then the validation will fail since draft-03 says that the $schema property can only be a string. if you leave the $schema property as a uri and pass in the draft-03 schema as the 2nd param to validate then the validator fails with the message 'Invalid schema/property definition http://json-schema.org/draft-03/schema#'.

my current workaround is to delete the $schema property from the instance and pass the draft-03 schema as the 2nd param to validate