Comparing version 0.1.3 to 0.1.4
var async = require('async'); | ||
var us = require('underscore'); | ||
var FlowError = require('./flowError'); | ||
var FlowTaskError = require('./flowTaskError'); | ||
@@ -34,9 +36,10 @@ module.exports = { | ||
var flowCall = function flowCall(taskArgs, taskName, tasks, data) { | ||
var fn; | ||
var args = []; | ||
var autoTask = []; | ||
var fn; //function to call within each async.auto task (does the work). | ||
var fnIndex; //index where fn was found. | ||
var args = []; //arguments to pass to each function during task execution | ||
var autoTask = []; //array value for each async.auto task | ||
if(typeof taskArgs == 'function') { | ||
fn = taskArgs; | ||
} else if(!Array.isArray(taskArgs)) throw new Error("Invalid flow type for \"" + taskName + "\". Must be function or array: " + taskArgs); | ||
} else if(!Array.isArray(taskArgs)) throw new FlowTaskError(taskName, "Invalid flow type. Must be function or array."); | ||
else { | ||
@@ -46,31 +49,40 @@ for(var i in taskArgs) { | ||
if(typeof taskArg == 'function') { | ||
if(fn) throw new Error("Flow task \"" + taskName + "\" has more than one function specified."); | ||
if(fn) throw new FlowTaskError(taskName, "More than one function specified (at index " + fnIndex + " and " + i + ")."); | ||
fn = taskArg; | ||
} else if(tasks.hasOwnProperty(taskArg) || data.hasOwnProperty(taskArg)) { | ||
fnIndex = i; | ||
} else if((tasks.hasOwnProperty(taskArg) || data.hasOwnProperty(taskArg)) && taskArg != taskName) { | ||
if(fn) args.push(taskArg); | ||
autoTask.push(taskArg); | ||
} else { | ||
if(fn) throw new Error("Flow task \"" + taskName + "\" has more than one function specified."); | ||
fn = { name: taskArg, receiver: taskArgs[i - 1] }; | ||
if(!fn.receiver) throw new Error("Flow task \"" + taskName + "\" marked for instance execution of function \"" + taskArg + "\", but no receiver was specified."); | ||
if(fn) throw new FlowTaskError(taskName, "More than one function specified (at index " + fnIndex + " and " + i + ")."); | ||
fn = { name: taskArg, receiverName: taskArgs[i - 1] }; | ||
fnIndex = i; | ||
if(!fn.receiverName) throw new FlowTaskError(taskName, "Unknown symbol at index '" + i + "' must be either the name of a task, the name of data, or be the name of a function on the result of a task or data"); | ||
} | ||
} | ||
if(!fn) throw new Error("Function required for flow call of \"" + taskName + "\"."); | ||
if(!fn) throw new FlowTaskError(taskName, "Function required."); | ||
} | ||
autoTask.push(function(cb, results){ | ||
var fnArgs = us.map(args, function(arg){ return results[arg]; }); | ||
var fnArgs = []; | ||
for(var i in args) { | ||
var arg = args[i]; | ||
fnArgs[i] = results[arg]; | ||
} | ||
fnArgs.push(cb); | ||
var receiver; | ||
if(typeof fn != 'function') { | ||
var receiverName = fn.receiverName; | ||
receiver = results[receiverName]; | ||
var fnName = fn.name; | ||
if(!receiver) throw new FlowTaskError(taskName, "Cannot call function '" + fn.name + "' on " + receiver); | ||
fn = receiver[fnName]; | ||
if(!fn) throw new FlowTaskError(taskName, "Unknown symbol '" + fnName + "' must be either the name of a task, the name of data, or the name of a function on '" + receiverName + "'"); | ||
} | ||
try { | ||
if(typeof fn == 'function') fn.apply(null, fnArgs); | ||
else { | ||
var receiver = results[fn.receiver] | ||
receiver[fn.name].apply(receiver, fnArgs); | ||
} | ||
fn.apply(receiver, fnArgs); | ||
} catch(e){ | ||
console.log('err') | ||
var err = new Error("Flow error in " + taskName); | ||
err.stack = err.stack + "\n" + e.stack; | ||
throw err; | ||
throw new FlowTaskError(taskName, "Error during execution of function.", e); | ||
} | ||
@@ -81,2 +93,1 @@ }); | ||
} | ||
@@ -6,3 +6,3 @@ { | ||
"author": "David Fenster <david@dfenster.com>", | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"repository": { | ||
@@ -9,0 +9,0 @@ "type": "git", |
@@ -20,2 +20,3 @@ var util = require('util'); | ||
BaseClass = function BaseClass(){}; | ||
BaseClass.getAll = function(cb){ return cb(null, this.all); } | ||
BaseClass.getByAttribute = function(attribute, value, cb){ | ||
@@ -45,2 +46,4 @@ var self = this; | ||
Genre.prototype.findBooksByAuthor = function(author, cb) { return Book.findByGenreAndAuthor(this, author, cb); } | ||
Genre.prototype.getBooks = function(cb){ return Book.findByGenreId(this.id, cb); } | ||
Genre.prototype.getGenre = function(cb){ return cb(null, this.id); } | ||
bindFunctions(Genre); | ||
@@ -51,2 +54,3 @@ | ||
Author.getByName = function(name, cb){ return this.getByAttribute('name', name, cb); }; | ||
Author.prototype.getBooks = function(cb){ return Book.findByAuthorId(this.id, cb); }; | ||
bindFunctions(Author); | ||
@@ -72,2 +76,3 @@ | ||
}; | ||
Book.prototype.getAuthor = function(cb){ return Author.getById(this.author_id, cb); } | ||
bindFunctions(Book); | ||
@@ -162,4 +167,17 @@ | ||
module.exports["flow task error"] = function(test){ | ||
module.exports["function as task"] = function(test){ | ||
flow({ | ||
}, { | ||
getAuthors: Author.getAll | ||
}, function(err, results){ | ||
test.ok(!err, "no error"); | ||
test.deepEqual(results, { | ||
getAuthors: Author.all | ||
}, 'results match'); | ||
test.done(); | ||
}); | ||
} | ||
module.exports["flow task callback with error"] = function(test){ | ||
flow({ | ||
authorName: 'Dan Brown', | ||
@@ -415,1 +433,231 @@ genreName: '???' | ||
} | ||
module.exports["task name same as instance method"] = function(test){ | ||
flow({ | ||
genreName: 'Fantasy' | ||
}, { | ||
getGenre: [Genre.getByName, 'genreName'], | ||
getBooks: ['getGenre', 'getBooks'] | ||
}, function(err, results){ | ||
test.ok(!err); | ||
test.deepEqual(results, { | ||
genreName: 'Fantasy', | ||
getGenre: Genre.all[1], | ||
getBooks: [Book.all[7], Book.all[8], Book.all[9], Book.all[10], Book.all[11]] | ||
}); | ||
test.done(); | ||
}); | ||
} | ||
module.exports["different task name same as instance method"] = function(test){ | ||
try { | ||
flow({ | ||
genreName: 'Fantasy' | ||
}, { | ||
getGenre: [Genre.getByName, 'genreName'], | ||
getBooksByGenre: ['getGenre', 'getBooks'], | ||
getBooks: ['getBooksByGenre', Book.findByGenreId, 'getGenre'] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getBooksByGenre': Function required.", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["undefined instance error"] = function(test){ | ||
try { | ||
flow({ | ||
genreName: 'Fictiony' | ||
}, { | ||
getGenre: [Genre.getByName, 'genreName'], | ||
getBooks: ['getGenre', 'getBooks'] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getBooks': Cannot call function 'getBooks' on undefined", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["multiple functions error"] = function(test){ | ||
try { | ||
flow({ | ||
bookId: 1 | ||
}, { | ||
getBook: [Book.getById, Book.getById, 'bookId'] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getBook': More than one function specified (at index 0 and 1).", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["multiple instance functions error"] = function(test){ | ||
try { | ||
flow({ | ||
bookId: 1 | ||
}, { | ||
getBook: [Book.getById, 'bookId'], | ||
getBookAuthor: ['getBook', 'getAuthor', 'getAuthor'] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getBookAuthor': More than one function specified (at index 1 and 2).", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["unknown symbol error"] = function(test){ | ||
try { | ||
flow({ | ||
bookId: 1 | ||
}, { | ||
getBook: [Book.getById, 'bookId'], | ||
getAuthor: ['getBook', 'notafunction'] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getAuthor': Unknown symbol 'notafunction' must be either the name of a task, the name of data, or the name of a function on 'getBook'", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["unknown symbol for first task argument"] = function(test){ | ||
try { | ||
flow({ | ||
bookId: 1 | ||
}, { | ||
getBook: [Book.getById, 'bookId'], | ||
getAuthor: ['notafunction'] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, 'FlowTaskError') | ||
test.equals(e.message, "Flow error in 'getAuthor': Unknown symbol at index '0' must be either the name of a task, the name of data, or be the name of a function on the result of a task or data", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["undefined task argument error"] = function(test){ | ||
try { | ||
flow({ | ||
bookId: 1 | ||
}, { | ||
getBook: [Book.getById, 'bookId'], | ||
getAuthor: [Book.getAuthorByBookId, 'getBook'] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getAuthor': Unknown symbol at index '0' must be either the name of a task, the name of data, or be the name of a function on the result of a task or data", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["missing task args error"] = function(test){ | ||
try { | ||
flow({ | ||
bookId: 1 | ||
}, { | ||
getBook: [Book.getById, 'bookId'], | ||
getAuthor: [] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getAuthor': Function required.", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["missing function in task args error"] = function(test){ | ||
try { | ||
flow({ | ||
bookId: 1 | ||
}, { | ||
getBook: [Book.getById, 'bookId'], | ||
getAuthor: ['getBook'] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getAuthor': Function required.", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["missing function in task args error"] = function(test){ | ||
try { | ||
flow({ | ||
bookId: 1 | ||
}, { | ||
getBook: [Book.getById, 'bookId'], | ||
getAuthor: 'getBook' | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getAuthor': Invalid flow type. Must be function or array.", "error message match") | ||
test.done(); | ||
} | ||
} | ||
module.exports["error in task function"] = function(test){ | ||
try { | ||
flow({ | ||
bookId: 1 | ||
}, { | ||
getBook: [Book.getById, 'bookId'], | ||
getAuthor: [Author.getById] | ||
}, function(err, results){ | ||
test.fail(null, null, "no error received"); | ||
test.done(); | ||
}); | ||
} catch(e) { | ||
test.ok(e, 'got an error'); | ||
test.equals(e.name, "FlowTaskError", "got FlowTaskError"); | ||
test.equals(e.message, "Flow error in 'getAuthor': Error during execution of function.", "error message match") | ||
test.ok(/TypeError: undefined is not a function/.test(e.stack)) | ||
test.done(); | ||
} | ||
} |
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
33589
7
712