Skip to content

Commit

Permalink
test: add more validate tests (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickhulce committed Feb 27, 2018
1 parent 081bf27 commit 2d8c732
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 5 deletions.
8 changes: 5 additions & 3 deletions packages/klay/lib/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,10 @@ Model.prototype.validations = function (validations) {
var msg = 'validations must be a regex, function, or array of functions';
if (_.isArray(validations)) {
validations.forEach(item => assert.ok(typeof item === 'function', msg));
} else if (validations instanceof RegExp) {
assert.equal(this.spec.type, 'string', 'model must be of type string');
} else {
assert.ok(validations instanceof RegExp || typeof validations === 'function', msg);
assert.ok(typeof validations === 'function', msg);
}

return this._with({validations: validations});
Expand Down Expand Up @@ -216,8 +218,8 @@ Model.prototype._validateValue = function (value) {
if (validate instanceof RegExp) {
var regexp = validate;
validate = function (value) {
assert.equal(typeof value, 'string', 'typeof');
assert.ok(value.match(regexp), 'pattern');
assert.typeof(value, 'string');
assert.match(value, regexp);
};
} else if (_.isArray(validate)) {
var validateFuncs = validate;
Expand Down
2 changes: 2 additions & 0 deletions packages/klay/lib/transformations.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ module.exports = {
return value;
} else if (value === 'string') {
return Number(value);
} else {
return value;
}
}
},
Expand Down
5 changes: 5 additions & 0 deletions packages/klay/lib/validations.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ module.exports = {
assert.typeof(value, 'boolean');
}
},
number: {
__default: function (value) {
assert.typeof(value, 'number');
}
},
conditional: {
__default: function (value, root, path) {
var options = this._getOrThrow('options');
Expand Down
99 changes: 97 additions & 2 deletions packages/klay/test/Model.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var _ = require('lodash');
var assert = require('assert');
var ValidationError = relativeRequire('ValidationError');
var ValidationResult = relativeRequire('ValidationResult');
Expand Down Expand Up @@ -197,6 +198,12 @@ defineTest('Model.js', function (Model) {
model.spec.should.have.property('default', 'foobar');
});

it('should set spec.default as array', function () {
var arr = [1, 2, 3];
var model = new Model().type('array').default(arr);
model.spec.should.have.property('default', arr);
});

it('should unset spec.default', function () {
var model = new Model({type: 'number', default: 1}).default();
model.spec.should.have.property('default', undefined);
Expand All @@ -213,6 +220,12 @@ defineTest('Model.js', function (Model) {
new Model().type('number').default('12');
}).should.throw();
});

it('should fail when default is not array but type is', function () {
(function () {
new Model().type('array').default({'0': 1});
}).should.throw();
});
});

describe('#parse', function () {
Expand Down Expand Up @@ -404,6 +417,12 @@ defineTest('Model.js', function (Model) {
}).should.throw();
});

it('should fail when given a regexp and type is not string', function () {
(function () {
new Model().validations(/foo/);
}).should.throw();
});

it('should fail when given an array with invalid values', function () {
(function () {
new Model().validations([function () {}, 'other']);
Expand All @@ -418,6 +437,12 @@ defineTest('Model.js', function (Model) {
}).should.throw(/defined/);
});

it('should fail loudly when told to', function () {
(function () {
new Model({type: 'number'}).validate({}, true);
}).should.throw();
});

context('when required', function () {
it('should conform when present', function () {
var model = new Model({type: 'string', required: true});
Expand Down Expand Up @@ -546,8 +571,6 @@ defineTest('Model.js', function (Model) {
});
});



context('when transform is set', function () {
it('should transform the value', function () {
var transform = function (value) { return Number(value); };
Expand Down Expand Up @@ -595,5 +618,77 @@ defineTest('Model.js', function (Model) {
});
});

context('when validations is a RegExp', function () {
it('should pass a valid match', function () {
var model = new Model({type: 'string', validations: /^foo.*bar$/});
model.validate('fooANYTHINGbar').asObject().should.eql({
value: 'fooANYTHINGbar',
conforms: true,
errors: [],
});
});

it('should fail an invalid match', function () {
var model = new Model({type: 'string', validations: /^foo.*bar$/});
model.validate('somethingElsebar').asObject().should.eql({
value: 'somethingElsebar',
conforms: false,
errors: [{message: 'expected somethingElsebar to match /^foo.*bar$/'}],
});
});

it('should fail a non-string', function () {
var model = new Model({type: 'string', validations: /\d+/});
model.validate(12312).asObject().should.eql({
value: 12312,
conforms: false,
errors: [{message: 'expected 12312 to have typeof string'}],
});
});
});

context('when validations is an array', function () {
it('should pass a valid match', function () {
var model = new Model({type: 'string', validations: [_.noop, _.noop]});
model.validate('a string').asObject().should.eql({
value: 'a string',
conforms: true,
errors: [],
});
});

it('should fail when one element fails', function () {
var fail = function () { assert.ok(false, 'oops'); };
var model = new Model({type: 'number', validations: [_.noop, fail, _.noop]});
model.validate(123).asObject().should.eql({
value: 123,
conforms: false,
errors: [{message: 'oops'}],
});
});
});

context('when validations returns a ValidationResult', function () {
it('should short-circuit when does conform', function () {
var myFunc = function () { return new ValidationResult('x', true); };
var model = new Model({type: 'string', validations: myFunc});
model.validate('a string').asObject().should.eql({
value: 'x',
conforms: true,
errors: [],
});
});

it('should short-circuit when does not conform', function () {
var error = {message: 'y no work?'};
var myFunc = function () { return new ValidationResult('z', false, [error]); };
var model = new Model({type: 'string', validations: myFunc});
model.validate('a string').asObject().should.eql({
value: 'z',
conforms: false,
errors: [error],
});
});
});
});
});

0 comments on commit 2d8c732

Please sign in to comment.