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

Add support for timestamp on date assert #102

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
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
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ The following set of extra asserts are provided by this package:
- [Iso3166Country](#iso3166country) (requires `isoc`)
- [Json](#json)
- [NotEmpty](#notempty)
- [NullOrDate](#nullordate)
- [NullOrDate](#nullordate) (requires `moment` for format validation only)
- [NullOrString](#nullorstring)
- [Phone](#phone) (requires `google-libphonenumber`)
- [PlainObject](#plainobject)
Expand Down Expand Up @@ -152,6 +152,9 @@ Tests if the value is valid json.
### NotEmpty
Tests if the value is not an empty (empty object, empty array, empty string, etc).

### NullOrDate
Tests if the value is a `null` or `date`.
Copy link
Author

@madeiras madeiras Apr 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...or a number ? (timestamp)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If so we need to update here as well.


### NullOrString
Tests if the value is a `null` or `string`, optionally within some boundaries.

Expand Down
10 changes: 9 additions & 1 deletion src/asserts/date-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,16 @@ export default function dateAssert({ format } = {}) {
*/

this.validate = value => {
if (typeof value === 'number') {
if (new Date(value).toString() === 'Invalid Date') {
throw new Violation(this, value);
}

return true;
}

if (typeof value !== 'string' && Object.prototype.toString.call(value) !== '[object Date]') {
throw new Violation(this, value, { value: 'must_be_a_date_or_a_string' });
throw new Violation(this, value, { value: 'must_be_a_date_or_a_string_or_a_number' });
}

if (isNaN(Date.parse(value)) === true) {
Expand Down
19 changes: 12 additions & 7 deletions src/asserts/date-diff-greater-than-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@
* Module dependencies.
*/

import { Violation } from 'validator.js';
import DateAssert from './date-assert';
import { Assert as BaseAssert, Violation } from 'validator.js';
import { assign } from 'lodash';

/**
* Extend Assert with `DateAssert`.
*/

const Assert = BaseAssert.extend({ Date: DateAssert });

/**
* Export `DateDiffGreaterThanAssert`.
*/
Expand Down Expand Up @@ -53,12 +60,10 @@ export default function dateDiffGreaterThanAssert(threshold, options) {
*/

this.validate = value => {
if (typeof value !== 'string' && Object.prototype.toString.call(value) !== '[object Date]') {
throw new Violation(this, value, { value: 'must_be_a_date_or_a_string' });
}

if (isNaN(Date.parse(value)) === true) {
throw new Violation(this, value, { absolute: this.absolute, asFloat: this.asFloat, fromDate: this.fromDate, threshold: this.threshold, unit: this.unit });
try {
new Assert().Date().validate(value);
} catch (e) {
throw new Violation(this, value, { value: 'must_be_a_date_or_a_string_or_a_number' });
}

let diff = moment(this.fromDate || Date.now()).diff(value, this.unit, this.asFloat);
Expand Down
19 changes: 12 additions & 7 deletions src/asserts/date-diff-less-than-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,16 @@
* Module dependencies.
*/

import { Violation } from 'validator.js';
import DateAssert from './date-assert';
import { Assert as BaseAssert, Violation } from 'validator.js';
import { assign } from 'lodash';

/**
* Extend Assert with `DateAssert`.
*/

const Assert = BaseAssert.extend({ Date: DateAssert });

/**
* Export `DateDiffLessThanAssert`.
*/
Expand Down Expand Up @@ -53,12 +60,10 @@ export default function dateDiffLessThanAssert(threshold, options) {
*/

this.validate = value => {
if (typeof value !== 'string' && Object.prototype.toString.call(value) !== '[object Date]') {
throw new Violation(this, value, { value: 'must_be_a_date_or_a_string' });
}

if (isNaN(Date.parse(value)) === true) {
throw new Violation(this, value, { absolute: this.absolute, asFloat: this.asFloat, fromDate: this.fromDate, threshold: this.threshold, unit: this.unit });
try {
new Assert().Date().validate(value);
} catch (e) {
throw new Violation(this, value, { value: 'must_be_a_date_or_a_string_or_a_number' });
}

let diff = moment(this.fromDate || Date.now()).diff(value, this.unit, this.asFloat);
Expand Down
27 changes: 19 additions & 8 deletions src/asserts/null-or-date-assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,45 @@
* Module dependencies.
*/

import { Violation } from 'validator.js';
import DateAssert from './date-assert';
import { Assert as BaseAssert, Violation } from 'validator.js';

/**
* Extend Assert with `DateAssert`.
*/

const Assert = BaseAssert.extend({ Date: DateAssert });

/**
* Export `NullOrDateAssert`.
*/

export default function nullOrDateAssert() {
export default function nullOrDateAssert({ format } = {}) {
/**
* Class name.
*/

this.__class__ = 'NullOrDate';

/**
* Format to match the input.
*/

this.format = format;

/**
* Validation algorithm.
*/

this.validate = value => {
if (typeof value !== 'string' && value !== null && Object.prototype.toString.call(value) !== '[object Date]') {
throw new Violation(this, value, { value: 'must_be_null_or_a_date' });
}

if (value === null) {
return true;
}

if (isNaN(Date.parse(value)) === true) {
throw new Violation(this, value);
try {
new Assert().Date({ format }).validate(value);
} catch (e) {
throw new Violation(this, value, { value: 'must_be_null_or_a_date_or_a_number' });
}

return true;
Expand Down
31 changes: 25 additions & 6 deletions test/asserts/date-assert_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ const Assert = BaseAssert.extend({
*/

describe('DateAssert', () => {
it('should throw an error if the input value is not a string or a date', () => {
const choices = [[], {}, 123];
it('should throw an error if the input value is not a date or a string or a number', () => {
const choices = [[], {}];

choices.forEach(choice => {
try {
Expand All @@ -30,7 +30,7 @@ describe('DateAssert', () => {
should.fail();
} catch (e) {
e.should.be.instanceOf(Violation);
e.violation.value.should.equal('must_be_a_date_or_a_string');
e.violation.value.should.equal('must_be_a_date_or_a_string_or_a_number');
}
});
});
Expand Down Expand Up @@ -61,6 +61,17 @@ describe('DateAssert', () => {
}
});

it('should throw an error if the input value is an invalid timestamp', () => {
try {
new Assert().Date().validate(-Number.MAX_VALUE);

should.fail();
} catch (e) {
e.should.be.instanceOf(Violation);
e.show().assert.should.equal('Date');
}
});

it('should throw an error if value does not pass strict validation', () => {
try {
new Assert().Date({ format: 'YYYY-MM-DD' }).validate('2000.12.30');
Expand All @@ -82,15 +93,23 @@ describe('DateAssert', () => {
}
});

it('should accept a `Date`', () => {
it('should accept an instance of `Date`', () => {
new Assert().Date().validate(new Date());
});

it('should accept a correctly formatted date', () => {
new Assert().Date({ format: 'YYYY-MM-DD' }).validate('2000-12-30');
});

it('should accept a `string`', () => {
new Assert().Date().validate('2014-10-16');
it('should accept a string date', () => {
new Assert().Date().validate('2016-04-23');
});

it('should accept an ISO-8601 string date', () => {
new Assert().Date().validate('2016-04-23T00:51:18.570Z');
});

it('should accept a numeric timestamp', () => {
new Assert().Date().validate(Date.now());
});
});
21 changes: 20 additions & 1 deletion test/asserts/date-diff-greater-than-assert_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe('DateDiffGreaterThanAssert', () => {
should.fail();
} catch (e) {
e.should.be.instanceOf(Violation);
e.violation.value.should.equal('must_be_a_date_or_a_string');
e.violation.value.should.equal('must_be_a_date_or_a_string_or_a_number');
}
});
});
Expand All @@ -81,6 +81,17 @@ describe('DateDiffGreaterThanAssert', () => {
}
});

it('should throw an error if the input value is an invalid timestamp', () => {
try {
new Assert().DateDiffGreaterThan(10).validate(-Number.MAX_VALUE);

should.fail();
} catch (e) {
e.should.be.instanceOf(Violation);
e.show().assert.should.equal('DateDiffGreaterThan');
}
});

it('should throw an error if the diff between `now` and input date is equal to `threshold`', () => {
const clock = sinon.useFakeTimers(0, 'Date');

Expand Down Expand Up @@ -243,6 +254,14 @@ describe('DateDiffGreaterThanAssert', () => {
clock.restore();
});

it('should accept a timestamp whose diff from `now` is greater than the threshold', () => {
const clock = sinon.useFakeTimers(0, 'Date');

new Assert().DateDiffGreaterThan(0).validate(-1);

clock.restore();
});

it('should accept a date whose diff from `fromDate` is greater than the threshold', () => {
new Assert().DateDiffGreaterThan(24, { asFloat: false, fromDate: new Date('1970-01-01 00:00:00'), unit: 'hours' }).validate(new Date('1969-12-30 00:00:00'));
});
Expand Down
21 changes: 20 additions & 1 deletion test/asserts/date-diff-less-than-assert_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe('DateDiffLessThanAssert', () => {
should.fail();
} catch (e) {
e.should.be.instanceOf(Violation);
e.violation.value.should.equal('must_be_a_date_or_a_string');
e.violation.value.should.equal('must_be_a_date_or_a_string_or_a_number');
}
});
});
Expand All @@ -81,6 +81,17 @@ describe('DateDiffLessThanAssert', () => {
}
});

it('should throw an error if the input value is an invalid timestamp', () => {
try {
new Assert().DateDiffLessThan(10).validate(-Number.MAX_VALUE);

should.fail();
} catch (e) {
e.should.be.instanceOf(Violation);
e.show().assert.should.equal('DateDiffLessThan');
}
});

it('should throw an error if the diff between `now` and input date is equal to `threshold`', () => {
const clock = sinon.useFakeTimers(0, 'Date');

Expand Down Expand Up @@ -255,6 +266,14 @@ describe('DateDiffLessThanAssert', () => {
clock.restore();
});

it('should accept a timestamp whose diff from `now` is less than the threshold', () => {
const clock = sinon.useFakeTimers(0, 'Date');

new Assert().DateDiffLessThan(1).validate(0);

clock.restore();
});

it('should accept a date whose diff from `fromDate` is less than the threshold', () => {
new Assert().DateDiffLessThan(24, { asFloat: false, fromDate: new Date('1970-01-01 09:00:00'), unit: 'hours' }).validate(new Date('1970-01-01 00:00:00'));
});
Expand Down
40 changes: 37 additions & 3 deletions test/asserts/null-or-date-assert_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ const Assert = BaseAssert.extend({
*/

describe('NullOrDateAssert', () => {
it('should throw an error if the input value is not a `null` or a date', () => {
const choices = [[], {}, 123];
it('should throw an error if the input value is not a `null` or a date or a number', () => {
const choices = [[], {}];

choices.forEach(choice => {
try {
Expand All @@ -30,7 +30,7 @@ describe('NullOrDateAssert', () => {
should.fail();
} catch (e) {
e.should.be.instanceOf(Violation);
e.violation.value.should.equal('must_be_null_or_a_date');
e.violation.value.should.equal('must_be_null_or_a_date_or_a_number');
}
});
});
Expand All @@ -46,6 +46,28 @@ describe('NullOrDateAssert', () => {
}
});

it('should throw an error if the input value is an invalid timestamp', () => {
try {
new Assert().NullOrDate().validate(-Number.MAX_VALUE);

should.fail();
} catch (e) {
e.should.be.instanceOf(Violation);
e.show().assert.should.equal('NullOrDate');
}
});

it('should throw an error if value does not pass strict validation', () => {
try {
new Assert().NullOrDate({ format: 'YYYY-MM-DD' }).validate('2000.12.30');

should.fail();
} catch (e) {
e.should.be.instanceOf(Violation);
e.show().assert.should.equal('NullOrDate');
}
});

it('should expose `assert` equal to `NullOrDate`', () => {
try {
new Assert().NullOrDate().validate({});
Expand All @@ -64,7 +86,19 @@ describe('NullOrDateAssert', () => {
new Assert().NullOrDate().validate(new Date());
});

it('should accept a correctly formatted date', () => {
new Assert().NullOrDate({ format: 'YYYY' }).validate('2000');
});

it('should accept a string', () => {
new Assert().NullOrDate().validate('2014-10-16');
});

it('should accept an ISO-8601 string date', () => {
new Assert().NullOrDate().validate('2016-04-23T00:51:18.570Z');
});

it('should accept a numeric timestamp', () => {
new Assert().NullOrDate().validate(Date.now());
});
});