Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding additional date validation options. #168

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions addon/validators/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ const {
* #### Options
* - `allowBlank` (**Boolean**): If true, skips validation if the value is empty
* - `before` (**String**): The specified date must be before this date
* - `onOrBefore` (**String**): The specified date must be on or before this date
* - `after` (**String**): The specified date must be after this date
* - `onOrAfter` (**String**): The specified date must be on or after this date
* - `percision` (**String**): Limit the comparison check to a specific granularity. Options: year, month, week, day, hour, minute, second.
* - `format` (**String**): Input value date format
* - `errorFormat` (**String**): Error output date format. Defaults to `MMM Do, YYYY`
*
Expand All @@ -33,10 +36,11 @@ const {
* validator('date', {
* after: 'now',
* before: '1/1/2020',
* percision: 'day',
* format: 'M/D/YYY',
* errorFormat: 'M/D/YYY'
* })
* // If before or after is set to 'now', the value given to the validator will be tested against the current date and time.
* // If before, onOrBefore, after, or onOrAfter is set to 'now', the value given to the validator will be tested against the current date and time.
* ```
*
* @class Date
Expand All @@ -55,7 +59,8 @@ export default Base.extend({
validate(value, options) {
const errorFormat = options.errorFormat || 'MMM Do, YYYY';
const format = options.format;
let { before, after } = options;
const percision = options.percision;
let { before, onOrBefore, after, onOrAfter } = options;

if (options.allowBlank && isEmpty(value)) {
return true;
Expand All @@ -73,20 +78,36 @@ export default Base.extend({

if (before) {
before = this._parseDate(before, format);
if (before < date) {
if (!date.isBefore(before, percision)) {
options.before = before.format(errorFormat);
return this.createErrorMessage('before', value, options);
}
}

if (onOrBefore) {
onOrBefore = this._parseDate(onOrBefore, format);
if (!date.isSameOrBefore(onOrBefore, percision)) {
options.onOrBefore = onOrBefore.format(errorFormat);
return this.createErrorMessage('onOrBefore', value, options);
}
}

if (after) {
after = this._parseDate(after, format);
if (after > date) {
if (!date.isAfter(after, percision)) {
options.after = after.format(errorFormat);
return this.createErrorMessage('after', value, options);
}
}

if (onOrAfter) {
onOrAfter = this._parseDate(onOrAfter, format);
if (!date.isSameOrAfter(onOrAfter, percision)) {
options.onOrAfter = onOrAfter.format(errorFormat);
return this.createErrorMessage('onOrAfter', value, options);
}
}

return true;
}
});
2 changes: 2 additions & 0 deletions addon/validators/messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ export default Ember.Object.extend({
tooLong: '{description} is too long (maximum is {max} characters)',
tooShort: '{description} is too short (minimum is {min} characters)',
before: '{description} must be before {before}',
onOrBefore: '{description} must be on or before {onOrBefore}',
after: '{description} must be after {after}',
onOrAfter: '{description} must be on or after {onOrAfter}',
wrongDateFormat: '{description} must be in the format of {format}',
wrongLength: '{description} is the wrong length (should be {is} characters)',
notANumber: '{description} must be a number',
Expand Down
148 changes: 133 additions & 15 deletions tests/unit/validators/date-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ from 'ember-qunit';

var options, validator, message;
var set = Ember.set;
const assign = Ember.assign || Ember.merge;

moduleFor('validator:date', 'Unit | Validator | date', {
needs: ['validator:messages'],
Expand All @@ -37,10 +38,10 @@ test('allow blank', function(assert) {
before: '1/1/2015'
};

message = validator.validate('', options);
message = validator.validate('', assign({}, options));
assert.equal(message, true);

message = validator.validate('1/1/2016', options);
message = validator.validate('1/1/2016', assign({}, options));
assert.equal(message, 'This field must be before Jan 1st, 2015');
});

Expand All @@ -49,10 +50,10 @@ test('valid date', function(assert) {

options = {};

message = validator.validate('abc', options);
message = validator.validate('abc', assign({}, options));
assert.equal(message, 'This field must be a valid date');

message = validator.validate(new Date(), options);
message = validator.validate(new Date(), assign({}, options));
assert.equal(message, true);
});

Expand All @@ -63,10 +64,10 @@ test('valid input date format', function(assert) {
format: 'M/D/YYYY'
};

message = validator.validate('1/1/15', options);
message = validator.validate('1/1/15', assign({}, options));
assert.equal(message, 'This field must be in the format of M/D/YYYY');

message = validator.validate('1/1/2015', options);
message = validator.validate('1/1/2015', assign({}, options));
assert.equal(message, true);
});

Expand All @@ -78,7 +79,7 @@ test('error date format', function(assert) {
before: '1/1/2015'
};

message = validator.validate('1/1/2016', options);
message = validator.validate('1/1/2016', assign({}, options));
assert.equal(message, 'This field must be before 1/1/2015');
});

Expand All @@ -89,10 +90,10 @@ test('before', function(assert) {
before: '1/1/2015'
};

message = validator.validate('1/1/2016', options);
message = validator.validate('1/1/2016', assign({}, options));
assert.equal(message, 'This field must be before Jan 1st, 2015');

message = validator.validate('1/1/2014', options);
message = validator.validate('1/1/2014', assign({}, options));
assert.equal(message, true);
});

Expand All @@ -102,24 +103,82 @@ test('before now', function(assert) {
options = {
before: 'now'
};
message = validator.validate('1/1/3015', options);
message = validator.validate('1/1/3015', assign({}, options));
assert.equal(message, `This field must be before ${now}`);

message = validator.validate('1/1/2014', options);
message = validator.validate('1/1/2014', assign({}, options));
assert.equal(message, true);
});

test('before or on', function(assert) {
assert.expect(3);

options = {
onOrBefore: '1/1/2015'
};

message = validator.validate('1/1/2016', assign({}, options));
assert.equal(message, 'This field must be on or before Jan 1st, 2015');

message = validator.validate('1/1/2014', assign({}, options));
assert.equal(message, true);

message = validator.validate('1/1/2015', assign({}, options));
assert.equal(message, true);
});

test('before now or on', function(assert) {
assert.expect(3);
var now = moment().format('MMM Do, YYYY');
options = {
onOrBefore: 'now'
};
message = validator.validate('1/1/3015', assign({}, options));
assert.equal(message, `This field must be on or before ${now}`);

message = validator.validate('1/1/2014', assign({}, options));
assert.equal(message, true);

message = validator.validate('now', assign({}, options));
assert.equal(message, true);
});

test('before or on percision', function(assert) {
var percisions = ['second', 'minute', 'hour', 'day', 'week', 'month', 'year'];

assert.expect((percisions.length * 3) -1);
var date = '2013-02-08T09:30:26';
var now = moment(date);
var dateString = now.toString();
var nowMessage = now.format('MMM Do, YYYY');

for (var i = 0; i < percisions.length; i++) {
var percision = percisions[i];

message = validator.validate(dateString, { onOrBefore: dateString });
assert.equal(message, true);

message = validator.validate(moment(dateString).add(1, percision), { onOrBefore: dateString });
assert.equal(message, `This field must be on or before ${nowMessage}`);

if ((i + 1) !== percisions.length) {
message = validator.validate(moment(dateString).add(1, percisions), { onOrBefore: dateString, percision: percisions[i + 1] });
assert.equal(message, true);
}
}
});

test('after', function(assert) {
assert.expect(2);

options = {
after: '1/1/2015'
};

message = validator.validate('1/1/2014', options);
message = validator.validate('1/1/2014', assign({}, options));
assert.equal(message, 'This field must be after Jan 1st, 2015');

message = validator.validate('1/1/2016', options);
message = validator.validate('1/1/2016', assign({}, options));
assert.equal(message, true);
});

Expand All @@ -130,9 +189,68 @@ test('after now', function(assert) {
after: 'now'
};

message = validator.validate('1/1/2014', options);
message = validator.validate('1/1/2014', assign({}, options));
assert.equal(message, `This field must be after ${now}`);

message = validator.validate('1/1/3015', options);
message = validator.validate('1/1/3015', assign({}, options));
assert.equal(message, true);
});

test('after or on', function(assert) {
assert.expect(3);

options = {
onOrAfter: '1/1/2015'
};

message = validator.validate('1/1/2014', assign({}, options));
assert.equal(message, 'This field must be on or after Jan 1st, 2015');

message = validator.validate('1/1/2016', assign({}, options));
assert.equal(message, true);

message = validator.validate('1/1/2015', assign({}, options));
assert.equal(message, true);
});

test('after now or on', function(assert) {
assert.expect(3);
var now = moment().format('MMM Do, YYYY');
options = {
onOrAfter: 'now'
};

message = validator.validate('1/1/2014', assign({}, options));
assert.equal(message, `This field must be on or after ${now}`);

message = validator.validate('1/1/3015', assign({}, options));
assert.equal(message, true);

message = validator.validate('now', assign({}, options));
assert.equal(message, true);
});

test('after or on percision', function(assert) {
var percisions = ['second', 'minute', 'hour', 'day', 'week', 'month', 'year'];

assert.expect((percisions.length * 3) -1);
var date = '2013-02-08T09:30:26';
var now = moment(date);
var dateString = now.toString();
var nowMessage = now.format('MMM Do, YYYY');

for (var i = 0; i < percisions.length; i++) {
var percision = percisions[i];

message = validator.validate(dateString, { onOrAfter: dateString });
assert.equal(message, true);

message = validator.validate(moment(dateString).subtract(1, percision), { onOrAfter: dateString });
assert.equal(message, `This field must be on or after ${nowMessage}`);

if ((i + 1) !== percisions.length) {
message = validator.validate(moment(dateString).subtract(1, percisions), { onOrAfter: dateString, percision: percisions[i + 1] });
assert.equal(message, true);
}
}
});