Comparing version 0.2.2 to 0.2.3
@@ -28,3 +28,3 @@ 'use strict'; | ||
var TASKDEF_IS_OBJECT = 'task must be an object'; | ||
var NO_TASKS_RUNNING_WONT_COMPLETE = 'no tasks running, flow will not complete'; | ||
var NO_TASKS_RUNNING_WONT_COMPLETE = 'no tasks running, flow will not complete, remaining tasks: %s'; | ||
var TASK_TYPE_SHOULD_MATCH = 'task.type should match one of ' + | ||
@@ -205,3 +205,8 @@ Object.keys(TASK_TYPES).join(', '); | ||
}); | ||
if (!tasksRunning.length) handleError({}, new Error(NO_TASKS_RUNNING_WONT_COMPLETE)); | ||
if (!tasksRunning.length) { | ||
var remainingTasks = tasks.filter(function (t) { return (!t.status); }); | ||
var remainingTNames = remainingTasks.map(function (t) { return t.name; }); | ||
var errMsg = sprintf(NO_TASKS_RUNNING_WONT_COMPLETE, remainingTNames.join(', ')); | ||
handleError({}, new Error(errMsg)); | ||
} | ||
} | ||
@@ -208,0 +213,0 @@ |
@@ -14,5 +14,6 @@ 'use strict'; | ||
var DUP_OUTPUTS = 'multiple tasks output the same param, must be unique. param'; | ||
var MISSING_INPUTS = 'missing or mispelled variable referenced in flow definition: %s'; | ||
var validateInParams, validateTasks, validateOutTask, validateTaskNamesUnique; | ||
var validateLocals, validateOuputsUnique; | ||
var validateLocals, validateOuputsUnique, validateNoMissingNames; | ||
@@ -23,2 +24,6 @@ function format_error(errmsg, obj) { | ||
function isProp(str) { // true if is a property name (contains a dot) | ||
return (str.indexOf('.') !== -1); | ||
} | ||
/** | ||
@@ -42,2 +47,3 @@ validate the AST return Errors | ||
errors = errors.concat(tutil.validateLocalFunctions(ast.inParams, ast.tasks, ast.locals)); | ||
errors = errors.concat(validateNoMissingNames(ast)); | ||
} | ||
@@ -105,2 +111,44 @@ return errors; | ||
/** | ||
validate there are no missing or mispelled param names in any task inputs | ||
or the final task output | ||
@return array of errors, or empty array if none | ||
*/ | ||
function validateNoMissingNames(ast) { | ||
var errors = []; | ||
var names = {}; | ||
if (ast.locals) { | ||
names = Object.keys(ast.locals).reduce(function (accum, k) { // start with locals | ||
accum[k] = true; | ||
return accum; | ||
}, names); | ||
} | ||
ast.inParams.reduce(function (accum, p) { // add input params | ||
accum[p] = true; | ||
return accum; | ||
}, names); | ||
ast.tasks.reduce(function (accum, t) { // add task outputs | ||
return t.out.reduce(function (innerAccum, p) { | ||
innerAccum[p] = true; | ||
return innerAccum; | ||
}, accum); | ||
}, names); | ||
// now we have all possible provided vars, check task inputs are accounted for | ||
ast.tasks.reduce(function (accum, t) { // for all tasks | ||
return t.a.reduce(function (innerAccum, p) { // for all in params, except property | ||
if (!isProp(p) && !names[p]) innerAccum.push(sprintf(MISSING_INPUTS, p)); // add error if missing | ||
return innerAccum; | ||
}, accum); | ||
}, errors); | ||
// now check the final task outputs | ||
ast.outTask.a.reduce(function (accum, p) { // for final task out params | ||
if (!isProp(p) && !names[p]) accum.push(sprintf(MISSING_INPUTS, p)); // add error if missing | ||
return accum; | ||
}, errors); | ||
return errors; | ||
} | ||
module.exports = validate; |
{ | ||
"name": "react", | ||
"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.", | ||
"version": "0.2.2", | ||
"version": "0.2.3", | ||
"author": "Jeff Barczewski <jeff.barczewski@gmail.com>", | ||
@@ -6,0 +6,0 @@ "repository": { "type": "git", "url": "http://github.com/jeffbski/react.git" }, |
@@ -245,3 +245,3 @@ # React.js | ||
- 2012-01-10 - Create default DSL for react() | ||
- 2012-01-10 - Create default DSL for react(), create error for missing variables, list remaining tasks when flow won't complete | ||
- 2011-12-21 - Refactor from ground up with tests, changes to the interfaces | ||
@@ -248,0 +248,0 @@ - 2011-10-26 - React is in active development and interface may change frequently in these early stages. Current code is functional but does not perform validation yet. Additional interfaces are planned to make it easy to define flows in a variety of ways. Documentation and examples forthcoming. |
@@ -66,6 +66,7 @@ 'use strict'; | ||
var fn = chainDefine() | ||
.in('a', 'b') | ||
.out('c') | ||
.async(falpha).in('a', 'b').out('c') | ||
.end(); | ||
t.deepEqual(fn.ast.inParams, []); | ||
t.deepEqual(fn.ast.inParams, ['a', 'b']); | ||
t.deepEqual(fn.ast.tasks, [ | ||
@@ -81,7 +82,7 @@ { f: falpha, type: 'cb', a: ['a', 'b'], out: ['c'], name: 'falpha' } | ||
.out('err', 'c') | ||
.async(falpha).in('a', 'b').out('err', 'c') | ||
.async(falpha).in().out('err', 'c') | ||
.end(); | ||
t.deepEqual(fn.ast.inParams, []); | ||
t.deepEqual(fn.ast.tasks, [ | ||
{ f: falpha, type: 'cb', a: ['a', 'b'], out: ['c'], name: 'falpha' } | ||
{ f: falpha, type: 'cb', a: [], out: ['c'], name: 'falpha' } | ||
]); | ||
@@ -95,7 +96,7 @@ t.deepEqual(fn.ast.outTask, { a: ['c'], type: 'finalcb' }); | ||
.out('ERR', 'c') | ||
.async(falpha).in('a', 'b').out('ERR', 'c') | ||
.async(falpha).in().out('ERR', 'c') | ||
.end(); | ||
t.deepEqual(fn.ast.inParams, []); | ||
t.deepEqual(fn.ast.tasks, [ | ||
{ f: falpha, type: 'cb', a: ['a', 'b'], out: ['c'], name: 'falpha' } | ||
{ f: falpha, type: 'cb', a: [], out: ['c'], name: 'falpha' } | ||
]); | ||
@@ -102,0 +103,0 @@ t.deepEqual(fn.ast.outTask, { a: ['c'], type: 'finalcb' }); |
@@ -201,10 +201,11 @@ 'use strict'; | ||
{ f: multiply, a: ['a', 'b'], out: ['c.mult'] }, | ||
{ f: fnRetsSum, a: ['c.bad', 'b'], out: ['c.sum'], type: 'ret' } | ||
{ f: fnRetsSum, a: ['c.bad', 'b'], out: ['c.sum'], type: 'ret' }, | ||
{ f: add, a: ['c.sum', 'a'], out: ['d']} | ||
], | ||
outTask: { a: ['c.mult', 'c.sum', 'c'] } | ||
outTask: { a: ['c.mult', 'c.sum', 'd'] } | ||
}); | ||
t.deepEqual(errors, [], 'no validation errors'); | ||
fn(2, 3, { foo: 1 }, function (err, cmult, csum, c) { | ||
t.equal(err.message, 'no tasks running, flow will not complete'); | ||
fn(2, 3, { foo: 1 }, function (err, cmult, csum, d) { | ||
t.equal(err.message, 'no tasks running, flow will not complete, remaining tasks: fnRetsSum, add'); | ||
t.end(); | ||
@@ -211,0 +212,0 @@ }); |
@@ -58,7 +58,7 @@ 'use strict'; | ||
var r = react('myName', 'cb -> err, c', | ||
falpha, 'a, b, cb -> err, c' | ||
falpha, 'cb -> err, c' | ||
); | ||
t.deepEqual(r.ast.inParams, []); | ||
t.deepEqual(r.ast.tasks, [ | ||
{ f: falpha, a: ['a', 'b'], out: ['c'], type: 'cb', name: 'falpha'} | ||
{ f: falpha, a: [], out: ['c'], type: 'cb', name: 'falpha'} | ||
]); | ||
@@ -71,7 +71,7 @@ t.deepEqual(r.ast.outTask, { a: ['c'], type: 'finalcb' }); | ||
var r = react('myName', 'cb -> err, c', | ||
falpha, 'a, b, cb -> err, c' | ||
falpha, 'cb -> err, c' | ||
); | ||
t.deepEqual(r.ast.inParams, []); | ||
t.deepEqual(r.ast.tasks, [ | ||
{ f: falpha, a: ['a', 'b'], out: ['c'], type: 'cb', name: 'falpha'} | ||
{ f: falpha, a: [], out: ['c'], type: 'cb', name: 'falpha'} | ||
]); | ||
@@ -84,7 +84,7 @@ t.deepEqual(r.ast.outTask, { a: ['c'], type: 'finalcb' }); | ||
var r = react('myName', 'cb -> ERR, c', | ||
falpha, 'a, b, cb -> ERR, c' | ||
falpha, 'cb -> ERR, c' | ||
); | ||
t.deepEqual(r.ast.inParams, []); | ||
t.deepEqual(r.ast.tasks, [ | ||
{ f: falpha, a: ['a', 'b'], out: ['c'], type: 'cb', name: 'falpha'} | ||
{ f: falpha, a: [], out: ['c'], type: 'cb', name: 'falpha'} | ||
]); | ||
@@ -91,0 +91,0 @@ t.deepEqual(r.ast.outTask, { a: ['c'], type: 'finalcb' }); |
@@ -51,6 +51,6 @@ 'use strict'; | ||
test('single task, single out params', function (t) { | ||
var r = fstrDefine('', [ | ||
var r = fstrDefine('a, b', [ | ||
falpha, 'a, b -> err, c' | ||
], 'c'); | ||
t.deepEqual(r.ast.inParams, []); | ||
t.deepEqual(r.ast.inParams, ['a', 'b']); | ||
t.deepEqual(r.ast.tasks, [ | ||
@@ -64,6 +64,6 @@ { f: falpha, a: ['a', 'b'], out: ['c'], type: 'cb', name: 'falpha'} | ||
test('single task, err and out params', function (t) { | ||
var r = fstrDefine('', [ | ||
var r = fstrDefine('a, b', [ | ||
falpha, 'a, b -> err, c' | ||
], 'err, c'); | ||
t.deepEqual(r.ast.inParams, []); | ||
t.deepEqual(r.ast.inParams, ['a', 'b']); | ||
t.deepEqual(r.ast.tasks, [ | ||
@@ -77,6 +77,6 @@ { f: falpha, a: ['a', 'b'], out: ['c'], type: 'cb', name: 'falpha'} | ||
test('single task, ERR and out params', function (t) { | ||
var r = fstrDefine('', [ | ||
var r = fstrDefine('a, b', [ | ||
falpha, 'a, b -> ERR, c' | ||
], 'ERR, c'); | ||
t.deepEqual(r.ast.inParams, []); | ||
t.deepEqual(r.ast.inParams, ['a', 'b']); | ||
t.deepEqual(r.ast.tasks, [ | ||
@@ -83,0 +83,0 @@ { f: falpha, a: ['a', 'b'], out: ['c'], type: 'cb', name: 'falpha'} |
@@ -53,7 +53,7 @@ 'use strict'; | ||
var locals = { falpha: falpha }; | ||
var r = pcode('', [ | ||
var r = pcode('a, b', [ | ||
'c := falpha(a, b)', | ||
'cb(err, c)' | ||
], locals); | ||
t.deepEqual(r.ast.inParams, []); | ||
t.deepEqual(r.ast.inParams, ['a', 'b']); | ||
t.deepEqual(r.ast.tasks, [ | ||
@@ -68,7 +68,7 @@ { f: 'falpha', a: ['a', 'b'], out: ['c'], type: 'cb', name: 'falpha'} | ||
var locals = { falpha: falpha }; | ||
var r = pcode('', [ | ||
var r = pcode('a, b', [ | ||
'c := falpha(a, b)', | ||
'cb(err, c)' | ||
], locals); | ||
t.deepEqual(r.ast.inParams, []); | ||
t.deepEqual(r.ast.inParams, ['a', 'b']); | ||
t.deepEqual(r.ast.tasks, [ | ||
@@ -75,0 +75,0 @@ { f: 'falpha', a: ['a', 'b'], out: ['c'], type: 'cb', name: 'falpha'} |
@@ -213,3 +213,3 @@ 'use strict'; | ||
], | ||
outTask: { a: ['bar'] } | ||
outTask: { a: ['baz'] } | ||
}; | ||
@@ -219,2 +219,50 @@ var msg = 'multiple tasks output the same param, must be unique. param: c'; | ||
t.end(); | ||
}); | ||
test('missing or mispelled input variable', function (t) { | ||
var ast = { | ||
inParams: [], | ||
tasks: [ | ||
{ f: foo, a: [], out: [] }, | ||
{ f: bar, a: ['abc'], out: [] } | ||
], | ||
outTask: { a: [] } | ||
}; | ||
var msg = 'missing or mispelled variable referenced in flow definition: abc'; | ||
t.deepEqual(validate(ast), [msg]); | ||
t.end(); | ||
}); | ||
test('missing or mispelled input variables', function (t) { | ||
var ast = { | ||
inParams: ['aaa', 'bbb'], | ||
tasks: [ | ||
{ f: foo, a: ['aaa', 'cat'], out: ['ccc'] }, | ||
{ f: bar, a: ['abc', 'bbb', 'ccc'], out: [] } | ||
], | ||
outTask: { a: [] } | ||
}; | ||
var messages = [ | ||
'missing or mispelled variable referenced in flow definition: cat', | ||
'missing or mispelled variable referenced in flow definition: abc' | ||
]; | ||
t.deepEqual(validate(ast), messages); | ||
t.end(); | ||
}); | ||
test('missing or mispelled final output variables', function (t) { | ||
var ast = { | ||
inParams: ['aaa'], | ||
tasks: [ | ||
{ f: foo, a: ['aaa'], out: ['bbb'] }, | ||
{ f: bar, a: ['bbb'], out: ['ccc'] } | ||
], | ||
outTask: { a: ['ccc', 'ddd', 'eee'] } | ||
}; | ||
var messages = [ | ||
'missing or mispelled variable referenced in flow definition: ddd', | ||
'missing or mispelled variable referenced in flow definition: eee' | ||
]; | ||
t.deepEqual(validate(ast), messages); | ||
t.end(); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
224090
5294