From becdbb2a8ccd982192e07c5e2fb2505b13607262 Mon Sep 17 00:00:00 2001 From: Kirill Kaysarov Date: Sat, 4 Jun 2016 20:30:32 +0600 Subject: [PATCH] Async actions cache --- src/appstate.js | 28 ++++++++++++++++--- test/suites/appstate.js | 60 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 6 deletions(-) diff --git a/src/appstate.js b/src/appstate.js index 135babe..41f11bf 100755 --- a/src/appstate.js +++ b/src/appstate.js @@ -32,7 +32,7 @@ module.exports = { create (actions) { analyze(actions); - return (state, services = {}, args = {}) => { + return (state, services = {}, args = {}, history) => { return new Promise((resolve, reject) => { var promise = { resolve, reject }; var start = Date.now(); @@ -43,7 +43,7 @@ module.exports = { // Create signal definition var signal = { - args, + args, history, branches: tree.branches, isExecuting: true, duration: 0 @@ -124,9 +124,27 @@ function runAsyncBranch (index, currentBranch, options) { action.isExecuting = true; action.args = merge({}, args); - var next = createNextAsyncAction(actionFunc, outputs); + var next; - actionFunc.apply(null, actionArgs.concat(next.fn, services)); + // If history provided, emulate action run, + // by passing to next action with found path and args + if (signal.history) { + var cachedAction = signal.history; + + action.path.forEach((branchId) => { + cachedAction = cachedAction[branchId]; + }); + + next = Object.create(null); + + next.promise = Promise.resolve({ + path: cachedAction.outputPath, + args: cachedAction.output + }); + } else { + next = createNextAsyncAction(actionFunc, outputs); + actionFunc.apply(null, actionArgs.concat(next.fn, services)); + } return next.promise .then(result => { @@ -494,6 +512,8 @@ function transformSyncBranch (action, parentAction, path, actions, isSync) { * @param {Array} actions */ function analyze (actions) { + + actions.forEach((action, index) => { if (typeof action === 'undefined' || typeof action === 'string') { throw new Error( diff --git a/test/suites/appstate.js b/test/suites/appstate.js index 034c384..7a1638c 100755 --- a/test/suites/appstate.js +++ b/test/suites/appstate.js @@ -526,7 +526,7 @@ lab.experiment('#appstate', function () { }).catch(done); }); - lab.test('should throw error if function defined in async action is miss', function(done) { + lab.test('should throw error if function defined in async action is miss', (done) => { var asyncActionsGroup = {}; function async (args, state, output) { @@ -551,7 +551,7 @@ lab.experiment('#appstate', function () { done(); }); - lab.test('should throw error if function defined in sync action is miss', function(done) { + lab.test('should throw error if function defined in sync action is miss', (done) => { var syncActionsGroup = {}; function sync (args, state, output) { @@ -571,4 +571,60 @@ lab.experiment('#appstate', function () { assert.throws(appstate.create.bind(null, actions), Error); done(); }); + + lab.test('should use history in async actions if it passed', (done) => { + var counter1 = 0; + var counter2 = 0; + var outputTimes1 = 0; + var outputTimes2 = 0; + + function async (args, state, output) { + counter1 += 1; + output.success({ test: 'test' }); + } + + function sync (args) { + assert(args.test); + outputTimes1 += 1; + } + + function async2 (args, state, output) { + counter2 += 1; + output.success({ test2: 'test' }); + } + + function sync2 (args) { + assert(args.test2); + outputTimes2 += 1; + } + + var signal = appstate.create([ + [ + async, { + success: [ + sync + ] + }, + async2, { + success: [ + sync2 + ] + } + ] + ]); + + signal(tree) + .then((result) => { + return signal(tree, {}, {}, result.branches); + }) + .then(() => { + assert.equal(counter1, 1); + assert.equal(counter2, 1); + assert.equal(outputTimes1, 2); + assert.equal(outputTimes2, 2); + + done(); + }) + .catch(done); + }); });