@deskpro/react-forms
Version:
Forms library for React
684 lines (597 loc) • 19 kB
JavaScript
;
var _cosmic = require('./fixtures/cosmic');
var _cosmic2 = _interopRequireDefault(_cosmic);
var _compileValidator = require('../compileValidator');
var _compileValidator2 = _interopRequireDefault(_compileValidator);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @copyright (c) 2014 Mathias Buus
* @copyright (c) 2015 Prometheus Research
*/
describe('JSONSchema custom test cases', function () {
it('simple', function () {
var schema = {
required: true,
type: 'object',
properties: {
hello: { type: 'string', required: true }
}
};
var validate = (0, _compileValidator2.default)(schema);
assert(validate({ hello: 'world' }), 'should be valid');
assert(!validate(), 'should be invalid');
assert(!validate({}), 'should be invalid');
});
it('advanced', function () {
var validate = (0, _compileValidator2.default)(_cosmic2.default.schema);
assert(validate(_cosmic2.default.valid), 'should be valid');
assert(!validate(_cosmic2.default.invalid), 'should be invalid');
});
it('greedy/false', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
x: {
type: 'number'
}
},
required: ['x', 'y']
});
assert(!validate({}), 'should be invalid');
assert(validate.errors.length === 2);
assert(validate.errors[0].field === 'data.x');
assert(validate.errors[0].message === 'is required');
assert(validate.errors[1].field === 'data.y');
assert(validate.errors[1].message === 'is required');
assert(!validate({ x: 'string' }), 'should be invalid');
assert(validate.errors.length === 1);
assert(validate.errors[0].field === 'data.y');
assert(validate.errors[0].message === 'is required');
assert(!validate({ x: 'string', y: 'value' }), 'should be invalid');
assert(validate.errors.length === 1);
assert(validate.errors[0].field === 'data.x');
assert(validate.errors[0].message === 'is the wrong type');
});
it('greedy/true', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
x: {
type: 'number'
}
},
required: ['x', 'y']
}, {
greedy: true
});
assert(!validate({}), 'should be invalid');
assert(validate.errors.length === 2);
assert(validate.errors[0].field === 'data.x');
assert(validate.errors[0].message === 'is required');
assert(validate.errors[1].field === 'data.y');
assert(validate.errors[1].message === 'is required');
assert(!validate({ x: 'string' }), 'should be invalid');
assert(validate.errors.length === 2);
assert(validate.errors[0].field === 'data.y');
assert(validate.errors[0].message === 'is required');
assert(validate.errors[1].field === 'data.x');
assert(validate.errors[1].message === 'is the wrong type');
assert(!validate({ x: 'string', y: 'value' }), 'should be invalid');
assert(validate.errors.length === 1);
assert(validate.errors[0].field === 'data.x');
assert(validate.errors[0].message === 'is the wrong type');
assert(validate({ x: 1, y: 'value' }), 'should be invalid');
});
it('additional props', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
additionalProperties: false
}, {
verbose: true
});
assert(validate({}));
assert(!validate({ foo: 'bar' }));
assert(validate.errors[0].value === 'data.foo', 'should output the property not allowed in verbose mode');
});
it('array', function () {
var validate = (0, _compileValidator2.default)({
type: 'array',
required: true,
items: {
type: 'string'
}
});
assert(!validate({}), 'wrong type');
assert(!validate(), 'is required');
assert(validate(['test']));
});
it('nested array', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
list: {
type: 'array',
required: true,
items: {
type: 'string'
}
}
}
});
assert(!validate({}), 'is required');
assert(validate({ list: ['test'] }));
assert(!validate({ list: [1] }));
assert(validate.errors[0].field === 'data.list.0');
assert(!validate({ list: ['test', 2] }));
assert(validate.errors[0].field === 'data.list.1');
});
it('enum', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'number',
required: true,
enum: [42]
}
}
});
assert(!validate({}), 'is required');
assert(validate({ foo: 42 }));
assert(!validate({ foo: 43 }));
});
it('minimum/maximum', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'number',
minimum: 0,
maximum: 0
}
}
});
assert(!validate({ foo: -42 }));
assert(validate({ foo: 0 }));
assert(!validate({ foo: 42 }));
});
it('exclusiveMinimum/exclusiveMaximum', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'number',
minimum: 10,
maximum: 20,
exclusiveMinimum: true,
exclusiveMaximum: true
}
}
});
assert(!validate({ foo: 10 }));
assert(validate({ foo: 11 }));
assert(!validate({ foo: 20 }));
assert(validate({ foo: 19 }));
});
it('allow to validate undefined as object', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'string'
}
},
required: ['foo']
}, { undefinedAsObject: true });
assert(!validate(undefined));
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'is required');
});
it('allow to validate null as object', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'string'
}
},
required: ['foo']
}, { nullAsObject: true });
assert(!validate(null));
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'is required');
});
it('allow to validate null and undefined as objects', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'string'
}
},
required: ['foo']
}, { nullAsObject: true, undefinedAsObject: true });
assert(!validate(null));
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'is required');
assert(!validate(undefined));
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'is required');
});
it('allow to validate undefined as array', function () {
var validate = (0, _compileValidator2.default)({
type: 'array',
minItems: 1
}, { undefinedAsArray: true });
assert(!validate(undefined));
assert(validate.errors[0].field === 'data');
assert(validate.errors[0].message === 'has less items than allowed');
});
it('allow to validate null as object', function () {
var validate = (0, _compileValidator2.default)({
type: 'array',
minItems: 1
}, { nullAsArray: true });
assert(!validate(null));
assert(validate.errors[0].field === 'data');
assert(validate.errors[0].message === 'has less items than allowed');
});
it('allow to validate null and undefined as objects', function () {
var validate = (0, _compileValidator2.default)({
type: 'array',
minItems: 1
}, { nullAsArray: true, undefinedAsArray: true });
assert(!validate(null));
assert(validate.errors[0].field === 'data');
assert(validate.errors[0].message === 'has less items than allowed');
assert(!validate(undefined));
assert(validate.errors[0].field === 'data');
assert(validate.errors[0].message === 'has less items than allowed');
});
it('custom format', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'string',
format: 'as'
}
}
}, { formats: { as: /^a+$/ } });
assert(!validate({ foo: '' }), 'not as');
assert(!validate({ foo: 'b' }), 'not as');
assert(!validate({ foo: 'aaab' }), 'not as');
assert(validate({ foo: 'a' }), 'as');
assert(validate({ foo: 'aaaaaa' }), 'as');
});
it('custom format function', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'string',
format: 'as'
}
}
}, { formats: { as: function as(s) {
return (/^a+$/.test(s)
);
} } });
assert(!validate({ foo: '' }), 'not as');
assert(!validate({ foo: 'b' }), 'not as');
assert(!validate({ foo: 'aaab' }), 'not as');
assert(validate({ foo: 'a' }), 'as');
assert(validate({ foo: 'aaaaaa' }), 'as');
});
it('custom format function with custom error reporting', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'string',
format: 'as'
}
}
}, {
formats: {
as: function as(s) {
if (s !== 'as') {
return 'custom error message';
}
return true;
}
}
});
assert(!validate({ foo: '' }), 'should be "as"');
assert(validate.errors);
assert(validate.errors[0]);
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'custom error message');
});
it('custom format function (inline) with custom error reporting', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'string',
format: function format(s) {
if (s !== 'as') {
return 'custom error message';
}
return true;
}
}
}
});
assert(!validate({ foo: '' }), 'should be "as"');
assert(validate.errors);
assert(validate.errors[0]);
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'custom error message');
});
it('custom format function (inline) with custom metadata', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'string',
format: function format(s) {
if (s !== 'as') {
return {
message: 'custom error message',
force: true
};
}
return true;
}
}
}
});
assert(!validate({ foo: '' }), 'should be "as"');
assert(validate.errors);
assert(validate.errors[0]);
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'custom error message');
assert(validate.errors[0].force);
});
it('custom format function with custom error locations', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
format: function format(value) {
if (value.foo !== value.bar) {
return { field: 'foo', message: 'foo should be equal to bar' };
} else {
return true;
}
},
properties: {
foo: { type: 'number' },
bar: { type: 'number' }
}
});
assert(!validate({ foo: 1, bar: 2 }));
assert(validate.errors);
assert(validate.errors.length === 1);
assert(validate.errors[0]);
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'foo should be equal to bar');
});
it('custom format function with custom error meta', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
format: function format(value) {
if (value.foo !== value.bar) {
return {
field: 'foo',
message: 'foo should be equal to bar',
force: true
};
} else {
return true;
}
},
properties: {
foo: { type: 'number' },
bar: { type: 'number' }
}
});
assert(!validate({ foo: 1, bar: 2 }));
assert(validate.errors);
assert(validate.errors.length === 1);
assert(validate.errors[0]);
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'foo should be equal to bar');
assert(validate.errors[0].force);
});
it('custom format function with custom errors locations', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
format: function format(value) {
if (value.foo !== value.bar) {
return [{ field: 'foo', message: 'foo should be equal to bar' }, 'oops'];
} else {
return true;
}
},
properties: {
foo: { type: 'number' },
bar: { type: 'number' }
}
});
assert(!validate({ foo: 1, bar: 2 }));
assert(validate.errors);
assert(validate.errors.length === 2);
assert(validate.errors[0]);
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'foo should be equal to bar');
assert(validate.errors[1]);
assert(validate.errors[1].field === 'data');
assert(validate.errors[1].message === 'oops');
});
it('custom format function with custom errors meta', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
format: function format(value) {
if (value.foo !== value.bar) {
return [{ field: 'foo', message: 'foo should be equal to bar', force: true }, 'oops'];
} else {
return true;
}
},
properties: {
foo: { type: 'number' },
bar: { type: 'number' }
}
});
assert(!validate({ foo: 1, bar: 2 }));
assert(validate.errors);
assert(validate.errors.length === 2);
assert(validate.errors[0]);
assert(validate.errors[0].field === 'data.foo');
assert(validate.errors[0].message === 'foo should be equal to bar');
assert(validate.errors[0].force);
assert(validate.errors[1]);
assert(validate.errors[1].field === 'data');
assert(validate.errors[1].message === 'oops');
});
it('custom format function accept current node as second argument', function () {
var touchedNodes = [];
var schema = {
type: 'object',
properties: {
foo: {
type: 'string',
format: 'as'
}
}
};
var validate = (0, _compileValidator2.default)(schema, {
formats: {
as: function as(s, n) {
touchedNodes.push(n);
return s === 'as';
}
}
});
assert(validate({ foo: 'as' }), 'as');
assert(touchedNodes[0] === schema.properties.foo);
});
it('custom format function can be specified inline', function () {
var validate = (0, _compileValidator2.default)({
type: 'object',
properties: {
foo: {
type: 'string',
format: function format(s) {
return s === 'as';
}
}
}
});
assert(!validate({ foo: 's' }));
assert(validate({ foo: 'as' }));
});
it('do not mutate schema', function () {
var sch = {
items: [{}],
additionalItems: {
type: 'integer'
}
};
var copy = JSON.parse(JSON.stringify(sch));
(0, _compileValidator2.default)(sch);
assert.deepEqual(sch, copy, 'did not mutate');
});
it('#toJSON()', function () {
var schema = {
required: true,
type: 'object',
properties: {
hello: { type: 'string', required: true }
}
};
var validate = (0, _compileValidator2.default)(schema);
assert.deepEqual(validate.toJSON(), schema, 'should return original schema');
});
it('external schemas', function () {
var ext = { type: 'string' };
var schema = {
required: true,
$ref: '#ext'
};
var validate = (0, _compileValidator2.default)(schema, { schemas: { ext: ext } });
assert(validate('hello string'), 'is a string');
assert(!validate(42), 'not a string');
});
it('nested required array decl', function () {
var schema = {
properties: {
x: {
type: 'object',
properties: {
y: {
type: 'object',
properties: {
z: {
type: 'string'
}
},
required: ['z']
}
}
}
},
required: ['x']
};
var validate = (0, _compileValidator2.default)(schema);
assert(validate({ x: {} }), 'should be valid');
assert(!validate({}), 'should not be valid');
assert(validate.errors[0].field === 'data.x', 'should output the missing field');
});
it('verbose mode', function () {
var schema = {
required: true,
type: 'object',
properties: {
hello: {
required: true,
type: 'string'
}
}
};
var validate = (0, _compileValidator2.default)(schema, { verbose: true });
assert(validate({ hello: 'string' }), 'should be valid');
assert(!validate({ hello: 100 }), 'should not be valid');
assert(validate.errors[0].value === 100, 'error object should contain the invalid value');
});
it('additional props in verbose mode', function () {
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 = (0, _compileValidator2.default)(schema, { verbose: true });
validate({ 'hello world': { bar: 'string' } });
assert(validate.errors[0].value === 'data["hello world"].bar', 'should output the path to the additional prop in the error');
});
it('Date.now() is an integer', function () {
var schema = { type: 'integer' };
var validate = (0, _compileValidator2.default)(schema);
assert(validate(Date.now()), 'is integer');
});
});