Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

fnflow

Package Overview
Dependencies
Maintainers
1
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fnflow - npm Package Compare versions

Comparing version 0.1.13 to 0.2.0

lib/flowTask.js

219

lib/fnFlow.js

@@ -0,56 +1,66 @@

var util = require('util');
var async = require('async');
var us = require('underscore');
var errors = require('errors');
var FlowTaskError = require('./flowTaskError');
var FlowTaskArgumentNullError = require('./flowTaskArgumentNullError');
var Task = require('./flowTask').Task;
var AsyncTask = require('./flowTask').AsyncTask;
var SyncTask = require('./flowTask').SyncTask;
module.exports = {
flow: function flow(data, tasks, callback){
if(arguments.length == 2){
if(typeof tasks == 'function'){
callback = tasks;
tasks = data;
data = undefined;
}
} else if(arguments.length == 1){
var workflow = new Workflow(data, tasks, callback);
workflow.execute();
}
}
var Workflow = function Workflow(data, tasks, callback){
if(arguments.length == 2){
if(typeof tasks == 'function'){
callback = tasks;
tasks = data;
callback = undefined;
data = undefined;
}
} else if(arguments.length == 1){
tasks = data;
callback = undefined;
data = undefined;
}
flowExec(data, tasks, null, callback);
}
this.data = data;
this.tasks = tasks;
this.callback = callback || function(){};
}
var flowExec = function flowExec(data, tasks, contextName, callback) {
if (data instanceof Array) {
return async.map(data, function (dataItem, cb) {
var context;
if(contextName) context = dataItem[contextName]
flowGo(dataItem, tasks, context, function(err, results){
if(contextName) cb(err, us.pick(results, Object.keys(tasks)));
else cb(err, results);
})
}, callback);
} else {
Workflow.prototype.execute = function execute(contextName) {
var self = this;
self.contextName = contextName;
var exec = function(data, cb){
var context;
if(contextName) context = data[contextName];
return flowGo(data, tasks, context, function(err, results){
if(contextName) callback(err, us.pick(results, Object.keys(tasks)));
else callback(err, results);
var newTasks;
if(data) newTasks = us.object(Object.keys(data), us.map(Object.keys(data), function(key){ return function(cb){ cb(null, data[key]); } }))
if(context) us.extend(newTasks, us.object(Object.keys(context), us.map(Object.keys(context), function(key){ return function(cb){ cb(null, context[key]); } })));
if(self.tasks) us.extend(newTasks, us.object(Object.keys(self.tasks), us.map(Object.keys(self.tasks), function(taskName){
var taskPlan = self.interpretTask(taskName, data, context);
return self.executeTaskPlan(taskPlan, taskName);
} )));
return async.auto(newTasks, function(err, results){
if(contextName) cb(err, us.pick(results, Object.keys(self.tasks)));
else cb(err, results);
});
}
}
};
var flowGo = function flowGo(data, tasks, context, callback) {
var newTasks;
if(data) newTasks = us.object(Object.keys(data), us.map(Object.keys(data), function(key){ return function(cb){ cb(null, data[key]); } }))
if(context) us.extend(newTasks, us.object(Object.keys(context), us.map(Object.keys(context), function(key){ return function(cb){ cb(null, context[key]); } })));
if(tasks) us.extend(newTasks, us.object(Object.keys(tasks), us.map(Object.keys(tasks), function(key){
var taskPlan = interpretTask(tasks[key], key, tasks, data, context);
return flowCall(taskPlan, key);
} )));
return async.auto(newTasks, callback);
if (this.data instanceof Array) async.map(this.data, exec, this.callback);
else exec(this.data, this.callback);
}
var interpretTask = function interpretTask(taskArgs, taskName, tasks, data, context) {
Workflow.prototype.interpretTask = function interpretTask(taskName, data, context) {
var self = this;
var taskArgs = Array.isArray(self.tasks[taskName]) ? new AsyncTask(self.tasks[taskName]) : self.tasks[taskName];
this.tasks[taskName] = taskArgs;
var tasks = self.tasks;
var fn; //function to call within each async.auto task (does the work).

@@ -60,10 +70,11 @@ var fnIndex; //index where fn was found.

var autoTask = []; //array value for each async.auto task
var task = taskArgs instanceof Task ? taskArgs : null;
var interpretSubFlow = function(subFlow){
if(fn) throw new FlowTaskError(taskName, "A task may have a SubFlow (index " + i + ") or a function call (index " + i + "), but not both. " + fnIndex + " and " + i + ").");
if(Array.isArray(taskArgs) && i < taskArgs.length - 1) throw new FlowTaskError(taskName, "SubFlows must be the at the last index.");
if(taskArgs instanceof Task && i < taskArgs.task_array.length - 1) throw new FlowTaskError(taskName, "SubFlows must be at the last index.");
if(!tasks.hasOwnProperty(subFlow.dataName) && (!data || !data.hasOwnProperty(subFlow.dataName)) || subFlow.dataName == taskName) throw new FlowTaskError(taskName, "SubFlow data '" + subFlow.dataName + "' does not exist. Provide the name of a task or data from the parent flow. Possible values include: " + Object.keys(tasks).concat(Object.keys(data)).filter(function(name){ return name != taskName }).join(', '));
fn = { receiverName: subFlow.dataName, tasks: subFlow.tasks };
var prereqs = scanForPrereqs(subFlow.tasks, us.extend({}, data, tasks));
autoTask.push(subFlow.dataName);
autoTask.push(subFlow.dataName);
autoTask = autoTask.concat(Object.keys(prereqs));

@@ -76,5 +87,10 @@ }

fn = taskArgs;
} else if(Array.isArray(taskArgs)) {
for(var i in taskArgs) {
var taskArg = taskArgs[i];
} else if(task) {
task.name = taskName;
task.workflow = self;
task.task_requirements = [];
task.data_requirements = [];
// task.context_requirements = [];
for(var i in task.task_array) {
var taskArg = task.task_array[i];
if(typeof taskArg == 'function') {

@@ -90,15 +106,15 @@ if(fn) throw new FlowTaskError(taskName, "More than one function specified (at index " + fnIndex + " and " + i + ").");

taskArg = taskArgParts[0];
if((tasks.hasOwnProperty(taskArg) || data && data.hasOwnProperty(taskArg) || context && context.hasOwnProperty(taskArg) && typeof context[taskArg] != 'function') && taskArg != taskName) {
if(fn) args.push(taskArgParts);
var auto_task_type = tasks.hasOwnProperty(taskArg) && 'task' || data && data.hasOwnProperty(taskArg) && 'data' || context && context.hasOwnProperty(taskArg) && typeof context[taskArg] != 'function' && 'context';
if(taskArg == taskName) auto_task_type = null;
if(auto_task_type) {
if(fn) args.push(taskArgParts); //there's already a fn, so assume that 'foo.bar.baz' must be a parameter to fn.
else if(taskArgParts.length > 1) {
fn = { name: taskArgParts.pop(), receiverName: taskArgParts };
fn = { name: taskArgParts.pop(), receiverName: taskArgParts }; //there's no fn yet, so assume that 'foo.bar.baz' means baz must be a function to execute on foo.bar
fnIndex = i;
}
if(auto_task_type == 'task') task.task_requirements.push(taskArg);
else if(auto_task_type == 'data' || auto_task_type == 'context') task.data_requirements.push(taskArg);
//else if(auto_task_type == 'context') task.context_requirements.push(taskArg);
autoTask.push(taskArg);
} else if(fn) throw new FlowTaskError(taskName, "More than one function specified (at index " + fnIndex + " and " + i + ").");
else if(taskArgParts.length > 1 || !taskArgs[i - 1]) 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");
else {
fn = { name: taskArg, receiverName: taskArgs[i - 1] };
fnIndex = i;
}
} else throw new FlowTaskError(taskName, "Unknown string '" + taskArg + "' must be either the name of a task or the name of data");
} else 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");

@@ -108,12 +124,14 @@ }

} else {
throw new FlowTaskError(taskName, "Invalid flow type. Must be function, or array.");
throw new FlowTaskError(taskName, "Invalid flow type. Must be function, subFlow, or array.");
}
return { fn: fn, args: args, autoTask: autoTask };
return { fn: fn, args: args, autoTask: autoTask, task: task, isSync: (task instanceof SyncTask) };
}
var flowCall = function flowCall(taskPlan, taskName) {
Workflow.prototype.executeTaskPlan = function executeTaskPlan(taskPlan, taskName){
var self = this;
var fn = taskPlan.fn;
var args = taskPlan.args;
var autoTask = taskPlan.autoTask;
var task = taskPlan.task;

@@ -135,26 +153,46 @@ if(typeof fn == 'object' && fn.tasks) { //subflows

}
flowExec(newData, fn.tasks, fn.receiverName, cb);
var sub_workflow = new Workflow(newData, fn.tasks, cb);
sub_workflow.parent = self;
sub_workflow.execute(fn.receiverName);
});
} else {
autoTask.push(function(cb, results){
var fnArgs = [];
for(var i in args) {
var arg = args[i];
if(Array.isArray(arg)) {
var result = results;
for(var j in arg) {
if(result === undefined) return cb(new FlowTaskArgumentNullError(taskName, arg[j-1], arg[j]));
result = result[arg[j]];
}
fnArgs[i] = result;
} else fnArgs[i] = results[arg];
autoTask.push(function(callback, results){
var cb = function(err, result){
if(err && err.name == "ArgumentNullError" && self.tasks[err.argumentName]) err.message = "Not Found: " + self.tasks[err.argumentName].toString(results)
if(err) return callback(err);
if(arguments.length > 2) result = Array.prototype.slice.call(arguments, 1);
if(task) return Task.complete.call(task, result, results, callback);
else callback(null, result);
};
var fnArgs;
try {
//we will generate the list of args to apply to the fn.
fnArgs = args.map(function(arg){
return evalMessages(results, arg, taskName);
});
} catch(e) {
if(e.name == "FlowTaskArgumentNullError") {
e = new errors.ArgumentNull(e.argumentName);
e.message = "Not Found: " + self.tasks[taskName].toString(results, e.argumentName);
}
return callback(e);
}
fnArgs.push(cb);
if(!taskPlan.isSync) fnArgs.push(cb);
var receiver;
if(typeof fn != 'function') {
var fnName = fn.name;
var receiverName = fn.receiverName;
receiver = results[receiverName];
var fnName = fn.name;
if(!receiver) return cb(new FlowTaskArgumentNullError(taskName, receiverName, fnName));
try {
receiver = evalMessages(results, receiverName, taskName);
} catch(e) {
if(e.name == "FlowTaskArgumentNullError") e.message = "Not Found: " + self.tasks[taskName].toString(results, e.argumentName);
return callback(e);
}
if(!receiver) {
var err = new errors.ArgumentNull(receiverName.join('.'));
if(self.tasks[receiverName[0]]) err.message = "Not Found: " + self.tasks[receiverName[0]].toString(results, err.argumentName);
return callback(err)
}
fn = receiver[fnName];

@@ -165,3 +203,4 @@ 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 {
fn.apply(receiver, fnArgs);
var return_value = fn.apply(receiver, fnArgs);
if(taskPlan.isSync) cb(null, return_value);
} catch(e){

@@ -176,2 +215,17 @@ throw new FlowTaskError(taskName, "Error during execution of function.", e);

var evalMessages = function evalMessages(receiver, messages, taskName){
if(Array.isArray(messages)) {
for(var i in messages) {
if(receiver === undefined) {
var receiverName = messages.slice(1,i).join('.');
var err = new FlowTaskArgumentNullError(taskName, messages[i-1], messages[i]);
err.argumentName = receiverName;
throw err;
}
receiver = receiver[messages[i]];
}
return receiver;
} else return receiver[messages];
}
var scanForPrereqs = function scanForPrereqs(tasks, allTasks) {

@@ -183,5 +237,5 @@ var prereqs = {};

us.extend(prereqs, scanForPrereqs(taskArgs.tasks, us.extend({}, allTasks, tasks)));
} else if(Array.isArray(taskArgs)){
for(var i in taskArgs) {
var taskArg = taskArgs[i];
} else if(taskArgs instanceof Task){
for(var i in taskArgs.task_array) {
var taskArg = taskArgs.task_array[i];
if(taskArg instanceof SubFlow) {

@@ -210,5 +264,20 @@ us.extend(prereqs, scanForPrereqs(taskArg.tasks, us.extend({}, allTasks, tasks)));

if(!tasks) throw new Error("SubFlow error: No tasks given for subFlow.");
if(typeof tasks == 'object') {
for(var name in tasks) if(Array.isArray(tasks[name])) tasks[name] = new AsyncTask(tasks[name]);
}
};
module.exports.flow.subFlow = function(dataName, tasks) {
return new SubFlow(dataName, tasks);
};
};
module.exports.flow.asyncTask = function(task_array) {
if(!(task_array instanceof Array)) task_array = us.values(arguments);
return new AsyncTask(task_array);
}
module.exports.flow.syncTask = function(task_array) {
if(!(task_array instanceof Array)) task_array = us.values(arguments);
return new SyncTask(task_array);
}

@@ -6,3 +6,3 @@ {

"author": "David Fenster <david@dfenster.com>",
"version": "0.1.13",
"version": "0.2.0",
"repository": {

@@ -9,0 +9,0 @@ "type": "git",

@@ -1,5 +0,10 @@

var util = require('util');
var flow = require('../lib/fnFlow').flow;
var us = require('underscore');
var test_data = require('../support/test-data');
Book = test_data.Book;
Author = test_data.Author;
Genre = test_data.Genre;
BookSeries = test_data.BookSeries;
module.exports.setUp = function(cb){

@@ -12,104 +17,2 @@ cb();

var bindFunctions = function(C){
for(var name in C){
var fn = C[name];
if(typeof fn == 'function') C[name] = fn.bind(C);
}
}
BaseClass = function BaseClass(){};
BaseClass.getAll = function(cb){ return cb(null, this.all); }
BaseClass.getByAttribute = function(attribute, value, cb){
var self = this;
var o = self.all[us.find(Object.keys(self.all), function(id){ return self.all[id][attribute] == value; })];
return cb(null, o);
}
BaseClass.findByAttribute = function(attribute, value, cb){
var self = this;
value = value && value.id || value;
var results = us.map(us.filter(Object.keys(self.all), function(id){ return self.all[id][attribute] == value; }), function(o){ return self.all[o]; });
return cb(null, results);
}
BaseClass.getById = function(id, cb){
id = id && id.id || id;
return cb(null, this.all[id]);
}
BaseClass.assertExistence = function(object, cb){
if(!object) return cb(new Error(this.name + " did not exist"));
return cb(null, true);
};
Genre = us.extend(function Genre(){}, BaseClass);
util.inherits(Genre, BaseClass);
Genre.getByName = function(name, cb){ return this.getByAttribute('name', name, cb); };
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);
Author = us.extend(function Author(){}, BaseClass);
util.inherits(Author, BaseClass);
Author.getByName = function(name, cb){ return this.getByAttribute('name', name, cb); };
Author.prototype.getBooks = function(cb){ return Book.findByAuthorId(this.id, cb); };
bindFunctions(Author);
BookSeries = us.extend(function BookSeries(){}, BaseClass);
util.inherits(BookSeries, BaseClass);
BookSeries.getByName = function(name, cb){ return this.getByAttribute('name', name, cb); };
BookSeries.findByAuthorId = function(authorId, cb){ return BookSeries.findByAttribute('authorId', authorId, cb); };
bindFunctions(BookSeries);
Book = us.extend(function Book(){}, BaseClass);
util.inherits(Book, BaseClass);
Book.getByTitle = function(title, cb){ return Book.getByAttribute('title', title, cb); };
Book.findBySeriesId = function(seriesId, cb){ return Book.findByAttribute('bookSeriesId', seriesId, cb); };
Book.findByAuthorId = function(authorId, cb){ return Book.findByAttribute('authorId', authorId, cb); };
Book.findByGenreId = function(genreId, cb){ return Book.findByAttribute('genreId', genreId, cb); };
Book.findByGenreAndAuthor = function(genreId, authorId, cb){
genreId = genreId && genreId.id || genreId;
authorId = authorId && authorId.id || authorId;
if(genreId == 5) return cb(new Error("this was a test"));
cb(null, us.where(Book.all, {genreId: genreId, authorId: authorId}));
};
Book.prototype.getAuthor = function(cb){ return Author.getById(this.authorId, cb); }
bindFunctions(Book);
Genre.all = {
1: us.extend(new Genre(), {id: 1, name: "Fantasy", book_ids: [7,8,9,10,11]}),
2: us.extend(new Genre(), {id: 2, name: "Romance"}),
3: us.extend(new Genre(), {id: 3, name: "Fiction"}),
4: us.extend(new Genre(), {id: 4, name: "Sports"}),
5: us.extend(new Genre(), {id: 5, name: "???"})
}
Author.all = {
1: us.extend(new Author(), {id: 1, name: "Patricia Briggs"}),
2: us.extend(new Author(), {id: 2, name: "Clive Cussler"}),
3: us.extend(new Author(), {id: 3, name: "Tom Coughlin"}),
4: us.extend(new Author(), {id: 4, name: "Dan Brown"}),
5: us.extend(new Author(), {id: 5, name: "Robert Jordan"}),
6: us.extend(new Author(), {id: 6, name: "Barbara Hambly"})
}
BookSeries.all = {
1: us.extend(new BookSeries(), {id: 1, name: "Mercy Thompson", authorId: 1}),
2: us.extend(new BookSeries(), {id: 2, name: "The Wheel of Time", authorId: 5}),
3: us.extend(new BookSeries(), {id: 3, name: "Sun-Cross", authorId: 6})
}
Book.all = {
1: us.extend(new Book(), {id: 1, title: "Frost Burned", authorId: 1, bookSeriesId: 1, genreId: 2}),
2: us.extend(new Book(), {id: 2, title: "Moon Called", authorId: 1, bookSeriesId: 1, genreId: 2}),
3: us.extend(new Book(), {id: 3, title: "River Marked", authorId: 1, bookSeriesId: 1, genreId: 2}),
4: us.extend(new Book(), {id: 4, title: "The Striker", authorId: 2, genreId: 3}),
5: us.extend(new Book(), {id: 5, title: "Earn the Right to Win", authorId: 3, genreId: 4}),
6: us.extend(new Book(), {id: 6, title: "Inferno", authorId: 4, genreId: 3}),
7: us.extend(new Book(), {id: 7, title: "The Rainbow Abyss", authorId: 6, bookSeriesId: 3, genreId: 1}),
8: us.extend(new Book(), {id: 8, title: "The Magicians of Night", authorId: 6, bookSeriesId: 3, genreId: 1}),
9: us.extend(new Book(), {id: 9, title: "The Eye of the World", authorId: 5, bookSeriesId: 2, genreId: 1}),
10: us.extend(new Book(), {id: 10, title: "The Gathering Storm", authorId: 5, bookSeriesId: 2, genreId: 1}),
11: us.extend(new Book(), {id: 11, title: "The Towers of Midnight", authorId: 5, bookSeriesId: 2, genreId: 1})
}
module.exports["flow data"] = function(test){

@@ -199,3 +102,3 @@ flow({

getGenre: [Genre.getByName, 'genreName'],
getBooks: ['getGenre', 'findBooksByAuthor', 'getAuthor']
getBooks: ['getGenre.findBooksByAuthor', 'getAuthor']
}, function(err, results){

@@ -270,3 +173,3 @@ test.ok(!err);

assertGenreExistence: [Genre.assertExistence, 'getGenre'],
getBooks: ['assertGenreExistence', 'getGenre', 'findBooksByAuthor', 'getAuthor']
getBooks: ['assertGenreExistence', 'getGenre.findBooksByAuthor', 'getAuthor']
}, function(err, results){

@@ -295,3 +198,3 @@ test.ok(!err);

assertGenreExistence: [Genre.assertExistence, 'getGenre'],
getBooks: ['assertGenreExistence', 'getGenre', 'findBooksByAuthor', 'getAuthor']
getBooks: ['assertGenreExistence', 'getGenre.findBooksByAuthor', 'getAuthor']
}, function(err, results){

@@ -311,25 +214,38 @@ test.ok(err);

module.exports["instance task execution with dot notation parameter"] = function(test){
module.exports["multiple instance parameter"] = function(test){
flow({
authorName: 'Dan Brown',
genreName: 'Fiction'
page: {
number: 1,
chapter: {
number: 2,
book: Book.all[5]
}
}
}, {
getAuthor: [Author.getByName, 'authorName'],
getGenre: [Genre.getByName, 'genreName'],
getBooks: ['getGenre', 'findBooksByAuthor', 'getAuthor.id']
getGenre: [Genre.getById, 'page.chapter.book.genreId']
}, function(err, results){
test.ok(!err);
test.deepEqual(results, {
authorName: 'Dan Brown',
genreName: 'Fiction',
getAuthor: Author.all[4],
getGenre: Genre.all[3],
getBooks: [Book.all[6]]
});
test.deepEqual(results.getGenre, Genre.all[4]);
test.done();
});
});
}
module.exports["instance task execution with dot notation function"] = function(test){
module.exports["result multi instance function"] = function(test){
flow({
page: {
number: 1,
chapter: {
number: 2,
book: Book.all[5]
}
}
}, {
getAuthor: ['page.chapter.book.getAuthor']
}, function(err, results){
test.deepEqual(results.getAuthor, Author.all[3]);
test.done();
});
}
module.exports["instance task execution with result instance parameter"] = function(test){
flow({
authorName: 'Dan Brown',

@@ -340,3 +256,3 @@ genreName: 'Fiction'

getGenre: [Genre.getByName, 'genreName'],
getBooks: ['getGenre.findBooksByAuthor', 'getAuthor']
getBooks: ['getGenre.findBooksByAuthor', 'getAuthor.id']
}, function(err, results){

@@ -355,18 +271,2 @@ test.ok(!err);

module.exports["instance task execution with undefined dot notation function"] = function(test){
flow({
authorName: 'Dan Brown',
genreName: 'Superfiction'
}, {
getAuthor: [Author.getByName, 'authorName'],
getGenre: [Genre.getByName, 'genreName'],
getBooks: ['getGenre.findBooksByAuthor', 'getAuthor']
}, function(err, results){
test.ok(err);
test.equals(err.message, 'Flow error in \'getBooks\': Cannot call function \'findBooksByAuthor\' on null/undefined \'getGenre\'')
test.done();
});
}
module.exports["multiple asyncronus tasks with prerequisite task execution"] = function(test){

@@ -444,3 +344,3 @@ flow( [

assertGenreExistence: [Genre.assertExistence, 'getGenre'],
getBooks: ['assertGenreExistence', 'getGenre', 'findBooksByAuthor', 'getAuthor']
getBooks: ['assertGenreExistence', 'getGenre.findBooksByAuthor', 'getAuthor']
}, function(err, results){

@@ -479,3 +379,3 @@ test.ok(!err);

assertGenreExistence: [Genre.assertExistence, 'getGenre'],
getBooks: ['assertGenreExistence', 'getGenre', 'findBooksByAuthor', 'getAuthor']
getBooks: ['assertGenreExistence', 'getGenre.findBooksByAuthor', 'getAuthor']
}, function(err, results){

@@ -502,3 +402,3 @@ test.ok(err);

getGenre: [Genre.getByName, 'genreName'],
getBooks: ['getGenre', 'getBooks']
getBooks: ['getGenre.getBooks']
}, function(err, results){

@@ -515,33 +415,26 @@ test.ok(!err);

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) {
module.exports["undefined instance error"] = function(test){
flow({
genreName: 'Fictiony'
}, {
getGenre: [Genre.getByName, 'genreName'],
getBooks: ['getGenre.getBooks']
}, function(e, results){
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.equals(e.name, "ArgumentNullError", "got proper error");
test.equals(e.message, 'Not Found: "getGenre" with genreName "Fictiony"')
test.done();
}
});
}
module.exports["undefined instance error"] = function(test){
module.exports["undefined instance error 2"] = function(test){
flow({
genreName: 'Fictiony'
genreName: 'Fiction'
}, {
getGenre: [Genre.getByName, 'genreName'],
getBooks: ['getGenre', 'getBooks']
getBooks: [Book.findByGenreId, 'getGenre.id.undef_value.err']
}, function(e, results){
test.ok(e, 'got an error');
test.equals(e.name, "FlowTaskArgumentNullError", "got FlowTaskError");
test.equals(e.message, "Flow error in 'getBooks': Cannot call function 'getBooks' on null/undefined 'getGenre'", "error message match")
test.equals(e.name, "ArgumentNullError", "got proper error");
test.equals(e.message, 'Not Found: "id.undef_value" for getGenre with genreName "Fiction"')
test.done();

@@ -569,20 +462,20 @@ });

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["multiple instance functions error"] = function(test){
// try {
// flow({
// bookId: 1
// }, {
// getBook: [Book.getById, 'bookId'],
// getBookAuthor: ['getBook.getAuthor', 'getBook.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();
// }
// }

@@ -595,3 +488,3 @@ module.exports["unknown symbol error"] = function(test){

getBook: [Book.getById, 'bookId'],
getAuthor: ['getBook', 'notafunction']
getAuthor: ['getBook.notafunction']
}, function(err, results){

@@ -623,3 +516,3 @@ test.fail(null, null, "no error received");

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.equals(e.message, "Flow error in 'getAuthor': Unknown string 'notafunction' must be either the name of a task or the name of data", "error message match")
test.done();

@@ -687,3 +580,3 @@ }

module.exports["missing function in task args error"] = function(test){
module.exports["invalid flow type task"] = function(test){
try {

@@ -702,3 +595,3 @@ flow({

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.equals(e.message, "Flow error in 'getAuthor': Invalid flow type. Must be function, subFlow, or array.", "error message match")
test.done();

@@ -730,3 +623,3 @@ }

module.exports["array result data execution"] = function(test){
module.exports["subFlow execution"] = function(test){
flow({

@@ -736,5 +629,5 @@ genreName: 'Fantasy'

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('getBooksByGenre', {
getBookAuthor: ['getBooksByGenre', 'getAuthor']
getBookAuthor: ['getBooksByGenre.getAuthor']
})

@@ -764,3 +657,3 @@ }, function(err, results){

module.exports["array result data execution with context"] = function(test){
module.exports["subFlow execution with context"] = function(test){
flow({

@@ -770,3 +663,3 @@ genreName: 'Fantasy'

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('getBooksByGenre', {

@@ -798,3 +691,3 @@ getBookAuthor: [Author.getById, 'authorId']

module.exports["array result data execution using subFlow"] = function(test){
module.exports["subFlow execution using subFlow"] = function(test){
flow({

@@ -804,5 +697,5 @@ genreName: 'Fantasy'

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('getBooksByGenre', {
getBookAuthor: ['getBooksByGenre', 'getAuthor']
getBookAuthor: ['getBooksByGenre.getAuthor']
})

@@ -833,3 +726,3 @@ }, function(err, results){

module.exports["array result data execution with prereqs using subFlow"] = function(test){
module.exports["subFlow execution with prereqs"] = function(test){
flow({

@@ -840,3 +733,3 @@ genreName: 'Fantasy',

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('getBooksByGenre', {

@@ -877,5 +770,5 @@ getHambly2: [Author.getById, 'getHambly']

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('getBooksByGenre', {
getBookAuthor: ['getBooksByGenre', 'getAuthor'],
getBookAuthor: ['getBooksByGenre.getAuthor'],
getBooksByAuthor: [Book.findByAuthorId, 'getBookAuthor'],

@@ -947,3 +840,3 @@ getManyHamblies: flow.subFlow('getBooksByAuthor', {

module.exports["subflow with prereqs and dot notation"] = function(test){
module.exports["subflow with prereqs and result instance parameter"] = function(test){
flow({

@@ -954,3 +847,3 @@ genreName: 'Fantasy',

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('getBooksByGenre', {

@@ -990,5 +883,5 @@ getHambly2: [Author.getById, 'getHambly.id']

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('', {
getBookAuthor: ['getBooksByGenre', 'getAuthor']
getBookAuthor: ['getBooksByGenre.getAuthor']
})

@@ -1013,3 +906,3 @@ }, function(err, results){

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('getBooksByGenre', null)

@@ -1035,5 +928,5 @@ }, function(err, results){

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('asdf', {
getBookAuthor: ['getBooksByGenre', 'getAuthor']
getBookAuthor: ['getBooksByGenre.getAuthor']
})

@@ -1058,5 +951,5 @@ }, function(err, results){

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('getAuthors', {
getBookAuthor: ['getBooksByGenre', 'getAuthor']
getBookAuthor: ['getBooksByGenre.getAuthor']
})

@@ -1082,3 +975,3 @@ }, function(err, results){

assertGenreExistence: [Genre.assertExistence, 'getGenre'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: ['assertGenreExistence', flow.subFlow('getBooksByGenre', {

@@ -1117,3 +1010,3 @@ getBookAuthor: [Author.getById, 'authorId']

assertGenreExistence: [Genre.assertExistence, 'getGenre'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: [flow.subFlow('getBooksByGenre', {

@@ -1129,3 +1022,3 @@ getBookAuthor: [Author.getById, 'authorId']

test.equals(e.name, "FlowTaskError", "got Error");
test.equals(e.message, "Flow error in 'getAuthors': SubFlows must be the at the last index.", "error message match")
test.equals(e.message, "Flow error in 'getAuthors': SubFlows must be at the last index.", "error message match")
test.done();

@@ -1143,3 +1036,3 @@ }

assertGenreExistence: [Genre.assertExistence, 'getGenre'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: ['assertGenreExistence', flow.subFlow('asdf', {

@@ -1168,3 +1061,3 @@ getBookAuthor: [Author.getById, 'authorId']

assertGenreExistence: [Genre.assertExistence, 'getGenre'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: ['assertGenreExistence', flow.subFlow('getAuthors', {

@@ -1230,3 +1123,3 @@ getBookAuthor: [Author.getById, 'authorId']

module.exports["subflow with dot notation for parameter"] = function(test){
module.exports["subflow with result instance parameter"] = function(test){
flow({

@@ -1236,3 +1129,3 @@ genreName: 'Fantasy'

getGenre: [Genre.getByName, 'genreName'],
getBooksByGenre: ['getGenre', 'getBooks'],
getBooksByGenre: ['getGenre.getBooks'],
getAuthors: flow.subFlow('getBooksByGenre', {

@@ -1263,3 +1156,75 @@ getBookAuthor: [Author.getById, 'getBooksByGenre.authorId']

module.exports["asynchronous task execution"] = function(test){
flow({
id: 3,
}, {
getBook: flow.asyncTask(Book.getById, 'id'),
getAuthor: flow.asyncTask(Author.getById, 'getBook.authorId'),
}, function(err, results){
test.deepEqual({
id: 3,
getBook: Book.all[3],
getAuthor: Author.all[1],
}, results);
test.done();
});
}
module.exports["asynchronous task execution with array"] = function(test){
flow({
id: 3,
}, {
getBook: flow.asyncTask([Book.getById, 'id']),
getAuthor: flow.asyncTask([Author.getById, 'getBook.authorId']),
}, function(err, results){
test.deepEqual({
id: 3,
getBook: Book.all[3],
getAuthor: Author.all[1],
}, results);
test.done();
});
}
module.exports["synchronous task execution"] = function(test){
flow({
id: 3,
new_object: {}
}, {
getBook: [Book.getById, 'id'],
getAuthor: [Author.getById, 'getBook.authorId'],
getBookAuthorData: flow.syncTask(us.extend, 'new_object', 'getBook', 'getAuthor')
}, function(err, results){
test.deepEqual({
id: 3,
new_object: us.extend({}, Book.all[3], Author.all[1]),
getBook: Book.all[3],
getAuthor: Author.all[1],
getBookAuthorData: us.extend({}, Book.all[3], Author.all[1])
}, results);
test.done();
});
}
module.exports["synchronous task execution with array"] = function(test){
flow({
id: 3,
new_object: {}
}, {
getBook: [Book.getById, 'id'],
getAuthor: [Author.getById, 'getBook.authorId'],
getBookAuthorData: flow.syncTask([us.extend, 'new_object', 'getBook', 'getAuthor'])
}, function(err, results){
test.deepEqual({
id: 3,
new_object: us.extend({}, Book.all[3], Author.all[1]),
getBook: Book.all[3],
getAuthor: Author.all[1],
getBookAuthorData: us.extend({}, Book.all[3], Author.all[1])
}, results);
test.done();
});
}
// module.exports["array result data execution"] = function(test){

@@ -1299,1 +1264,8 @@ // var authors, fantasyAuthors;

// flow({
// some_data: 2,
// some_value: '3.2',
// }, {
// test1: flow.asyncTask([Class.doSomething, 'some_data']),
// test3: flow.syncTask([parseInt, 'some_value'])
// })
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc