diff --git a/README.md b/README.md index 1a87e31..67dc47f 100644 --- a/README.md +++ b/README.md @@ -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) @@ -152,8 +152,14 @@ 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 `null` or a valid date. + +#### Arguments +- `format` (optional) - the format in which the date must be in. + ### NullOrString -Tests if the value is a `null` or `string`, optionally within some boundaries. +Tests if the value is `null` or a string, optionally within some boundaries. #### Arguments - `boundaries` (optional) - `max` and/or `min` boundaries to test the string for. diff --git a/src/asserts/date-assert.js b/src/asserts/date-assert.js index 97743ee..4c65eaa 100644 --- a/src/asserts/date-assert.js +++ b/src/asserts/date-assert.js @@ -50,15 +50,15 @@ export default function dateAssert({ format } = {}) { throw new Violation(this, value, { value: 'must_be_a_date_or_a_string' }); } - if (isNaN(Date.parse(value)) === true) { - throw new Violation(this, value); - } + if (this.format) { + if (!moment(value, this.format, true).isValid()) { + throw new Violation(this, value); + } - if (!this.format) { return true; } - if (!moment(value, this.format, true).isValid()) { + if (isNaN(Date.parse(value)) === true) { throw new Violation(this, value); } diff --git a/src/asserts/date-diff-greater-than-assert.js b/src/asserts/date-diff-greater-than-assert.js index 2d3c0bd..9d515c0 100644 --- a/src/asserts/date-diff-greater-than-assert.js +++ b/src/asserts/date-diff-greater-than-assert.js @@ -57,7 +57,7 @@ export default function dateDiffGreaterThanAssert(threshold, options) { throw new Violation(this, value, { value: 'must_be_a_date_or_a_string' }); } - if (isNaN(Date.parse(value)) === true) { + if (!moment(value).isValid()) { throw new Violation(this, value, { absolute: this.absolute, asFloat: this.asFloat, fromDate: this.fromDate, threshold: this.threshold, unit: this.unit }); } diff --git a/src/asserts/date-diff-less-than-assert.js b/src/asserts/date-diff-less-than-assert.js index 533c002..2a42418 100644 --- a/src/asserts/date-diff-less-than-assert.js +++ b/src/asserts/date-diff-less-than-assert.js @@ -57,7 +57,7 @@ export default function dateDiffLessThanAssert(threshold, options) { throw new Violation(this, value, { value: 'must_be_a_date_or_a_string' }); } - if (isNaN(Date.parse(value)) === true) { + if (!moment(value).isValid()) { throw new Violation(this, value, { absolute: this.absolute, asFloat: this.asFloat, fromDate: this.fromDate, threshold: this.threshold, unit: this.unit }); } diff --git a/src/asserts/null-or-date-assert.js b/src/asserts/null-or-date-assert.js index 43db5ec..d91cc11 100644 --- a/src/asserts/null-or-date-assert.js +++ b/src/asserts/null-or-date-assert.js @@ -4,18 +4,43 @@ */ import { Violation } from 'validator.js'; +import { isString } from 'lodash'; /** * Export `NullOrDateAssert`. */ -export default function nullOrDateAssert() { +export default function nullOrDateAssert({ format } = {}) { /** * Class name. */ this.__class__ = 'NullOrDate'; + /** + * Optional peer dependency. + */ + + let moment; + + /** + * Validate format. + */ + + if (format) { + if (!isString(format)) { + throw new Error(`Unsupported format ${format} given`); + } + + moment = require('moment'); + } + + /** + * Format to match the input. + */ + + this.format = format; + /** * Validation algorithm. */ @@ -29,6 +54,14 @@ export default function nullOrDateAssert() { return true; } + if (this.format) { + if (!moment(value, this.format, true).isValid()) { + throw new Violation(this, value); + } + + return true; + } + if (isNaN(Date.parse(value)) === true) { throw new Violation(this, value); } diff --git a/test/asserts/date-assert_test.js b/test/asserts/date-assert_test.js index 0ee7086..00b96a7 100644 --- a/test/asserts/date-assert_test.js +++ b/test/asserts/date-assert_test.js @@ -82,15 +82,15 @@ describe('DateAssert', () => { } }); - it('should accept a `Date`', () => { + it('should accept a 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'); + new Assert().Date({ format: 'MM/YYYY' }).validate('12/2000'); }); - it('should accept a `string`', () => { + it('should accept a string', () => { new Assert().Date().validate('2014-10-16'); }); }); diff --git a/test/asserts/null-or-date-assert_test.js b/test/asserts/null-or-date-assert_test.js index ea2780b..e748a16 100644 --- a/test/asserts/null-or-date-assert_test.js +++ b/test/asserts/null-or-date-assert_test.js @@ -35,14 +35,40 @@ describe('NullOrDateAssert', () => { }); }); - it('should throw an error if the input value is not a valid date', () => { + it('should throw an error if an invalid format is given', () => { + const formats = [[], {}, 123]; + + formats.forEach(format => { + try { + new Assert().NullOrDate({ format }).validate(); + + should.fail(); + } catch (e) { + e.should.be.instanceOf(Error); + e.message.should.equal(`Unsupported format ${format} given`); + } + }); + }); + + it('should throw an error if value is not correctly formatted', () => { try { - new Assert().NullOrDate().validate('2015-99-01'); + new Assert().NullOrDate({ format: 'YYYY-MM-DD' }).validate('20003112'); should.fail(); } catch (e) { e.should.be.instanceOf(Violation); - e.show().value.should.equal('2015-99-01'); + 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'); } }); @@ -64,6 +90,10 @@ describe('NullOrDateAssert', () => { new Assert().NullOrDate().validate(new Date()); }); + it('should accept a correctly formatted date', () => { + new Assert().NullOrDate({ format: 'MM/YYYY' }).validate('12/2000'); + }); + it('should accept a string', () => { new Assert().NullOrDate().validate('2014-10-16'); });