UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

351 lines (350 loc) 8.96 kB
/*global Person,Task*/ steal("can/map/validations", "can/compute", "can/test", "steal-qunit", function () { QUnit.module('can/map/validations', { setup: function () { can.Map.extend('Person', {}, {}); } }); test('observe can validate, events, callbacks', 7, function () { Person.validate('age', { message: 'it\'s a date type' }, function (val) { return !(this.date instanceof Date); }); var task = new Person({ age: 'bad' }), errors = task.errors(); ok(errors, 'There are errors'); equal(errors.age.length, 1, 'there is one error'); equal(errors.age[0], 'it\'s a date type', 'error message is right'); task.bind('error', function (ev, attr, errs) { ok(this === task, 'we get task back by binding'); ok(errs, 'There are errors'); equal(errs.age.length, 1, 'there is one error'); equal(errs.age[0], 'it\'s a date type', 'error message is right'); }); task.attr('age', 'blah'); task.unbind('error'); task.attr('age', 'blaher'); }); test('validatesFormatOf', function () { Person.validateFormatOf('thing', /\d-\d/); ok(!new Person({ thing: '1-2' }) .errors(), 'no errors'); var errors = new Person({ thing: 'foobar' }) .errors(); ok(errors, 'there are errors'); equal(errors.thing.length, 1, 'one error on thing'); equal(errors.thing[0], 'is invalid', 'basic message'); Person.validateFormatOf('otherThing', /\d/, { message: 'not a digit' }); var errors2 = new Person({ thing: '1-2', otherThing: 'a' }) .errors(); equal(errors2.otherThing[0], 'not a digit', 'can supply a custom message'); ok(!new Person({ thing: '1-2', otherThing: null }) .errors(), 'can handle null'); ok(!new Person({ thing: '1-2' }) .errors(), 'can handle undefiend'); }); test('validatesInclusionOf', function () { Person.validateInclusionOf('thing', [ 'yes', 'no', 'maybe' ]); ok(!new Person({ thing: 'yes' }) .errors(), 'no errors'); var errors = new Person({ thing: 'foobar' }) .errors(); ok(errors, 'there are errors'); equal(errors.thing.length, 1, 'one error on thing'); equal(errors.thing[0], 'is not a valid option (perhaps out of range)', 'basic message'); Person.validateInclusionOf('otherThing', [ 'yes', 'no', 'maybe' ], { message: 'not a valid option' }); var errors2 = new Person({ thing: 'yes', otherThing: 'maybe not' }) .errors(); equal(errors2.otherThing[0], 'not a valid option', 'can supply a custom message'); }); test('validatesLengthOf', function () { Person.validateLengthOf('undefinedValue', 0, 5); Person.validateLengthOf('nullValue', 0, 5); Person.validateLengthOf('thing', 2, 5); ok(!new Person({ thing: 'yes', nullValue: null }) .errors(), 'no errors'); var errors = new Person({ thing: 'foobar' }) .errors(); ok(errors, 'there are errors'); equal(errors.thing.length, 1, 'one error on thing'); equal(errors.thing[0], 'is too long (max=5)', 'basic message'); Person.validateLengthOf('otherThing', 2, 5, { message: 'invalid length' }); var errors2 = new Person({ thing: 'yes', otherThing: 'too long' }) .errors(); equal(errors2.otherThing[0], 'invalid length', 'can supply a custom message'); Person.validateLengthOf('undefinedValue2', 1, 5); Person.validateLengthOf('nullValue2', 1, 5); var errors3 = new Person({ thing: 'yes', nullValue2: null }) .errors(); equal(errors3.undefinedValue2.length, 1, 'can handle undefined'); equal(errors3.nullValue2.length, 1, 'can handle null'); }); test('validatesPresenceOf', function () { can.Map.extend('Task', { init: function () { this.validatePresenceOf('dueDate'); } }, {}); //test for undefined var task = new Task(), errors = task.errors(); ok(errors); ok(errors.dueDate); equal(errors.dueDate[0], 'can\'t be empty', 'right message'); //test for null task = new Task({ dueDate: null }); errors = task.errors(); ok(errors); ok(errors.dueDate); equal(errors.dueDate[0], 'can\'t be empty', 'right message'); //test for "" task = new Task({ dueDate: '' }); errors = task.errors(); ok(errors); ok(errors.dueDate); equal(errors.dueDate[0], 'can\'t be empty', 'right message'); //Affirmative test task = new Task({ dueDate: 'yes' }); errors = task.errors(); ok(!errors, 'no errors ' + typeof errors); can.Map.extend('Task', { init: function () { this.validatePresenceOf('dueDate', { message: 'You must have a dueDate' }); } }, {}); task = new Task({ dueDate: 'yes' }); errors = task.errors(); ok(!errors, 'no errors ' + typeof errors); }); test('validatesPresenceOf with numbers and a 0 value', function () { can.Map.extend('Person', { attributes: { age: 'number' } }); Person.validatePresenceOf('age'); var person = new Person(); var errors = person.errors(); ok(errors); ok(errors.age); equal(errors.age[0], 'can\'t be empty', 'A new Person with no age generates errors.'); //test for null person = new Person({ age: null }); errors = person.errors(); ok(errors); ok(errors.age); equal(errors.age[0], 'can\'t be empty', 'A new Person with null age generates errors.'); //test for "" person = new Person({ age: '' }); errors = person.errors(); ok(errors); ok(errors.age); equal(errors.age[0], 'can\'t be empty', 'A new Person with an empty string age generates errors.'); //Affirmative test person = new Person({ age: 12 }); errors = person.errors(); ok(!errors, 'A new Person with a valid >0 age doesn\'t generate errors.'); //Affirmative test with 0 person = new Person({ age: 0 }); errors = person.errors(); ok(!errors, 'A new Person with a valid 0 age doesn\'t generate errors'); }); test('validatesRangeOf', function () { Person.validateRangeOf('thing', 2, 5); Person.validateRangeOf('nullValue', 0, 5); Person.validateRangeOf('undefinedValue', 0, 5); ok(!new Person({ thing: 4, nullValue: null }) .errors(), 'no errors'); var errors = new Person({ thing: 6 }) .errors(); ok(errors, 'there are errors'); equal(errors.thing.length, 1, 'one error on thing'); equal(errors.thing[0], 'is out of range [2,5]', 'basic message'); Person.validateRangeOf('otherThing', 2, 5, { message: 'value out of range' }); var errors2 = new Person({ thing: 4, otherThing: 6 }) .errors(); equal(errors2.otherThing[0], 'value out of range', 'can supply a custom message'); Person.validateRangeOf('nullValue2', 1, 5); Person.validateRangeOf('undefinedValue2', 1, 5); var errors3 = new Person({ thing: 2, nullValue2: null }) .errors(); equal(errors3.nullValue2.length, 1, 'one error on nullValue2'); equal(errors3.undefinedValue2.length, 1, 'one error on undefinedValue2'); }); test('validatesNumericalityOf', function () { Person.validatesNumericalityOf(['foo']); var errors; errors = new Person({ foo: 0 }) .errors(); ok(!errors, 'no errors'); errors = new Person({ foo: 1 }) .errors(); ok(!errors, 'no errors'); errors = new Person({ foo: 1.5 }) .errors(); ok(!errors, 'no errors'); errors = new Person({ foo: -1.5 }) .errors(); ok(!errors, 'no errors'); errors = new Person({ foo: '1' }) .errors(); ok(!errors, 'no errors'); errors = new Person({ foo: '1.5' }) .errors(); ok(!errors, 'no errors'); errors = new Person({ foo: '.5' }) .errors(); ok(!errors, 'no errors'); errors = new Person({ foo: '-1.5' }) .errors(); ok(!errors, 'no errors'); errors = new Person({ foo: ' ' }) .errors(); equal(errors.foo.length, 1, 'one error on foo'); errors = new Person({ foo: '1f' }) .errors(); equal(errors.foo.length, 1, 'one error on foo'); errors = new Person({ foo: 'f1' }) .errors(); equal(errors.foo.length, 1, 'one error on foo'); errors = new Person({ foo: '1.5.5' }) .errors(); equal(errors.foo.length, 1, 'one error on foo'); errors = new Person({ foo: '\t\t' }) .errors(); equal(errors.foo.length, 1, 'one error on foo'); errors = new Person({ foo: '\n\r' }) .errors(); equal(errors.foo.length, 1, 'one error on foo'); }); test('Validate with compute (#410)', function () { expect(4); Person.validate('age', { message: 'it\'s a date type' }, function (val) { return !(this.date instanceof Date); }); var task = new Person({ age: 20 }), errors = can.compute(function () { return task.errors(); }); errors.bind('change', function (ev, errorObj) { equal(errorObj.age.length, 1, 'there is one error'); equal(errorObj.age.length, 1, 'there is one error'); }); task.attr('age', 'bad'); task.attr('age', 'still bad'); }); test('Validate undefined property', function () { new can.Map().errors( "foo" ); ok(true, "does not throw" ); }); });