You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

220 lines
6.7 KiB

'use strict';
var _ = require('lodash'), util = require('./util');
exports.TimeoutsAndIntervals = function(durationToMs) {
return {
setTimeout: function (callback, timeout) {
return setTimeout(callback, durationToMs(timeout));
},
clearTimeout: function (id) {
return clearTimeout(id);
},
setInterval: function (callback, interval) {
return setInterval(callback, durationToMs(interval));
},
clearInterval: function (id) {
return clearInterval(id);
}
};
}
function StubTimeoutsAndIntervals() {
var exists = _.partialRight(util.ensure, 'a truthy value', function (value) {
return value !== undefined;
});
var intervals = {};
var timeouts = {};
return {
setTimeout: function (callback, timeout) {
exists(timeout);
var id = util.createGuid();
timeouts[id] = {
callback: callback,
timeout: timeout
};
return id;
},
clearTimeout: function (id) {
delete timeouts[id];
return id;
},
setInterval: function (callback, interval) {
exists(interval);
var id = util.createGuid();
intervals[id] = {
callback: callback,
interval: interval
};
return id;
},
clearInterval: function (id) {
delete intervals[id];
return id;
},
timeouts: function () {
return _(timeouts).map(function (timeout, id) {
return [id, timeout.timeout];
}).fromPairs().value();
},
intervals: function () {
return _(timeouts).map(function (timeout, id) {
return [id, intervals.timeout];
}).fromPairs().value();
},
triggerAll: function () {
var ids = _.keys(timeouts).concat(_.keys(intervals));
_.map(timeouts, function (timeout, id) {
timeout.callback();
delete timeouts[id];
return id;
});
_.each(intervals, function (interval) {
interval.callback();
});
return ids;
}
};
}
var StubClockwork = function (fns, current, tickSize, implicitTickFlag) {
current = current ? fns.ensureDate(current) : fns.dateFn(0);
tickSize = tickSize ? fns.ensureDuration(tickSize) : fns.durationFn(1000);
implicitTickFlag = implicitTickFlag === undefined ? false : implicitTickFlag;
return {
lastKnownTime: function () {
return current;
},
now: function () {
if (arguments.length > 0) {
current = fns.ensureDate(arguments[0]);
} else if (implicitTickFlag) {
current = fns.incrementBy(current, tickSize);
}
return fns.dateFn(current);
},
timeIn: function (tickSize) {
return fns.incrementBy(current, tickSize);
},
durationUntil: function (time) {
return fns.durationDiff(current, time);
},
tick: function (duration) {
current = fns.incrementBy(current, duration ? fns.ensureDuration(arguments[0]) : tickSize);
return fns.dateFn(current);
},
tickSize: function (duration) {
if (duration) {
tickSize = fns.ensureDuration(duration);
}
return tickSize;
},
implicitTick: function () {
if (arguments.length > 0) {
implicitTickFlag = arguments[0];
}
return implicitTickFlag;
}
};
};
/* NATIVE JAVASCRIPT DATE IMPLEMENTATION */
var numberOfMillisOrThrow = _.partialRight(util.ensure, 'number of milliseconds', _.isNumber);
var dateClockwork = {
now: function () {
return new Date();
},
timeIn: function (duration) {
return new Date(this.now().getTime() + duration);
},
durationUntil: function (other) {
return other.getTime() - this.now().getTime();
}
};
var dateConversions = {
numberOfMillisecondsAsDuration: function (durationInMillis) {
return durationInMillis;
}
};
exports.DateClock = function () {
return _.extend(new exports.TimeoutsAndIntervals(numberOfMillisOrThrow), dateClockwork, dateConversions);
};
exports.StubDateClock = function (current, tickSize, implicitTickFlag) {
var fns = {
dateFn: function (millis) {
return new Date(millis);
},
durationFn: function (ms) {
return ms;
},
incrementBy: function (date, tickSize) {
return new Date(date.getTime() + tickSize);
},
durationDiff: function(current, other) {
return other.getTime() - current.getTime();
},
ensureDate: _.partialRight(util.ensure, 'date', _.isDate),
ensureDuration: numberOfMillisOrThrow
};
return _.extend(new StubTimeoutsAndIntervals(), new StubClockwork(fns, current, tickSize, implicitTickFlag), dateConversions);
};
/* MOMENT.JS IMPLEMENTATION */
var moment = require('moment');
var durationOrThrow = _.partialRight(util.ensure, 'duration', moment.isDuration);
var momentOrThrow = _.partialRight(util.ensure, 'moment', moment.isMoment, function (value) {
return value.clone();
});
var momentClockwork = {
now: function () {
return moment();
},
timeIn: function (duration) {
return this.now().add(duration);
},
durationUntil: function (other) {
return this.numberOfMillisecondsAsDuration(other.diff(this.now()));
}
};
var momentConversions = {
numberOfMillisecondsAsDuration: function (durationInMillis) {
return moment.duration(durationInMillis);
}
};
exports.MomentClock = function () {
return _.extend(new exports.TimeoutsAndIntervals(function (duration) {
return durationOrThrow(duration).asMilliseconds();
}), momentClockwork, momentConversions);
};
exports.StubMomentClock = function (current, tickSize, implicitTickFlag) {
var fns = {
dateFn: moment,
durationFn: function (ms) {
return moment.duration(ms, 'milliseconds');
},
incrementBy: function (date, tickSize) {
return moment(date).add(tickSize);
},
durationDiff: function(current, other) {
return moment.duration(other.diff(current), 'milliseconds');
},
ensureDate: momentOrThrow,
ensureDuration: durationOrThrow
};
return _.extend(new StubTimeoutsAndIntervals(), new StubClockwork(fns, current, tickSize, implicitTickFlag), momentConversions);
};