kefir-test-utils
Version:
Framework-agnostic testing tools for Kefir
398 lines (324 loc) • 11.2 kB
JavaScript
(function (global, factory) {
if (typeof define === "function" && define.amd) {
define(["exports", "@sinonjs/fake-timers"], factory);
} else if (typeof exports !== "undefined") {
factory(exports, require("@sinonjs/fake-timers"));
} else {
var mod = {
exports: {}
};
factory(mod.exports, global.fakeTimers);
global.index = mod.exports;
}
})(typeof globalThis !== "undefined" ? globalThis : typeof self !== "undefined" ? self : this, function (_exports, _fakeTimers) {
"use strict";
Object.defineProperty(_exports, "__esModule", {
value: true
});
_exports["default"] = createTestHelpers;
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function extend(target
/*, mixin1, mixin2... */
) {
for (var i = 1; i < arguments.length; i++) {
for (var prop in arguments[i]) {
target[prop] = arguments[i][prop];
}
}
return target;
}
var throwEventTypeError = function throwEventTypeError(event) {
throw new TypeError("Expected event object, received:\n".concat(JSON.stringify(event, null, ' ')));
};
function createTestHelpers(Kefir) {
var END = 'end';
var VALUE = 'value';
var ERROR = 'error';
var send = function send(obs, events) {
var _iterator = _createForOfIteratorHelper(events),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var event = _step.value;
switch (event.type) {
case VALUE:
obs._emitValue(event.value);
break;
case ERROR:
obs._emitError(event.value);
break;
case END:
obs._emitEnd();
break;
default:
throwEventTypeError(event);
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return obs;
};
var parseDiagram = function parseDiagram(diagram, events) {
var _events$frame;
var frames = [];
var _iterator2 = _createForOfIteratorHelper(diagram),
_step2;
try {
advancing: for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var frame = _step2.value;
switch (frame) {
case '-':
frames.push([]);
break;
case '#':
frames.push([error(new Error())]);
break;
case '|':
frames.push([end()]);
break advancing;
default:
var event = (_events$frame = events[frame]) !== null && _events$frame !== void 0 ? _events$frame : value(frame.match(/\d/) ? Number(frame) : frame);
frames.push(Array.isArray(event) ? event : [event]);
break;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
return frames;
};
var sendFrames = function sendFrames(obs, _ref) {
var frames = _ref.frames,
advance = _ref.advance;
var _iterator3 = _createForOfIteratorHelper(frames),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var frame = _step3.value;
send(obs, frame);
advance();
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
};
var value = function value(val) {
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref2$current = _ref2.current,
current = _ref2$current === void 0 ? false : _ref2$current;
return {
type: VALUE,
value: val,
current: current
};
};
var error = function error(err) {
var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
_ref3$current = _ref3.current,
current = _ref3$current === void 0 ? false : _ref3$current;
return {
type: ERROR,
value: err,
current: current
};
};
var end = function end() {
var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref4$current = _ref4.current,
current = _ref4$current === void 0 ? false : _ref4$current;
return {
type: END,
current: current
};
};
var _activateHelper = function _activateHelper() {};
var activate = function activate(obs) {
obs.onEnd(_activateHelper);
return obs;
};
var deactivate = function deactivate(obs) {
obs.offEnd(_activateHelper);
return obs;
};
var prop = function prop() {
return new Kefir.Property();
};
var stream = function stream() {
return new Kefir.Stream();
};
var pool = function pool() {
return new Kefir.Pool();
}; // This function changes timers' IDs so "simultaneous" timers are reversed
// Also sets createdAt to 0 so closk.tick will sort by ID
// FIXME:
// 1) Not sure how well it works with interval timers (setInterval), probably bad
// 2) We need to restore (unshake) them back somehow (after calling tick)
// Hopefully we'll get a native implementation, and wont have to fix those
// https://github.com/sinonjs/lolex/issues/24
var shakeTimers = function shakeTimers(clock) {
var ids = Object.keys(clock.timers);
var timers = ids.map(function (id) {
return clock.timers[id];
}); // see https://github.com/sinonjs/lolex/blob/a93c8a9af05fb064ae5c2ad1bfc72874973167ee/src/lolex.js#L175-L209
timers.sort(function (a, b) {
if (a.callAt < b.callAt) {
return -1;
}
if (a.callAt > b.callAt) {
return 1;
}
if (a.immediate && !b.immediate) {
return -1;
}
if (!a.immediate && b.immediate) {
return 1;
} // Following two cheks are reversed
if (a.createdAt < b.createdAt) {
return 1;
}
if (a.createdAt > b.createdAt) {
return -1;
}
if (a.id < b.id) {
return 1;
}
if (a.id > b.id) {
return -1;
}
});
ids.sort(function (a, b) {
return a - b;
});
timers.forEach(function (timer, i) {
var id = ids[i];
timer.createdAt = 0;
timer.id = id;
clock.timers[id] = timer;
});
};
var withFakeTime = function withFakeTime(cb) {
var reverseSimultaneous = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var clock = (0, _fakeTimers.install)({
now: 1000
});
var tick = function tick(t) {
if (reverseSimultaneous && clock.timers) {
shakeTimers(clock);
}
clock.tick(t);
};
var error = null;
try {
cb(tick, clock);
} catch (e) {
error = e;
} finally {
clock.uninstall();
if (error) {
throw error;
}
}
};
var logItem = function logItem(event, current) {
switch (event.type) {
case VALUE:
return value(event.value, {
current: current
});
case ERROR:
return error(event.value, {
current: current
});
case END:
return end({
current: current
});
default:
throwEventTypeError(event);
}
};
var watch = function watch(obs) {
var log = [];
var isCurrent = true;
var fn = function fn(event) {
return log.push(logItem(event, isCurrent));
};
var unwatch = function unwatch() {
return obs.offAny(fn);
};
obs.onAny(fn);
isCurrent = false;
return {
log: log,
unwatch: unwatch
};
};
var watchWithTime = function watchWithTime(obs) {
var startTime = +new Date();
var log = [];
var isCurrent = true;
var fn = function fn(event) {
return log.push([+new Date() - startTime, logItem(event, isCurrent)]);
};
var unwatch = function unwatch() {
return obs.offAny(fn);
};
obs.onAny(fn);
isCurrent = false;
return {
log: log,
unwatch: unwatch
};
};
var observables = {
active: [],
clear: function clear() {
this.active = [];
}
};
var _Kefir$Observable$pro = Kefir.Observable.prototype,
_onActivation2 = _Kefir$Observable$pro._onActivation,
_onDeactivation2 = _Kefir$Observable$pro._onDeactivation;
extend(Kefir.Observable.prototype, {
_onActivation: function _onActivation() {
observables.active.push(this);
_onActivation2.apply(this);
},
_onDeactivation: function _onDeactivation() {
observables.active.splice(observables.active.indexOf(this), 1);
_onDeactivation2.apply(this);
}
});
return {
END: END,
VALUE: VALUE,
ERROR: ERROR,
observables: observables,
send: send,
parseDiagram: parseDiagram,
sendFrames: sendFrames,
value: value,
error: error,
end: end,
activate: activate,
deactivate: deactivate,
prop: prop,
stream: stream,
pool: pool,
shakeTimers: shakeTimers,
withFakeTime: withFakeTime,
logItem: logItem,
watch: watch,
watchWithTime: watchWithTime
};
}
});