react 0.2.4 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +146 -94
- package/doc/alternate-dsls.md +103 -0
- package/{lib → dsl}/chain.js +5 -3
- package/{lib → dsl}/fstr.js +17 -6
- package/{lib → dsl}/pcode.js +19 -8
- package/examples/chain-events1.js +28 -7
- package/examples/chain1.js +2 -2
- package/examples/default-events1.js +33 -6
- package/examples/default-log-events.js +43 -0
- package/examples/fstr-events1.js +4 -17
- package/examples/fstr1.js +3 -2
- package/examples/pcode1.js +2 -2
- package/lib/base-task.js +8 -6
- package/lib/cb-task.js +14 -1
- package/lib/core.js +46 -15
- package/lib/dsl.js +14 -6
- package/lib/event-manager.js +29 -15
- package/lib/finalcb-first-task.js +16 -10
- package/lib/finalcb-task.js +17 -10
- package/lib/input-parser.js +7 -3
- package/lib/log-events.js +71 -0
- package/lib/parse.js +6 -3
- package/lib/promise-task.js +89 -0
- package/lib/ret-task.js +1 -1
- package/lib/task.js +32 -23
- package/lib/track-tasks.js +117 -0
- package/lib/validate.js +14 -5
- package/lib/vcon.js +8 -3
- package/lib/when-task.js +81 -0
- package/package.json +4 -2
- package/promise-resolve.js +35 -0
- package/react.js +0 -4
- package/test/core-deferred.test.js +134 -0
- package/test/core-promised.test.js +132 -0
- package/test/core-when.test.js +84 -0
- package/test/core.test.js +108 -60
- package/test/dsl.test.js +58 -6
- package/test/{chain.test.js → dsl/chain.test.js} +85 -1
- package/test/{fstr.test.js → dsl/fstr.test.js} +13 -1
- package/test/{pcode.test.js → dsl/pcode.test.js} +128 -1
- package/test/exec-options.test.js +2 -1
- package/test/finalcb-task.test.js +6 -5
- package/test/input-parser.test.js +10 -6
- package/test/module-use.test.js +13 -199
- package/test/promise-auto-resolve.test.js +51 -0
- package/test/validate.test.js +30 -1
- package/test/vcon.test.js +13 -0
- package/oldExamples/analyze.js +0 -29
- package/oldExamples/analyze2.js +0 -29
- package/oldExamples/example10-dsl.js +0 -63
- package/oldExamples/example11.js +0 -62
- package/oldExamples/example12.js +0 -63
- package/oldExamples/example13.js +0 -63
- package/oldExamples/example14.js +0 -63
- package/oldExamples/example15.js +0 -75
- package/oldExamples/example6-ast.js +0 -47
- package/oldExamples/example6-dsl.js +0 -49
- package/oldExamples/example8-ast.js +0 -55
- package/oldExamples/example8-dsl.js +0 -53
- package/oldExamples/example9-ast.js +0 -58
- package/oldExamples/example9-dsl.js +0 -57
- package/oldExamples/function-str-ex1.js +0 -33
- package/oldExamples/function-str-ex2.js +0 -67
- package/oldExamples/trait1.js +0 -41
- package/oldExamples/trait2.js +0 -44
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Track the tasks, start, complete, args, results, elapsed time
|
|
5
|
+
Emits events that can be monitored
|
|
6
|
+
|
|
7
|
+
- track start and complete
|
|
8
|
+
- record args each task was called with
|
|
9
|
+
- record results at completion
|
|
10
|
+
- record start, end, and calc elapsed time
|
|
11
|
+
- emits flow.begin with flowEnv
|
|
12
|
+
- emits task.begin with task
|
|
13
|
+
- emits task.complete with task
|
|
14
|
+
- emits flow complete with flowEnv
|
|
15
|
+
- emits flow errored with flowEnv
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
var react = require('../'); // require('react');
|
|
20
|
+
|
|
21
|
+
var TASK_EVENTS_RE = /^task\./;
|
|
22
|
+
var FLOW_EVENTS_RE = /^flow\./;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
Accumulator to make it easy to capture events
|
|
26
|
+
|
|
27
|
+
@example
|
|
28
|
+
var EventCollector = require('react/lib/track-tasks').EventCollector;
|
|
29
|
+
var collector = new EventCollector();
|
|
30
|
+
|
|
31
|
+
collector.captureGlobal('*'); // capture all react events for all flows
|
|
32
|
+
|
|
33
|
+
// OR
|
|
34
|
+
|
|
35
|
+
collector.capture(flowFn, 'task.'); // capture task events on a flow
|
|
36
|
+
collector.capture(flowFn, 'flow.'); // add capture flow events on a flow
|
|
37
|
+
|
|
38
|
+
var events = collector.list(); // retrieve the list of events
|
|
39
|
+
*/
|
|
40
|
+
function EventCollector() {
|
|
41
|
+
this.events = [];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
register listener to capture all events
|
|
46
|
+
@param eventId event id or wildcarded id
|
|
47
|
+
*/
|
|
48
|
+
EventCollector.prototype.captureGlobal = function (eventId) {
|
|
49
|
+
this.capture(react, eventId);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
register listener to capture events for a specific flow
|
|
54
|
+
@param flowFn the react flow function or can pass global react
|
|
55
|
+
@param eventId event id or wildcarded id
|
|
56
|
+
*/
|
|
57
|
+
EventCollector.prototype.capture = function (flowFn, eventId) {
|
|
58
|
+
var emitter = flowFn.events;
|
|
59
|
+
var self = this;
|
|
60
|
+
function accumEvents(obj) {
|
|
61
|
+
var eventObject = {
|
|
62
|
+
event: this.event,
|
|
63
|
+
time: Date.now()
|
|
64
|
+
};
|
|
65
|
+
if (FLOW_EVENTS_RE.test(this.event)) {
|
|
66
|
+
eventObject.env = obj;
|
|
67
|
+
} else if (TASK_EVENTS_RE.test(this.event)) {
|
|
68
|
+
eventObject.task = obj;
|
|
69
|
+
}
|
|
70
|
+
self.events.push(eventObject);
|
|
71
|
+
}
|
|
72
|
+
emitter.on(eventId, accumEvents);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
EventCollector.prototype.list = function () {
|
|
76
|
+
return this.events;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
react.events.on(react.events.TYPES.EXEC_FLOW_START, function (env){
|
|
80
|
+
env.startTime = Date.now();
|
|
81
|
+
env.flowEmitter.emit(react.events.TYPES.FLOW_BEGIN, env); //fire public ev
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
react.events.on(react.events.TYPES.EXEC_TASK_START, function (task) {
|
|
85
|
+
task.startTime = Date.now();
|
|
86
|
+
task.env.flowEmitter.emit(react.events.TYPES.TASK_BEGIN, task); //fire public ev
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
react.events.on(react.events.TYPES.EXEC_TASK_COMPLETE, function (task) {
|
|
90
|
+
task.endTime = Date.now();
|
|
91
|
+
task.elapsedTime = task.endTime - task.startTime;
|
|
92
|
+
task.env.flowEmitter.emit(react.events.TYPES.TASK_COMPLETE, task); // fire public ev
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
react.events.on(react.events.TYPES.EXEC_TASK_ERRORED, function (task) {
|
|
96
|
+
task.endTime = Date.now();
|
|
97
|
+
task.elapsedTime = task.endTime - task.startTime;
|
|
98
|
+
task.env.flowEmitter.emit(react.events.TYPES.TASK_ERRORED, task); // fire public ev
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
react.events.on(react.events.TYPES.EXEC_FLOW_COMPLETE, function (env) {
|
|
102
|
+
env.endTime = Date.now();
|
|
103
|
+
env.elapsedTime = env.endTime - env.startTime;
|
|
104
|
+
env.flowEmitter.emit(react.events.TYPES.FLOW_COMPLETE, env); //fire public ev
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
react.events.on(react.events.TYPES.EXEC_FLOW_ERRORED, function (env) {
|
|
108
|
+
env.endTime = Date.now();
|
|
109
|
+
env.elapsedTime = env.endTime - env.startTime;
|
|
110
|
+
env.flowEmitter.emit(react.events.TYPES.FLOW_ERRORED, env); //fire public ev
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
module.exports = react; // return react
|
|
117
|
+
module.exports.EventCollector = EventCollector;
|
package/lib/validate.js
CHANGED
|
@@ -13,6 +13,9 @@ var LOCALS_NOTNULL = 'ast.locals should not be null';
|
|
|
13
13
|
var DUP_OUTPUTS = 'multiple tasks output the same param, must be unique. param';
|
|
14
14
|
var MISSING_INPUTS = 'missing or mispelled variable referenced in flow definition: %s';
|
|
15
15
|
|
|
16
|
+
// match any of our literals true, false, int, float, quoted strings, or is property (has dot), match vcon.js
|
|
17
|
+
var LITERAL_OR_PROP_RE = /^(true|false|this|null|\-?[0-9\.]+)$|'|"|\./i;
|
|
18
|
+
|
|
16
19
|
var validateInParams, validateTasks, validateOutTask, validateTaskNamesUnique;
|
|
17
20
|
var validateLocals, validateOuputsUnique, validateNoMissingNames;
|
|
18
21
|
|
|
@@ -20,10 +23,15 @@ function format_error(errmsg, obj) {
|
|
|
20
23
|
return sprintf('%s - %s', errmsg, util.inspect(obj));
|
|
21
24
|
}
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
/**
|
|
27
|
+
true if is a literal name
|
|
28
|
+
*/
|
|
29
|
+
function isLiteralOrProp(name) { // need to match what is in vcon.js, TODO consolidate?
|
|
30
|
+
return LITERAL_OR_PROP_RE.test(name);
|
|
25
31
|
}
|
|
26
32
|
|
|
33
|
+
|
|
34
|
+
|
|
27
35
|
/**
|
|
28
36
|
validate the AST return Errors
|
|
29
37
|
@example
|
|
@@ -105,6 +113,7 @@ function validateOuputsUnique(taskDefs) {
|
|
|
105
113
|
return errors;
|
|
106
114
|
}
|
|
107
115
|
|
|
116
|
+
|
|
108
117
|
/**
|
|
109
118
|
validate there are no missing or mispelled param names in any task inputs
|
|
110
119
|
or the final task output
|
|
@@ -134,17 +143,17 @@ function validateNoMissingNames(ast) {
|
|
|
134
143
|
// now we have all possible provided vars, check task inputs are accounted for
|
|
135
144
|
ast.tasks.reduce(function (accum, t) { // for all tasks
|
|
136
145
|
return t.a.reduce(function (innerAccum, p) { // for all in params, except property
|
|
137
|
-
if (!
|
|
146
|
+
if (!isLiteralOrProp(p) && !names[p]) innerAccum.push(sprintf(MISSING_INPUTS, p)); // add error if missing
|
|
138
147
|
return innerAccum;
|
|
139
148
|
}, accum);
|
|
140
149
|
}, errors);
|
|
141
150
|
|
|
142
151
|
// now check the final task outputs
|
|
143
152
|
ast.outTask.a.reduce(function (accum, p) { // for final task out params
|
|
144
|
-
if (!
|
|
153
|
+
if (!isLiteralOrProp(p) && !names[p]) accum.push(sprintf(MISSING_INPUTS, p)); // add error if missing
|
|
145
154
|
return accum;
|
|
146
155
|
}, errors);
|
|
147
|
-
return errors;
|
|
156
|
+
return errors;
|
|
148
157
|
}
|
|
149
158
|
|
|
150
159
|
module.exports = validate;
|
package/lib/vcon.js
CHANGED
|
@@ -9,11 +9,14 @@ VContext.prototype.getLastResults = function () { return this.getVar(LAST_RESULT
|
|
|
9
9
|
VContext.prototype.setLastResults = function (args) { this.setVar(LAST_RESULTS_KEY, args); };
|
|
10
10
|
|
|
11
11
|
VContext.prototype.getVar = function (name) { //name might be simple or obj.prop, also literals
|
|
12
|
+
/*jshint regexp: false */
|
|
12
13
|
var vConValues = this.values;
|
|
13
14
|
if (typeof(name) !== 'string') return name; // literal boolean or number
|
|
14
15
|
name = name.trim();
|
|
16
|
+
// literal checks need to match what is in validate.js
|
|
15
17
|
if (name === 'true') return true;
|
|
16
18
|
if (name === 'false') return false;
|
|
19
|
+
if (name === 'null') return null;
|
|
17
20
|
if (/^-?[0-9]+$/.test(name)) return parseInt(name, 10); //int
|
|
18
21
|
if (/^-?[0-9.]+$/.test(name)) return parseFloat(name); //float
|
|
19
22
|
var m = /^("|')([^\1]*)\1$/.exec(name); //check for quoted string " or '
|
|
@@ -30,13 +33,13 @@ VContext.prototype.getVar = function (name) { //name might be simple or obj.prop
|
|
|
30
33
|
variable :LAST_RESULTS which keeps an array of the last values
|
|
31
34
|
which can be used for chaining and testing last results, etc.
|
|
32
35
|
*/
|
|
33
|
-
VContext.prototype.saveResults = function(paramArr, valuesArr) { // set values for params
|
|
36
|
+
VContext.prototype.saveResults = function (paramArr, valuesArr) { // set values for params
|
|
34
37
|
var self = this;
|
|
35
38
|
paramArr.forEach(function (k, idx) { //save values to v context
|
|
36
39
|
self.setVar(k, (valuesArr[idx] !== undefined) ? valuesArr[idx] : null); //upgrade any undefined to null
|
|
37
40
|
});
|
|
38
41
|
this.setLastResults(valuesArr);
|
|
39
|
-
}
|
|
42
|
+
};
|
|
40
43
|
|
|
41
44
|
VContext.prototype.setVar = function (name, value) { //name might be simple or obj.prop
|
|
42
45
|
if (!name) return; // if name is undefined or null, then discard
|
|
@@ -59,9 +62,11 @@ VContext.prototype.setVar = function (name, value) { //name might be simple or o
|
|
|
59
62
|
Ignore extra arguments passed in. Locals can be
|
|
60
63
|
passed into seed the VContext otherwise empty {}
|
|
61
64
|
will be used
|
|
65
|
+
@param self used to pass 'this' context in
|
|
62
66
|
*/
|
|
63
|
-
VContext.create = function (args, inParams, locals) {
|
|
67
|
+
VContext.create = function (args, inParams, locals, self) {
|
|
64
68
|
var initValues = {};
|
|
69
|
+
if (self) initValues['this'] = self;
|
|
65
70
|
if (locals) Object.keys(locals).forEach(function (k) { initValues[k] = locals[k]; }); // copy over keys
|
|
66
71
|
var vContext = new VContext();
|
|
67
72
|
vContext.values = args.reduce(function (vcon, x, idx) { // create vCon start with input args
|
package/lib/when-task.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
When task which checks if is a promise (has a then method)
|
|
5
|
+
and waits for it to resolve.
|
|
6
|
+
|
|
7
|
+
If argument does not have a then method, it resolves immediately
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var util = require('util');
|
|
11
|
+
var sprintf = require('sprintf').sprintf;
|
|
12
|
+
|
|
13
|
+
var BaseTask = require('./base-task.js');
|
|
14
|
+
|
|
15
|
+
function format_error(errmsg, obj) {
|
|
16
|
+
return sprintf('%s - %s', errmsg, util.inspect(obj));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var REQ = 'whenTask requires a, out';
|
|
20
|
+
var A_REQ = 'whenTask requires a to be an array[1] of string param names';
|
|
21
|
+
var OUT_REQ = 'whenTask requires out to be an array[1] of string param names';
|
|
22
|
+
|
|
23
|
+
function WhenTask(taskDef) {
|
|
24
|
+
var self = this;
|
|
25
|
+
Object.keys(taskDef).forEach(function (k) { self[k] = taskDef[k]; });
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
WhenTask.prototype = new BaseTask();
|
|
29
|
+
WhenTask.prototype.constructor = WhenTask;
|
|
30
|
+
|
|
31
|
+
WhenTask.prototype.f = function when() { // just here to keep validations happy
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
WhenTask.validate = function (taskDef) {
|
|
35
|
+
var errors = [];
|
|
36
|
+
if (!taskDef.a || !taskDef.out) {
|
|
37
|
+
errors.push(format_error(REQ, taskDef));
|
|
38
|
+
} else {
|
|
39
|
+
if (! (Array.isArray(taskDef.a) && taskDef.a.length === 1 &&
|
|
40
|
+
taskDef.a.every(function (x) { return (typeof(x) === 'string'); }))) {
|
|
41
|
+
errors.push(format_error(A_REQ, taskDef));
|
|
42
|
+
}
|
|
43
|
+
if (! (Array.isArray(taskDef.out) && taskDef.out.length <= 1 &&
|
|
44
|
+
taskDef.out.every(function (x) { return (typeof(x) === 'string'); }))) {
|
|
45
|
+
errors.push(format_error(OUT_REQ, taskDef));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return errors;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
WhenTask.prototype.prepare = function prepare(handleTaskError, vCon, contExec) {
|
|
52
|
+
var self = this;
|
|
53
|
+
this.nextFn = function (arg) {
|
|
54
|
+
var args = Array.prototype.slice.call(arguments);
|
|
55
|
+
vCon.saveResults(self.out, args);
|
|
56
|
+
self.complete(args);
|
|
57
|
+
contExec();
|
|
58
|
+
};
|
|
59
|
+
this.failFn = function (err) {
|
|
60
|
+
handleTaskError(self, err);
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
WhenTask.prototype.exec = function exec(vCon, handleError, contExec) {
|
|
65
|
+
try {
|
|
66
|
+
var args = this.a.map(function (k) { return vCon.getVar(k); }); //get args from vCon
|
|
67
|
+
//console.error('WhenTask.exec.args=', args);
|
|
68
|
+
//console.error('WhenTask.exec.vCon=', vCon);
|
|
69
|
+
this.start(args); //note the start time, args
|
|
70
|
+
var arg = args[0]; // one value allowed
|
|
71
|
+
if (arg && typeof(arg.then) === 'function') { // is a promise
|
|
72
|
+
arg.then(this.nextFn, this.failFn);
|
|
73
|
+
} else { // not a promise continue immediately
|
|
74
|
+
this.nextFn(arg);
|
|
75
|
+
}
|
|
76
|
+
} catch (err) { //catch and handle the task error, calling final cb
|
|
77
|
+
handleError(this, err);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
module.exports = WhenTask;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react",
|
|
3
3
|
"description": "React is a javascript module to make it easier to work with asynchronous code, by reducing boilerplate code and improving error and exception handling while allowing variable and task dependencies when defining flow.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.4",
|
|
5
5
|
"author": "Jeff Barczewski <jeff.barczewski@gmail.com>",
|
|
6
6
|
"repository": { "type": "git", "url": "http://github.com/jeffbski/react.git" },
|
|
7
7
|
"bugs" : { "url": "http://github.com/jeffbski/react/issues" },
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"tap" : "~0.1.0",
|
|
18
|
-
"tapr" : "~0.1.0"
|
|
18
|
+
"tapr" : "~0.1.0",
|
|
19
|
+
"promised-io" : "~0.3.0",
|
|
20
|
+
"Deferred" : "~0.1.1"
|
|
19
21
|
},
|
|
20
22
|
"scripts": {
|
|
21
23
|
"test": "node_modules/.bin/tapr test"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Auto resolve promises passed in as arguments to the flow
|
|
5
|
+
|
|
6
|
+
- Detects promises by checking for .then()
|
|
7
|
+
- Create promise name for param (param__promise)
|
|
8
|
+
- moves existing vCon promise into the param__promise
|
|
9
|
+
- creates WhenTask which resolves param__promise into param
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var react = require('./'); // require('react');
|
|
14
|
+
|
|
15
|
+
var PROMISE_SUFFIX = '__promise'; // added to param names that are promises
|
|
16
|
+
|
|
17
|
+
react.events.on(react.events.TYPES.EXEC_TASKS_PRECREATE, function (env) {
|
|
18
|
+
var vConValues = env.vCon.values;
|
|
19
|
+
var promiseParams = env.ast.inParams.filter(function (p) {
|
|
20
|
+
var value = vConValues[p];
|
|
21
|
+
return (value && typeof(value.then) === 'function');
|
|
22
|
+
});
|
|
23
|
+
promiseParams.forEach(function (p) {
|
|
24
|
+
var promiseName = p + PROMISE_SUFFIX;
|
|
25
|
+
vConValues[promiseName] = vConValues[p];
|
|
26
|
+
vConValues[p] = undefined;
|
|
27
|
+
env.taskDefs.push({
|
|
28
|
+
type: 'when',
|
|
29
|
+
a: [promiseName],
|
|
30
|
+
out: [p]
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
module.exports = react; // return react
|
package/react.js
CHANGED
|
@@ -6,7 +6,3 @@ module.exports = require('./lib/dsl.js'); // core + default dsl
|
|
|
6
6
|
module.exports.options = core.options; // global react options
|
|
7
7
|
module.exports.events = core.events; // global react event emitter
|
|
8
8
|
|
|
9
|
-
// additional interfaces
|
|
10
|
-
module.exports.fstrDefine = require('./lib/fstr.js');
|
|
11
|
-
module.exports.pcodeDefine = require('./lib/pcode.js');
|
|
12
|
-
module.exports.chainDefine = require('./lib/chain.js');
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
Test core PromiseTasks using Deferred - jquery style promises
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
var test = require('tap').test;
|
|
9
|
+
var Deferred = require('Deferred');
|
|
10
|
+
//var when = Deferred.when;
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
var react = require('../'); //require('react');
|
|
14
|
+
|
|
15
|
+
function multiply(x, y) {
|
|
16
|
+
var deferred = new Deferred();
|
|
17
|
+
setTimeout(function () {
|
|
18
|
+
deferred.resolve(x * y);
|
|
19
|
+
}, 10);
|
|
20
|
+
return deferred.promise();
|
|
21
|
+
}
|
|
22
|
+
function add(x, y) {
|
|
23
|
+
var deferred = new Deferred();
|
|
24
|
+
setTimeout(function () {
|
|
25
|
+
deferred.resolve(x + y);
|
|
26
|
+
}, 10);
|
|
27
|
+
return deferred.promise();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function badFunc(a, b) {
|
|
31
|
+
throw new Error('badFuncThrow');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function badF2(a, b) {
|
|
35
|
+
var deferred = new Deferred();
|
|
36
|
+
setTimeout(function () {
|
|
37
|
+
deferred.reject(new Error('my-error'));
|
|
38
|
+
}, 10);
|
|
39
|
+
return deferred.promise();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
test('multi-step', function (t) {
|
|
44
|
+
t.plan(4);
|
|
45
|
+
var fn = react();
|
|
46
|
+
var errors = fn.setAndValidateAST({
|
|
47
|
+
inParams: ['a', 'b'],
|
|
48
|
+
tasks: [
|
|
49
|
+
{ f: multiply, a: ['a', 'b'], out: ['c'], type: 'promise' },
|
|
50
|
+
{ f: add, a: ['c', 'b'], out: ['d'], type: 'promise' }
|
|
51
|
+
],
|
|
52
|
+
outTask: { a: ['c', 'd'] }
|
|
53
|
+
});
|
|
54
|
+
t.deepEqual(errors, [], 'no validation errors');
|
|
55
|
+
|
|
56
|
+
fn(2, 3, function (err, c, d) {
|
|
57
|
+
t.equal(err, null);
|
|
58
|
+
t.equal(c, 6);
|
|
59
|
+
t.equal(d, 9);
|
|
60
|
+
t.end();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('using "this" in a cb function', function (t) {
|
|
65
|
+
t.plan(3);
|
|
66
|
+
function getA(cb) {
|
|
67
|
+
/*jshint validthis: true */
|
|
68
|
+
var deferred = new Deferred();
|
|
69
|
+
var self = this;
|
|
70
|
+
setTimeout(function () {
|
|
71
|
+
deferred.resolve(self.a);
|
|
72
|
+
}, 10);
|
|
73
|
+
return deferred.promise();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
var fn = react();
|
|
77
|
+
var errors = fn.setAndValidateAST({
|
|
78
|
+
inParams: [],
|
|
79
|
+
tasks: [
|
|
80
|
+
{ f: getA, a: [], out: ['a'], type: 'promise' }
|
|
81
|
+
],
|
|
82
|
+
outTask: { a: ['a'] }
|
|
83
|
+
});
|
|
84
|
+
t.deepEqual(errors, [], 'no validation errors');
|
|
85
|
+
|
|
86
|
+
var obj = {
|
|
87
|
+
a: 100
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
fn.apply(obj, [function (err, a) {
|
|
91
|
+
t.equal(err, null);
|
|
92
|
+
t.equal(a, 100);
|
|
93
|
+
t.end();
|
|
94
|
+
}]);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
test('throws error', function (t) {
|
|
99
|
+
t.plan(2);
|
|
100
|
+
var fn = react();
|
|
101
|
+
var errors = fn.setAndValidateAST({
|
|
102
|
+
inParams: ['a', 'b'],
|
|
103
|
+
tasks: [
|
|
104
|
+
{ f: badFunc, a: ['a', 'b'], out: ['c'], type: 'promise' },
|
|
105
|
+
{ f: add, a: ['c', 'b'], out: ['d'], type: 'promise' }
|
|
106
|
+
],
|
|
107
|
+
outTask: { a: ['c', 'd'] }
|
|
108
|
+
});
|
|
109
|
+
t.deepEqual(errors, [], 'no validation errors');
|
|
110
|
+
|
|
111
|
+
fn(2, 3, function (err, c, d) {
|
|
112
|
+
t.equal(err.message, 'badFuncThrow');
|
|
113
|
+
t.end();
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('rejects with error', function (t) {
|
|
118
|
+
t.plan(2);
|
|
119
|
+
var fn = react();
|
|
120
|
+
var errors = fn.setAndValidateAST({
|
|
121
|
+
inParams: ['a', 'b'],
|
|
122
|
+
tasks: [
|
|
123
|
+
{ f: badF2, a: ['a', 'b'], out: ['c'], type: 'promise' },
|
|
124
|
+
{ f: add, a: ['c', 'b'], out: ['d'], type: 'promise' }
|
|
125
|
+
],
|
|
126
|
+
outTask: { a: ['c', 'd'] }
|
|
127
|
+
});
|
|
128
|
+
t.deepEqual(errors, [], 'no validation errors');
|
|
129
|
+
|
|
130
|
+
fn(2, 3, function (err, c, d) {
|
|
131
|
+
t.equal(err.message, 'my-error');
|
|
132
|
+
t.end();
|
|
133
|
+
});
|
|
134
|
+
});
|