are-we-there-yet
Advanced tools
Comparing version 1.0.6 to 1.1.0
136
index.js
@@ -1,132 +0,4 @@ | ||
"use strict" | ||
var stream = require("readable-stream") | ||
var EventEmitter = require("events").EventEmitter | ||
var util = require("util") | ||
var delegate = require("delegates") | ||
function noteChange (trackerGroup) { | ||
return function (name) { | ||
trackerGroup.emit('change', name || trackerGroup.name); | ||
} | ||
} | ||
var TrackerGroup = exports.TrackerGroup = function (name) { | ||
EventEmitter.call(this) | ||
this.name = name | ||
this.trackGroup = [] | ||
this.totalWeight = 0 | ||
this.noteChange = noteChange(this) | ||
} | ||
util.inherits(TrackerGroup, EventEmitter) | ||
TrackerGroup.prototype.completed = function () { | ||
if (this.trackGroup.length==0) return 0 | ||
var valPerWeight = 1 / this.totalWeight | ||
var completed = 0 | ||
for (var i = 0, len = this.trackGroup.length; i < len; i++){ | ||
var group = this.trackGroup[i]; | ||
completed += valPerWeight * group.weight * group.completed() | ||
} | ||
return completed | ||
} | ||
TrackerGroup.prototype.addUnit = function (unit, weight, noChange) { | ||
unit.weight = weight || 1 | ||
this.totalWeight += unit.weight | ||
this.trackGroup.push(unit) | ||
// Bubble events back up | ||
unit.on("change", this.noteChange) | ||
if (! noChange) this.emit("change", this.name) | ||
return unit | ||
} | ||
TrackerGroup.prototype.newGroup = function (name, weight) { | ||
return this.addUnit(new TrackerGroup(name), weight) | ||
} | ||
TrackerGroup.prototype.newItem = function (name, todo, weight) { | ||
return this.addUnit(new Tracker(name, todo), weight) | ||
} | ||
TrackerGroup.prototype.newStream = function (name, todo, weight) { | ||
return this.addUnit(new TrackerStream(name, todo), weight) | ||
} | ||
TrackerGroup.prototype.finish = function () { | ||
if (! this.trackGroup.length) this.addUnit(new Tracker(), 1, true) | ||
for (var i = 0, len = this.trackGroup.length; i < len; i++) { | ||
var group = this.trackGroup[i] | ||
group.removeListener("change", this.noteChange) | ||
group.finish() | ||
} | ||
this.emit("change", this.name) | ||
} | ||
var buffer = " " | ||
TrackerGroup.prototype.debug = function (depth) { | ||
depth = depth || 0 | ||
var indent = depth ? buffer.substr(0,depth) : "" | ||
var output = indent + (this.name||"top") + ": " + this.completed() + "\n" | ||
this.trackGroup.forEach(function(T) { | ||
if (T instanceof TrackerGroup) { | ||
output += T.debug(depth + 1) | ||
} | ||
else { | ||
output += indent + " " + T.name + ": " + T.completed() + "\n" | ||
} | ||
}) | ||
return output | ||
} | ||
var Tracker = exports.Tracker = function (name,todo) { | ||
EventEmitter.call(this) | ||
this.name = name | ||
this.workDone = 0 | ||
this.workTodo = todo || 0 | ||
} | ||
util.inherits(Tracker, EventEmitter) | ||
Tracker.prototype.completed = function () { | ||
return this.workTodo === 0 ? 0 : this.workDone / this.workTodo | ||
} | ||
Tracker.prototype.addWork = function (work) { | ||
this.workTodo += work | ||
this.emit("change", this.name) | ||
} | ||
Tracker.prototype.completeWork = function (work) { | ||
this.workDone += work | ||
if (this.workDone > this.workTodo) this.workDone = this.workTodo | ||
this.emit("change", this.name) | ||
} | ||
Tracker.prototype.finish = function () { | ||
this.workTodo = this.workDone = 1 | ||
this.emit("change", this.name) | ||
} | ||
var TrackerStream = exports.TrackerStream = function (name, size, options) { | ||
stream.Transform.call(this, options) | ||
this.tracker = new Tracker(name, size) | ||
this.name = name | ||
var self = this | ||
this.tracker.on("change", function (name) { self.emit("change", name) }) | ||
} | ||
util.inherits(TrackerStream, stream.Transform) | ||
TrackerStream.prototype._transform = function (data, encoding, cb) { | ||
this.tracker.completeWork(data.length ? data.length : 1) | ||
this.push(data) | ||
cb() | ||
} | ||
TrackerStream.prototype._flush = function (cb) { | ||
this.tracker.finish() | ||
cb() | ||
} | ||
delegate(TrackerStream.prototype, "tracker") | ||
.method("completed") | ||
.method("addWork") | ||
'use strict' | ||
exports.TrackerGroup = require('./tracker-group.js') | ||
exports.Tracker = require('./tracker.js') | ||
exports.TrackerStream = require('./tracker-stream.js') |
{ | ||
"name": "are-we-there-yet", | ||
"version": "1.0.6", | ||
"version": "1.1.0", | ||
"description": "Keep track of the overall completion of many dispirate processes", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "tap test/*.js" | ||
"test": "standard && tap test/*.js" | ||
}, | ||
@@ -20,2 +20,3 @@ "repository": { | ||
"devDependencies": { | ||
"standard": "^5.4.1", | ||
"tap": "^5.2.0" | ||
@@ -22,0 +23,0 @@ }, |
@@ -65,5 +65,15 @@ are-we-there-yet | ||
All tracker objects emit `change` events with an argument of the name of the | ||
thing changing. | ||
All tracker objects emit `change` events with the following arguments: | ||
``` | ||
function (name, completed, tracker) | ||
``` | ||
`name` is the name of the tracker that originally emitted the event, | ||
or if it didn't have one, the first containing tracker group that had one. | ||
`completed` is the percent complete (as returned by `tracker.completed()` method). | ||
`tracker` is the tracker object that you are listening for events on. | ||
TrackerGroup | ||
@@ -70,0 +80,0 @@ ============ |
@@ -1,56 +0,57 @@ | ||
"use strict" | ||
var test = require("tap").test | ||
var Tracker = require("../index.js").Tracker | ||
'use strict' | ||
var test = require('tap').test | ||
var Tracker = require('../index.js').Tracker | ||
var timeoutError = new Error("timeout") | ||
var testEvent = function (obj,event,next) { | ||
var timeout = setTimeout(function(){ | ||
obj.removeListener(event, eventHandler) | ||
next(timeoutError) | ||
}, 10) | ||
var eventHandler = function () { | ||
var args = Array.prototype.slice.call(arguments) | ||
args.unshift(null) | ||
clearTimeout(timeout) | ||
next.apply(null, args) | ||
} | ||
obj.once(event, eventHandler) | ||
} | ||
var testEvent = require('./lib/test-event.js') | ||
test("Tracker", function (t) { | ||
t.plan(10) | ||
var name = 'test' | ||
var name = "test" | ||
var track = new Tracker(name) | ||
test('initialization', function (t) { | ||
var simple = new Tracker(name) | ||
t.is(track.completed(), 0, "Nothing todo is 0 completion") | ||
t.is(simple.completed(), 0, 'Nothing todo is 0 completion') | ||
t.done() | ||
}) | ||
var todo = 100 | ||
var track | ||
var todo = 100 | ||
test('completion', function (t) { | ||
track = new Tracker(name, todo) | ||
t.is(track.completed(), 0, "Nothing done is 0 completion") | ||
t.is(track.completed(), 0, 'Nothing done is 0 completion') | ||
testEvent(track, "change", afterCompleteWork) | ||
track.completeWork(100) | ||
function afterCompleteWork(er, onChangeName) { | ||
t.is(er, null, "completeWork: on change event fired") | ||
t.is(onChangeName, name, "completeWork: on change emits the correct name") | ||
testEvent(track, 'change', afterCompleteWork) | ||
track.completeWork(todo) | ||
t.is(track.completed(), 1, 'completeWork: 100% completed') | ||
function afterCompleteWork (er, onChangeName) { | ||
t.is(er, null, 'completeWork: on change event fired') | ||
t.is(onChangeName, name, 'completeWork: on change emits the correct name') | ||
t.done() | ||
} | ||
t.is(track.completed(), 1, "completeWork: 100% completed") | ||
}) | ||
testEvent(track, "change", afterAddWork) | ||
track.addWork(100) | ||
function afterAddWork(er, onChangeName) { | ||
t.is(er, null, "addWork: on change event fired") | ||
t.is(onChangeName, name, "addWork: on change emits the correct name") | ||
test('add more work', function (t) { | ||
testEvent(track, 'change', afterAddWork) | ||
track.addWork(todo) | ||
t.is(track.completed(), 0.5, 'addWork: 50% completed') | ||
function afterAddWork (er, onChangeName) { | ||
t.is(er, null, 'addWork: on change event fired') | ||
t.is(onChangeName, name, 'addWork: on change emits the correct name') | ||
t.done() | ||
} | ||
t.is(track.completed(), 0.5, "addWork: 50% completed") | ||
}) | ||
test('complete more work', function (t) { | ||
track.completeWork(200) | ||
t.is(track.completed(), 1, "completeWork: Over completion is still only 100% complete") | ||
t.is(track.completed(), 1, 'completeWork: Over completion is still only 100% complete') | ||
t.done() | ||
}) | ||
track = new Tracker(name, todo) | ||
track.completeWork(50) | ||
track.finish() | ||
t.is(track.completed(), 1, "finish: Explicitly finishing moves to 100%") | ||
test('finish is always 100%', function (t) { | ||
var finishtest = new Tracker(name, todo) | ||
finishtest.completeWork(50) | ||
finishtest.finish() | ||
t.is(finishtest.completed(), 1, 'finish: Explicitly finishing moves to 100%') | ||
t.done() | ||
}) |
@@ -1,87 +0,78 @@ | ||
"use strict" | ||
var test = require("tap").test | ||
var Tracker = require("../index.js").Tracker | ||
var TrackerGroup = require("../index.js").TrackerGroup | ||
'use strict' | ||
var test = require('tap').test | ||
var TrackerGroup = require('../index.js').TrackerGroup | ||
var testEvent = require('./lib/test-event.js') | ||
var timeoutError = new Error("timeout") | ||
var testEvent = function (obj,event,next) { | ||
var timeout = setTimeout(function(){ | ||
obj.removeListener(event, eventHandler) | ||
next(timeoutError) | ||
}, 10) | ||
var eventHandler = function () { | ||
var args = Array.prototype.slice.call(arguments) | ||
args.unshift(null) | ||
clearTimeout(timeout) | ||
next.apply(null, args) | ||
} | ||
obj.once(event, eventHandler) | ||
} | ||
test('TrackerGroup', function (t) { | ||
var name = 'test' | ||
test("TrackerGroup", function (t) { | ||
var name = "test" | ||
var track = new TrackerGroup(name) | ||
t.is(track.completed(), 0, "Nothing todo is 0 completion") | ||
testEvent(track, "change", afterFinishEmpty) | ||
t.is(track.completed(), 0, 'Nothing todo is 0 completion') | ||
testEvent(track, 'change', afterFinishEmpty) | ||
track.finish() | ||
var a, b | ||
function afterFinishEmpty(er, onChangeName) { | ||
t.is(er, null, "finishEmpty: on change event fired") | ||
t.is(onChangeName, name, "finishEmpty: on change emits the correct name") | ||
t.is(track.completed(), 1, "finishEmpty: Finishing an empty group actually finishes it") | ||
function afterFinishEmpty (er, onChangeName, completion) { | ||
t.is(er, null, 'finishEmpty: on change event fired') | ||
t.is(onChangeName, name, 'finishEmpty: on change emits the correct name') | ||
t.is(completion, 1, 'finishEmpty: passed through completion was correct') | ||
t.is(track.completed(), 1, 'finishEmpty: Finishing an empty group actually finishes it') | ||
track = new TrackerGroup(name) | ||
a = track.newItem("a", 10, 1) | ||
b = track.newItem("b", 10, 1) | ||
t.is(track.completed(), 0, "Initially empty") | ||
testEvent(track, "change", afterCompleteWork) | ||
a = track.newItem('a', 10, 1) | ||
b = track.newItem('b', 10, 1) | ||
t.is(track.completed(), 0, 'Initially empty') | ||
testEvent(track, 'change', afterCompleteWork) | ||
a.completeWork(5) | ||
} | ||
function afterCompleteWork(er, onChangeName) { | ||
t.is(er, null, "on change event fired") | ||
t.is(onChangeName, "a", "on change emits the correct name") | ||
t.is(track.completed(), 0.25, "Complete half of one is a quarter overall") | ||
testEvent(track, "change", afterFinishAll) | ||
function afterCompleteWork (er, onChangeName, completion) { | ||
t.is(er, null, 'on change event fired') | ||
t.is(onChangeName, 'a', 'on change emits the correct name') | ||
t.is(completion, 0.25, 'Complete half of one is a quarter overall') | ||
t.is(track.completed(), 0.25, 'Complete half of one is a quarter overall') | ||
testEvent(track, 'change', afterFinishAll) | ||
track.finish() | ||
} | ||
function afterFinishAll(er, onChangeName) { | ||
t.is(er, null, "finishAll: on change event fired") | ||
t.is(onChangeName, name, "finishAll: on change emits the correct name") | ||
t.is(track.completed(), 1, "Finishing everything ") | ||
function afterFinishAll (er, onChangeName, completion) { | ||
t.is(er, null, 'finishAll: on change event fired') | ||
t.is(onChangeName, name, 'finishAll: on change emits the correct name') | ||
t.is(completion, 1, 'Finishing everything ') | ||
t.is(track.completed(), 1, 'Finishing everything ') | ||
track = new TrackerGroup(name) | ||
a = track.newItem("a", 10, 2) | ||
b = track.newItem("b", 10, 1) | ||
t.is(track.completed(), 0, "weighted: Initially empty") | ||
testEvent(track, "change", afterWeightedCompleteWork) | ||
a = track.newItem('a', 10, 2) | ||
b = track.newItem('b', 10, 1) | ||
t.is(track.completed(), 0, 'weighted: Initially empty') | ||
testEvent(track, 'change', afterWeightedCompleteWork) | ||
a.completeWork(5) | ||
} | ||
function afterWeightedCompleteWork(er, onChangeName) { | ||
t.is(er, null, "weighted: on change event fired") | ||
t.is(onChangeName, "a", "weighted: on change emits the correct name") | ||
t.is(Math.round(track.completed()*100), 33, "weighted: Complete half of double weighted") | ||
testEvent(track, "change", afterWeightedFinishAll) | ||
function afterWeightedCompleteWork (er, onChangeName, completion) { | ||
t.is(er, null, 'weighted: on change event fired') | ||
t.is(onChangeName, 'a', 'weighted: on change emits the correct name') | ||
t.is(Math.floor(completion * 100), 33, 'weighted: Complete half of double weighted') | ||
t.is(Math.floor(track.completed() * 100), 33, 'weighted: Complete half of double weighted') | ||
testEvent(track, 'change', afterWeightedFinishAll) | ||
track.finish() | ||
} | ||
function afterWeightedFinishAll(er, onChangeName) { | ||
t.is(er, null, "weightedFinishAll: on change event fired") | ||
t.is(onChangeName, name, "weightedFinishAll: on change emits the correct name") | ||
t.is(track.completed(), 1, "weightedFinishaAll: Finishing everything ") | ||
function afterWeightedFinishAll (er, onChangeName, completion) { | ||
t.is(er, null, 'weightedFinishAll: on change event fired') | ||
t.is(onChangeName, name, 'weightedFinishAll: on change emits the correct name') | ||
t.is(completion, 1, 'weightedFinishaAll: Finishing everything ') | ||
t.is(track.completed(), 1, 'weightedFinishaAll: Finishing everything ') | ||
track = new TrackerGroup(name) | ||
a = track.newGroup("a", 10) | ||
b = track.newGroup("b", 10) | ||
var a1 = a.newItem("a.1",10) | ||
a = track.newGroup('a', 10) | ||
b = track.newGroup('b', 10) | ||
var a1 = a.newItem('a.1', 10) | ||
a1.completeWork(5) | ||
t.is(track.completed(), 0.25, "nested: Initially quarter done") | ||
testEvent(track, "change", afterNestedComplete) | ||
t.is(track.completed(), 0.25, 'nested: Initially quarter done') | ||
testEvent(track, 'change', afterNestedComplete) | ||
b.finish() | ||
} | ||
function afterNestedComplete(er, onChangeName) { | ||
t.is(er, null, "nestedComplete: on change event fired") | ||
t.is(onChangeName, "b", "nestedComplete: on change emits the correct name") | ||
t.is(track.completed(), 0.75, "nestedComplete: Finishing everything ") | ||
function afterNestedComplete (er, onChangeName, completion) { | ||
t.is(er, null, 'nestedComplete: on change event fired') | ||
t.is(onChangeName, 'b', 'nestedComplete: on change emits the correct name') | ||
t.is(completion, 0.75, 'nestedComplete: Finishing everything ') | ||
t.is(track.completed(), 0.75, 'nestedComplete: Finishing everything ') | ||
t.end() | ||
} | ||
}) |
@@ -1,24 +0,10 @@ | ||
"use strict" | ||
var test = require("tap").test | ||
var util = require("util") | ||
var stream = require("readable-stream") | ||
var TrackerStream = require("../index.js").TrackerStream | ||
'use strict' | ||
var test = require('tap').test | ||
var util = require('util') | ||
var stream = require('readable-stream') | ||
var TrackerStream = require('../index.js').TrackerStream | ||
var testEvent = require('./lib/test-event.js') | ||
var timeoutError = new Error("timeout") | ||
var testEvent = function (obj,event,next) { | ||
var timeout = setTimeout(function(){ | ||
obj.removeListener(event, eventHandler) | ||
next(timeoutError) | ||
}, 10) | ||
var eventHandler = function () { | ||
var args = Array.prototype.slice.call(arguments) | ||
args.unshift(null) | ||
clearTimeout(timeout) | ||
next.apply(null, args) | ||
} | ||
obj.once(event, eventHandler) | ||
} | ||
var Sink = function () { | ||
stream.Writable.apply(this,arguments) | ||
stream.Writable.apply(this, arguments) | ||
} | ||
@@ -30,37 +16,37 @@ util.inherits(Sink, stream.Writable) | ||
test("TrackerStream", function (t) { | ||
test('TrackerStream', function (t) { | ||
t.plan(9) | ||
var name = "test" | ||
var name = 'test' | ||
var track = new TrackerStream(name) | ||
t.is(track.completed(), 0, "Nothing todo is 0 completion") | ||
t.is(track.completed(), 0, 'Nothing todo is 0 completion') | ||
var todo = 10 | ||
track = new TrackerStream(name, todo) | ||
t.is(track.completed(), 0, "Nothing done is 0 completion") | ||
t.is(track.completed(), 0, 'Nothing done is 0 completion') | ||
track.pipe(new Sink()) | ||
testEvent(track, "change", afterCompleteWork) | ||
track.write("0123456789") | ||
function afterCompleteWork(er, onChangeName) { | ||
t.is(er, null, "write: on change event fired") | ||
t.is(onChangeName, name, "write: on change emits the correct name") | ||
t.is(track.completed(), 1, "write: 100% completed") | ||
testEvent(track, 'change', afterCompleteWork) | ||
track.write('0123456789') | ||
function afterCompleteWork (er, onChangeName) { | ||
t.is(er, null, 'write: on change event fired') | ||
t.is(onChangeName, name, 'write: on change emits the correct name') | ||
t.is(track.completed(), 1, 'write: 100% completed') | ||
testEvent(track, "change", afterAddWork) | ||
testEvent(track, 'change', afterAddWork) | ||
track.addWork(10) | ||
} | ||
function afterAddWork(er, onChangeName) { | ||
t.is(er, null, "addWork: on change event fired") | ||
t.is(track.completed(), 0.5, "addWork: 50% completed") | ||
function afterAddWork (er, onChangeName) { | ||
t.is(er, null, 'addWork: on change event fired') | ||
t.is(track.completed(), 0.5, 'addWork: 50% completed') | ||
testEvent(track, "change", afterAllWork) | ||
track.write("ABCDEFGHIJKLMNOPQRST") | ||
testEvent(track, 'change', afterAllWork) | ||
track.write('ABCDEFGHIJKLMNOPQRST') | ||
} | ||
function afterAllWork(er) { | ||
t.is(er, null, "allWork: on change event fired") | ||
t.is(track.completed(), 1, "allWork: 100% completed") | ||
function afterAllWork (er) { | ||
t.is(er, null, 'allWork: on change event fired') | ||
t.is(track.completed(), 1, 'allWork: 100% completed') | ||
} | ||
}) |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
20030
13
331
195
2
1