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

apw

Package Overview
Dependencies
Maintainers
3
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

apw - npm Package Compare versions

Comparing version 0.2.0 to 0.2.1

27

lib/apw.js
var INHERIT = require('inherit');
module.exports = INHERIT({
module.exports = INHERIT(/** @lends APW.prototype */ {

@@ -8,11 +8,9 @@ /**

*
* @constructor
* @class APW
* @constructs
* @param {Arch} arch The Arch to work with.
* @param {number} [maxWorkers] Maximum number of workers to run in one time.
* @param {object} [ctx] The hash to mix with default context in node 'run' function.
* @param {Number} [maxWorkers] Maximum number of workers to run simultaneously.
* @param {Object} [ctx] The hash to mix with default context in node 'run' function.
*/
__constructor: function(arch /*, maxWorkers, ctx*/) {
var maxWorkers = arguments[1],
ctx = arguments[2];
__constructor: function(arch, maxWorkers, ctx) {
this.arch = arch;

@@ -33,4 +31,4 @@

*
* @param {string[]|string} targets IDs (or ID) of jobs to process.
* @returns {promise} Promise of this process.
* @param {String[]|String} targets IDs (or ID) of jobs to process.
* @returns {Promise * Undefined} Promise of this process to complete.
*/

@@ -41,9 +39,16 @@ process: function(targets) {

}, {
}, /** @lends APW */ {
/** @type COA.api */
api: require('./coa').api,
/** @type Arch */
Arch: require('./arch'),
/** @type Plan */
Plan: require('./plan'),
/** @type Workers */
Workers: require('./workers')
});

@@ -5,8 +5,7 @@ var Q = require('qq'),

Plan = require('./plan'),
util = require('./util'),
arraySlice = Array.prototype.slice,
U = require('./util'),
nodeIDSequence = 1;
arraySlice = Array.prototype.slice;
module.exports = INHERIT({
module.exports = INHERIT(/** @lends Arch.prototype */ {

@@ -16,3 +15,4 @@ /**

*
* @constructor
* @class Arch
* @constructs
*/

@@ -73,3 +73,3 @@ __constructor: function() {

* @param {Object} context Call context.
* @returns {promise} The result of Q.when().fin().
* @returns {Promise}.
*/

@@ -86,45 +86,138 @@ withLock: function(cb, context) {

/**
* Add new node.
* If id argument is absent, autogenerated ID will be used.
* Return node by ID.
* If there is no such node, return default node.
*
* @param {String} [id] Node ID.
* @param {Object} node Node to add.
* @param {String[]|String} [parents] Parent node IDs to link with.
* @param {String[]|String} [children] Child node IDs to link with.
* @returns {String} Node ID.
* @param {String} id Node id
* @returns {Object} Node object
*/
setNode: function(id, node, parents, children) {
if (id && typeof id !== 'string') {
children = parents;
parents = node;
node = id;
id = null;
}
if (!id) id = (node.getId && node.getId())? node.getId() : nodeIDSequence++;
getNode: function(id) {
return this.hasNode(id)? this.nodes[id] : this.getDefaultNode(id);
},
this._assertNode('setNode call', id, parents, children);
/**
* Create and return default node with specified ID.
*
* Returned node does not belong to this Arch.
* It will return rejected promise on run() call.
*
* @param {String} id ID of node to create.
* @returns {Object} Default node object
*/
getDefaultNode: function(id) {
return {
getId: function() {
return id;
},
run: function() {
return Q.reject("** No rule to make target '" + id + "'");
}
};
},
/**
* Add new node to arch.
*
* @param {Object} node Node to add
* @param {String[]|String} [parents] Node parents to link with
* @param {String[]|String} [children] Node children to link with
* @throws AssertionError In case of there is node with same id in the arch already
* @return {Arch} Chainable API.
*/
addNode: function(node, parents, children) {
ASSERT.ok(!this.hasNode(node));
var id = node.getId();
this._assertNode('addNode call', id, parents, children);
this.nodes[id] = node;
// TODO: seems like copy-paste between parents and childs
// Proposal: add private method for both link types management
if (!this.parents[id] || (parents && parents !== true)) this.parents[id] = [];
if (parents && parents !== true) {
this.link([id], parents);
// NOTE: we are letting here premature linking with
// not already existant nodes
this.parents[id] = this.parents[id] || [];
this.children[id] = this.children[id] || [];
parents && this.link([id], parents);
children && this.link(children, [id]);
return this;
},
/**
* Add new node or replace existing node having same id with specified.
*
* If node exists and parents and children arguments are not specified
* then links with other nodes will left unchanged.
*
* @param {Object} node Node to add or replace
* @param {String[]|String} [parents] Node parents to link with
* @param {String[]|String} [children] Node children to link with
* @return {Arch} Chainable API.
*/
setNode: function(node, parents, children) {
return this.hasNode(node)
? this.replaceNode(node, parents, children)
: this.addNode(node, parents, children);
},
/**
* Replace existing node in arch with specified.
*
* @param {Object} node Node to add or replace
* @param {String[]|String} [parents] Node parents to link with
* @param {String[]|String} [children] Node children to link with
* @throws AssertionError In case of there is no node with same id in the arch
* @return {Arch} Chainable API.
*/
replaceNode: function(node, parents, children) {
ASSERT.ok(this.hasNode(node));
var id = node.getId();
if (parents || children) {
this.removeNode(id);
return this.addNode(node, parents, children);
}
if (!this.children[id] || (children && children !== true)) this.children[id] = [];
if (children && children !== true) {
this.link(children, [id]);
this.nodes[id] = node;
return this;
},
/**
* Remove node from arch.
*
* @param {String|Object} id Node to remove (ID or node object with getId())
* @returns {Arch} Chainable API.
*/
removeNode: function(id) {
id = U.getNodeId(id);
U.removeNode(this.children, this.parents, id);
delete this.nodes[id];
for (var k in this.plans) {
var p = this.plans[k];
if (p.hasNode(id)) p.removeNode(id);
}
return id;
return this;
},
/**
* Check if node exists in this arch.
*
* @param {String|Object} id Node to check (ID or node object with getId()).
* @returns {Boolean} True if exists, otherwise false.
*/
hasNode: function(id) {
return !!this.nodes[U.getNodeId(id)];
},
/**
* Assert simple loops for node.
*
* @param {String} [id] Node ID.
* @param {String[]|String} [parents] Parent node IDs to link with.
* @param {String[]|String} [children] Child node IDs to link with.
* @param {String} id Node ID.
* @param {String[]|String} [parents] Parent nodes IDs to link with.
* @param {String[]|String} [children] Children nodes IDs to link with.
*/

@@ -135,4 +228,4 @@ _assertNode: function(place, id, parents, children) {

if (children === true) children = [];
parents = util.toArray(parents);
children = util.toArray(children);
parents = U.toArray(parents);
children = U.toArray(children);
ASSERT.ok(parents.indexOf(id) === -1, 'found loop in ' + place + ': id = ' + id + ', parents = ' + parents);

@@ -146,33 +239,10 @@ ASSERT.ok(children.indexOf(id) === -1, 'found loop in ' + place + ': id = ' + id + ', children = ' + children);

/**
* Replace node 'body'.
*
* @param {String} id ID of node to replace.
* @param {Object} node New node.
* @returns {String} Node ID.
*/
replaceNode: function(id, node) {
var args = arraySlice.call(arguments);
args = (args.length < 2? [null] : []).concat(args, [true, true]);
return this.setNode.apply(this, args);
},
/**
* Check if node with such ID exists in this arch.
*
* @param {String} id Node ID to check.
* @returns {boolean} True if exists, otherwise false.
*/
hasNode: function(id) {
return !!this.nodes[id];
},
/**
* Check if node with such ID has parents with provided IDs.
*
* @param {String} id Child node ID to check.
* @param {String|String[]} parents Parent IDs to check.
* @returns {boolean} True if all IDs are parent for this child, otherwise false.
* @param {String|Object} id Node to check (ID or node object).
* @param {String|String[]} parents IDs of parents to check.
* @returns {Boolean} True if all IDs are parent for this child, otherwise false.
*/
hasParents: function(id, parents) {
return util.hasLink(id, this, 'parents', parents);
return U.hasLink(U.getNodeId(id), this, 'parents', parents);
},

@@ -183,58 +253,50 @@

*
* @param {String} id Parent node ID to check.
* @param {String|Object} id Node to check (ID or node object).
* @param {String|String[]} children Child IDs to check.
* @returns {boolean} True if all IDs are children for this parent, otherwise false.
* @returns {Boolean} True if all IDs are children for this parent, otherwise false.
*/
hasChildren: function(id, children) {
return util.hasLink(id, this, 'children', children);
return U.hasLink(U.getNodeId(id), this, 'children', children);
},
/**
* Return node by ID.
* If there are no such node, return default node.
* Return node children IDs.
*
* @param {String} id Node id
* @returns {Object} Node object
* @param {String|Object} id Node (ID or node object).
* @returns {Array} Children IDs.
*/
getNode: function(id) {
return this.hasNode(id)? this.nodes[id] : this.getDefaultNode(id);
getChildren: function(id) {
return [].concat(this.children[U.getNodeId(id)] || []);
},
/**
* Create and return stub node for ID.
* NB: it is not belongs to this Arch, just utility function.
* Return node parent IDs.
*
* @param {String} id ID of node to create.
* @returns {Object} Object with .getId() and .run() inside.
* @param {String|Object} id Node (ID or node object).
* @returns {Array} Parent IDs.
*/
getDefaultNode: function(id) {
return {
getId: function() {
return id;
},
run: function() {
return Q.reject("** No rule to make target '" + id + "'");
}
};
getParents: function(id) {
return [].concat(this.parents[U.getNodeId(id)] || []);
},
/**
* Return node children IDs.
* Link specified children to node.
*
* @param {String} id Node ID.
* @returns {String[]} Children IDs.
* @param {String|Object} id Node (ID or node object).
* @param {String[]|String} children Children nodes IDs.
* @return {Arch}
*/
getChildren: function(id) {
return [].concat(this.children[id] || []);
addChildren: function(id, children) {
return this.link(children, U.getNodeId(id));
},
/**
* Return node parent IDs.
* Link specified parents to node.
*
* @param {String} id Node ID.
* @returns {String[]} Parent IDs.
* @param {String|Object} id Node (ID or node object).
* @param {String[]|String} parents Parents nodes IDs.
* @return {Arch}
*/
getParents: function(id) {
return [].concat(this.parents[id] || []);
addParents: function(id, parents) {
return this.link(U.getNodeId(id), parents);
},

@@ -250,4 +312,4 @@

link: function(children, parents) {
parents = util.toArray(parents);
util.toArray(children).forEach(function(child) {
parents = U.toArray(parents);
U.toArray(children).forEach(function(child) {
this._link(child, parents);

@@ -266,2 +328,4 @@ }, this);

_link: function(child, parents) {
child = U.getNodeId(child);
var _parents = this.parents[child],

@@ -271,2 +335,4 @@ children;

parents.forEach(function(parent) {
parent = U.getNodeId(parent);
if (this.hasParents(child, parent)) return;

@@ -294,4 +360,4 @@

unlink: function(id1, id2) {
util.unlink(this.parents[id1], this.children[id1], id2);
util.unlink(this.parents[id2], this.children[id2], id1);
U.unlink(this.parents[id1], this.children[id1], id2);
U.unlink(this.parents[id2], this.children[id2], id1);

@@ -312,3 +378,3 @@ for (var k in this.plans) {

* @param {String} id Tree root node ID.
* @param {boolean} forced Remove child nodes with links to other parents too.
* @param {Boolean} forced Remove child nodes with links to other parents too.
* @returns {Arch} Chainable API.

@@ -341,26 +407,7 @@ */

/**
* Remove node from arch.
*
* @param {String} id Node ID to remove.
* @returns {Arch} Chainable API.
*/
removeNode: function(id) {
util.removeNode(this.children, this.parents, id);
delete this.nodes[id];
for (var k in this.plans) {
var p = this.plans[k];
if (p.hasNode(id)) p.removeNode(id);
}
return this;
},
/**
* Create plan instance from this arch.
* Targets are (is) node IDs to run. If you have A -> B -> C arch and it is needed to build 'A', you target is 'A'.
*
* @param {Array|String} targets Node IDs to build.
* @returns {Plan} Created plan.
* @param {String[]|String} targets Node IDs to build.
* @returns {Plan} Newly created plan.
*/

@@ -406,3 +453,3 @@ createPlan: function(targets) {

/**
* Dump this arch to Graphviz string for debug purposes.
* Dump this arch to string in Graphviz format for debug purposes.
*

@@ -423,2 +470,3 @@ * @returns {String} Graphviz string representation of this arch.

* @param {String} spaces Left indent spaces.
* @returns {String} String representation of specified node.
*/

@@ -435,5 +483,6 @@ nodeToString: function(id, spaces) {

/**
* Dump node with its children to Graphviz string.
* Dump node with its children to string in Graphviz format.
*
* @param {String} id Node ID to dump.
* @returns {String} Graphviz string representation of specified node.
*/

@@ -440,0 +489,0 @@ nodeToGraphviz: function(id, done) {

@@ -7,3 +7,3 @@ var INHERIT = require('inherit'),

module.exports = INHERIT(EventEmitter, {
module.exports = INHERIT(EventEmitter, /** @lends Plan.prototype */ {

@@ -13,3 +13,4 @@ /**

*
* @constructor
* @class Plan
* @constructs
* @param {Arch} arch Arch from this plan created.

@@ -626,19 +627,1 @@ * @param {String[]|String} targets Root node IDs to build.

});
/**
* Convert array to object.
*
* @param {Array} a Array to convert.
* @returns {Object} Converted array.
*/
function arrayToObject(a) {
var o = {},
n = 0;
for (var i = 0; i < a.length; i++) {
if (!o[a[i]]) n++;
o[a[i]] = 1;
}
return o;
}

@@ -10,2 +10,30 @@ /**

/**
* Convert array to object.
*
* @param {Array} a Array to convert.
* @returns {Object} Converted array.
*/
exports.arrayToObject = function(a) {
var o = {},
n = 0;
for (var i = 0; i < a.length; i++) {
if (!o[a[i]]) n++;
o[a[i]] = 1;
}
return o;
};
/**
* Returns node ID.
*
* @param id {String|Object} Node ID or object.
* @return {String} Node ID.
*/
exports.getNodeId = function(id) {
return typeof id == 'string'? id : id.getId();
};
/**
* Unlink node from parents and children.

@@ -12,0 +40,0 @@ *

@@ -5,10 +5,11 @@ var Q = require('qq'),

module.exports = INHERIT({
module.exports = INHERIT(/** @lends Workers.prototype */ {
/**
* Creates an instance of Plan.
* Creates an instance of Workers.
*
* @constructor
* @param {number} [maxWorkers] Maximum number of workers to run in one time.
* @param {object} [ctx] The hash to mix with default context in node 'run' function.
* @class Workers
* @constructs
* @param {Number} [maxWorkers] Maximum number of workers to run simultaneously.
* @param {Object} [ctx] The hash to mix with default context in node 'run' function.
*/

@@ -29,2 +30,15 @@ __constructor: function(maxWorkers, ctx) {

this.defers = {};
var _this = this;
process.once('exit', function() {
if (Object.keys(_this.plans).length) {
console.error('WARNING! There are %s unfinished build processes!', Object.keys(_this.plans).length);
console.error(
'This application exit is not planned. Please check',
'that all nodes in arch resolve or reject promises',
'they return.');
}
});
},

@@ -36,3 +50,3 @@

* @param {Plan} plan Plan to start.
* @returns {promise} Promise of this start.
* @returns {Promise * Undefined} Promise of this start.
*/

@@ -49,12 +63,12 @@ start: function(plan) {

/**
* Create Q.defer for plan ID.
* Create deffered for the plan ID.
*
* @param {String} id Plan ID to defer.
* @returns {defer} Defer of this plan ID.
* @param {Boolean} [remove=false] Remove defer from registry just before return
* @returns {Q.Defer} Defer of this plan ID.
*/
getDefer: function(id) {
if (!this.defers[id]) {
this.defers[id] = Q.defer();
}
return this.defers[id];
getDefer: function(id, remove) {
var defer = this.defers[id] || (this.defers[id] = Q.defer());
remove && delete this.defers[id];
return defer;
},

@@ -178,3 +192,11 @@

workPlan: function(job, plan) {
var _this = this;
var _this = this,
onDone = function() {
_this.activeWorkers--;
_this.onJobFinished(job.id);
_this.next();
},
onError = function(err) {
_this.onJobFinished(job.id, err);
};

@@ -184,12 +206,3 @@ this.activeWorkers++;

this.work(job, plan)
.then(function() {
_this.activeWorkers--;
_this.onJobFinished(job.id);
_this.next();
})
.fail(function(err) {
_this.onJobFinished(job.id, err);
})
.then(onDone, onError)
.end();

@@ -224,3 +237,3 @@

defer = this.getDefer(plan.getId());
defer = this.getDefer(plan.getId(), true);
err? defer.reject(err) : defer.resolve();

@@ -238,3 +251,3 @@ }

* @param {Plan} plan Plan from which this job is.
* @returns {Q.call} The result of Q.call.
* @returns {Promise} The result of Q.call.
*/

@@ -263,3 +276,3 @@ work: function(job, plan) {

* @param {String} planID Listener plan ID.
* @returns {boolean} Was it new listener or not.
* @returns {Boolean} Was it new listener or not.
*/

@@ -266,0 +279,0 @@ addFinishListener: function(jobID, planID) {

{
"name": "apw",
"version": "0.2.0",
"version": "0.2.1",
"homepage": "http://github.com/bem/apw",

@@ -5,0 +5,0 @@ "author": "Sergey Kryzhanovsky <skryzhanovsky@ya.ru> (http://github.com/afelix)",

@@ -6,2 +6,16 @@ var VOWS = require('vows'),

function createNode(id) {
return {
getId: function() {
return id;
},
run: function() {
return 'test' + id;
}
};
}
function getEmptyArch() {

@@ -12,8 +26,47 @@ return new APW.Arch();

function getSimpleArch() {
var arch = getEmptyArch();
/*
A
|
B
*/
return getEmptyArch()
.addNode(createNode('A'))
.addNode(createNode('B'), 'A');
}
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testB' }, 'A');
function getArch1() {
/*
A
/ \
B C
\ /
D
*/
return getEmptyArch()
.addNode(createNode('A'))
.addNode(createNode('B'), 'A')
.addNode(createNode('C'), 'A')
.addNode(createNode('D'), ['B', 'C']);
}
return arch;
function getArch2() {
/*
A
/ \
B D
| |
C E
\ /
F
|
G
*/
return getEmptyArch()
.addNode(createNode('A'))
.addNode(createNode('B'), 'A')
.addNode(createNode('D'), 'A')
.addNode(createNode('C'), 'B')
.addNode(createNode('E'), 'D')
.addNode(createNode('F'), ['C', 'E'])
.addNode(createNode('G'), 'F');
}

@@ -23,48 +76,100 @@

.addBatch({
'Node set / get': {
'Arch getters': {
topic: getSimpleArch,
'children': function(arch) {
assert.lengthOf(arch.children['A'], 1);
assert.equal(arch.children['A'][0], 'B');
assert.lengthOf(arch.children['B'], 0);
},
'parents': function(arch) {
assert.lengthOf(arch.parents['B'], 1);
assert.equal(arch.parents['B'][0], 'A');
assert.lengthOf(arch.parents['A'], 0);
},
'getNode() A': function(arch) {
var node = arch.getNode('A');
assert.equal(node.run, 'testA');
assert.equal(arch.getNode('A').run(), 'testA');
},
'getNode() default': function(arch) {
var node = arch.getNode('XXX');
assert.equal(node.getId(), 'XXX');
assert.equal(arch.getNode('XXX').getId(), 'XXX');
},
'getChildren() A': function(arch) {
var children = arch.getChildren('A');
assert.lengthOf(children, 1);
assert.equal(children[0], 'B');
assert.equal(children.pop(), 'B');
},
'getParents() B': function(arch) {
var parents = arch.getParents('B');
assert.lengthOf(parents, 1);
assert.equal(parents[0], 'A');
assert.equal(parents.pop(), 'A');
}
},
'Arch.addNode()': {
topic: getSimpleArch,
'new': function(arch) {
arch.addNode(createNode('new'), 'A', 'B');
assert.ok(arch.hasNode('new'));
assert.equal(arch.getChildren('new'), 'B');
assert.equal(arch.getParents('new'), 'A');
},
'already existent throws': function(arch) {
assert.throws(function() {
arch.addNode(createNode('A'));
});
}
},
'Arch.setNode()': {
topic: getArch1,
'new': function(arch) {
arch.setNode(createNode('new'), 'A', 'D');
assert.ok(arch.hasNode('new'));
assert.equal(arch.getParents('new'), 'A');
assert.equal(arch.getChildren('new'), 'D');
},
'already existent': function(arch) {
var replaceNode = 'D';
arch.setNode({
getId: function() {
return replaceNode;
},
run: function() {
return 'new ' + replaceNode;
}
}, 'A', 'B');
assert.ok(arch.hasNode(replaceNode));
assert.equal(arch.getNode(replaceNode).run(), 'new ' + replaceNode);
assert.equal(arch.getParents(replaceNode), 'A');
assert.equal(arch.getChildren(replaceNode), 'B');
}
},
'Arch.replaceNode()': {
topic: getArch1,
'new throws': function(arch) {
assert.throws(function() {
arch.replaceNode(createNode('new'));
});
},
'already existent': function(arch) {
var replaceNode = 'D';
arch.replaceNode({
getId: function() {
return replaceNode;
},
run: function() {
return 'new ' + replaceNode;
}
}, 'A', 'B');
assert.ok(arch.hasNode(replaceNode));
assert.equal(arch.getNode(replaceNode).run(), 'new ' + replaceNode);
assert.equal(arch.getParents(replaceNode), 'A');
assert.equal(arch.getChildren(replaceNode), 'B');
}
},
'Node availability check': {
topic: function() {
var arch = getEmptyArch();
arch.setNode('A1', { run: 'testA1' });
arch.setNode('A2', { run: 'testA2' });
arch.setNode('B', { run: 'testB' }, 'A1');
arch.setNode('C', { run: 'testC' }, ['A1', 'A2']);
return arch;
return getEmptyArch()
.addNode(createNode('A1'))
.addNode(createNode('A2'))
.addNode(createNode('B'), 'A1')
.addNode(createNode('C'), ['A1', 'A2']);
},

@@ -140,10 +245,7 @@ 'hasNode() A1': function(arch) {

topic: function() {
var arch = getEmptyArch();
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testA' });
arch.link('B', 'A');
arch.link('B', 'A');
return arch;
return getEmptyArch()
.addNode(createNode('A'))
.addNode(createNode('B'))
.link('B', 'A')
.link('B', 'A');
},

@@ -160,3 +262,3 @@ 'link() B -> A': function(arch) {

assert.equal(parents[0], 'A');
}
}
},

@@ -166,10 +268,5 @@

topic: function() {
var arch = getEmptyArch();
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testB' }, 'A');
arch.unlink('B', 'A');
arch.unlink('B', 'A');
return arch;
return getSimpleArch()
.unlink('B', 'A')
.unlink('B', 'A');
},

@@ -184,12 +281,3 @@ 'unlink() B - A': function(arch) {

topic: function() {
var arch = getEmptyArch();
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testB' }, 'A');
arch.setNode('C', { run: 'testC' }, 'A');
arch.setNode('D', { run: 'testD' }, ['B', 'C']);
arch.removeTree('C');
return arch;
return getArch1().removeTree('C');
},

@@ -206,12 +294,3 @@ 'removeTree() C unforced': function(arch) {

topic: function() {
var arch = getEmptyArch();
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testB' }, 'A');
arch.setNode('C', { run: 'testC' }, 'A');
arch.setNode('D', { run: 'testD' }, ['B', 'C']);
arch.removeTree('C', true);
return arch;
return getArch1().removeTree('C', true);
},

@@ -229,15 +308,3 @@ 'removeTree() C forced': function(arch) {

topic: function() {
var arch = getEmptyArch();
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testB' }, 'A');
arch.setNode('D', { run: 'testD' }, 'A');
arch.setNode('C', { run: 'testC' }, 'B');
arch.setNode('E', { run: 'testE' }, 'D');
arch.setNode('F', { run: 'testF' }, ['C', 'E']);
arch.setNode('G', { run: 'testG' }, 'F');
arch.removeTree('D');
return arch;
return getArch2().removeTree('D');
},

@@ -256,15 +323,3 @@ 'removeTree() D unforced': function(arch) {

topic: function() {
var arch = getEmptyArch();
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testB' }, 'A');
arch.setNode('D', { run: 'testD' }, 'A');
arch.setNode('C', { run: 'testC' }, 'B');
arch.setNode('E', { run: 'testE' }, 'D');
arch.setNode('F', { run: 'testF' }, ['C', 'E']);
arch.setNode('G', { run: 'testG' }, 'F');
arch.removeTree('D', true);
return arch;
return getArch2().removeTree('D', true);
},

@@ -284,11 +339,5 @@ 'removeTree() D forced': function(arch) {

topic: function() {
var arch = getEmptyArch();
var arch = getArch1(),
plan = arch.createPlan('A');
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testB' }, 'A');
arch.setNode('C', { run: 'testC' }, 'A');
arch.setNode('D', { run: 'testD' }, ['B', 'C']);
var plan = arch.createPlan('A');
arch.removeTree('C');

@@ -295,0 +344,0 @@

@@ -6,2 +6,16 @@ var VOWS = require('vows'),

function createNode(id) {
return {
getId: function() {
return id;
},
run: function() {
return 'test' + id;
}
};
}
function getEmptyArch() {

@@ -12,9 +26,6 @@ return new APW.Arch();

function getSimpleArch() {
var arch = getEmptyArch();
arch.setNode('A', { run: function() {} });
arch.setNode('B', { run: function() {} }, 'A');
arch.setNode('C', { run: function() {} }, 'B');
return arch;
return getEmptyArch()
.addNode(createNode('A'))
.addNode(createNode('B'), 'A')
.addNode(createNode('C'), 'B');
}

@@ -71,11 +82,10 @@

topic: function() {
var arch = getEmptyArch();
var arch = getEmptyArch()
.addNode(createNode('A'))
.addNode(createNode('B'), 'A')
.addNode(createNode('C'), 'A')
.addNode(createNode('D'), ['B', 'C']),
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testB' }, 'A');
arch.setNode('C', { run: 'testC' }, 'A');
arch.setNode('D', { run: 'testD' }, ['B', 'C']);
plan = arch.createPlan('A');
var plan = arch.createPlan('A');
arch.removeTree('C');

@@ -95,11 +105,10 @@

topic: function() {
var arch = getEmptyArch();
var arch = getEmptyArch()
.addNode(createNode('A'))
.addNode(createNode('B'), 'A')
.addNode(createNode('C'), 'A')
.addNode(createNode('D'), ['B', 'C']),
arch.setNode('A', { run: 'testA' });
arch.setNode('B', { run: 'testB' }, 'A');
arch.setNode('C', { run: 'testC' }, 'A');
arch.setNode('D', { run: 'testD' }, ['B', 'C']);
plan = arch.createPlan('A');
var plan = arch.createPlan('A');
arch.removeTree('C', true);

@@ -140,2 +149,2 @@

suite.export(module);
suite.export(module);

@@ -8,78 +8,110 @@ var Q = require('qq'),

function getArch(state) {
var arch = new APW.Arch();
var createNode = function(id) {
return {
arch.setNode('0A', { run: function() { state.push('0A') } });
arch.setNode('1A', { run: function() { state.push('1A') } });
arch.setNode('1B', { run: function() { state.push('1B') } }, '1A');
arch.setNode('2A', { run: function() { state.push('2A') } });
arch.setNode('2B', {
run: function(ctx) {
state.push('2B');
ctx.arch.setNode('2C', { run: function() { state.push('2C') } }, '2A');
ctx.arch.setNode('2D', { run: function() { state.push('2D') } }, '2A');
}
}, '2A');
getId: function() {
return id;
},
arch.setNode('3A', { run: function() { state.push('3A') } });
arch.setNode('3B', {
run: function(ctx) {
state.push('3B');
return ctx.arch.withLock(function() {
ctx.arch.setNode('3C', { run: function() { state.push('3C') } }, '3A');
ctx.arch.setNode('3D', { run: function() { state.push('3D') } }, '3A');
});
}
}, '3A');
run: function() {
state.push(id);
}
arch.setNode('4A', { run: function() { state.push('4A') } });
arch.setNode('4B', {
run: function(ctx) {
ctx.plan.on('allDone', function(id) {
state.push('4B');
});
}
}, '4A');
};
};
arch.setNode('5A', {
run: function(ctx) {
state.push(ctx.plan);
}
});
arch.setNode('5B', {
run: function(ctx) {
ctx.plan.lock();
ctx.plan.link('5D', '5C');
ctx.plan.unlock();
}
}, '5A');
arch.setNode('5C', { run: function() {} }, '5B');
arch.setNode('5D', { run: function() {} }, '5C');
return new APW.Arch()
.addNode(createNode('0A'))
arch.setNode('6A', {
run: function(ctx) {
state.push(ctx.plan);
}
});
arch.setNode('6B', { run: function() {} }, '6A');
arch.setNode('6C', { run: function() {} }, '6A');
arch.setNode('6D', { run: function() {} }, '6B');
arch.setNode('6E', {
run: function(ctx) {
ctx.plan.lock();
ctx.plan.link('6C', '6B');
ctx.plan.unlock();
}
}, ['6B', '6C']);
arch.setNode('6F', { run: function() {} }, '6D');
arch.setNode('6G', { run: function() {} }, '6D');
arch.setNode('6H', { run: function() {} }, '6E');
arch.setNode('6I', { run: function() {} }, '6H');
.addNode(createNode('1A'))
.addNode(createNode('1B'), '1A')
arch.setNode('7A', { run: function() { state.push('7A') } });
arch.setNode('7B', { run: function() { state.push('7B') } }, '7A');
arch.setNode('7C', { run: function() { state.push('7C') } }, '7B');
.addNode(createNode('2A'))
.addNode({
getId: function() {
return '2B';
},
run: function(ctx) {
state.push('2B');
ctx.arch.addNode(createNode('2C'), '2A');
ctx.arch.addNode(createNode('2D'), '2A');
}
}, '2A')
return arch;
.addNode(createNode('3A'))
.addNode({
getId: function() {
return '3B';
},
run: function(ctx) {
state.push('3B');
return ctx.arch.withLock(function() {
ctx.arch.addNode(createNode('3C'), '3A');
ctx.arch.addNode(createNode('3D'), '3A');
});
}
}, '3A')
.addNode(createNode('4A'))
.addNode({
getId: function() {
return '4B';
},
run: function(ctx) {
ctx.plan.on('allDone', function(id) {
state.push('4B');
});
}
}, '4A')
.addNode({
getId: function() {
return '5A';
},
run: function(ctx) {
state.push(ctx.plan);
}
})
.addNode({
getId: function() {
return '5B';
},
run: function(ctx) {
ctx.plan.lock();
ctx.plan.link('5D', '5C');
ctx.plan.unlock();
}
}, '5A')
.addNode(createNode('5C'), '5B')
.addNode(createNode('5D'), '5C')
.addNode({
getId: function() {
return '6A';
},
run: function(ctx) {
state.push(ctx.plan);
}
})
.addNode(createNode('6B'), '6A')
.addNode(createNode('6C'), '6A')
.addNode(createNode('6D'), '6B')
.addNode({
getId: function() {
return '6E';
},
run: function(ctx) {
ctx.plan.lock();
ctx.plan.link('6C', '6B');
ctx.plan.unlock();
}
}, ['6B', '6C'])
.addNode(createNode('6F'), '6D')
.addNode(createNode('6G'), '6D')
.addNode(createNode('6H'), '6E')
.addNode(createNode('6I'), '6H')
.addNode(createNode('7A'))
.addNode(createNode('7B'), '7A')
.addNode(createNode('7C'), '7B');
}

@@ -101,3 +133,3 @@

function(error) { _this.callback(error, null) }
)
).end();
},

@@ -119,3 +151,3 @@ 'correct run': function(error, state) {

function(error) { _this.callback(error, null) }
)
).end();
},

@@ -138,3 +170,3 @@ 'correct run order': function(error, state) {

function(error) { _this.callback(error, null) }
)
).end();
},

@@ -159,3 +191,3 @@ 'correct plan update on-the-fly': function(error, state) {

function(error) { _this.callback(error, null) }
)
).end();
},

@@ -180,6 +212,6 @@ 'correct plan update on-the-fly': function(error, state) {

function(error) { _this.callback(error, null) }
)
).end();
},
'there are no double done jobs': function(error, state) {
var plan = state[0];
var plan = state.pop();
assert.isNull(error);

@@ -207,7 +239,6 @@ assert.lengthOf(plan.doneJobs, 4);

function(error) { _this.callback(error, null) }
)
).end();
},
'test': function(error, state) {
assert.isNull(error);
console.log(state);
}

@@ -224,6 +255,6 @@ },

function(error) { _this.callback(error, null) }
)
).end();
},
'there are no double done jobs': function(error, state) {
var plan = state[0];
var plan = state.pop();
assert.isNull(error);

@@ -246,3 +277,3 @@ assert.lengthOf(plan.doneJobs, 9);

function(error) { _this.callback(error, null) }
)
).end();
},

@@ -249,0 +280,0 @@ 'allDone subscribers fired': function(error, state) {

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