UNPKG

@opstarts/chimp

Version:

Develop acceptance tests & end-to-end tests with realtime feedback.

179 lines (166 loc) 6.16 kB
'use strict'; var d = require('d') , pad = require('es5-ext/number/#/pad') , date = require('es5-ext/date/valid-date') , daysInMonth = require('es5-ext/date/#/days-in-month') , copy = require('es5-ext/date/#/copy') , dfloor = require('es5-ext/date/#/floor-day') , mfloor = require('es5-ext/date/#/floor-month') , yfloor = require('es5-ext/date/#/floor-year') , toInteger = require('es5-ext/number/to-integer') , toPosInt = require('es5-ext/number/to-pos-integer') , abs = Math.abs , format, valueOf, getYear, Duration, getCalcData; format = require('es5-ext/string/format-method')({ y: function () { return String(abs(this.year)); }, m: function () { return pad.call(abs(this.month), 2); }, d: function () { return pad.call(abs(this.day), 2); }, H: function () { return pad.call(abs(this.hour), 2); }, M: function () { return pad.call(abs(this.minute), 2); }, S: function () { return pad.call(abs(this.second), 2); }, L: function () { return pad.call(abs(this.millisecond), 3); }, ms: function () { return String(abs(this.months)); }, ds: function () { return String(abs(this.days)); }, Hs: function () { return String(abs(this.hours)); }, Ms: function () { return String(abs(this.minutes)); }, Ss: function () { return String(abs(this.seconds)); }, Ls: function () { return String(abs(this.milliseconds)); }, sign: function () { return (this.to < this.from) ? '-' : ''; } }); getCalcData = function (duration) { return (duration.to < duration.from) ? { to: duration.from, from: duration.to, sign: -1 } : { to: duration.to, from: duration.from, sign: 1 }; }; Duration = module.exports = function (from, to) { // Make it both constructor and factory if (!(this instanceof Duration)) return new Duration(from, to); this.from = date(from); this.to = (to == null) ? new Date() : date(to); }; Duration.prototype = Object.create(Object.prototype, { valueOf: d(valueOf = function () { return this.to - this.from; }), millisecond: d.gs(function () { return this.milliseconds % 1000; }), second: d.gs(function () { return this.seconds % 60; }), minute: d.gs(function () { return this.minutes % 60; }), hour: d.gs(function () { return this.hours % 24; }), day: d.gs(function () { var data = getCalcData(this) , x = copy.call(data.to); x.setMonth(x.getMonth() - 1); x = daysInMonth.call(x); return data.sign * ((x - data.from.getDate() + data.to.getDate()) % x - ((data.from - dfloor.call(copy.call(data.from))) > (data.to - dfloor.call(copy.call(data.to))))); }), month: d.gs(function () { var data = getCalcData(this); return data.sign * ((12 - data.from.getMonth() + data.to.getMonth()) % 12 - ((data.from - mfloor.call(copy.call(data.from))) > (data.to - mfloor.call(copy.call(data.to))))); }), year: d.gs(getYear = function () { var data = getCalcData(this); return data.sign * (data.to.getFullYear() - data.from.getFullYear() - ((data.from - yfloor.call(copy.call(data.from))) > (data.to - yfloor.call(copy.call(data.to))))); }), milliseconds: d.gs(valueOf, null), seconds: d.gs(function () { return toInteger(this.valueOf() / 1000); }), minutes: d.gs(function () { return toInteger(this.valueOf() / (1000 * 60)); }), hours: d.gs(function () { return toInteger(this.valueOf() / (1000 * 60 * 60)); }), days: d.gs(function () { return toInteger(this.valueOf() / (1000 * 60 * 60 * 24)); }), months: d.gs(function () { var data = getCalcData(this); return data.sign * ((data.to.getFullYear() - data.from.getFullYear()) * 12 + data.to.getMonth() - data.from.getMonth() - ((data.from - mfloor.call(copy.call(data.from))) > (data.to - mfloor.call(copy.call(data.to))))); }), years: d.gs(getYear), toString: d(function (pattern/*, threshold*/) { var s, threshold, last; if (pattern == null) pattern = 0; if (isNaN(pattern)) return format.call(this, pattern); pattern = Number(pattern); threshold = toPosInt(arguments[1]); s = ""; if (pattern === 1) { if (threshold-- <= 0) s += abs(last = this.millisecond) + "ms"; if (this.seconds || (threshold >= 0)) { if (threshold-- <= 0) { s = abs(last = this.second) + "s" + (s ? " " : "") + s; } if (this.minutes || (threshold >= 0)) { if (threshold-- <= 0) { s = abs(last = this.minute) + "m" + (s ? " " : "") + s; } if (this.hours || (threshold >= 0)) { if (threshold-- <= 0) { s = abs(last = this.hour) + "h" + (s ? " " : "") + s; } if (this.days || (threshold >= 0)) { if (threshold-- <= 0) { s = abs(last = this.day) + "d" + (s ? " " : "") + s; } if (this.months || (threshold >= 0)) { if (threshold-- <= 0) { s = abs(last = this.month) + "m" + (s ? " " : "") + s; } if (this.years || (threshold >= 0)) { s = abs(last = this.year) + "y" + (s ? " " : "") + s; } } } } } } } else { if (threshold-- <= 0) { s += "." + pad.call(abs(last = this.millisecond), 3); } if (this.seconds || (threshold >= 0)) { if (threshold-- <= 0) { last = this.second; s = (this.minutes ? pad.call(abs(last), 2) : abs(last)) + s; } if (this.minutes || (threshold >= 0)) { if (threshold-- <= 0) { last = this.minute; s = ((this.hours || s) ? pad.call(abs(last), 2) : abs(last)) + (s ? ":" : "") + s; } if (this.hours || (threshold >= 0)) { if (threshold-- <= 0) { s = pad.call(abs(last = this.hour), 2) + (s ? ":" : "") + s; } if (this.days || (threshold >= 0)) { if (threshold-- <= 0) { s = abs(last = this.day) + "d" + (s ? " " : "") + s; } if (this.months || (threshold >= 0)) { if (threshold-- <= 0) { s = abs(last = this.month) + "m" + (s ? " " : "") + s; } if (this.years || (threshold >= 0)) { s = abs(last = this.year) + "y" + (s ? " " : "") + s; } } } } } } } if (last && (this.to < this.from)) (s = '-' + s); return s; }) });