GithubHelp home page GithubHelp logo

jsv's People

Contributors

eirikurn avatar garycourt avatar jukart avatar silas avatar stefanw avatar uwe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsv's Issues

UniqueItems check error

It seams that uniqueItems check is not working for array of objects. For instance
env.validate([{"a":1}, {"a": 1}], { uniqueItems : true }) generates no errors.

validation appears to leak memory

I have the following program:

var mod_jsv = require('JSV');

var schema = {
    'type': 'object',
    'properties': {
    'phases': {
        'type': 'array',
        'required': true,
        'minItems': 1,
        'items': {
            'type': 'object',
            'properties': {
                'type': {
                    'type': 'string',
                    'required': true,
                    'enum': [ 'generic', 'other' ]
                },
                'assets': {
                    'type': 'array',
                    'items': { 'type': 'string' }
                }
            }
        }
    },
    'input': {
        'type': 'array',
        'required': true,
        'minItems': 1,
        'items': { 'type': 'string' }
    }
    }
};

var env = mod_jsv.JSV.createEnvironment();
var input = {};
var count = 0;

for (;;) {
    env.validate(input, schema);
    if (++count % 1000 === 0)
            console.log(count);
}

I ran it for a little over 5 minutes. It started at about 30MB of memory (as measured by RSS and VSZ). I killed it after several minutes, when it was just past 18000 iterations, and it was at 64MB of VSZ and 59MB of RSS. It had taken:

real    5m42.447s
user    5m20.630s
sys 0m2.873s

I killed it with SIGABRT to get a core dump and used ::findjsobjects to see what was in memory (http://dtrace.org/blogs/bmc/2012/05/05/debugging-node-js-memory-leaks/), and found:

> ::findjsobjects
OBJECT   #OBJECTS #PROPS CONSTRUCTOR: PROPS
...
f8f5c0b9      458      5 Object: schemaUri, message, attribute, uri, ...
f8f65651      834      0 Object:
f8f4f95d     8762      4 JSONInstance: _fd, _uri, _env, _value
f8f61f81    18044      3 Object: type, required, enum
f8f61f99    18049      2 Object: type, items
f8f4fdb1    18075      2 Object: type, assets
f8f4fdbd    18076      2 Object: input, phases
f8f61fb1    36088      4 Object: type, required, items, minItems
f8f61fa5    36089      2 Object: type, properties
f8f61f8d    36174      1 Object: type
f8f61ef5   144782      7 JSONSchema: _fd, _schema, _attributes, _refs, ...

I haven't dug much further into this, but it looks like we're leaking several objects per validation, and a few objects twice per validation, and a JSONSchema object 8 times per validation. This is node v0.6.17 on SmartOS joyent_20120507T171111Z.

IPV4ADDRESS regex uses "." instead of "\\."

IPV4ADDRESS$ = subexp(DEC_OCTET$ + "." + DEC_OCTET$ + "." + DEC_OCTET$ + "." + DEC_OCTET$),

should read

IPV4ADDRESS$ = subexp(DEC_OCTET$ + "." + DEC_OCTET$ + "." + DEC_OCTET$ + "." + DEC_OCTET$),

otherwise this will match:

123,43j3@43

Validation always returns a single parse error.

We'd been using an old version of JSV for a while, and recently updated to the most recent commit. However, with every commit after and including 793c171, validation always returns a single error, with all fields undefined except message, and with message like this:

"Parse error on line 1:
urn:uuid:cfb86a1d-c6
^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got 'undefined'"

extending a string with pattern throws errors

Given the following schema :

{
    "extends": {
        "type": "object",
        "properties": {
            "id": {
                "type": "string",
                "minLength": 1,
                "pattern": "^\\S.+\\S$",
            },
        },
    },
    "properties": {
        "role": {
            "extends": {
                "type": "string",
                "minLength": 1,
                "pattern": "^\\S.+\\S$",
            },
            "description": "some description"
        },
    },
}

And the following Json :

{ "id" : "some id"
, "role" : "yunowork?"
}

I get the following validation error :

{ uri: 'urn:approval#/properties/role/pattern',
  schemaUri: 'http://json-schema.org/draft-03/hyper-schema#/properties/pattern',
  attribute: 'type',
  message: 'Instance is not a required type',
  details: [ 'string' ] }

Any idea ?

Wrong validation of a nested array

If you execute the following example, both JSONs are validated being correct but the schema specifies a nested non-empty array and thus the JSON should be validated as incorrect.

var JSV = require('../lib/jsv').JSV;
var env = JSV.createEnvironment("json-schema-draft-03");

var schema = 
    {
        "properties":{
            "sensors":{
                "required": false,
                "type":"object",
                "properties":{
                    "temp":{ 
                        "required": false,
                        "type":"array",
                        "items":{
                            "required": true,
                            "type":"array",
                            "items":{
                                "required": true,
                                "minItems": 2,
                                "maxItems": 2,
                                "type": "string"
                            }
                        }
                    }
                }
            }
        }
    }

var report;

report = env.validate( {"sensors": {"temp":[]}} , schema);
for(i=0; i<report.errors.length; i++)
    console.log(report.errors[i].message);

console.log("---------------------------------------");

report = env.validate( {"sensors": {"temp":[["Lab","2C"],["Lounge","4C"]]}} , schema);
for(i=0; i<report.errors.length; i++)
    console.log(report.errors[i].message);

publish to npm

I'd like to be able to use this in my projects! could you publish this to npm to make it easier for everyone to use under node.js?

npm publish https://github.com/garycourt/JSV/tarball/master should work!

Thanks,
-- Elijah

Custom types?

Hi

Maybe I'm a bit dense but I cannot figure out how I could define custom types with their own validation logic with JSV. Could you help me out with a pointer to some example?

regards
Sakari

Some comments on the attribute "default"

HI Gary:

I've been playing around with JSV for a few days now, and also following the 3rd draft of the json-schema spec in depth. I found the schema version 3 .js file to implement the attr. "default" for most of the schema schema's ones, but while using JSV to validate instances, it doesn't seem to be doing anything.

In any case, when you look at the 3rd json schema draft, it doesn't specify very clearly what to do with default in those cases; where or how it should be. Some examples of use:

"additionalProperties": {
   "default": null
},
"properties":  {
   "myProp": {"type": "number", "default": 0}
}

So this makes it even more difficult to make a good use of validated properties in a given report. I think "default" is a very powerful feature, but I can't seem to fully understand its implementation in JSV.

Hopefully you can throw some light about this here, and perhaps we can implement something like "defaultValue", which would be very useful for validators to export data.

Ultimately the point to improve also, is to have a better access of the validated properties, to leave out from a JSON instance those who weren't validated, other than having to write extra logic in order to lookup URIs in the resulting report, because this way of filtering is an overkill IMO.

Best,

-- Luis

Broken in IE

I initially thought it was a case of missing Array.indexOf but it seems that there are other issues.

Do you have plans to make this script run in IE<9 as I, and probably others, use Visual Studio's JS debugging which is tied to IE.

coercion

Hi!

At what point could I add coercion in order to mangle the data to fit the schema? Of particular interest is simple workaround to make autoconversion of strings obtained from web forms to booleans ('on' --> true), dates, arrays (by .split(/\W+/))?

Do you ever consider feasible to have coersive validators?

TIA,
--Vladimir

URI checking

There is an error which allows a non-URI string to be validated even if it is restricted to have valid URI values only. That is env.validate("fourty two", { type : 'string', format: 'uri' }) generates no errors.

How to write schema for validation properties of array type?

Hi,
How to validate properties in object array type?
For example, i want validate that property bar 'required' in arr, but it doesn't work.

obj = {
  arr: []
};

schema = {
    type: 'object',
    additionalProperties: false,
    properties: {
      arr: {
            type: 'array',
        properties: {
            bar: {
                required: true
            }
        }
      }
   }
};

report = env.validate(obj, schema);

report.errors.length; // => 0

Problem with "enum"

Using JSV through vickeryj's validator_form.html, I have a problem with the following JSON schema and JSON:

JSON schema: http://pastebin.com/3f7H6yDT

JSON: http://pastebin.com/rPhR7rym

The schema only allows "letter" to be set to "a" or "b", but doesn't catch the value of "c" on the second object in the array. Setting the value of "letter" of the first object to "c" does result in a validation error, as expected.

Reusing extended schemas

It appears that JSV's implementation of schema extension is buggy when reusing extended schemas. I'm not sure what is happening internally, but it manifests when adding required properties to multiple extensions of a single schema. It appears that all additional constraints from the extending schemas are merged into a single base one, resulting in every instance failing due to the absence of different required properties.

Code to reproduce follows.

Main schema:

{
    "id"            : "http://example.com/schemas/extendTest",
    "$schema"       : "http://json-schema.org/draft-03/schema",
    "description"   : "Testing extending the same schema multiple times",

    "type" : "object",
    "properties" : {
        "set1" : {
            "type" : "array",
            "items" : {
                "extends" : {"$ref" : "http://example.com/schemas/extendTest/subrecord"},
                "properties" : {
                    "newVar1" : {
                        "type" : "string",
                        "required" : true
                    }
                },
                "additionalProperties" : false
            },
            "additionalItems" : false
        },
        "set2" : {
            "type" : "array",
            "items" : {
                "extends" : {"$ref" : "http://example.com/schemas/extendTest/subrecord"},
                "properties" : {
                    "newVar2" : {
                        "type" : "string",
                        "required" : true
                    }
                },
                "additionalProperties" : false
            },
            "additionalItems" : false
        }
    },
    "additionalProperties" : false
}

Child schema:

{
    "id" : "http://example.com/schemas/extendTest/subrecord",
    "$schema"       : "http://json-schema.org/draft-03/schema",
    "type" : "object",
    "properties" : {
        "someVar" : {
            "type" : "string"
        }
    }
}

I feel like this should be working, but perhaps I am implementing the inheritance incorrectly.
Cheers!

patternProperties sub objects problem

Hi!

I think i encountered a bug with patternProperties containing a object, see following example which should be invalid imho.:

JSON schema:
{
"patternProperties" : {
{ "^[a-z]$" : {
"type" : "object",
"properties": {
"owner": {
"type": "string"
}
}
}
}
}

JSON data:
{ "a" : { "own": "test" }, "b" : { "owner": "test" }, "c" : { "owner": "test" } }

patternProperies: regexp doesn't work - it should work?

Hi,
I'm not sure if it's bug or I'm doing something wrong

- the following code reports always success. It seems regexp isn't taken into account.

var JSV = require('JSV').JSV;
var env = JSV.createEnvironment();
var json, schema;
var result = env.validate(json = {Z:1}, schema = {type: 'object', patternProperties: {'[a-z]': {type:'number'}}});
console.log('\njson:\n' + JSON.stringify(json, null, 4) + '\nschema:\n' + JSON.stringify(schema, null, 4));
if (result.errors.length === 0) {
console.log('success');
} else {
console.log('failure');
}
result = env.validate(json = {a:1}, schema = {type: 'object', patternProperties: {'[A-Z]': {type:'number'}}});
console.log('\njson:\n' + JSON.stringify(json, null, 4) + '\nschema:\n' + JSON.stringify(schema, null, 4));
if (result.errors.length === 0) {
console.log('success');
} else {
console.log('failure');
}
result = env.validate(json = {a:1}, schema = {type: 'object', patternProperties: {'^a\d': {type:'number'}}});
console.log('\njson:\n' + JSON.stringify(json, null, 4) + '\nschema:\n' + JSON.stringify(schema, null, 4));
if (result.errors.length === 0) {
console.log('success');
} else {
console.log('failure');
}

Union Types and errors

I'm trying to describe a physical multibody system in JSON and wanted to use your validation tool. Works great, thanks for your hard work!
I'm feeling uncomfortable with one thing though, perhaps you could give me some pointers on either how I should redesign my schema or if this is a bug that could be fixed.

Here is my situation. I have a "system" that can be described with different types of coordinates (cartesian 2d, cartesian 3d, polar, spherical etc etc). I want the user to pick a coordinate system and the validator will validate according to that. For instance:

{
  "system":{
    "type":"Cartesian2D",
    "bodies":[{
      "id":"b1",
      "type":"RigidBody",
      "position":[0.2,1.0]
    }]
  }
}

Here we see that the 2D system contains a RigidBody with a "position" attribute, a 2-element number array that corresponds to a 2D coordinate.
When I switch to "Cartesian3D", I want the validator to check for 3 coordinates in the position array, so I designed my schema like this:

{
  "id" : "multibody#",
  "type":"object",
  "properties":
    {
      "system":{
        "type":[{
          // ...here goes the 2d part ...
        },{
          // ...and here the 3d ...
        }
...

Further down in the schema tree there are mechanisms to validate against 2D and 3D rigid bodies respectively, and they are forced to have coordinates according to their coordinate system.

The problem comes when I want to validate this. If I for example write

position:[1,2,"ooops!"]

then I get the error

[ { uri: 'urn:uuid:b3c666fc-9e46-436c-83db-8e3f7370053a#/system',
    schemaUri: 'urn:multibody#/properties/system',
    attribute: 'type',
    message: 'Instance is not a required type',
    details: 
     [ 'urn:multibody#/properties/system/type/0',
       'urn:multibody#/properties/system/type/1' ] } ]

No matter what I do, I get the top error at the system/type "switch". This is very annoying and tells me nothing about what I am really doing wrong. Is there any way I could get the actual error at the position array level?

Note: I could of course write a schema for each coordinate system type, but that would be too easy, wouldn't it? :)

Late Binding

Maybe I am doing something wrong but does JSV support late binding?

schemas.createSchema( { 'id' : 'test', properties : { 'propa' : { 'type' : 'string', 'required' : true } } });
schemas.createSchema( { 'id' : 'test2', properties : { 'propb' : { 'type' : 'string', 'required' : true } }, 'extends' : { '$ref' : 'test' } });

console.log(schemas.validate({ }, { '$ref' : 'test2' }).errors);

This works fine and returns errors for both prop a and prop b.

schemas.createSchema( { 'id' : 'test2', properties : { 'propb' : { 'type' : 'string', 'required' : true } }, 'extends' : { '$ref' : 'test' } });
schemas.createSchema( { 'id' : 'test', properties : { 'propa' : { 'type' : 'string', 'required' : true } } });

console.log(schemas.validate({ }, { '$ref' : 'test2' }).errors);

this only validates propA

tests do not work in Firefox 4

Hello,

thanks for this great work :-) I am currently trying it out, and found out that there are some problems with Firefox 4, which you see when running the tests in firefox 4.

Greets, Sebastian

'Instance is not a required type' when it is

Object:

var json = {
    "iamastring": "123"
};

Schema (passes):

var wtf = {
    description : "My schema",
    type : "object",
    additionalProperties : false,
    properties : {
        "iamastring" : {
            type : "string",
            required : true
        }
  }
};

Schema (fails):

var wtf = {
    description : "My schema",
    type : "object",
    additionalProperties : false,
    properties : {
        "iamastring" : {
            type : "string",
            pattern: /.+/,
            required : true
        }
  }
};

Error:

{
    uri: 'urn:uuid:ef619dc8-948b-4422-9e0c-b3bbc1898dc7#/properties/iamastring/pattern',
    schemaUri: 'http://json-schema.org/draft-03/hyper-schema#/properties/pattern',
    attribute: 'type',
    message: 'Instance is not a required type',
    details: [ 'string' ]
}

Is it me or validator?

Union type validation only checks against first definition

It seems to me like JSV takes only the very first union constraint for validation, but not any subsequent. My JSON schema definition looks like ...

{
    "type":"object",
    "additionalProperties":false,
    "properties":{
        "imgs":{
            "type":"array",
            "title":"Images",
            "items":[
                {
                    "type":"object",
                    "additionalProperties":false,
                    "properties":{
                        "image_url":{
                            "title":"Image (intern)",
                            "type":"string",
                            "format":"uri"
                        }
                    }
                },
                {
                    "type":"object",
                    "additionalProperties":false,
                    "properties":{
                        "flickr_url":{
                            "title":"Image (flickr)",
                            "type":"string",
                            "format":"uri"
                        }
                    }
                }
            ]
        }
    }
}

It is fine for

{
"imgs":[
  {"image_url":"http://example.org"}
]
}

but not

{
"imgs":[
  {"flickr_url":"http://example.org"}
]
}

Any help would on this would be very much appreciated,
thanks for your time, Niko

Support AMD for lazy loading

With Dojo etc. moving to AMD for lazy module loading, it would be great if JSV could support the AMD loader, rather than/as well as the CommonJS require() behaviour currently in place.

For minimal sites, Almond, a really small AMD shim, is only 2.3KB compiled.

There are instructions on converting "traditional" CommonJS loading behaviour to AMD here: http://requirejs.org/docs/commonjs.html

This means that those using the AMD loader method would be able to do the following, thus only loading JSV when required:

  1. Register the module path for JSV
  2. require(["jsv/json-schema-draft-03"], function(env) { // JSV code goes here });

additionalProperties not working in some cases ?

Hi, I tried:

env.validate([{foo:"string",bar:"nan"}], {
properties:{
foo:{type:"string"}
},
additionalProperties:{
type:"number"
}
})

I expected to get an error on the additional property applied on "bar" which should have been a number, but I did not. Is that correct ?

Cannot validate circular structures

While I understand that circular structures aren't valid JSON, JSV chokes up when trying to validate a circular object:

var a = {};
var b = {};
a.foo = b;
b.foo = a;

var schema = {
    "id": "foo",
    "type": "object",
    "properties": {
        "foo": {
            "$ref": "foo"
        }
    }
};

var report = env.validate(a, schema);
console.warn(report.errors);

Support for default property

Hi,

does JSV support default? And if so could it be, that it doesn't work? At least neither in the object i pass in the defaults are set, nor is in the outpurt anything that looks like the object with my changes.

Extending schemas in multiple parent schemas

Hey there

This issue is related to #32 - I think the issue is valid, but my reasoning as to why is not.

additionalProperties & additionalItems sealing the schema is fine, as I was extending from a base schema without these restrictions (all schemas specifying no additions were childmost ones in the hierarchy, which seems to work perfectly). The example I gave in issue 37 will actually work no problem.

The problem with child schema attributes all being merged into the same parent seems to arise when a base schema is extended multiple times within different parent schemas. Note that none of the schemas I'm testing with use additionalProperties/Items anymore.

Complete code to reproduce follows:

var schema1 = {
    "id"            : "http://example.com/schemas/extendTest",
    "$schema"       : "http://json-schema.org/draft-03/schema",
    "description"   : "Testing extending the same schema multiple times",

    "type" : "object",
    "properties" : {
        "set1" : {
            "type" : "array",
            "items" : {
                "extends" : {"$ref" : "http://example.com/subRecord"},
                "properties" : {
                    "newVar1" : {
                        "type" : "string",
                        "required" : true
                    }
                }
            }
        },
        "set2" : {
            "type" : "array",
            "items" : {
                "extends" : {"$ref" : "http://example.com/subRecord"},
                "properties" : {
                    "newVar2" : {
                        "type" : "string",
                        "required" : true
                    }
                }
            }
        }
    }
};

var schema2 = {
    "id"            : "http://example.com/schemas/extendTest2",
    "$schema"       : "http://json-schema.org/draft-03/schema",
    "description"   : "Testing extending the same schema multiple times",

    "type" : "object",
    "properties" : {
        "setA" : {
            "type" : "array",
            "items" : {
                "extends" : {"$ref" : "http://example.com/subRecord"},
                "properties" : {
                    "newVarA" : {
                        "type" : "string",
                        "required" : true
                    }
                }
            }
        },
        "setB" : {
            "type" : "array",
            "items" : {
                "extends" : {"$ref" : "http://example.com/subRecord"},
                "properties" : {
                    "newVarB" : {
                        "type" : "string",
                        "required" : true
                    }
                }
            }
        }
    }
};

var subschema = {
    "id" : "http://example.com/subRecord",
    "$schema"       : "http://json-schema.org/draft-03/schema",
    "type" : "object",
    "properties" : {
        "someVar" : {
            "type" : "string"
        }
    }
};

var Validator = JSV.createEnvironment('json-schema-draft-03');

Validator.createSchema(subschema, undefined, subschema.id);
Validator.createSchema(schema1, undefined, schema1.id);
Validator.createSchema(schema2, undefined, schema2.id);

console.log(Validator.validate({

    set1 : [{
        newVar1 : 'assigned',
        someVar : 'assigned'
    }]

}, Validator.findSchema('http://example.com/schemas/extendTest')));

console.log(JSchema.Validator.validate({

    setA : [{
        newVarA : 'assigned',
        someVar : 'assigned'
    }]

}, Validator.findSchema('http://example.com/schemas/extendTest2')));

Note that the first instance passes validation fine, but the second seems to inherit all properties from the first schema's extensions into its own and gives required property errors. If you reverse the order of schema registration, the errors will be in the first schema instead of the second.

Extending a $ref in two places causes problems

With this:

       "uri": {
            "id": "#uri",
            "type": "string",
            "format": "uri"
        }

This:

                "mbox": {
                    "required": true,
                    "extends": {"$ref": "#uri"},
                    "pattern": "^mailto:"
                }

and this:

                "openid": {
                    "required": true,
                    "extends": {"$ref": "#uri"}
                }

in play, items validated with openid were returning this error:

[ { uri: 'urn:uuid:f917bd09-94b8-4095-9230-57502f4c5c2a#/actor/openid',
    schemaUri: 'tcapi:special#uri',
    attribute: 'pattern',
    message: 'String does not match pattern',
    details: '/^mailto:/' } ]

publish to npm

can you please publish to npm?

npm install jsv

npm http GET https://registry.npmjs.org/jsv
npm http 404 https://registry.npmjs.org/jsv

npm ERR! 404 'jsv' is not in the npm registry.
npm ERR! 404 You should bug the author to publish it
npm ERR! 404
npm ERR! 404 Note that you can also install from a
npm ERR! 404 tarball, folder, or http url, or git url.
npm ERR!
npm ERR! System Linux 2.6.18-308.4.1.el5
npm ERR! command "node-unwrapped" "/home/ericstob/blekko/bin/npm" "install" "jsv"
npm ERR! cwd /home/ericstob/b
npm ERR! node -v v0.6.12
npm ERR! npm -v 1.1.1
npm ERR! code E404
npm ERR! message 404 Not Found: jsv
npm ERR! errno {}
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! /home/ericstob/b/npm-debug.log
npm not ok

Rounding errors with divisibleBy

This is really much more of a JavaScript limitation than any problem with your library.

But just wondering - when using "divisibleBy" validation with fractional values (the common use-case is dollar values, ie. divisibleBy 0.01), JavaScript has a nasty habit of introducing rounding errors.

So you end up getting things like 291.14 / 0.01 = 29113.999999999996, which really breaks things badly. How would you feel about working around this stuff by multiplying by the inverse of the divisor first ((291.14 * (0.01/1)) / (0.01 * (0.01/1)) = 29114)? Good idea, or outside the scope of your work?

cheers

create instance with scheme is not valid per default?

Hi, I've the following case:

…
var json = {"defined":"hello"};
var schema = {"type" : "object", properties:{"implicitelyDefined":{default:"hi", optional:false}}};
var env = JSV.createEnvironment();
var test = env.createInstance(json, schema);

I expected the "test" object to be inflated with default values i.e. to have the following:

test.getValueOfProperty("implicitelyDefined") == "hi"; 

being true

I therefore conclude that creating an instance from a schema does not results in a valid instance.

env.validate(test,schema).errors.length > 0;

is true…
But should it be ? In my opinion, the created instance should fit to all the scheme requirement, (it's basically a matter of non optional default values)

git tag

Any chance of getting a git tag for the latest (and possibly previous) release of JSV? Would be great to have stable tags to reference in the repo.

No validator property in schema causes empty report with no error message

I'm using jammit to package my javascript, so I've added JSV to my assets.yml:

- public/javascripts/JSV/uri.js
- public/javascripts/JSV/jsv.js
- public/javascripts/JSV/json-schema-draft-03.js

And then I fire up the app and try to run this in a Firebug console:

var JSV = require("./jsv").JSV;
console.log("JSV", JSV);
var env = JSV.createEnvironment();
console.log("env", env);
env.validate({ a : 1 }, { type : 'object', properties : { a : { type : 'string' }} }).errors;

Output:

JSV, Object { _environments={...}, _defaultEnvironmentID="json-schema-draft-03", isJSONInstance=function(), more...}
env, Environment { _id="dc9799c1-63ed-4846-9151-ed75be38933d", _schemas={...}, _options={...}}
[]

You will note that that's the example on the front page; however, the error report is always empty, regardless of what sort of tosh I try to validate.

Adding console logs at random, I've narrowed the problem down to the method at jsv.js line 747:

JSONSchema.prototype.validate = function (instance, report, parent, parentSchema, name) {
  console.log(this._schema)
  var validator = this._schema.getValueOfProperty("validator");
  console.log('validator', validator)

 JSONInstance { _env=Environment, _value={...}, _uri="http://json-schema.org/draft-03/hyper-schema#", more...}
 validator undefined

In other words, the instance of the schema has no validator function, and thus fails completely silently. What's going on, and whatever it is, could it give a more informative error message?

Report.prototype.addError checks instance instead of schema

        uri : instance instanceof JSONInstance ? instance.getURI() : instance,
        schemaUri : instance instanceof JSONInstance ? schema.getURI() : schema,

the second line should be

        schemaUri : schema instanceof JSONInstance ? schema.getURI() : schema,

instead of checking to see if instance is an instanceof JSONInstance.

referral tests

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");

 });

test("Validate Schema", function () {

     setupEnv();

     var jsonschema = env.findSchema(env.getOption("latestJSONSchemaSchemaURI"));
     var explicit_schema = env.findSchema("http://example.com/addressbook.json");
     var referring_schema = env.findSchema("http://example.com/addressbook_ref.json");
     var card_schema = env.findSchema("http://example.com/subdir/card.json");

     ok(explicit_schema, "explicit addressbook schema");
     ok(referring_schema, "referring addressbook schema");
     ok(card_schema, "card schema");

     equal(jsonschema.validate(explicit_schema).errors.length, 0, 'valid explicit schema');
     equal(jsonschema.validate(referring_schema).errors.length, 0, 'valid referring schema');
     equal(jsonschema.validate(card_schema).errors.length, 0, 'valid referral target schema');

 });

test("Simple Referral", function () {

     setupEnv();

     var schema = { "$ref": "http://example.com/subdir/card.json" };
     notEqual(env.validate({}, schema).errors.length, 0, "card must be array");
     notEqual(env.validate([], schema).errors.length, 0, "card must have fields");
     notEqual(env.validate(["foo"], schema).errors.length, 0, "card must have two fields");
     notEqual(env.validate(["foo", {}], schema).errors.length, 0, "both fields must be string");
     notEqual(env.validate(["foo", "bar", "baz"], schema).errors.length, 0, "card maxItems 2");
     equal(env.validate(["foo", "bar"], schema).errors.length, 0, "card maxItems 2");
 });

function validateAddressbook (test_name, schema_uri) {
var schema = { "$ref": schema_uri };

test(test_name, function () {

         setupEnv();

         notEqual(env.validate('', schema).errors.length, 0, "addressbook is object");
         notEqual(env.validate({}, schema).errors.length, 0, "cards required");
         notEqual(env.validate({ "cards": {}}, schema).errors.length, 0, "cards must be array");
         equal(env.validate({ "cards": []}, schema).errors.length, 0, "empty array ok");

         notEqual(env.validate({ "cards": [ {} ] }, schema).errors.length, 0,
                  "cards schema is enforced on items");

         notEqual(env.validate({ "cards": [['foo']]}, schema).errors.length, 0,
                  "each card must have length 2");

         notEqual(env.validate({ "cards": [ ['foo', 'bar' ], ["foo" ] ] }, schema).errors.length, 0,
                  "second card is bad");

         equal(env.validate({ "cards": [ ["foo", "bar" ] ] }, schema).errors.length, 0,
               "good addressbook with one card");

         equal(env.validate({ "cards": [ ["foo", "bar" ], ["bar", "foo" ] ] }, schema).errors.length, 0,
               "good addressbook with two cards");
     });

}

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");

dot-delimited and slash-delimited support

Is both dot-delimited and slash-delimited fragmentResolution supported while reporting the errors?
I tried changing in the schema-draft-03.js (the default one), still getting the reported errors in slash-delimited format.

Local $ref doesn't work

When supplying a chema containing internal references, e.g. simplest one taken from example posted by "fge" in https://groups.google.com/forum/#!topic/json-schema/xiAEZG6fKT4:

{
"even-numbers": {
"type": "integer",
"divisibleBy": 2
},
"type": "array",
"additionalItems": {
"$ref": "#/even-numbers"
}
}

trying to validate simplest example:

[2,4]

returns following error:

/additionalItems Unknown schema reference urn:uuid:fb503557-341d-4f70-a3c1-fa6791338b6b#/even-numbers

Replacing JSON Pointer addressing by relative URI referring to "id" attribute doesn't work, either:

{
"even-numbers": {
"id": "even",
"type": "integer",
"divisibleBy": 2
},
"id": "root",
"type": "array",
"additionalItems": {
"$ref": "#even"
}
}

returns following error:

/additionalItems Unknown schema reference urn:root#even

Please explain if I am doing something wrong or whether it is a JSV error.

"format": "regex"

I have a schema with a section as below

"matching": {
    "title": "include parameter keys matching",
    "description": "only use query parameters whose keys match this regexp",
    "type": "string",
    "format": "regex",
    "default": "/^*$/"
}

My expectation is that an instance whose value for 'matching' is a string but not a valid regular expression will fail validation. However, this is not the case when validating with JSV. Validation does not fail as expected for value "[" which is not a valid ECMA 262/Perl 5 regexp.
Am I doing it wrong? Is "format": "regex" not supported in JSV?

Self-validating schema doesn't self-validate

Hi. The self validating json schema schema doesn't self validate :(

http://json-schema.org/schema
http://json-schema.org/

[ { uri: 'http://json-schema.org/schema#/properties/properties/additionalProperties',
    schemaUri: 'http://json-schema.org/draft-03/hyper-schema#/properties/additionalProperties',
    attribute: 'type',
    message: 'Instance is not a required type',
    details: [ 'http://json-schema.org/draft-03/hyper-schema#', 'boolean' ] },
  { uri: 'http://json-schema.org/schema#/properties/items/items',
    schemaUri: 'http://json-schema.org/draft-03/hyper-schema#/properties/items',
    attribute: 'type',
    message: 'Instance is not a required type',
    details: [ 'http://json-schema.org/draft-03/hyper-schema#', 'array' ] },
  { uri: 'http://json-schema.org/schema#/properties/extends/items',
    schemaUri: 'http://json-schema.org/draft-03/hyper-schema#/properties/items',
    attribute: 'type',
    message: 'Instance is not a required type',
    details: [ 'http://json-schema.org/draft-03/hyper-schema#', 'array' ] } ]

Circular JSON structure

I have a schema roughly like so. To sum up, I want the JSON to accept these two different kinds of objects. I was told this can't be done in JSON, but someone gave me this structure and it seems to validate on the right stuff. However, on a failure I am getting a circular structure error when trying to print out the errors. I tried to print out some fields manually and it looks like the bad field is "details" in the error object.

Input JSON (invalid, circular object upon printing errors out):

{ "type" : "ice_cream", "bun" : "wheat", "ketchup" : "2 packets" }

Input JSON (valid):

{ "type" : "hot_dog", "bun" : "wheat", "ketchup" : "2 packets" }

{
"description" : "Food",
"type" : [
{
"type" : "object",
"additionalProperties" : false,
"properties" : {
"type" : {
"type" : "string",
"required" : true,
"enum": [
"hot_dog"
]
},
"bun" : {
"type" : "string",
"required" : true
},
"ketchup" : {
"type" : "string",
"required" : true
}
}
},
{
"type" : "object",
"additionalProperties" : false,
"properties" : {
"type" : {
"type" : "string",
"required" : true,
"enum": [
"ice_cream"
]
},
"cone" : {
"type" : "string",
"required" : true
},
"chocolate_sauce" : {
"type" : "string",
"required" : true
}
}
}
]
}

"too much recursion" when using self reference in extends

When trying to validate a schema containing a property that extends the root schema (not only references it), I run into a "too much recursion" error (on Firefox 3.6.13).

{
    "id" : "http://base/#",
    "type" : "object",
    "properties" : {
        "child" : {
            "extends" : { "$ref" :"#" },
        }
    }
}

Is this an invalid json-schema construct or a bug?

Type checking error

There is an error in type checking, which allows to use non-allowable values if requested type value can be taken through conversion. For example, if I have a scheme like this

{
    "type": "array",
    "items": { "type": "integer" }
}

it allows me to have instances like these:
[ 42, "42", 42.0 ]

Update readme to show that it takes js vars not json

While the code sample clearly shows that the input to validate() are two objects, the naming of the objects (especially "json") made me think that it expected as its input JSON. Easy enough for me to JSON.parse my input, but I spent some amount of time debugging a cryptic error until I looked a little closer. Making it more explicit would help!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.