[483] | 1 | dojo.provide("dojox.json.tests.schema"); |
---|
| 2 | dojo.require("dojox.json.schema"); |
---|
| 3 | dojo.require("dojox.json.ref"); |
---|
| 4 | |
---|
| 5 | var simpleObj = { |
---|
| 6 | "name" : "John Doe", |
---|
| 7 | "age" : 30, |
---|
| 8 | "$schema":{ |
---|
| 9 | "type" : { |
---|
| 10 | "name": {"type":"string", |
---|
| 11 | "required":true}, |
---|
| 12 | "age" : {"type":"number", |
---|
| 13 | "maximum":125} |
---|
| 14 | } |
---|
| 15 | } |
---|
| 16 | }; |
---|
| 17 | var biggerObj = { |
---|
| 18 | "name" : "John Doe", |
---|
| 19 | "born" : "1979-03-23T06:26:07Z", |
---|
| 20 | "gender" : "male", |
---|
| 21 | tuple:[1,"a",false], |
---|
| 22 | "address" : {"street":"123 S Main St", |
---|
| 23 | "city":"Springfield", |
---|
| 24 | "state":"CA"} |
---|
| 25 | |
---|
| 26 | }; |
---|
| 27 | var invalidBiggerObj = { |
---|
| 28 | "name" : "John Doe", |
---|
| 29 | "born" : false, |
---|
| 30 | "gender" : "mal", |
---|
| 31 | "address" : {"street":"123 S Main St", |
---|
| 32 | "city":"Springfield", |
---|
| 33 | "state":"CA"} |
---|
| 34 | |
---|
| 35 | }; |
---|
| 36 | var biggerSchema = { |
---|
| 37 | "readonly":true, |
---|
| 38 | "type":"object", |
---|
| 39 | "properties":{ |
---|
| 40 | "name": {"type":"string", |
---|
| 41 | length:5, |
---|
| 42 | "optional":false}, |
---|
| 43 | "tuple":{items:[{"type":"integer"}, |
---|
| 44 | {"type":"string"}, |
---|
| 45 | {"type":"boolean"}]}, |
---|
| 46 | "born" : {"type":["number","string"], //allow for a numeric year, or a full date |
---|
| 47 | "format":"date", //format when a string value is used |
---|
| 48 | "minimum":1900, //min/max for when a number value is used |
---|
| 49 | "maximum":2010 |
---|
| 50 | }, |
---|
| 51 | "gender" : {"type":"string", |
---|
| 52 | "enum":["male","female"], |
---|
| 53 | "options":[{"label":"Male",value:"male"},{"label":"Female",value:"female"}]}, |
---|
| 54 | "address" : {"type":"object", |
---|
| 55 | "properties": |
---|
| 56 | {"street":{"type":"string"}, |
---|
| 57 | "city":{"type":"string"}, |
---|
| 58 | "state":{"type":"string"}} |
---|
| 59 | } |
---|
| 60 | } |
---|
| 61 | }; |
---|
| 62 | var schemaForSchemas ={"description":"This is the JSON Schema for JSON Schemas.", |
---|
| 63 | "type":["object","array"], |
---|
| 64 | "items":{ |
---|
| 65 | "type":"object", |
---|
| 66 | "properties":{"$ref":"$.properties"}, |
---|
| 67 | "description":"When the schema is an array, it indicates that it is enforcing tuple typing. Each item in the instance array must correspond to the item in the schema array"}, |
---|
| 68 | "properties":{ |
---|
| 69 | "type":{ |
---|
| 70 | "type":["string","array"], |
---|
| 71 | "items":{"$ref":"$.properties.type"}, |
---|
| 72 | "description":"This is a type definition value. This can be a simple type, or a union type", |
---|
| 73 | "options":[{"value":"string"},{"value":"object"},{"value":"array"},{"value":"boolean"},{"value":"number"},{"value":"integer"},{"value":"null"},{"value":"any"}], |
---|
| 74 | "unconstrained":true, |
---|
| 75 | "optional":true, |
---|
| 76 | "default":"any"}, |
---|
| 77 | "optional":{ |
---|
| 78 | "type":"boolean", |
---|
| 79 | "description":"This indicates that the instance property in the instance object is not required.", |
---|
| 80 | "optional":true, |
---|
| 81 | "default":false}, |
---|
| 82 | "properties":{ |
---|
| 83 | "type":"object", |
---|
| 84 | "additionalProperties":{"$ref":"$"}, |
---|
| 85 | "description":"This is a definition for the properties of an object value", |
---|
| 86 | "optional":true, |
---|
| 87 | "default":{} |
---|
| 88 | }, |
---|
| 89 | "items":{ |
---|
| 90 | "type":"object", |
---|
| 91 | "properties":{"$ref":"$.properties"}, |
---|
| 92 | "description":"When the value is an array, this indicates the schema to use to validate each item in an array", |
---|
| 93 | "optional":true, |
---|
| 94 | "default":{}}, |
---|
| 95 | "additionalProperties":{ |
---|
| 96 | "type":["boolean","object"], |
---|
| 97 | "properties":{"$ref":"$.properties"}, |
---|
| 98 | "description":"This provides a default property definition for all properties that are not explicitly defined in an object type definition.", |
---|
| 99 | "optional":true, |
---|
| 100 | "default":{}}, |
---|
| 101 | "specificity":{ |
---|
| 102 | "type":"number", |
---|
| 103 | "description":"This indicates an order of specificity of properties. If an instance defines another property with a higher specificity than this one, than this instance property is required.", |
---|
| 104 | "optional":true, |
---|
| 105 | "default":false}, |
---|
| 106 | "identity":{ |
---|
| 107 | "type":"boolean", |
---|
| 108 | "description":"This indicates that the instance property should have unique values. No other property with the same name in the instance object tree should have the same value.", |
---|
| 109 | "optional":true, |
---|
| 110 | "default":false}, |
---|
| 111 | "minimum":{ |
---|
| 112 | "type":"number", |
---|
| 113 | "optional":true, |
---|
| 114 | "description":"This indicates the minimum value for the instance property when the type of the instance value is a number, or it indicates the minimum number of values in an array when an array is the instance value."}, |
---|
| 115 | "maximum":{ |
---|
| 116 | "type":"number", |
---|
| 117 | "optional":true, |
---|
| 118 | "description":"This indicates the maximum value for the instance property when the type of the instance value is a number, or it indicates the maximum number of values in an array when an array is the instance value."}, |
---|
| 119 | "pattern":{ |
---|
| 120 | "type":"string", |
---|
| 121 | "format":"regex", |
---|
| 122 | "description":"When the instance value is a string, this provides a regular expression that a instance string value should match in order to be valid.", |
---|
| 123 | "optional":true, |
---|
| 124 | "default":".*"}, |
---|
| 125 | "maxLength" :{ |
---|
| 126 | "type":"number", |
---|
| 127 | "optional":true, |
---|
| 128 | "description":"When the instance value is a string, this indicates maximum length of the string."}, |
---|
| 129 | "minLength" :{ |
---|
| 130 | "type":"number", |
---|
| 131 | "optional":true, |
---|
| 132 | "description":"When the instance value is a string, this indicates minimum length of the string."}, |
---|
| 133 | "maxItems" :{ |
---|
| 134 | "type":"number", |
---|
| 135 | "optional":true, |
---|
| 136 | "description":"When the instance value is an array, this indicates maximum number of items."}, |
---|
| 137 | "minItems" :{ |
---|
| 138 | "type":"number", |
---|
| 139 | "optional":true, |
---|
| 140 | "description":"When the instance value is an array, this indicates minimum number of items."}, |
---|
| 141 | "enum" : { |
---|
| 142 | "type":"array", |
---|
| 143 | "optional":true, |
---|
| 144 | "description":"This provides an enumeration of possible values that are valid for the instance property."}, |
---|
| 145 | "options" : { |
---|
| 146 | "type":"array", |
---|
| 147 | "items":{ |
---|
| 148 | "properties":{ |
---|
| 149 | "label":{ |
---|
| 150 | "type":"string", |
---|
| 151 | "description":"This is the label for this option", |
---|
| 152 | "optional":true |
---|
| 153 | }, |
---|
| 154 | "value":{ |
---|
| 155 | "description":"This is the value for this option" |
---|
| 156 | } |
---|
| 157 | }, |
---|
| 158 | "description":"This is an option for list of possible values" |
---|
| 159 | }, |
---|
| 160 | "optional":true, |
---|
| 161 | "description":"This provides a list of suggested options for the instance property."}, |
---|
| 162 | "readonly":{ |
---|
| 163 | "type":"boolean", |
---|
| 164 | "description":"This indicates that the instance property should not be changed (this is only for interaction, it has no effect for standalone validation).", |
---|
| 165 | "optional":true, |
---|
| 166 | "default":false}, |
---|
| 167 | "description":{ |
---|
| 168 | "type":"string", |
---|
| 169 | "optional":true, |
---|
| 170 | "description":"This provides a description of the purpose the instance property. The value can be a string or it can be an object with properties corresponding to various different instance languages (with an optional default property indicating the default description)."}, |
---|
| 171 | "format":{ |
---|
| 172 | "type":"string", |
---|
| 173 | "optional":true, |
---|
| 174 | "description":"This indicates what format the data is among some predefined formats which may include:\n\ndate - a string following the ISO format \naddress \nschema - a schema definition object \nperson \npage \nhtml - a string representing HTML"}, |
---|
| 175 | "default":{ |
---|
| 176 | "type":"any", |
---|
| 177 | "optional":true, |
---|
| 178 | "description":"This indicates the default for the instance property."}, |
---|
| 179 | "transient":{ |
---|
| 180 | "type":"boolean", |
---|
| 181 | "optional":true, |
---|
| 182 | "description":"This indicates that the property will be used for transient/volatile values that should not be persisted.", |
---|
| 183 | "default":false}, |
---|
| 184 | "maxDecimal":{ |
---|
| 185 | "type":"integer", |
---|
| 186 | "optional":true, |
---|
| 187 | "description":"This indicates the maximum number of decimal places in a floating point number."}, |
---|
| 188 | "hidden":{ |
---|
| 189 | "type":"boolean", |
---|
| 190 | "optional":true, |
---|
| 191 | "description":"This indicates whether the property should be hidden in user interfaces."}, |
---|
| 192 | "extends":{ |
---|
| 193 | "type":"object", |
---|
| 194 | "properties":{"$ref":"$.properties"}, |
---|
| 195 | "description":"This indicates the schema extends the given schema. All instances of this schema must be valid to by the extended schema also.", |
---|
| 196 | "optional":true, |
---|
| 197 | "default":{}}, |
---|
| 198 | "id":{ |
---|
| 199 | "type":["string","number"], |
---|
| 200 | "optional":true, |
---|
| 201 | "format":"url", |
---|
| 202 | "identity":true} |
---|
| 203 | } |
---|
| 204 | }; |
---|
| 205 | |
---|
| 206 | |
---|
| 207 | schemaForSchemas = dojox.json.ref.resolveJson(schemaForSchemas); |
---|
| 208 | doh.register("dojox.validate.tests.jsonSchema", |
---|
| 209 | [{ |
---|
| 210 | name:"isValidForSchema", |
---|
| 211 | runTest: function(t){ |
---|
| 212 | doh.t(dojox.json.schema.validate(simpleObj).valid); //a simple self-validating test |
---|
| 213 | doh.t(dojox.json.schema.validate(biggerObj,biggerSchema).valid); //a bigger instance and schema |
---|
| 214 | doh.f(dojox.json.schema.validate(invalidBiggerObj,biggerSchema).valid); //should have two errors |
---|
| 215 | doh.t(dojox.json.schema.validate(schemaForSchemas,schemaForSchemas).valid); //test the schema for schemas against it's self. Narcissitic testing |
---|
| 216 | doh.t(dojox.json.schema.validate(biggerSchema,schemaForSchemas).valid); //Test the big schema against the schema for schemas |
---|
| 217 | } |
---|
| 218 | }, |
---|
| 219 | { |
---|
| 220 | name:"isValidPropertyChange", |
---|
| 221 | runTest: function(t){ |
---|
| 222 | doh.f(dojox.json.schema.checkPropertyChange(biggerObj,biggerSchema).valid); //this should fail because of the |
---|
| 223 | doh.t(dojox.json.schema.checkPropertyChange(schemaForSchemas,schemaForSchemas).valid); //schema should be valid |
---|
| 224 | } |
---|
| 225 | }, |
---|
| 226 | function disallow(t){ |
---|
| 227 | var schema={ |
---|
| 228 | disallow: [{maxLength:4}] |
---|
| 229 | } |
---|
| 230 | doh.t(dojox.json.schema.validate("hello", schema).valid); |
---|
| 231 | doh.f(dojox.json.schema.validate("hi", schema).valid); |
---|
| 232 | }, |
---|
| 233 | function maxDecimal(t){ |
---|
| 234 | var schema={ |
---|
| 235 | maxDecimal: 4 |
---|
| 236 | } |
---|
| 237 | doh.t(dojox.json.schema.validate(4.44, schema).valid); |
---|
| 238 | doh.f(dojox.json.schema.validate(4.444444, schema).valid); |
---|
| 239 | |
---|
| 240 | }, |
---|
| 241 | function tuple(t){ |
---|
| 242 | var schema={ |
---|
| 243 | items: [{type:"string"},{type:"number"}] |
---|
| 244 | }; |
---|
| 245 | doh.t(dojox.json.schema.validate(["hi",33], schema).valid); |
---|
| 246 | doh.f(dojox.json.schema.validate([22,22], schema).valid); |
---|
| 247 | |
---|
| 248 | }, |
---|
| 249 | function union(t){ |
---|
| 250 | var schema={ |
---|
| 251 | type: ["string", "number"] |
---|
| 252 | }; |
---|
| 253 | doh.t(dojox.json.schema.validate(22, schema).valid); |
---|
| 254 | doh.t(dojox.json.schema.validate("hi", schema).valid); |
---|
| 255 | doh.f(dojox.json.schema.validate(null, schema).valid); |
---|
| 256 | doh.f(dojox.json.schema.validate({foo:"bar"}, schema).valid); |
---|
| 257 | }, |
---|
| 258 | function aLittleComplex(t){ |
---|
| 259 | var schema = {type:[ |
---|
| 260 | {type:"object", properties:{name:{type:"string"}, id:{type:"integer"}}, additionalProperties:false}, |
---|
| 261 | {type:"object", properties:{brand:{type:"string"}, id:{type:"integer"}}, additionalProperties:false}] |
---|
| 262 | }; |
---|
| 263 | doh.t(dojox.json.schema.validate({name:"Bill", id:3}, schema).valid); |
---|
| 264 | doh.t(dojox.json.schema.validate({brand:"Dojo", id:3}, schema).valid); |
---|
| 265 | doh.f(dojox.json.schema.validate({foo:"bar"}, schema).valid); |
---|
| 266 | doh.f(dojox.json.schema.validate({foo:"bar", brand:"Dojo", id:3}, schema).valid); |
---|
| 267 | doh.f(dojox.json.schema.validate("a string", schema).valid); |
---|
| 268 | }, |
---|
| 269 | function invalidSchema(t){ |
---|
| 270 | var schema = { |
---|
| 271 | properties: { foo:"string"} |
---|
| 272 | }; |
---|
| 273 | doh.f(dojox.json.schema.validate({foo:"bar"}, schema).valid); |
---|
| 274 | } |
---|
| 275 | ]); |
---|
| 276 | |
---|