@dmail/action
Advanced tools
Comparing version 1.3.0 to 1.5.0
@@ -16,2 +16,4 @@ "use strict"; | ||
var result = void 0; | ||
var willShortCircuit = false; | ||
var ignoreNext = false; | ||
var action = {}; | ||
@@ -37,4 +39,7 @@ | ||
return state === "unknown" || isPassing() || isFailing(); | ||
}; // const isEnded = () => isPassed() || isFailed() | ||
}; | ||
var isEnded = function isEnded() { | ||
return isPassed() || isFailed(); | ||
}; | ||
@@ -71,2 +76,12 @@ var pendingActions = []; | ||
var fail = function fail(value) { | ||
if (ignoreNext) { | ||
ignoreNext = false; | ||
return; | ||
} | ||
if (willShortCircuit) { | ||
ignoreNext = true; | ||
willShortCircuit = false; | ||
} | ||
if (isFailed() || isFailing()) { | ||
@@ -84,2 +99,12 @@ throw new Error("fail must be called once, it was already called with ".concat(result)); | ||
var pass = function pass(value) { | ||
if (ignoreNext) { | ||
ignoreNext = false; | ||
return; | ||
} | ||
if (willShortCircuit) { | ||
ignoreNext = true; | ||
willShortCircuit = false; | ||
} | ||
if (isPassing() || isPassed()) { | ||
@@ -136,2 +161,7 @@ throw new Error("pass must be called once, it was already called with ".concat(result)); | ||
var shortcircuit = function shortcircuit(fn, value) { | ||
willShortCircuit = true; | ||
return fn(value); | ||
}; | ||
var mixin = function mixin() { | ||
@@ -168,5 +198,6 @@ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
isRunning: isRunning, | ||
// isEnded, | ||
isEnded: isEnded, | ||
pass: pass, | ||
fail: fail, | ||
shortcircuit: shortcircuit, | ||
then: then | ||
@@ -173,0 +204,0 @@ }); |
@@ -33,2 +33,50 @@ "use strict"; | ||
}); | ||
ensure("action.shortcircuit(action.pass) prevent next pass throw", function () { | ||
var action = (0, _action.createAction)(); | ||
action.shortcircuit(action.pass, "foo"); | ||
(0, _assertions.assertPassed)(action); | ||
(0, _assertions.assertResult)(action, "foo"); | ||
_assertions.assert.doesNotThrow(action.pass); | ||
_assertions.assert.throws(action.pass); | ||
_assertions.assert.throws(action.fail); | ||
(0, _assertions.assertResult)(action, "foo"); | ||
}); | ||
ensure("action.shortcircuit(action.fail) prevent next fail throw", function () { | ||
var action = (0, _action.createAction)(); | ||
action.shortcircuit(action.fail, "foo"); | ||
(0, _assertions.assertFailed)(action); | ||
(0, _assertions.assertResult)(action, "foo"); | ||
_assertions.assert.doesNotThrow(action.fail); | ||
_assertions.assert.throws(action.pass); | ||
_assertions.assert.throws(action.fail); | ||
(0, _assertions.assertResult)(action, "foo"); | ||
}); | ||
ensure("action.shortcircuit(action.pass) prevent next fail throw", function () { | ||
var action = (0, _action.createAction)(); | ||
action.shortcircuit(action.pass); | ||
_assertions.assert.doesNotThrow(action.fail); | ||
_assertions.assert.throws(action.pass); | ||
_assertions.assert.throws(action.fail); | ||
}); | ||
ensure("action.shortcircuit(action.fail) prevent next pass throw", function () { | ||
var action = (0, _action.createAction)(); | ||
action.shortcircuit(action.fail); | ||
_assertions.assert.doesNotThrow(action.pass); | ||
_assertions.assert.throws(action.pass); | ||
_assertions.assert.throws(action.fail); | ||
}); | ||
ensure("action.fail throw when called more than once", function () { | ||
@@ -35,0 +83,0 @@ var action = (0, _action.createAction)(); |
@@ -29,3 +29,7 @@ "use strict"; | ||
handle = _ref$handle === void 0 ? defaultHandle : _ref$handle, | ||
composer = _ref.composer; | ||
composer = _ref.composer, | ||
_ref$failureIsCritica = _ref.failureIsCritical, | ||
failureIsCritical = _ref$failureIsCritica === void 0 ? function () { | ||
return false; | ||
} : _ref$failureIsCritica; | ||
@@ -42,3 +46,3 @@ var map = function map(value, index) { | ||
function (result) { | ||
return (0, _passed.passed)({ | ||
return failureIsCritical(result) ? result : (0, _passed.passed)({ | ||
state: "failed", | ||
@@ -60,15 +64,13 @@ result: result | ||
var composeSequence = exports.composeSequence = function composeSequence(iterable, handle) { | ||
return compose(iterable, { | ||
composer: _sequence.sequence, | ||
handle: handle | ||
}); | ||
var composeSequence = exports.composeSequence = function composeSequence(iterable, params) { | ||
return compose(iterable, Object.assign({ | ||
composer: _sequence.sequence | ||
}, params)); | ||
}; | ||
var composeTogether = exports.composeTogether = function composeTogether(iterable, handle) { | ||
return compose(iterable, { | ||
composer: _all.all, | ||
handle: handle | ||
}); | ||
var composeTogether = exports.composeTogether = function composeTogether(iterable, params) { | ||
return compose(iterable, Object.assign({ | ||
composer: _all.all | ||
}, params)); | ||
}; | ||
//# sourceMappingURL=compose.js.map |
@@ -53,13 +53,24 @@ "use strict"; | ||
}); | ||
ensure("composeSequence with critical failure", function () { | ||
var action = (0, _compose.composeSequence)([(0, _failed.failed)(0), (0, _failed.failed)(1), (0, _passed.passed)(2)], { | ||
failureIsCritical: function failureIsCritical(failure) { | ||
return failure === 1; | ||
} | ||
}); | ||
(0, _assertions.assertFailed)(action); | ||
(0, _assertions.assertResult)(action, 1); | ||
}); | ||
ensure("composeSequence complex example", function () { | ||
var action = (0, _compose.composeSequence)([0, 1, 2], function (action, value, index) { | ||
if (index === 0) { | ||
return (0, _passed.passed)(value); | ||
} | ||
var action = (0, _compose.composeSequence)([0, 1, 2], { | ||
handle: function handle(action, value, index) { | ||
if (index === 0) { | ||
return (0, _passed.passed)(value); | ||
} | ||
if (index === 1) { | ||
return (0, _failed.failed)(value + 1); | ||
if (index === 1) { | ||
return (0, _failed.failed)(value + 1); | ||
} | ||
return (0, _passed.passed)(value + 1); | ||
} | ||
return (0, _passed.passed)(value + 1); | ||
}); | ||
@@ -82,5 +93,7 @@ | ||
var callCount = 0; | ||
(0, _compose.composeSequence)([firstAction, secondAction], function (action) { | ||
callCount++; | ||
return action; | ||
(0, _compose.composeSequence)([firstAction, secondAction], { | ||
handle: function handle(action) { | ||
callCount++; | ||
return action; | ||
} | ||
}); | ||
@@ -96,5 +109,7 @@ | ||
var callCount = 0; | ||
(0, _compose.composeTogether)([0, 1], function () { | ||
callCount++; | ||
return (0, _action.createAction)(); | ||
(0, _compose.composeTogether)([0, 1], { | ||
handle: function handle() { | ||
callCount++; | ||
return (0, _action.createAction)(); | ||
} | ||
}); | ||
@@ -101,0 +116,0 @@ |
@@ -20,30 +20,36 @@ "use strict"; | ||
var _ref$handle = _ref.handle, | ||
handle = _ref$handle === void 0 ? defaultHandle : _ref$handle, | ||
_handle = _ref$handle === void 0 ? defaultHandle : _ref$handle, | ||
composer = _ref.composer, | ||
_ref$allocatedMs = _ref.allocatedMs, | ||
allocatedMs = _ref$allocatedMs === void 0 ? Infinity : _ref$allocatedMs; | ||
var previousAction = void 0; | ||
return composer(iterable, function (composedAction, value, index) { | ||
composedAction.mixin(_withAllocableMs.withAllocableMs); | ||
composedAction.allocateMs(index === 0 ? allocatedMs : previousAction.getRemainingMs()); | ||
previousAction = composedAction; | ||
return handle(composedAction, value, index, iterable); | ||
return composer(iterable, { | ||
handle: function handle(composedAction, value, index) { | ||
composedAction.mixin(_withAllocableMs.withAllocableMs); | ||
composedAction.allocateMs(index === 0 ? allocatedMs : previousAction.getRemainingMs()); | ||
var allocateMs = composedAction.allocateMs; | ||
composedAction.allocateMs = function (allocatedMs) { | ||
return allocateMs(composedAction.getRemainingMs() + allocatedMs); | ||
}; | ||
previousAction = composedAction; | ||
return _handle(composedAction, value, index, iterable); | ||
}, | ||
failureIsCritical: _withAllocableMs.failureIsOutOfMs | ||
}); | ||
}; | ||
var composeSequenceWithAllocatedMs = exports.composeSequenceWithAllocatedMs = function composeSequenceWithAllocatedMs(iterable, handle, allocatedMs) { | ||
return composeWithAllocatedMs(iterable, { | ||
handle: handle, | ||
composer: _compose.composeSequence, | ||
allocatedMs: allocatedMs | ||
}); | ||
var composeSequenceWithAllocatedMs = exports.composeSequenceWithAllocatedMs = function composeSequenceWithAllocatedMs(iterable, params) { | ||
return composeWithAllocatedMs(iterable, Object.assign({ | ||
composer: _compose.composeSequence | ||
}, params)); | ||
}; | ||
var composeTogetherWithAllocatedMs = exports.composeTogetherWithAllocatedMs = function composeTogetherWithAllocatedMs(iterable, handle, allocatedMs) { | ||
return composeWithAllocatedMs(iterable, { | ||
handle: handle, | ||
composer: _compose.composeTogether, | ||
allocatedMs: allocatedMs | ||
}); | ||
var composeTogetherWithAllocatedMs = exports.composeTogetherWithAllocatedMs = function composeTogetherWithAllocatedMs(iterable, params) { | ||
return composeWithAllocatedMs(iterable, Object.assign({ | ||
composer: _compose.composeTogether | ||
}, params)); | ||
}; | ||
//# sourceMappingURL=composeWithAllocatedMs.js.map |
"use strict"; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
var _composeWithAllocatedMs = require("./composeWithAllocatedMs.js"); | ||
@@ -9,28 +9,32 @@ var _testCheap = require("@dmail/test-cheap"); | ||
var _composeWithAllocatedMs = require("./composeWithAllocatedMs.js"); | ||
var _assertions = require("../assertions.js"); | ||
var _lolex = require("lolex"); | ||
(0, _testCheap.test)("composeWithAllocableMs.js", function (_ref) { | ||
var ensure = _ref.ensure; | ||
ensure("each composed action is allocated the compositeAction remainingMs", function () { | ||
var clock = (0, _lolex.install)(); | ||
var firstAction = (0, _action.createAction)(); | ||
var secondAction = (0, _action.createAction)(); | ||
(0, _composeWithAllocatedMs.composeSequenceWithAllocatedMs)([firstAction, secondAction], undefined, 10); | ||
(0, _composeWithAllocatedMs.composeSequenceWithAllocatedMs)([firstAction, secondAction], { | ||
allocatedMs: 10 | ||
}); | ||
var firstActionRemainingMs = firstAction.getRemainingMs(); | ||
_assertions.assert.equal(_typeof(firstActionRemainingMs), "number"); | ||
_assertions.assert.equal(firstActionRemainingMs, 10); | ||
(0, _assertions.assert)(firstActionRemainingMs <= 10); | ||
_assertions.assert.equal(secondAction.getRemainingMs, undefined); // because first action is running | ||
clock.tick(2); | ||
firstAction.pass(); | ||
var secondActionRemainingMs = secondAction.getRemainingMs(); | ||
_assertions.assert.equal(_typeof(secondActionRemainingMs), "number"); | ||
_assertions.assert.equal(secondAction.getRemainingMs(), 8); | ||
firstActionRemainingMs = firstAction.getRemainingMs(); | ||
(0, _assertions.assert)(secondActionRemainingMs <= firstActionRemainingMs); | ||
secondAction.allocateMs(20); | ||
_assertions.assert.equal(secondAction.getRemainingMs(), 20 + 8); | ||
clock.uninstall(); | ||
}); | ||
@@ -41,8 +45,10 @@ ensure("handle always receive an action as first arg", function () { | ||
var iterable = [1, action]; | ||
(0, _composeWithAllocatedMs.composeTogetherWithAllocatedMs)(iterable, function () { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
(0, _composeWithAllocatedMs.composeTogetherWithAllocatedMs)(iterable, { | ||
handle: function handle() { | ||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { | ||
args[_key] = arguments[_key]; | ||
} | ||
calls.push(args); | ||
} | ||
calls.push(args); | ||
}); | ||
@@ -49,0 +55,0 @@ |
@@ -49,3 +49,11 @@ "use strict"; | ||
done(); | ||
var result = void 0; | ||
(0, _fromPromise.fromPromise)(Promise.resolve(10)).then(function (arg) { | ||
result = arg; | ||
}); | ||
setTimeout(function () { | ||
_assertions.assert.equal(result, 10); | ||
done(); | ||
}, 20); | ||
}, 20); | ||
@@ -52,0 +60,0 @@ }, 20); |
@@ -7,5 +7,12 @@ "use strict"; | ||
var failureIsOutOfMs = exports.failureIsOutOfMs = function failureIsOutOfMs(failure) { | ||
return typeof failure === "string" && failure.startsWith("must pass or fail in less"); | ||
}; | ||
var withAllocableMs = exports.withAllocableMs = function withAllocableMs(_ref) { | ||
var fail = _ref.fail, | ||
then = _ref.then; | ||
shortcircuit = _ref.shortcircuit, | ||
then = _ref.then, | ||
isEnded = _ref.isEnded, | ||
getState = _ref.getState; | ||
var timeoutid = void 0; | ||
@@ -24,3 +31,7 @@ var allocatedMs = Infinity; | ||
var allocateMs = function allocateMs(ms) { | ||
allocatedMs = ms < 0 ? Infinity : ms; | ||
if (isEnded()) { | ||
throw new Error("cannot allocateMs once the action has ".concat(getState())); | ||
} | ||
allocatedMs = ms; | ||
startMs = undefined; | ||
@@ -30,6 +41,8 @@ endMs = undefined; | ||
if (ms !== Infinity) { | ||
if (allocatedMs < 0) { | ||
shortcircuit(fail, "must pass or fail in less than ".concat(allocatedMs, "ms")); | ||
} else if (allocatedMs !== Infinity) { | ||
startMs = Date.now(); | ||
timeoutid = setTimeout(function () { | ||
return fail("must pass or fail in less than ".concat(allocatedMs, "ms")); | ||
return shortcircuit(fail, "must pass or fail in less than ".concat(allocatedMs, "ms")); | ||
}, allocatedMs); | ||
@@ -59,2 +72,10 @@ } | ||
var increaseAllocatedMs = function increaseAllocatedMs(ms) { | ||
return allocateMs(getRemainingMs() + ms); | ||
}; | ||
var decreaseAllocatedMs = function decreaseAllocatedMs(ms) { | ||
return allocateMs(getRemainingMs() - ms); | ||
}; | ||
var onEnded = function onEnded() { | ||
@@ -70,5 +91,7 @@ endMs = Date.now(); | ||
getConsumedMs: getConsumedMs, | ||
getRemainingMs: getRemainingMs | ||
getRemainingMs: getRemainingMs, | ||
increaseAllocatedMs: increaseAllocatedMs, | ||
decreaseAllocatedMs: decreaseAllocatedMs | ||
}; | ||
}; | ||
//# sourceMappingURL=withAllocableMs.js.map |
@@ -16,3 +16,2 @@ "use strict"; | ||
var clock = (0, _lolex.install)(); | ||
clock.tick(15); | ||
@@ -53,10 +52,2 @@ var createActionWithAllocableMs = function createActionWithAllocableMs() { | ||
tooLongAction.allocateMs(-1); | ||
_assertions.assert.equal(tooLongAction.getAllocatedMs(), Infinity); | ||
tooLongAction.allocateMs(-2); | ||
_assertions.assert.equal(tooLongAction.getAllocatedMs(), Infinity); | ||
var allocatedMs = 10; | ||
@@ -84,4 +75,72 @@ var consumedMs = 2; | ||
}); | ||
ensure("an action call pass too late", function () { | ||
var action = createActionWithAllocableMs(); | ||
action.allocateMs(10); | ||
setTimeout(action.pass, 11); | ||
clock.tick(10); | ||
(0, _assertions.assert)((0, _withAllocableMs.failureIsOutOfMs)(action.getResult())); | ||
_assertions.assert.doesNotThrow(function () { | ||
return clock.tick(1); | ||
}); | ||
}); | ||
ensure("an action call fail too late", function () { | ||
var action = createActionWithAllocableMs(); | ||
action.allocateMs(10); | ||
setTimeout(action.fail, 11); | ||
clock.tick(10); | ||
(0, _assertions.assert)((0, _withAllocableMs.failureIsOutOfMs)(action.getResult())); | ||
_assertions.assert.doesNotThrow(function () { | ||
return clock.tick(1); | ||
}); | ||
}); | ||
ensure("allocateMs called with negative ms", function () { | ||
var action = createActionWithAllocableMs(); | ||
action.allocateMs(-1); | ||
_assertions.assert.equal(action.getState(), "failed"); | ||
(0, _assertions.assert)((0, _withAllocableMs.failureIsOutOfMs)(action.getResult())); | ||
}); | ||
ensure("allocateMs() throw when action is passed", function () { | ||
var action = createActionWithAllocableMs(); | ||
action.pass(); | ||
_assertions.assert.throws(function () { | ||
return action.allocateMs(10); | ||
}); | ||
}); | ||
ensure("allocateMs() throw when action is failed", function () { | ||
var action = createActionWithAllocableMs(); | ||
action.fail(); | ||
_assertions.assert.throws(function () { | ||
return action.allocateMs(10); | ||
}); | ||
}); | ||
ensure("increaseAllocatedMs", function () { | ||
var clock = (0, _lolex.install)(); | ||
var action = createActionWithAllocableMs(); | ||
action.allocateMs(10); | ||
clock.tick(5); | ||
action.increaseAllocatedMs(20); | ||
_assertions.assert.equal(action.getAllocatedMs(), 25); | ||
clock.uninstall(); | ||
}); | ||
ensure("decreaseAllocatedMs", function () { | ||
var clock = (0, _lolex.install)(); | ||
var action = createActionWithAllocableMs(); | ||
action.allocateMs(30); | ||
clock.tick(5); | ||
action.decreaseAllocatedMs(10); | ||
_assertions.assert.equal(action.getAllocatedMs(), 15); | ||
clock.uninstall(); | ||
}); | ||
clock.uninstall(); | ||
}); | ||
//# sourceMappingURL=withAllocableMs.test.js.map |
{ | ||
"name": "@dmail/action", | ||
"version": "1.3.0", | ||
"version": "1.5.0", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "repository": { |
@@ -6,2 +6,4 @@ export const isAction = value => value && typeof value.then === "function" | ||
let result | ||
let willShortCircuit = false | ||
let ignoreNext = false | ||
@@ -14,3 +16,3 @@ const action = {} | ||
const isRunning = () => state === "unknown" || isPassing() || isFailing() | ||
// const isEnded = () => isPassed() || isFailed() | ||
const isEnded = () => isPassed() || isFailed() | ||
const pendingActions = [] | ||
@@ -39,2 +41,10 @@ | ||
const fail = value => { | ||
if (ignoreNext) { | ||
ignoreNext = false | ||
return | ||
} | ||
if (willShortCircuit) { | ||
ignoreNext = true | ||
willShortCircuit = false | ||
} | ||
if (isFailed() || isFailing()) { | ||
@@ -49,2 +59,10 @@ throw new Error(`fail must be called once, it was already called with ${result}`) | ||
const pass = value => { | ||
if (ignoreNext) { | ||
ignoreNext = false | ||
return | ||
} | ||
if (willShortCircuit) { | ||
ignoreNext = true | ||
willShortCircuit = false | ||
} | ||
if (isPassing() || isPassed()) { | ||
@@ -87,2 +105,6 @@ throw new Error(`pass must be called once, it was already called with ${result}`) | ||
const getResult = () => result | ||
const shortcircuit = (fn, value) => { | ||
willShortCircuit = true | ||
return fn(value) | ||
} | ||
const mixin = (...args) => { | ||
@@ -113,5 +135,6 @@ // maybe allow only function, add use defineProperty to make them non enumerable ? | ||
isRunning, | ||
// isEnded, | ||
isEnded, | ||
pass, | ||
fail, | ||
shortcircuit, | ||
then | ||
@@ -118,0 +141,0 @@ }) |
@@ -28,2 +28,40 @@ import { test } from "@dmail/test-cheap" | ||
ensure("action.shortcircuit(action.pass) prevent next pass throw", () => { | ||
const action = createAction() | ||
action.shortcircuit(action.pass, "foo") | ||
assertPassed(action) | ||
assertResult(action, "foo") | ||
assert.doesNotThrow(action.pass) | ||
assert.throws(action.pass) | ||
assert.throws(action.fail) | ||
assertResult(action, "foo") | ||
}) | ||
ensure("action.shortcircuit(action.fail) prevent next fail throw", () => { | ||
const action = createAction() | ||
action.shortcircuit(action.fail, "foo") | ||
assertFailed(action) | ||
assertResult(action, "foo") | ||
assert.doesNotThrow(action.fail) | ||
assert.throws(action.pass) | ||
assert.throws(action.fail) | ||
assertResult(action, "foo") | ||
}) | ||
ensure("action.shortcircuit(action.pass) prevent next fail throw", () => { | ||
const action = createAction() | ||
action.shortcircuit(action.pass) | ||
assert.doesNotThrow(action.fail) | ||
assert.throws(action.pass) | ||
assert.throws(action.fail) | ||
}) | ||
ensure("action.shortcircuit(action.fail) prevent next pass throw", () => { | ||
const action = createAction() | ||
action.shortcircuit(action.fail) | ||
assert.doesNotThrow(action.pass) | ||
assert.throws(action.pass) | ||
assert.throws(action.fail) | ||
}) | ||
ensure("action.fail throw when called more than once", () => { | ||
@@ -30,0 +68,0 @@ const action = createAction() |
@@ -12,3 +12,6 @@ import { isAction, createAction } from "../action.js" | ||
const compose = (iterable, { handle = defaultHandle, composer }) => { | ||
const compose = ( | ||
iterable, | ||
{ handle = defaultHandle, composer, failureIsCritical = () => false } | ||
) => { | ||
const map = (value, index) => | ||
@@ -20,3 +23,3 @@ mutateAction(isAction(value) ? value : createAction(), action => | ||
// transform failed into passed so that sequence & all does not stop on first failure | ||
result => passed({ state: "failed", result }) | ||
result => (failureIsCritical(result) ? result : passed({ state: "failed", result })) | ||
) | ||
@@ -32,5 +35,6 @@ | ||
export const composeSequence = (iterable, handle) => | ||
compose(iterable, { composer: sequence, handle }) | ||
export const composeSequence = (iterable, params) => | ||
compose(iterable, Object.assign({ composer: sequence }, params)) | ||
export const composeTogether = (iterable, handle) => compose(iterable, { composer: all, handle }) | ||
export const composeTogether = (iterable, params) => | ||
compose(iterable, Object.assign({ composer: all }, params)) |
@@ -6,3 +6,3 @@ import { test } from "@dmail/test-cheap" | ||
import { composeSequence, composeTogether } from "./compose.js" | ||
import { assert, assertPassed, assertFailed } from "../assertions.js" | ||
import { assert, assertPassed, assertFailed, assertResult } from "../assertions.js" | ||
@@ -37,11 +37,21 @@ test("compose.js", ({ ensure }) => { | ||
ensure("composeSequence with critical failure", () => { | ||
const action = composeSequence([failed(0), failed(1), passed(2)], { | ||
failureIsCritical: failure => failure === 1 | ||
}) | ||
assertFailed(action) | ||
assertResult(action, 1) | ||
}) | ||
ensure("composeSequence complex example", () => { | ||
const action = composeSequence([0, 1, 2], (action, value, index) => { | ||
if (index === 0) { | ||
return passed(value) | ||
const action = composeSequence([0, 1, 2], { | ||
handle: (action, value, index) => { | ||
if (index === 0) { | ||
return passed(value) | ||
} | ||
if (index === 1) { | ||
return failed(value + 1) | ||
} | ||
return passed(value + 1) | ||
} | ||
if (index === 1) { | ||
return failed(value + 1) | ||
} | ||
return passed(value + 1) | ||
}) | ||
@@ -59,5 +69,7 @@ assert.deepEqual(action.getResult(), [ | ||
let callCount = 0 | ||
composeSequence([firstAction, secondAction], action => { | ||
callCount++ | ||
return action | ||
composeSequence([firstAction, secondAction], { | ||
handle: action => { | ||
callCount++ | ||
return action | ||
} | ||
}) | ||
@@ -71,5 +83,7 @@ assert.equal(callCount, 1) | ||
let callCount = 0 | ||
composeTogether([0, 1], () => { | ||
callCount++ | ||
return createAction() | ||
composeTogether([0, 1], { | ||
handle: () => { | ||
callCount++ | ||
return createAction() | ||
} | ||
}) | ||
@@ -76,0 +90,0 @@ assert.equal(callCount, 2) |
import { passed } from "../passed/passed.js" | ||
import { withAllocableMs } from "../withAllocableMs/withAllocableMs.js" | ||
import { withAllocableMs, failureIsOutOfMs } from "../withAllocableMs/withAllocableMs.js" | ||
import { composeSequence, composeTogether } from "../compose/compose.js" | ||
@@ -12,14 +12,20 @@ | ||
let previousAction | ||
return composer(iterable, (composedAction, value, index) => { | ||
composedAction.mixin(withAllocableMs) | ||
composedAction.allocateMs(index === 0 ? allocatedMs : previousAction.getRemainingMs()) | ||
previousAction = composedAction | ||
return handle(composedAction, value, index, iterable) | ||
return composer(iterable, { | ||
handle: (composedAction, value, index) => { | ||
composedAction.mixin(withAllocableMs) | ||
composedAction.allocateMs(index === 0 ? allocatedMs : previousAction.getRemainingMs()) | ||
const allocateMs = composedAction.allocateMs | ||
composedAction.allocateMs = allocatedMs => | ||
allocateMs(composedAction.getRemainingMs() + allocatedMs) | ||
previousAction = composedAction | ||
return handle(composedAction, value, index, iterable) | ||
}, | ||
failureIsCritical: failureIsOutOfMs | ||
}) | ||
} | ||
export const composeSequenceWithAllocatedMs = (iterable, handle, allocatedMs) => | ||
composeWithAllocatedMs(iterable, { handle, composer: composeSequence, allocatedMs }) | ||
export const composeSequenceWithAllocatedMs = (iterable, params) => | ||
composeWithAllocatedMs(iterable, Object.assign({ composer: composeSequence }, params)) | ||
export const composeTogetherWithAllocatedMs = (iterable, handle, allocatedMs) => | ||
composeWithAllocatedMs(iterable, { handle, composer: composeTogether, allocatedMs }) | ||
export const composeTogetherWithAllocatedMs = (iterable, params) => | ||
composeWithAllocatedMs(iterable, Object.assign({ composer: composeTogether }, params)) |
@@ -1,3 +0,1 @@ | ||
import { test } from "@dmail/test-cheap" | ||
import { createAction, isAction } from "../action.js" | ||
import { | ||
@@ -7,21 +5,29 @@ composeSequenceWithAllocatedMs, | ||
} from "./composeWithAllocatedMs.js" | ||
import { test } from "@dmail/test-cheap" | ||
import { createAction, isAction } from "../action.js" | ||
import { assert } from "../assertions.js" | ||
import { install } from "lolex" | ||
test("composeWithAllocableMs.js", ({ ensure }) => { | ||
ensure("each composed action is allocated the compositeAction remainingMs", () => { | ||
const clock = install() | ||
const firstAction = createAction() | ||
const secondAction = createAction() | ||
composeSequenceWithAllocatedMs([firstAction, secondAction], undefined, 10) | ||
composeSequenceWithAllocatedMs([firstAction, secondAction], { | ||
allocatedMs: 10 | ||
}) | ||
let firstActionRemainingMs = firstAction.getRemainingMs() | ||
assert.equal(typeof firstActionRemainingMs, "number") | ||
assert(firstActionRemainingMs <= 10) | ||
assert.equal(firstActionRemainingMs, 10) | ||
assert.equal(secondAction.getRemainingMs, undefined) // because first action is running | ||
clock.tick(2) | ||
firstAction.pass() | ||
assert.equal(secondAction.getRemainingMs(), 8) | ||
const secondActionRemainingMs = secondAction.getRemainingMs() | ||
assert.equal(typeof secondActionRemainingMs, "number") | ||
firstActionRemainingMs = firstAction.getRemainingMs() | ||
assert(secondActionRemainingMs <= firstActionRemainingMs) | ||
secondAction.allocateMs(20) | ||
assert.equal(secondAction.getRemainingMs(), 20 + 8) | ||
clock.uninstall() | ||
}) | ||
@@ -33,4 +39,6 @@ | ||
const iterable = [1, action] | ||
composeTogetherWithAllocatedMs(iterable, (...args) => { | ||
calls.push(args) | ||
composeTogetherWithAllocatedMs(iterable, { | ||
handle: (...args) => { | ||
calls.push(args) | ||
} | ||
}) | ||
@@ -37,0 +45,0 @@ assert.equal(calls.length, 2) |
@@ -44,5 +44,13 @@ import { test } from "@dmail/test-cheap" | ||
assert.equal(caughtException, failException) | ||
done() | ||
let result | ||
fromPromise(Promise.resolve(10)).then(arg => { | ||
result = arg | ||
}) | ||
setTimeout(() => { | ||
assert.equal(result, 10) | ||
done() | ||
}, 20) | ||
}, 20) | ||
}, 20) | ||
}) |
@@ -1,2 +0,5 @@ | ||
export const withAllocableMs = ({ fail, then }) => { | ||
export const failureIsOutOfMs = failure => | ||
typeof failure === "string" && failure.startsWith("must pass or fail in less") | ||
export const withAllocableMs = ({ fail, shortcircuit, then, isEnded, getState }) => { | ||
let timeoutid | ||
@@ -13,10 +16,16 @@ let allocatedMs = Infinity | ||
const allocateMs = ms => { | ||
allocatedMs = ms < 0 ? Infinity : ms | ||
if (isEnded()) { | ||
throw new Error(`cannot allocateMs once the action has ${getState()}`) | ||
} | ||
allocatedMs = ms | ||
startMs = undefined | ||
endMs = undefined | ||
cancelTimeout() | ||
if (ms !== Infinity) { | ||
if (allocatedMs < 0) { | ||
shortcircuit(fail, `must pass or fail in less than ${allocatedMs}ms`) | ||
} else if (allocatedMs !== Infinity) { | ||
startMs = Date.now() | ||
timeoutid = setTimeout( | ||
() => fail(`must pass or fail in less than ${allocatedMs}ms`), | ||
() => shortcircuit(fail, `must pass or fail in less than ${allocatedMs}ms`), | ||
allocatedMs | ||
@@ -37,2 +46,4 @@ ) | ||
const getRemainingMs = () => (allocatedMs === Infinity ? Infinity : allocatedMs - getConsumedMs()) | ||
const increaseAllocatedMs = ms => allocateMs(getRemainingMs() + ms) | ||
const decreaseAllocatedMs = ms => allocateMs(getRemainingMs() - ms) | ||
const onEnded = () => { | ||
@@ -44,3 +55,10 @@ endMs = Date.now() | ||
return { allocateMs, getAllocatedMs, getConsumedMs, getRemainingMs } | ||
return { | ||
allocateMs, | ||
getAllocatedMs, | ||
getConsumedMs, | ||
getRemainingMs, | ||
increaseAllocatedMs, | ||
decreaseAllocatedMs | ||
} | ||
} |
import { test } from "@dmail/test-cheap" | ||
import { install } from "lolex" | ||
import { createAction } from "../action.js" | ||
import { withAllocableMs } from "./withAllocableMs.js" | ||
import { withAllocableMs, failureIsOutOfMs } from "./withAllocableMs.js" | ||
import { assert } from "../assertions.js" | ||
@@ -9,4 +9,2 @@ | ||
const clock = install() | ||
clock.tick(15) | ||
const createActionWithAllocableMs = () => createAction().mixin(withAllocableMs) | ||
@@ -38,6 +36,2 @@ | ||
assert.equal(tooLongAction.getAllocatedMs(), Infinity) | ||
tooLongAction.allocateMs(-1) | ||
assert.equal(tooLongAction.getAllocatedMs(), Infinity) | ||
tooLongAction.allocateMs(-2) | ||
assert.equal(tooLongAction.getAllocatedMs(), Infinity) | ||
@@ -61,3 +55,60 @@ const allocatedMs = 10 | ||
ensure("an action call pass too late", () => { | ||
const action = createActionWithAllocableMs() | ||
action.allocateMs(10) | ||
setTimeout(action.pass, 11) | ||
clock.tick(10) | ||
assert(failureIsOutOfMs(action.getResult())) | ||
assert.doesNotThrow(() => clock.tick(1)) | ||
}) | ||
ensure("an action call fail too late", () => { | ||
const action = createActionWithAllocableMs() | ||
action.allocateMs(10) | ||
setTimeout(action.fail, 11) | ||
clock.tick(10) | ||
assert(failureIsOutOfMs(action.getResult())) | ||
assert.doesNotThrow(() => clock.tick(1)) | ||
}) | ||
ensure("allocateMs called with negative ms", () => { | ||
const action = createActionWithAllocableMs() | ||
action.allocateMs(-1) | ||
assert.equal(action.getState(), "failed") | ||
assert(failureIsOutOfMs(action.getResult())) | ||
}) | ||
ensure("allocateMs() throw when action is passed", () => { | ||
const action = createActionWithAllocableMs() | ||
action.pass() | ||
assert.throws(() => action.allocateMs(10)) | ||
}) | ||
ensure("allocateMs() throw when action is failed", () => { | ||
const action = createActionWithAllocableMs() | ||
action.fail() | ||
assert.throws(() => action.allocateMs(10)) | ||
}) | ||
ensure("increaseAllocatedMs", () => { | ||
const clock = install() | ||
const action = createActionWithAllocableMs() | ||
action.allocateMs(10) | ||
clock.tick(5) | ||
action.increaseAllocatedMs(20) | ||
assert.equal(action.getAllocatedMs(), 25) | ||
clock.uninstall() | ||
}) | ||
ensure("decreaseAllocatedMs", () => { | ||
const clock = install() | ||
const action = createActionWithAllocableMs() | ||
action.allocateMs(30) | ||
clock.tick(5) | ||
action.decreaseAllocatedMs(10) | ||
assert.equal(action.getAllocatedMs(), 15) | ||
clock.uninstall() | ||
}) | ||
clock.uninstall() | ||
}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
227586
3626