Version 1
[yaffs-website] / node_modules / is-my-json-valid / test / misc.js
diff --git a/node_modules/is-my-json-valid/test/misc.js b/node_modules/is-my-json-valid/test/misc.js
new file mode 100644 (file)
index 0000000..4ea36d5
--- /dev/null
@@ -0,0 +1,471 @@
+var tape = require('tape')
+var cosmic = require('./fixtures/cosmic')
+var validator = require('../')
+var validatorRequire = require('../require')
+
+tape('simple', function(t) {
+  var schema = {
+    required: true,
+    type: 'object',
+    properties: {
+      hello: {type:'string', required:true}
+    }
+  }
+
+  var validate = validator(schema)
+
+  t.ok(validate({hello: 'world'}), 'should be valid')
+  t.notOk(validate(), 'should be invalid')
+  t.notOk(validate({}), 'should be invalid')
+  t.end()
+})
+
+tape('data is undefined', function (t) {
+  var validate = validator({type: 'string'})
+
+  t.notOk(validate(null))
+  t.notOk(validate(undefined))
+  t.end()
+})
+
+tape('advanced', function(t) {
+  var validate = validator(cosmic.schema)
+
+  t.ok(validate(cosmic.valid), 'should be valid')
+  t.notOk(validate(cosmic.invalid), 'should be invalid')
+  t.end()
+})
+
+tape('greedy/false', function(t) {
+  var validate = validator({
+    type: 'object',
+    properties: {
+      x: {
+        type: 'number'
+      }
+    },
+    required: ['x', 'y']
+  });
+  t.notOk(validate({}), 'should be invalid')
+  t.strictEqual(validate.errors.length, 2);
+  t.strictEqual(validate.errors[0].field, 'data.x')
+  t.strictEqual(validate.errors[0].message, 'is required')
+  t.strictEqual(validate.errors[1].field, 'data.y')
+  t.strictEqual(validate.errors[1].message, 'is required')
+  t.notOk(validate({x: 'string'}), 'should be invalid')
+  t.strictEqual(validate.errors.length, 1);
+  t.strictEqual(validate.errors[0].field, 'data.y')
+  t.strictEqual(validate.errors[0].message, 'is required')
+  t.notOk(validate({x: 'string', y: 'value'}), 'should be invalid')
+  t.strictEqual(validate.errors.length, 1);
+  t.strictEqual(validate.errors[0].field, 'data.x')
+  t.strictEqual(validate.errors[0].message, 'is the wrong type')
+  t.end();
+});
+
+tape('greedy/true', function(t) {
+  var validate = validator({
+    type: 'object',
+    properties: {
+      x: {
+        type: 'number'
+      }
+    },
+    required: ['x', 'y']
+  }, {
+    greedy: true
+  });
+  t.notOk(validate({}), 'should be invalid')
+  t.strictEqual(validate.errors.length, 2);
+  t.strictEqual(validate.errors[0].field, 'data.x')
+  t.strictEqual(validate.errors[0].message, 'is required')
+  t.strictEqual(validate.errors[1].field, 'data.y')
+  t.strictEqual(validate.errors[1].message, 'is required')
+  t.notOk(validate({x: 'string'}), 'should be invalid')
+  t.strictEqual(validate.errors.length, 2);
+  t.strictEqual(validate.errors[0].field, 'data.y')
+  t.strictEqual(validate.errors[0].message, 'is required')
+  t.strictEqual(validate.errors[1].field, 'data.x')
+  t.strictEqual(validate.errors[1].message, 'is the wrong type')
+  t.notOk(validate({x: 'string', y: 'value'}), 'should be invalid')
+  t.strictEqual(validate.errors.length, 1);
+  t.strictEqual(validate.errors[0].field, 'data.x')
+  t.strictEqual(validate.errors[0].message, 'is the wrong type')
+  t.ok(validate({x: 1, y: 'value'}), 'should be invalid')
+  t.end();
+});
+
+tape('additional props', function(t) {
+  var validate = validator({
+    type: 'object',
+    additionalProperties: false
+  }, {
+    verbose: true
+  })
+
+  t.ok(validate({}))
+  t.notOk(validate({foo:'bar'}))
+  t.ok(validate.errors[0].value === 'data.foo', 'should output the property not allowed in verbose mode')
+  t.strictEqual(validate.errors[0].type, 'object', 'error object should contain the type')
+  t.end()
+})
+
+tape('array', function(t) {
+  var validate = validator({
+    type: 'array',
+    required: true,
+    items: {
+      type: 'string'
+    }
+  })
+
+  t.notOk(validate({}), 'wrong type')
+  t.notOk(validate(), 'is required')
+  t.ok(validate(['test']))
+  t.end()
+})
+
+tape('nested array', function(t) {
+  var validate = validator({
+    type: 'object',
+    properties: {
+      list: {
+        type: 'array',
+        required: true,
+        items: {
+          type: 'string'
+        }
+      }
+    }
+  })
+
+  t.notOk(validate({}), 'is required')
+  t.ok(validate({list:['test']}))
+  t.notOk(validate({list:[1]}))
+  t.end()
+})
+
+tape('enum', function(t) {
+  var validate = validator({
+    type: 'object',
+    properties: {
+      foo: {
+        type: 'number',
+        required: true,
+        enum: [42]
+      }
+    }
+  })
+
+  t.notOk(validate({}), 'is required')
+  t.ok(validate({foo:42}))
+  t.notOk(validate({foo:43}))
+  t.end()
+})
+
+tape('minimum/maximum', function(t) {
+  var validate = validator({
+    type: 'object',
+    properties: {
+      foo: {
+        type: 'number',
+        minimum: 0,
+        maximum: 0
+      }
+    }
+  })
+
+  t.notOk(validate({foo:-42}))
+  t.ok(validate({foo:0}))
+  t.notOk(validate({foo:42}))
+  t.end()
+})
+
+tape('exclusiveMinimum/exclusiveMaximum', function(t) {
+  var validate = validator({
+    type: 'object',
+    properties: {
+      foo: {
+        type: 'number',
+        minimum: 10,
+        maximum: 20,
+        exclusiveMinimum: true,
+        exclusiveMaximum: true
+      }
+    }
+  })
+
+  t.notOk(validate({foo:10}))
+  t.ok(validate({foo:11}))
+  t.notOk(validate({foo:20}))
+  t.ok(validate({foo:19}))
+  t.end()
+})
+
+tape('minimum/maximum number type', function(t) {
+  var validate = validator({
+    type: ['integer', 'null'],
+    minimum: 1,
+    maximum: 100
+  })
+
+  t.notOk(validate(-1))
+  t.notOk(validate(0))
+  t.ok(validate(null))
+  t.ok(validate(1))
+  t.ok(validate(100))
+  t.notOk(validate(101))
+  t.end()
+})
+
+tape('custom format', function(t) {
+  var validate = validator({
+    type: 'object',
+    properties: {
+      foo: {
+        type: 'string',
+        format: 'as'
+      }
+    }
+  }, {formats: {as:/^a+$/}})
+
+  t.notOk(validate({foo:''}), 'not as')
+  t.notOk(validate({foo:'b'}), 'not as')
+  t.notOk(validate({foo:'aaab'}), 'not as')
+  t.ok(validate({foo:'a'}), 'as')
+  t.ok(validate({foo:'aaaaaa'}), 'as')
+  t.end()
+})
+
+tape('custom format function', function(t) {
+  var validate = validator({
+    type: 'object',
+    properties: {
+      foo: {
+        type: 'string',
+        format: 'as'
+      }
+    }
+  }, {formats: {as:function(s) { return /^a+$/.test(s) } }})
+
+  t.notOk(validate({foo:''}), 'not as')
+  t.notOk(validate({foo:'b'}), 'not as')
+  t.notOk(validate({foo:'aaab'}), 'not as')
+  t.ok(validate({foo:'a'}), 'as')
+  t.ok(validate({foo:'aaaaaa'}), 'as')
+  t.end()
+})
+
+tape('do not mutate schema', function(t) {
+  var sch = {
+    items: [
+      {}
+    ],
+    additionalItems: {
+      type: 'integer'
+    }
+  }
+
+  var copy = JSON.parse(JSON.stringify(sch))
+
+  validator(sch)
+
+  t.same(sch, copy, 'did not mutate')
+  t.end()
+})
+
+tape('#toJSON()', function(t) {
+  var schema = {
+    required: true,
+    type: 'object',
+    properties: {
+      hello: {type:'string', required:true}
+    }
+  }
+
+  var validate = validator(schema)
+
+  t.deepEqual(validate.toJSON(), schema, 'should return original schema')
+  t.end()
+})
+
+tape('external schemas', function(t) {
+  var ext = {type: 'string'}
+  var schema = {
+    required: true,
+    $ref: '#ext'
+  }
+
+  var validate = validator(schema, {schemas: {ext:ext}})
+
+  t.ok(validate('hello string'), 'is a string')
+  t.notOk(validate(42), 'not a string')
+  t.end()
+})
+
+tape('external schema URIs', function(t) {
+  var ext = {type: 'string'}
+  var schema = {
+    required: true,
+    $ref: 'http://example.com/schemas/schemaURIs'
+  }
+
+  var opts = {schemas:{}};
+  opts.schemas['http://example.com/schemas/schemaURIs'] = ext;
+  var validate = validator(schema, opts)
+
+  t.ok(validate('hello string'), 'is a string')
+  t.notOk(validate(42), 'not a string')
+  t.end()
+})
+
+tape('top-level external schema', function(t) {
+  var defs = {
+    "string": {
+      type: "string"
+    },
+    "sex": {
+      type: "string",
+      enum: ["male", "female", "other"]
+    }
+  }
+  var schema = {
+    type: "object",
+    properties: {
+      "name": { $ref: "definitions.json#/string" },
+      "sex": { $ref: "definitions.json#/sex" }
+    },
+    required: ["name", "sex"]
+  }
+
+  var validate = validator(schema, {
+    schemas: {
+      "definitions.json": defs
+    }
+  })
+  t.ok(validate({name:"alice", sex:"female"}), 'is an object')
+  t.notOk(validate({name:"alice", sex: "bob"}), 'recognizes external schema')
+  t.notOk(validate({name:2, sex: "female"}), 'recognizes external schema')
+  t.end()
+})
+
+tape('nested required array decl', function(t) {
+  var schema = {
+    properties: {
+      x: {
+        type: 'object',
+        properties: {
+          y: {
+            type: 'object',
+            properties: {
+              z: {
+                type: 'string'
+              }
+            },
+            required: ['z']
+          }
+        }
+      }
+    },
+    required: ['x']
+  }
+
+  var validate = validator(schema)
+
+  t.ok(validate({x: {}}), 'should be valid')
+  t.notOk(validate({}), 'should not be valid')
+  t.strictEqual(validate.errors[0].field, 'data.x', 'should output the missing field')
+  t.end()
+})
+
+tape('verbose mode', function(t) {
+  var schema = {
+    required: true,
+    type: 'object',
+    properties: {
+      hello: {
+        required: true,
+        type: 'string'
+      }
+    }
+  };
+
+  var validate = validator(schema, {verbose: true})
+
+  t.ok(validate({hello: 'string'}), 'should be valid')
+  t.notOk(validate({hello: 100}), 'should not be valid')
+  t.strictEqual(validate.errors[0].value, 100, 'error object should contain the invalid value')
+  t.strictEqual(validate.errors[0].type, 'string', 'error object should contain the type')
+  t.end()
+})
+
+tape('additional props in verbose mode', function(t) {
+  var schema = {
+    type: 'object',
+    required: true,
+    additionalProperties: false,
+    properties: {
+      foo: {
+        type: 'string'
+      },
+      'hello world': {
+        type: 'object',
+        required: true,
+        additionalProperties: false,
+        properties: {
+          foo: {
+            type: 'string'
+          }
+        }
+      }
+    }
+  };
+
+  var validate = validator(schema, {verbose: true})
+
+  validate({'hello world': {bar: 'string'}});
+
+  t.strictEqual(validate.errors[0].value, 'data["hello world"].bar', 'should output the path to the additional prop in the error')
+  t.end()
+})
+
+tape('Date.now() is an integer', function(t) {
+  var schema = {type: 'integer'}
+  var validate = validator(schema)
+
+  t.ok(validate(Date.now()), 'is integer')
+  t.end()
+})
+
+tape('field shows item index in arrays', function(t) {
+  var schema = {
+    type: 'array',
+    items: {
+      type: 'array',
+      items: {
+        properties: {
+          foo: {
+            type: 'string',
+            required: true
+          }
+        }
+      }
+    }
+  }
+
+  var validate = validator(schema)
+
+  validate([
+    [
+      { foo: 'test' },
+      { foo: 'test' }
+    ],
+    [
+      { foo: 'test' },
+      { baz: 'test' }
+    ]
+  ])
+
+  t.strictEqual(validate.errors[0].field, 'data.1.1.foo', 'should output the field with specific index of failing item in the error')
+  t.end()
+})