diff --git a/documentation/assertions/moment/to-be-after.md b/documentation/assertions/moment/to-be-after.md index 45e539f..1d12130 100644 --- a/documentation/assertions/moment/to-be-after.md +++ b/documentation/assertions/moment/to-be-after.md @@ -13,6 +13,6 @@ expect(moment('2015-02-03'), 'to be after', moment('2015-04-03')); ``` ```output -expected moment(2015-02-03T00:00:00.000+01:00) -to be after moment(2015-04-03T00:00:00.000+02:00) +expected moment('2015-02-03T00:00:00.000+01:00') +to be after moment('2015-04-03T00:00:00.000+02:00') ``` diff --git a/documentation/assertions/moment/to-be-before.md b/documentation/assertions/moment/to-be-before.md index d35325a..3b17c91 100644 --- a/documentation/assertions/moment/to-be-before.md +++ b/documentation/assertions/moment/to-be-before.md @@ -13,6 +13,6 @@ expect(moment('2015-04-03'), 'to be before', moment('2015-02-03')); ``` ```output -expected moment(2015-04-03T00:00:00.000+02:00) -to be before moment(2015-02-03T00:00:00.000+01:00) +expected moment('2015-04-03T00:00:00.000+02:00') +to be before moment('2015-02-03T00:00:00.000+01:00') ``` diff --git a/documentation/assertions/moment/to-be-between.md b/documentation/assertions/moment/to-be-between.md index 7e292f8..82a74b6 100644 --- a/documentation/assertions/moment/to-be-between.md +++ b/documentation/assertions/moment/to-be-between.md @@ -17,6 +17,6 @@ expect(moment('2015-01-01'), 'to be between', moment('2015-02-01'), moment('2015 ``` ```output -expected moment(2015-01-01T00:00:00.000+01:00) -to be between moment(2015-02-01T00:00:00.000+01:00) and moment(2015-03-01T00:00:00.000+01:00) +expected moment('2015-01-01T00:00:00.000+01:00') +to be between moment('2015-02-01T00:00:00.000+01:00') and moment('2015-03-01T00:00:00.000+01:00') ``` diff --git a/documentation/assertions/moment/to-be-same-or-after.md b/documentation/assertions/moment/to-be-same-or-after.md index f2a9942..fe74f3f 100644 --- a/documentation/assertions/moment/to-be-same-or-after.md +++ b/documentation/assertions/moment/to-be-same-or-after.md @@ -13,6 +13,6 @@ expect(moment('2015-02-03'), 'to be same or after', moment('2015-04-03')); ``` ```output -expected moment(2015-02-03T00:00:00.000+01:00) -to be same or after moment(2015-04-03T00:00:00.000+02:00) +expected moment('2015-02-03T00:00:00.000+01:00') +to be same or after moment('2015-04-03T00:00:00.000+02:00') ``` diff --git a/documentation/assertions/moment/to-be-same-or-before.md b/documentation/assertions/moment/to-be-same-or-before.md index 9e9a7fd..5fdc51f 100644 --- a/documentation/assertions/moment/to-be-same-or-before.md +++ b/documentation/assertions/moment/to-be-same-or-before.md @@ -13,6 +13,6 @@ expect(moment('2015-04-01'), 'to be same or before', moment('2015-01-01')); ``` ```output -expected moment(2015-04-01T00:00:00.000+02:00) -to be same or before moment(2015-01-01T00:00:00.000+01:00) +expected moment('2015-04-01T00:00:00.000+02:00') +to be same or before moment('2015-01-01T00:00:00.000+01:00') ``` diff --git a/documentation/assertions/moment/to-be-the-end-of.md b/documentation/assertions/moment/to-be-the-end-of.md index f435da3..fec16dd 100644 --- a/documentation/assertions/moment/to-be-the-end-of.md +++ b/documentation/assertions/moment/to-be-the-end-of.md @@ -13,5 +13,11 @@ expect(moment('2015-01-01 00:00:00'), 'to be the end of day'); ``` ```output -expected moment(2015-01-01T00:00:00.000+01:00) to be the end of day +expected moment('2015-01-01T00:00:00.000+01:00') to be the end of day + +moment( + '2015-01-01T00:00:00.000+01:00' // should be '2015-01-01T23:59:59.999+01:00' + // -2015-01-01T00:00:00.000+01:00 + // +2015-01-01T23:59:59.999+01:00 +) ``` diff --git a/documentation/assertions/moment/to-be-the-start-of.md b/documentation/assertions/moment/to-be-the-start-of.md index c5d2f6b..2763b4f 100644 --- a/documentation/assertions/moment/to-be-the-start-of.md +++ b/documentation/assertions/moment/to-be-the-start-of.md @@ -13,5 +13,11 @@ expect(moment('2015-01-01 01'), 'to be the start of year'); ``` ```output -expected moment(2015-01-01T01:00:00.000+01:00) to be the start of year +expected moment('2015-01-01T01:00:00.000+01:00') to be the start of year + +moment( + '2015-01-01T01:00:00.000+01:00' // should be '2015-01-01T00:00:00.000+01:00' + // -2015-01-01T01:00:00.000+01:00 + // +2015-01-01T00:00:00.000+01:00 +) ``` diff --git a/documentation/assertions/moment/to-equal.md b/documentation/assertions/moment/to-equal.md index 95a5604..b79fb69 100644 --- a/documentation/assertions/moment/to-equal.md +++ b/documentation/assertions/moment/to-equal.md @@ -27,9 +27,12 @@ expect(moment('2015-11-01'), 'to equal', moment('2015-11-02'), 'in days'); ``` ```output -expected moment(2015-11-01T00:00:00.000+01:00) -to equal moment(2015-11-02T00:00:00.000+01:00) in days +expected moment('2015-11-01T00:00:00.000+01:00') +to equal moment('2015-11-02T00:00:00.000+01:00') in days --2015-11-01T00:00:00.000+01:00 -+2015-11-02T00:00:00.000+01:00 +moment( + '2015-11-01T00:00:00.000+01:00' // should be '2015-11-02T00:00:00.000+01:00' + // -2015-11-01T00:00:00.000+01:00 + // +2015-11-02T00:00:00.000+01:00 +) ``` diff --git a/documentation/assertions/moment/to-satisfy.md b/documentation/assertions/moment/to-satisfy.md index b385026..4389bf5 100644 --- a/documentation/assertions/moment/to-satisfy.md +++ b/documentation/assertions/moment/to-satisfy.md @@ -18,6 +18,14 @@ expect(moment('2015-11-01'), 'to satisfy', { year: 2015, month: 11, day: 1 }); ``` ```output -expected moment(2015-11-01T00:00:00.000+01:00) +expected moment('2015-11-01T00:00:00.000+01:00') to satisfy { year: 2015, month: 11, day: 1 } + +moment( + { + years: 2015, + months: 10, // should equal 11 + date: 1 + } +) ``` diff --git a/documentation/assertions/moment/when-formatted-with.md b/documentation/assertions/moment/when-formatted-with.md index 21fd8ff..384c5ed 100644 --- a/documentation/assertions/moment/when-formatted-with.md +++ b/documentation/assertions/moment/when-formatted-with.md @@ -11,7 +11,7 @@ expect(moment('2015-11-02'), 'when formatted with', 'YYYYMMDD', 'to be', '2015') ``` ```output -expected moment(2015-11-02T00:00:00.000+01:00) +expected moment('2015-11-02T00:00:00.000+01:00') when formatted with 'YYYYMMDD' to be '2015' -20151102 diff --git a/documentation/assertions/moment/when-formatted.md b/documentation/assertions/moment/when-formatted.md new file mode 100644 index 0000000..e0c5834 --- /dev/null +++ b/documentation/assertions/moment/when-formatted.md @@ -0,0 +1,18 @@ +Format a moment instance using [the default ISO8601 format](http://momentjs.com/docs/#/displaying/format/), then delegate the formatted value to another assertion. + +```js +expect(moment('2015-11-02'), 'when formatted to be', '2015-11-02T00:00:00+01:00'); +``` + +When the assertion fails you'll get this output: + +```js +expect(moment('2015-11-02'), 'when formatted to be', '2015'); +``` + +```output +expected moment('2015-11-02T00:00:00.000+01:00') when formatted to be '2015' + +-2015-11-02T00:00:00+01:00 ++2015 +``` diff --git a/documentation/index.md b/documentation/index.md index d94e462..5374327 100644 --- a/documentation/index.md +++ b/documentation/index.md @@ -21,11 +21,14 @@ expect(date, 'to equal', moment('2015-11-03')); ``` ```output -expected moment(2015-11-06T00:00:00.000+01:00) -to equal moment(2015-11-03T00:00:00.000+01:00) - --2015-11-06T00:00:00.000+01:00 -+2015-11-03T00:00:00.000+01:00 +expected moment('2015-11-06T00:00:00.000+01:00') +to equal moment('2015-11-03T00:00:00.000+01:00') + +moment( + '2015-11-06T00:00:00.000+01:00' // should be '2015-11-03T00:00:00.000+01:00' + // -2015-11-06T00:00:00.000+01:00 + // +2015-11-03T00:00:00.000+01:00 +) ``` [![NPM version](https://badge.fury.io/js/unexpected-moment.svg)](http://badge.fury.io/js/unexpected-moment) diff --git a/lib/unexpected-moment.js b/lib/unexpected-moment.js index c8c4835..4e1a314 100644 --- a/lib/unexpected-moment.js +++ b/lib/unexpected-moment.js @@ -9,104 +9,331 @@ root.moment.unexpectedMoment = factory(root.moment); } }(this, function (moment) { - var outputFormat = 'YYYY-MM-DDTHH:mm:ss.SSSZ'; - return { name: 'unexpected-moment', installInto: function (expect) { + var outputFormat = 'YYYY-MM-DDTHH:mm:ss.SSSZ'; + + function normalizeObject(object) { + return Object.keys(object).reduce(function (normalizedObject, unit) { + var normalizedUnit = moment.normalizeUnits(unit); + if (normalizedUnit === 'day') { + normalizedUnit = 'date'; // Urgh + } + if (normalizedUnit !== 'date') { + normalizedUnit += 's'; // Urgh + } + normalizedObject[normalizedUnit] = object[unit]; + return normalizedObject; + }, {}); + } + + function formatDiff(actual, expected, output, diff, inspect, equal) { + var actualIsUtc = actual.isUtc(); + var functionName = actualIsUtc ? 'moment.utc' : 'moment'; + var expectedIsMoment = expected instanceof moment; + var expectedIsDate = expected instanceof Date; + var expectedIsArray = Array.isArray(expected); + var typeOfExpected = typeof expected; + var expectedIsObject = typeOfExpected === 'object' && + !(expectedIsArray || expectedIsMoment || expectedIsDate); + var expectedIsString = typeOfExpected === 'string'; + var expectedIsNumber = typeOfExpected === 'number'; + + var momentShouldBe; + var functionNameShouldBe; + if (expectedIsMoment) { + if (actualIsUtc) { + if (!expected.isUtc()) { + functionNameShouldBe = 'moment'; + } + } else { + if (expected.isUtc()) { + functionNameShouldBe = 'moment.utc'; + } + } + if (functionNameShouldBe) { + momentShouldBe = 'should be '; + } + } else { + if (actualIsUtc) { + momentShouldBe = 'should be in local time'; + } + } + + output.jsFunctionName(functionName).text('('); + if (momentShouldBe) { + output.sp().annotationBlock(function () { + this.error(momentShouldBe); + if (functionNameShouldBe) { + this.jsFunctionName(functionNameShouldBe).text('('); + } + }); + } + + var actualForDiff; + var expectedForDiff; + var formattedDiff; + if (expectedIsMoment) { + actualForDiff = actual.format(outputFormat); + expectedForDiff = expected.format(outputFormat); + } + if (expectedIsDate) { + actualForDiff = actual.toDate().toString(); + expectedForDiff = expected.toString(); + } + if (expectedIsArray) { + actualForDiff = actual.toArray().slice(0, expected.length); + expectedForDiff = expected; + } + if (expectedIsObject) { + expectedForDiff = normalizeObject(expected); + actualForDiff = actual.toObject(); + Object.keys(actualForDiff).forEach(function (key) { + if (!expectedForDiff.hasOwnProperty(key)) { + delete actualForDiff[key]; + } + }); + } + if (expectedIsString) { + var expectedFormat = moment(expected)._f; + actualForDiff = actual.format(expectedFormat || outputFormat); + expectedForDiff = expected; + } + if (expectedIsNumber) { + actualForDiff = actual.valueOf(); + expectedForDiff = expected; + formattedDiff = diff(String(actualForDiff), String(expected)); + } + + output.nl().indentLines().i(); + if (expectedIsDate) { + output.jsKeyword('new').sp().text('Date(').nl().i().i(); + } + + var isEqual; + if (!(expectedIsMoment || expectedIsDate)) { + if (equal(actualForDiff, expectedForDiff)) { + isEqual = true; + output.block(inspect(actualForDiff)); + } + } + if (!formattedDiff) { + formattedDiff = diff(actualForDiff, expectedForDiff); + } + if (expectedIsArray || expectedIsObject) { + if (!isEqual && formattedDiff) { + output.block(formattedDiff); + } + } else { + if (!isEqual) { + output.append(inspect(actualForDiff)).sp() + .annotationBlock(function () { + this.error('should be ') + .append(inspect(expectedForDiff)); + if (formattedDiff) { + this.nl().append(formattedDiff); + } + }); + } + } + if (expectedIsDate) { + output.nl().i().text(')'); + } + + return output.nl().text(')'); + } + expect.addType({ name: 'moment', base: 'object', identify: function (value) { - return value && moment.isMoment(value); + return value && value instanceof moment; }, equal: function (a, b) { return a.isSame(b); }, - inspect: function (value, depth, output) { - var name = value.isUtc() ? 'moment.utc' : 'moment'; - output.jsFunctionName(name) + inspect: function (value, depth, output, inspect) { + var functionName = value.isUtc() ? 'moment.utc' : 'moment'; + output.jsFunctionName(functionName) .text('(') - .jsPrimitive(value.format(outputFormat)) + .append(inspect(value.format(outputFormat))) .text(')'); }, - diff: function (actual, expected, output, diff) { - return diff(actual.format(outputFormat), expected.format(outputFormat)); - } + diff: formatDiff }); expect.addAssertion(' [not] to be a moment', function (expect, subject) { return expect(moment.isMoment(subject), '[not] to be true'); }); - expect.addAssertion(' [not] to be before ', function (expect, subject, value) { - return expect(subject.isBefore(value), '[not] to be true'); - }); + expect.addAssertion(' [not] to equal ', function (expect, subject, value, label) { + // TODO: validate granularity? + var granularity = (label || '').replace(/^in /, '').replace(/s$/, ''); - expect.addAssertion(' [not] to be after ', function (expect, subject, value) { - return expect(subject.isAfter(value), '[not] to be true'); + if (subject.isSame(value, granularity) === expect.flags.not) { + expect.argsOutput = function (output) { + output.appendInspected(value); + if (granularity) { + output.sp().text(label); + } + }; + return expect.fail({ + diff: function (output, diff, inspect, equal) { + if (!expect.flags.not) { + return diff(subject, value); + } + } + }); + } }); - expect.addAssertion(' [not] to be same or before ', function (expect, subject, value) { - return expect(subject.isSameOrBefore(value), '[not] to be true'); - }); + function ensureValid(value, expect) { + if (value instanceof moment || value instanceof Date) { + return; + } - expect.addAssertion(' [not] to be same or after ', function (expect, subject, value) { - return expect(subject.isSameOrAfter(value), '[not] to be true'); - }); + var originalSetting = moment.suppressDeprecationWarnings; + moment.suppressDeprecationWarnings = true; + var valueAsMoment = moment(value); + moment.suppressDeprecationWarnings = originalSetting; - expect.addAssertion(' [not] to be [inclusively] between ', function (expect, subject, from, to) { - expect.argsOutput = function (output) { - output.appendInspected(from).text(' and ').appendInspected(to); - }; + if (!valueAsMoment.isValid()) { + return expect.fail(); + } - var inclusivity; - if (expect.flags.inclusively) { - inclusivity = '[]'; + if (Array.isArray(value)) { + if (!value.length) { + return expect.fail(); + } + return; + } + + if (typeof value === 'object') { + var keys = Object.keys(value); + if (!keys.length) { + return expect.fail(); + } + for (var i = 0; i < keys.length; i++) { + var unit = keys[i]; + if (!moment.normalizeUnits(unit)) { + expect.errorMode = 'nested'; + return expect.fail({ + message: function (output) { + output.nl() + .text('Unit \'') + .jsString(unit) + .text('\'') + .sp() + .text('is not a valid unit'); + } + }); + } + } } + } + + function inspectDate(date, output) { + output.jsKeyword('new') + .sp() + .text('Date(') + .appendInspected(date.toString()) + .text(')'); + } - return expect(subject.isBetween(from, to, null, inclusivity), '[not] to be true'); + expect.addAssertion(' to satisfy ', function (expect, subject, value) { + ensureValid(value, expect); + if (value instanceof moment) { + return expect(subject, 'to equal', value); + } + if (!subject.isSame(value)) { + return expect.fail({ + diff: function (output, diff, inspect, equal) { + if (value instanceof Date) { + expect.argsOutput = function (output) { + inspectDate(value, output); + }; + } + return formatDiff(subject, value, output, diff, inspect, equal); + } + }); + } }); - expect.addAssertion(' when formatted with ', function (expect, subject, format) { - return expect.shift(subject.format(format)); + function assert(expect, subject, value, method) { + ensureValid(value, expect); + if (subject[method](value) === expect.flags.not) { + if (value instanceof Date) { + expect.argsOutput = function (output) { + inspectDate(value, output); + }; + } + return expect.fail(); + } + } + + expect.addAssertion(' [not] to be before ', function (expect, subject, value) { + return assert(expect, subject, value, 'isBefore'); }); - expect.addAssertion(' [not] to equal ', function (expect, subject, value, label) { - // TODO: validate granularity? - var granularity = (label || '').replace(/^in /, '').replace(/s$/, ''); + expect.addAssertion(' [not] to be after ', function (expect, subject, value) { + return assert(expect, subject, value, 'isAfter'); + }); - if (subject.isSame(value, granularity) === expect.flags.not) { + expect.addAssertion(' [not] to be same or before ', function (expect, subject, value) { + return assert(expect, subject, value, 'isSameOrBefore'); + }); + + expect.addAssertion(' [not] to be same or after ', function (expect, subject, value) { + return assert(expect, subject, value, 'isSameOrAfter'); + }); + + expect.addAssertion(' [not] to be [inclusively] between ', function (expect, subject, from, to) { + var inclusivity; + if (expect.flags.inclusively) { + inclusivity = '[]'; + } + if (subject.isBetween(from, to, null, inclusivity) === expect.flags.not) { expect.argsOutput = function (output) { - output.appendInspected(value); - if (granularity) { - output.sp().text(label); + if (from instanceof Date) { + output.append(function (output) { + inspectDate(from, output); + }); + } else { + output.appendInspected(from); } - }; - expect.fail({ - diff: function (output, diff, inspect, equal) { - return diff(subject, value); + output.text(' and '); + if (to instanceof Date) { + output.append(function (output) { + inspectDate(to, output); + }); + } else { + output.appendInspected(to); } - }); + }; + return expect.fail(); } }); - // TODO: error diff for this + expect.addAssertion([ + ' [when] formatted ', + ' [when] formatted with ' + ], function (expect, subject, format) { + if (expect.testDescription.indexOf('with') < 0) { + format = undefined; + } + return expect.shift(subject.format(format)); + }); + expect.addAssertion(' [not] to be the start of (second|minute|hour|day|week|isoWeek|month|quarter|year)', function (expect, subject) { var unitOfTime = expect.alternations[0]; - return expect(subject.isSame(subject.clone().startOf(unitOfTime)), '[not] to be true'); + return expect(subject, '[not] to equal', subject.clone().startOf(unitOfTime)); }); - // TODO: error diff for this expect.addAssertion(' [not] to be the end of (second|minute|hour|day|week|isoWeek|month|quarter|year)', function (expect, subject) { var unitOfTime = expect.alternations[0]; - return expect(subject.isSame(subject.clone().endOf(unitOfTime)), '[not] to be true'); - }); - - // TODO: error diff for this - expect.addAssertion(' to satisfy ', function (expect, subject, value) { - return expect(subject.isSame(value), 'to be true'); + return expect(subject, '[not] to equal', subject.clone().endOf(unitOfTime)); }); } }; diff --git a/package.json b/package.json index faa4f1c..4b31fd8 100644 --- a/package.json +++ b/package.json @@ -8,11 +8,11 @@ }, "scripts": { "lint": "eslint .", - "test": "mocha test/**/*.js documentation/**/*.md && npm run lint", - "travis": "npm test && npm run coverage && ( new Date('2016-01-01 00:00:00') + }, + 'to error with', + 'expected moment(\'2016-01-01T00:00:00.000+01:00\') ' + + 'to be same or before 1451602800' + ); + }); }); - it('allows formatting moments asserting against expected string outputs', function () { - expect(moment(1), 'when formatted with', 'YYYY', 'to be', '1970'); - expect(moment(1), 'when formatted with', 'YYYY', 'to equal', '1970'); - expect(moment(1), 'when formatted with', 'YYYYMM', 'not to be', '1970'); - expect(moment(1), 'when formatted with', 'YYYYMM', 'not to equal', '1970'); + describe('not to be same or before', function () { + it('passes if the value does not occur before the subject', function () { + expect(moment(1), 'not to be same or before', moment(0)); + }); - expect(moment.utc(), 'when formatted with', '', 'to be', '1970-01-01T00:00:00Z'); - expect(moment.utc(), 'when formatted with', '', 'to equal', '1970-01-01T00:00:00Z'); - expect(moment.utc(1000), 'when formatted with', '', 'not to be', '1970-01-01T00:00:00Z'); - expect(moment.utc(1000), 'when formatted with', '', 'not to equal', '1970-01-01T00:00:00Z'); + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-01'), 'not to be same or before', 1451689200000); // 1451689200000 -> new Date('2016-01-02 00:00:00') + }, + 'to error with', + 'expected moment(\'2016-01-01T00:00:00.000+01:00\')\n' + + 'not to be same or before 1451689200000' + ); + }); }); - it('identifies (un)equality in various granularity levels', function () { - expect(moment(1), 'to equal', moment(1), 'in milliseconds'); - expect(moment(1), 'to equal', moment(1), 'in seconds'); - expect(moment(1), 'to equal', moment(1), 'in minutes'); - expect(moment(1), 'to equal', moment(1), 'in hours'); - expect(moment(1), 'to equal', moment(1), 'in days'); - expect(moment(1), 'to equal', moment(1), 'in weeks'); - expect(moment(1), 'to equal', moment(1), 'in months'); - expect(moment(1), 'to equal', moment(1), 'in years'); - - expect(moment(1), 'not to equal', moment(2), 'in milliseconds'); - expect(moment(1), 'to equal', moment(2), 'in seconds'); - expect(moment(1), 'to equal', moment(2), 'in minutes'); - expect(moment(1), 'to equal', moment(2), 'in hours'); - expect(moment(1), 'to equal', moment(2), 'in days'); - expect(moment(1), 'to equal', moment(2), 'in weeks'); - expect(moment(1), 'to equal', moment(2), 'in months'); - expect(moment(1), 'to equal', moment(2), 'in years'); - - expect(moment(oneSecond), 'not to equal', moment(oneSecond + oneSecond), 'in milliseconds'); - expect(moment(oneSecond), 'not to equal', moment(oneSecond + oneSecond), 'in seconds'); - expect(moment(oneSecond), 'to equal', moment(oneSecond + oneSecond), 'in minutes'); - expect(moment(oneSecond), 'to equal', moment(oneSecond + oneSecond), 'in hours'); - expect(moment(oneSecond), 'to equal', moment(oneSecond + oneSecond), 'in days'); - expect(moment(oneSecond), 'to equal', moment(oneSecond + oneSecond), 'in weeks'); - expect(moment(oneSecond), 'to equal', moment(oneSecond + oneSecond), 'in months'); - expect(moment(oneSecond), 'to equal', moment(oneSecond + oneSecond), 'in years'); - - expect(moment(oneMinute), 'not to equal', moment(oneMinute + oneMinute), 'in milliseconds'); - expect(moment(oneMinute), 'not to equal', moment(oneMinute + oneMinute), 'in seconds'); - expect(moment(oneMinute), 'not to equal', moment(oneMinute + oneMinute), 'in minutes'); - expect(moment(oneMinute), 'to equal', moment(oneMinute + oneMinute), 'in hours'); - expect(moment(oneMinute), 'to equal', moment(oneMinute + oneMinute), 'in days'); - expect(moment(oneMinute), 'to equal', moment(oneMinute + oneMinute), 'in weeks'); - expect(moment(oneMinute), 'to equal', moment(oneMinute + oneMinute), 'in months'); - expect(moment(oneMinute), 'to equal', moment(oneMinute + oneMinute), 'in years'); - - expect(moment(oneHour), 'not to equal', moment(oneHour + oneHour), 'in milliseconds'); - expect(moment(oneHour), 'not to equal', moment(oneHour + oneHour), 'in seconds'); - expect(moment(oneHour), 'not to equal', moment(oneHour + oneHour), 'in minutes'); - expect(moment(oneHour), 'not to equal', moment(oneHour + oneHour), 'in hours'); - expect(moment(oneHour), 'to equal', moment(oneHour + oneHour), 'in days'); - expect(moment(oneHour), 'to equal', moment(oneHour + oneHour), 'in weeks'); - expect(moment(oneHour), 'to equal', moment(oneHour + oneHour), 'in months'); - expect(moment(oneHour), 'to equal', moment(oneHour + oneHour), 'in years'); - - expect(moment(oneDay), 'not to equal', moment(oneDay + oneDay), 'in milliseconds'); - expect(moment(oneDay), 'not to equal', moment(oneDay + oneDay), 'in seconds'); - expect(moment(oneDay), 'not to equal', moment(oneDay + oneDay), 'in minutes'); - expect(moment(oneDay), 'not to equal', moment(oneDay + oneDay), 'in hours'); - expect(moment(oneDay), 'not to equal', moment(oneDay + oneDay), 'in days'); - expect(moment(oneDay), 'to equal', moment(oneDay + oneDay), 'in weeks'); - expect(moment(oneDay), 'to equal', moment(oneDay + oneDay), 'in months'); - expect(moment(oneDay), 'to equal', moment(oneDay + oneDay), 'in years'); - - expect(moment(oneWeek), 'not to equal', moment(oneWeek + oneWeek), 'in milliseconds'); - expect(moment(oneWeek), 'not to equal', moment(oneWeek + oneWeek), 'in seconds'); - expect(moment(oneWeek), 'not to equal', moment(oneWeek + oneWeek), 'in minutes'); - expect(moment(oneWeek), 'not to equal', moment(oneWeek + oneWeek), 'in hours'); - expect(moment(oneWeek), 'not to equal', moment(oneWeek + oneWeek), 'in days'); - expect(moment(oneWeek), 'not to equal', moment(oneWeek + oneWeek), 'in weeks'); - expect(moment(oneWeek), 'to equal', moment(oneWeek + oneWeek), 'in months'); - expect(moment(oneWeek), 'to equal', moment(oneWeek + oneWeek), 'in years'); - - expect(moment(oneMonth), 'not to equal', moment(oneMonth + oneMonth), 'in milliseconds'); - expect(moment(oneMonth), 'not to equal', moment(oneMonth + oneMonth), 'in seconds'); - expect(moment(oneMonth), 'not to equal', moment(oneMonth + oneMonth), 'in minutes'); - expect(moment(oneMonth), 'not to equal', moment(oneMonth + oneMonth), 'in hours'); - expect(moment(oneMonth), 'not to equal', moment(oneMonth + oneMonth), 'in days'); - expect(moment(oneMonth), 'not to equal', moment(oneMonth + oneMonth), 'in weeks'); - expect(moment(oneMonth), 'not to equal', moment(oneMonth + oneMonth), 'in months'); - expect(moment(oneMonth), 'to equal', moment(oneMonth + oneMonth), 'in years'); - - expect(moment(oneYear), 'not to equal', moment(oneYear + oneYear), 'in milliseconds'); - expect(moment(oneYear), 'not to equal', moment(oneYear + oneYear), 'in seconds'); - expect(moment(oneYear), 'not to equal', moment(oneYear + oneYear), 'in minutes'); - expect(moment(oneYear), 'not to equal', moment(oneYear + oneYear), 'in hours'); - expect(moment(oneYear), 'not to equal', moment(oneYear + oneYear), 'in days'); - expect(moment(oneYear), 'not to equal', moment(oneYear + oneYear), 'in weeks'); - expect(moment(oneYear), 'not to equal', moment(oneYear + oneYear), 'in months'); - expect(moment(oneYear), 'not to equal', moment(oneYear + oneYear), 'in years'); + describe('to be same or after', function () { + it('passes if the value occurs after the subject', function () { + expect(moment(1), 'to be same or after', moment(0)); + }); + + it('passes if the value is the same as the subject', function () { + expect(moment(0), 'to be same or after', moment(0)); + }); + + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-01'), 'to be same or after', new Date('2016-01-02 00:00:00')); + }, + 'to error with', + 'expected moment(\'2016-01-01T00:00:00.000+01:00\')\n' + + 'to be same or after new Date(\'Sat Jan 02 2016 00:00:00 GMT+0100 (CET)\')' + ); + }); }); - it('identifies if a moment is the start of a unit of time', function () { - expect(moment(123456).startOf('second'), 'to be the start of second'); - expect(moment(123456).startOf('minute'), 'to be the start of minute'); - expect(moment(123456).startOf('hour'), 'to be the start of hour'); - expect(moment(123456).startOf('day'), 'to be the start of day'); - expect(moment(123456).startOf('week'), 'to be the start of week'); - expect(moment(123456).startOf('isoWeek'), 'to be the start of isoWeek'); - expect(moment(123456).startOf('month'), 'to be the start of month'); - expect(moment(123456).startOf('quarter'), 'to be the start of quarter'); - expect(moment(123456).startOf('year'), 'to be the start of year'); - - expect(moment(123456).startOf('second').add(1), 'not to be the start of second'); - expect(moment(123456).startOf('minute').add(1, 'second'), 'not to be the start of minute'); - expect(moment(123456).startOf('hour').add(1, 'second'), 'not to be the start of hour'); - expect(moment(123456).startOf('day').add(1, 'second'), 'not to be the start of day'); - expect(moment(123456).startOf('week').add(1, 'second'), 'not to be the start of week'); - expect(moment(123456).startOf('isoWeek').add(1, 'second'), 'not to be the start of isoWeek'); - expect(moment(123456).startOf('month').add(1, 'second'), 'not to be the start of month'); - expect(moment(123456).startOf('quarter').add(1, 'second'), 'not to be the start of quarter'); - expect(moment(123456).startOf('year').add(1, 'second'), 'not to be the start of year'); + describe('not to be same or after', function () { + it('passes if the value does not occur after the subject', function () { + expect(moment(0), 'not to be same or after', moment(1)); + }); + + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-02'), 'not to be same or after', moment('2016-01-01 00:00:00')); + }, + 'to error with', + 'expected moment(\'2016-01-02T00:00:00.000+01:00\')\n' + + 'not to be same or after moment(\'2016-01-01T00:00:00.000+01:00\')' + ); + }); }); - it('identifies if a moment is the end of a unit of time', function () { - expect(moment(123456).endOf('second'), 'to be the end of second'); - expect(moment(123456).endOf('minute'), 'to be the end of minute'); - expect(moment(123456).endOf('hour'), 'to be the end of hour'); - expect(moment(123456).endOf('day'), 'to be the end of day'); - expect(moment(123456).endOf('week'), 'to be the end of week'); - expect(moment(123456).endOf('isoWeek'), 'to be the end of isoWeek'); - expect(moment(123456).endOf('month'), 'to be the end of month'); - expect(moment(123456).endOf('quarter'), 'to be the end of quarter'); - expect(moment(123456).endOf('year'), 'to be the end of year'); - - expect(moment(123456).endOf('second').subtract(1), 'not to be the end of second'); - expect(moment(123456).endOf('minute').subtract(1, 'second'), 'not to be the end of minute'); - expect(moment(123456).endOf('hour').subtract(1, 'second'), 'not to be the end of hour'); - expect(moment(123456).endOf('day').subtract(1, 'second'), 'not to be the end of day'); - expect(moment(123456).endOf('week').subtract(1, 'second'), 'not to be the end of week'); - expect(moment(123456).endOf('isoWeek').subtract(1, 'second'), 'not to be the end of isoWeek'); - expect(moment(123456).endOf('month').subtract(1, 'second'), 'not to be the end of month'); - expect(moment(123456).endOf('quarter').subtract(1, 'second'), 'not to be the end of quarter'); - expect(moment(123456).endOf('year').subtract(1, 'second'), 'not to be the end of year'); + describe('to be between', function () { + it('passes if the subject occurs between the two values', function () { + expect(moment(1), 'to be between', moment(0), moment(2)); + }); + + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-01'), 'to be between', moment('2016-01-02'), moment('2016-01-03')); + }, + 'to error with', + 'expected moment(\'2016-01-01T00:00:00.000+01:00\')\n' + + 'to be between moment(\'2016-01-02T00:00:00.000+01:00\') and moment(\'2016-01-03T00:00:00.000+01:00\')' + ); + }); }); - it('identifies satisfaction and dissatisfaction in moments', function () { - // it('identifies satisfying and disatisfying moments/dates', function () { - var aMoment = moment('2015-01-01T00:00:00+01:00'); - var aUtcMoment = moment.utc('2015-01-01T00:00:00+00:00'); + describe('not to be between', function () { + it('passes if the subject does not occur between the two values', function () { + expect(moment(0), 'not to be between', moment(1), new Date(2)); + }); - expect(aMoment, 'to satisfy', aMoment.clone()); - expect(aMoment, 'not to satisfy', aMoment.clone().add(1)); + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-02'), 'not to be between', moment('2016-01-01'), moment('2016-01-03')); + }, + 'to error with', + 'expected moment(\'2016-01-02T00:00:00.000+01:00\')\n' + + 'not to be between moment(\'2016-01-01T00:00:00.000+01:00\') and moment(\'2016-01-03T00:00:00.000+01:00\')' + ); + }); + }); - expect(moment(1000), 'to satisfy', moment(1000)); - expect(moment(1000), 'not to satisfy', moment(2000)); + describe('to be inclusively between', function () { + it('passes if the subject is the same as the first value', function () { + expect(moment(0), 'to be inclusively between', moment(0), moment(1)); + }); - expect(aMoment, 'to satisfy', aMoment.toDate()); - expect(aMoment, 'not to equal', aMoment.toDate()); + it('passes if the subject is the same as the second value', function () { + expect(moment(1), 'to be inclusively between', moment(0), moment(1)); + }); - expect(aUtcMoment, 'to satisfy', new Date('Thu Jan 01 2015 01:00:00 GMT+0100 (CET)')); - expect(aUtcMoment, 'not to equal', new Date('Thu Jan 01 2015 01:00:00 GMT+0100 (CET)')); + it('passes if the subject occurs betwen the two values', function () { + expect(moment(1), 'to be inclusively between', moment(0), moment(2)); + }); - expect(aMoment, 'to satisfy', aMoment.toArray()); - expect(aMoment, 'not to equal', aMoment.toArray()); - expect(aMoment, 'not to satisfy', [1, 2, 3, 4, 5, 6, 7, 8]); + it('passes if the two values are the same', function () { + expect(moment(0), 'to be inclusively between', moment(0), moment(0)); + }); - expect(aUtcMoment, 'not to satisfy', [2015, 0, 1, 0, 0, 0, 0]); // see: https://github.com/moment/moment/issues/2633 - expect(aUtcMoment, 'not to equal', [2015, 0, 1, 0, 0, 0, 0]); + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-02'), 'to be inclusively between', new Date('2016-01-01 00:00:00'), new Date('2016-01-01 12:00:00')); + }, + 'to error with', + 'expected moment(\'2016-01-02T00:00:00.000+01:00\')\n' + + 'to be inclusively between new Date(\'Fri Jan 01 2016 00:00:00 GMT+0100 (CET)\') ' + + 'and new Date(\'Fri Jan 01 2016 12:00:00 GMT+0100 (CET)\')' + ); + }); + }); + describe('not to be inclusively between', function () { + it('passes if the subject is neither the same as the first value or the second, nor does it occur between them', function () { + expect(moment(0), 'not to be inclusively between', moment(1), moment(1)); + }); - expect(aMoment, 'to satisfy', aMoment.toISOString()); - expect(aMoment, 'to satisfy', aMoment.format()); + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-02'), 'not to be inclusively between', moment('2016-01-02'), moment('2016-01-02')); + }, + 'to error with', + 'expected moment(\'2016-01-02T00:00:00.000+01:00\')\n' + + 'not to be inclusively between moment(\'2016-01-02T00:00:00.000+01:00\') ' + + 'and moment(\'2016-01-02T00:00:00.000+01:00\')' + ); + }); + }); - expect(aMoment, 'to satisfy', aMoment.toJSON()); - expect(aMoment, 'not to equal', aMoment.toJSON()); + describe('when formatted', function () { + it('formats a moment with the default format and delegates to the next assertion', function () { + expect(moment(1000), 'when formatted to equal', '1970-01-01T01:00:01+01:00'); + }); - expect(aUtcMoment, 'to satisfy', '2015-01-01T00:00:00.000Z'); - expect(aUtcMoment, 'to satisfy', '2015-01-01T00:00:00+00:00'); - expect(aUtcMoment, 'not to equal', '2015-01-01T00:00:00.000Z'); + it('returns the formatted moment as the fulfilment value if an assertion is not provided', function () { + expect(moment(0), 'when formatted') + .then(function (formatted) { + expect(formatted, 'to equal', '1970-01-01T00:00:00+01:00'); + }); + }); - expect(aMoment, 'to satisfy', aMoment.toObject()); - expect(aMoment, 'not to equal', aMoment.toObject()); + it('also works without the \'when\'', function () { + expect(moment(0), 'formatted', 'to equal', '1970-01-01T01:00:00+01:00'); + }); + }); - expect(aUtcMoment, 'not to satisfy', aUtcMoment.toObject()); // see: https://github.com/moment/moment/issues/2633 + describe('when formatted with', function () { + it('formats a moment with the provided format and delegates to the next assertion', function () { + expect(moment(1), 'when formatted with', 'YYYY', 'to be', '1970'); + }); - // partial object passes - expect(aMoment, 'to satisfy', { - years: 2015, - date: 1, - seconds: 0 + it('formats a moment with the default format if called with an empty string format', function () { + expect(moment.utc(0), 'when formatted with', '', 'to equal', '1970-01-01T00:00:00Z'); }); - // but not an empty one - expect(aMoment, 'not to satisfy', {}); + it('returns the formatted moment as the fulfilment value if an assertion is not provided', function () { + expect(moment(0), 'when formatted with', 'YYYYMMDD') + .then(function (formatted) { + expect(formatted, 'to equal', '19700101'); + }); + }); - // TODO: nor one with unkown keys - // expect(aUtcMoment, 'not to satisfy', { - // years: 2015, - // mints: 0 - // }); + it('also works without the \'when\'', function () { + expect(moment(0), 'formatted with', 'YYYYMMDD', 'to equal', '19700101'); + }); }); - it('does not mutate the moment objects when checking for equality', function () { - var moment1 = moment(1000); - var moment2 = moment(123456); - var moment1Formartted = moment1.format(); - var moment2Formartted = moment2.format(); - expect(moment1, 'not to equal', moment2); - expect(moment1Formartted, 'to equal', moment1.format()); - expect(moment2Formartted, 'to equal', moment2.format()); - }); + describe('to be the start of', function () { + it('start of second', function () { + expect(moment('2016-01-01 00:00:01+01:00'), 'to be the start of second'); + }); + + it('start of minute', function () { + expect(moment('2016-01-01 00:01:00+01:00'), 'to be the start of minute'); + }); + + it('start of hour', function () { + expect(moment('2016-01-01 01:00:00+01:00'), 'to be the start of hour'); + }); + + it('start of day', function () { + expect(moment('2016-01-02 00:00:00+01:00'), 'to be the start of day'); + }); + + it('start of week', function () { + expect(moment('2016-01-03 00:00:00+01:00'), 'to be the start of week'); + }); + + it('start of isoWeek', function () { + expect(moment('2016-01-04 00:00:00+01:00'), 'to be the start of isoWeek'); + }); + + it('start of month', function () { + expect(moment('2016-01-01 00:00:00+01:00'), 'to be the start of month'); + }); + + it('start of quarter', function () { + expect(moment('2016-01-01 00:00:00+01:00'), 'to be the start of quarter'); + }); + + it('start of year', function () { + expect(moment('2016-01-01 00:00:00+01:00'), 'to be the start of year'); + }); + + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-02'), 'to be the start of year'); + }, + 'to error with', + 'expected moment(\'2016-01-02T00:00:00.000+01:00\') ' + + 'to be the start of year\n' + + '\n' + + 'moment(\n' + + ' \'2016-01-02T00:00:00.000+01:00\' // should be \'2016-01-01T00:00:00.000+01:00\'\n' + + ' // -2016-01-02T00:00:00.000+01:00\n' + + ' // +2016-01-01T00:00:00.000+01:00\n' + + ')' + ); + }); - it('does not mutate the moment objects when checking for satisfaction', function () { - var moment1 = moment(1000); - var moment2 = moment(123456); - var moment1Formartted = moment1.format(); - var moment2Formartted = moment2.format(); - expect(moment1, 'not to satisfy', moment2); - expect(moment1Formartted, 'to equal', moment1.format()); - expect(moment2Formartted, 'to equal', moment2.format()); + it('does not mutate the moment objects', function () { + var startOfDay = moment('2016-01-02T00:00:00.000+01:00'); + expect(startOfDay, 'to be the start of day'); + expect(startOfDay.format(), 'to be', '2016-01-02T00:00:00+01:00'); + }); }); - it('does not mutate the moment objects when checking for equality at various granularity levels', function () { - var moment1 = moment(1000); - var moment2 = moment(1500); - var moment1Formartted = moment1.format(); - var moment2Formartted = moment2.format(); - expect(moment1, 'to equal', moment2, 'in seconds'); - expect(moment1Formartted, 'to equal', moment1.format()); - expect(moment2Formartted, 'to equal', moment2.format()); + describe('not to be the start of', function () { + it('passes if the passed moment is not start of the unit of time provided', function () { + expect(moment('2016-01-01 00:00:01.002+01:00'), 'not to be the start of second'); + }); + + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-02'), 'not to be the start of day'); + }, + 'to error with', + 'expected moment(\'2016-01-02T00:00:00.000+01:00\') ' + + 'not to be the start of day' + ); + }); }); - it('does not mutate the moment objects when checking for equality against a certain format', function () { - var moment1 = moment(1000); - var moment1Formartted = moment1.format(); - expect(moment1, 'when formatted with', 'YYYYMMDD', 'to equal', '19700101'); - expect(moment1Formartted, 'to equal', moment1.format()); + describe('to be the end of', function () { + it('end of second', function () { + expect(moment('2016-01-01 00:00:01.999+01:00'), 'to be the end of second'); + }); + + it('end of minute', function () { + expect(moment('2016-01-01 00:01:59.999+01:00'), 'to be the end of minute'); + }); + + it('end of hour', function () { + expect(moment('2016-01-01 01:59:59.999+01:00'), 'to be the end of hour'); + }); + + it('end of day', function () { + expect(moment('2016-01-02 23:59:59.999+01:00'), 'to be the end of day'); + }); + + it('end of week', function () { + expect(moment('2016-01-09 23:59:59.999+01:00'), 'to be the end of week'); + }); + + it('end of isoWeek', function () { + expect(moment('2016-01-10 23:59:59.999+01:00'), 'to be the end of isoWeek'); + }); + + it('end of month', function () { + expect(moment('2016-01-31 23:59:59.999+01:00'), 'to be the end of month'); + }); + + it('end of quarter', function () { + expect(moment('2016-03-31 23:59:59.999+02:00'), 'to be the end of quarter'); + }); + + it('end of year', function () { + expect(moment('2016-12-31 23:59:59.999+01:00'), 'to be the end of year'); + }); + + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-02'), 'to be the end of year'); + }, + 'to error with', + 'expected moment(\'2016-01-02T00:00:00.000+01:00\') ' + + 'to be the end of year\n' + + '\n' + + 'moment(\n' + + ' \'2016-01-02T00:00:00.000+01:00\' // should be \'2016-12-31T23:59:59.999+01:00\'\n' + + ' // -2016-01-02T00:00:00.000+01:00\n' + + ' // +2016-12-31T23:59:59.999+01:00\n' + + ')' + ); + }); + + it('does not mutate the moment objects', function () { + var endOfYear = moment('2016-12-31T23:59:59.999+01:00'); + expect(endOfYear, 'to be the end of year'); + expect(endOfYear.format(), 'to be', '2016-12-31T23:59:59+01:00'); + }); }); - it('does not mutate the moment objects when checking for equality against the start of a unit of time', function () { - var moment1 = moment(1000).startOf('isoWeek'); - var moment1Formartted = moment1.format(); - expect(moment1, 'to be the start of isoWeek'); - expect(moment1Formartted, 'to equal', moment1.format()); + describe('not to be the end of', function () { + it('passes if the passed moment is not end of the unit of time provided', function () { + expect(moment('2016-01-01 00:00:01.002+01:00'), 'not to be the end of second'); + }); + + it('throws the correct error if the assertion fails', function () { + expect( + function () { + expect(moment('2016-01-02T23:59:59.999+01:00'), 'not to be the end of day'); + }, + 'to error with', + 'expected moment(\'2016-01-02T23:59:59.999+01:00\') ' + + 'not to be the end of day' + ); + }); }); - it('does not mutate the moment objects when checking for equality against the end of a unit of time', function () { - var moment1 = moment(1000); - var moment1Formartted = moment1.format(); - expect(moment1, 'not to be the end of day'); - expect(moment1Formartted, 'to equal', moment1.format()); + it('does not interfere with unexpected\'s date type', function () { + expect( + function () { + expect(new Date('2016-01-01'), 'to equal', new Date('2016-01-02')); + }, + 'to error with', + 'expected new Date(\'Fri, 01 Jan 2016 00:00:00 GMT\')\n' + + 'to equal new Date(\'Sat, 02 Jan 2016 00:00:00 GMT\')' + ); }); });