Launch Week Day 2: Introducing Reports: An Extensible Reporting Framework for Socket Data.Learn More
Socket
Book a DemoSign in
Socket

listen

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

listen - npm Package Compare versions

Comparing version
0.3.1
to
0.4.0
+16
CHANGES.md
# Changes
## v0.4.0
- Named callbacks
- Using Browserify to create standalone browser module
- Run tests in Phantom.JS using Browserify and Phantomic
- Run tests in browsers with a standalone test HTML file generated with Consolify
## v0.3.1
- Fix: Don't pass on undefined values from callbacks
## v0.3.0
- Listeners can take an optional function that gets invoked with the callback arguments.
+2
-2

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

/**
/*
* listen.js
*
* Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
* Copyright (c) 2012-2013 Maximilian Antoni <mail@maxantoni.de>
*

@@ -6,0 +6,0 @@ * @license MIT

@@ -1,2 +0,2 @@

/**
/*
* listen.js

@@ -75,7 +75,15 @@ *

function listener(fn, timeout) {
function listener(name, fn, timeout) {
assertUnresolved();
if (typeof fn === 'number') {
if (typeof name === 'function') {
timeout = fn;
fn = name;
name = null;
} else if (typeof name === 'number') {
timeout = name;
fn = null;
name = null;
} else if (typeof fn === 'number') {
timeout = fn;
fn = null;
}

@@ -98,2 +106,5 @@ var index = offset + count++;

values[index] = value;
if (name) {
values[name] = value;
}
}

@@ -100,0 +111,0 @@ if (++called === count && handler) {

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

/**
/*
* listen.js
*
* Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
* Copyright (c) 2012-2013 Maximilian Antoni <mail@maxantoni.de>
*

@@ -6,0 +6,0 @@ * @license MIT

{
"name" : "listen",
"version" : "0.3.1",
"version" : "0.4.0",
"description" : "Wait for the results of multiple callbacks",
"keywords" : ["callback", "thenable"],
"author" : "Maximilian Antoni (http://maxantoni.de)",

@@ -19,14 +20,12 @@ "homepage" : "https://github.com/mantoni/listen.js",

"devDependencies" : {
"utest" : "~0.0.6",
"utest" : "~0.0.8",
"urun" : "~0.0.6",
"sinon" : "~1.6.0",
"uglify-js" : "~1.2.6",
"autolint" : "~1.0.4"
"autolint" : "~1.0.4",
"phantomic" : "~0.2.0",
"browserify" : ">=2.13 <3",
"consolify" : "~0.2.0"
},
"nomo" : {
"name" : "listen.js",
"require" : "lib/listen",
"exportTarget" : "window.listen",
"fileName" : "listen.js"
}
"files" : ["lib", "README.md", "CHANGES.md", "LICENSE"]
}
+41
-27

@@ -1,2 +0,2 @@

# listen.js
# listen.js [![Build Status](https://secure.travis-ci.org/mantoni/listen.js.png?branch=master)](http://travis-ci.org/mantoni/listen.js)

@@ -7,5 +7,4 @@ Wait for the results of multiple callbacks

[![Build Status](https://secure.travis-ci.org/mantoni/listen.js.png?branch=master)](http://travis-ci.org/mantoni/listen.js)
## Install on Node
## Install with NPM

@@ -18,5 +17,8 @@ ```

Browser package are here: http://maxantoni.de/listen.js/
Standalone browser package are here: http://maxantoni.de/listen.js/
However, you may want to use npm and bundle it with your application using
[Browserify](http://browserify.org).
## Usage

@@ -56,11 +58,32 @@

#### `listen([values])`
Creates and returns a new listener. The values array with initial values is optional.
#### `listen()`
Creates and returns a new listener function.
#### `listener([timeout])`
Creates a new callback associated with the listener. If the optional timeout is given, the listener errs with a `TimeoutError` if the callback was not invoked. Throws if called after `then`.
#### `listen(values)`
Creates and returns a new listener with the given initial values.
#### `listener(func[, timeout])`
Creates a new callback which passes the arguments to the given function. Can be combined with an optional timeout. Throws if called after `then`.
#### `listener()`
Creates a new callback associated with the listener. Throws if called after `then`.
#### `listener(name)`
Creates a new named callback that provides its value under the given name.
#### `listener(timeout)`
Creates a new callback that errs with a `TimeoutError` if the callback was not invoked within the given timeout.
#### `listener(func)`
Creates a new callback that also invokes the given function with `(err, value)`.
#### `listener(name, func)`
Combined `listener(name)` and `listener(func)`.
#### `listener(name, timeout)`
Combined `listener(name)` and `listener(timeout)`.
#### `listener(func, timeout)`
Combined `listener(func)` and `listener(timeout)`.
#### `listener(name, func, timeout)`
Combined `listener(name)`, `listener(func)` and `listener(timeout)`.
#### `listener.then(func)`

@@ -75,23 +98,14 @@ Invokes the given function once all callbacks where invoked. If none of the callbacks had errors, the first argument is `null`, otherwise it's an `Error`. The second argument is the values array in order of callback creation. Can only be called once.

## Run tests
```
make
```
## Contributing
## Contrubuting
Here is what you need for development:
If you'd like to contribute to listen.js here is how to get started:
- `npm install` will install all the dev dependencies
- `make` does all of the following
- `make lint` lint the code with JSLint
- `make test` runs all unit tests in Node
- `make browser` generates a static web page at `test/all.html` to run the tests in a browser.
- `make phantom` runs all tests in a the headless [Phantom.JS](http://phantomjs.org). Make sure you have `phantomjs` in your path.
- Fork the project on GitHub.
- `npm install` will setup everything you need.
- `make` lints the code with JSLint and runs all unit tests.
- Use can also `make lint` or `make test` individually.
Running the test cases in a browser instead of Node requires [nomo.js](https://github.com/mantoni/nomo.js).
- Run `npm install -g nomo`
- Run `nomo server` from within the project directory.
- Open http://localhost:4444/test in your browser.
To build a browser package containing the merged / minified scripts run `make package`.

Sorry, the diff of this file is not supported yet

language: node_js
node_js:
- 0.6
- 0.8
module.exports = {
paths : ["lib/*.js", "test/*.js"],
linterOptions : {
indent : 2,
maxlen : 78,
node : true,
plusplus : true,
vars : true
}
};

Sorry, the diff of this file is not supported yet

SHELL := /bin/bash
default: lint test
lint:
@node_modules/.bin/autolint --once
.PHONY: test
test:
@node -e "require('urun')('test');"
compile: lint test
@nomo
@node_modules/.bin/uglifyjs listen.js > listen.min.js
version := $(shell node -e "console.log(require('./package.json').version)")
folder := listen-${version}
package: compile
@echo "Creating package ${folder}.tgz"
@mkdir ${folder}
@mv listen.js listen.min.js ${folder}
@cp LICENSE README.md ${folder}
@tar -czf ${folder}.tgz ${folder}
@rm -r ${folder}
release:
ifeq (v${version},$(shell git tag -l v${version}))
@echo "Version ${version} already released!"
@exit 1
endif
@make package
@echo "Creating tag v${version}"
@git tag -a -m "Release ${version}" v${version}
@git push --tags
@echo "Publishing to NPM"
@npm publish
/**
* listen.js
*
* Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
*
* @license MIT
*/
'use strict';
var test = require('utest');
var assert = require('assert');
var sinon = require('sinon');
var listen = require('../lib/listen');
var ErrorList = require('../lib/error-list');
test('err', {
before: function () {
this.listener = listen();
},
'should add error to error-list for then-callback': function () {
var spy = sinon.spy();
this.listener.err('a');
this.listener.err('b');
this.listener.then(spy);
sinon.assert.calledWithMatch(spy, {
errors : ['a', 'b']
});
},
'should add error-list to error-list for then-callback': function () {
var spy = sinon.spy();
this.listener.err('a');
this.listener.err(new ErrorList(['b', 'c']));
this.listener.then(spy);
sinon.assert.calledWithMatch(spy, {
errors : ['a', 'b', 'c']
});
},
'should throw if called after then': function () {
this.listener.then(function () {});
var error;
try {
this.listener.err();
} catch (e) {
error = e;
}
assert.equal("Error", error.name);
assert.equal("Cannot be called after then", error.message);
}
});
/**
* listen.js
*
* Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
*
* @license MIT
*/
'use strict';
var test = require('utest');
var assert = require('assert');
var ErrorList = require('../lib/error-list');
test('error-list', {
'should be error': function () {
var error = new ErrorList([]);
assert(error instanceof Error);
},
'should be named ErrorList': function () {
var error = new ErrorList([]);
assert.equal(error.name, 'ErrorList');
},
'should expose given errors': function () {
var errors = [new TypeError(), new RangeError()];
var error = new ErrorList(errors);
assert.strictEqual(error.errors, errors);
}
});
/**
* listen.js
*
* Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
*
* @license MIT
*/
'use strict';
var test = require('utest');
var assert = require('assert');
var sinon = require('sinon');
var listen = require('../lib/listen');
var ErrorList = require('../lib/error-list');
test('listen', {
'should return listener function': function () {
var listener = listen();
assert.equal(typeof listener, 'function');
},
'should require given argument to be array': function () {
var re = /^TypeError: Array expected$/;
assert.throws(function () {
listen(undefined);
}, re);
assert.throws(function () {
listen(null);
}, re);
assert.throws(function () {
listen(false);
}, re);
assert.throws(function () {
listen({});
}, re);
assert.doesNotThrow(function () {
listen([]);
});
},
'should append callback value to given value': function () {
var spy = sinon.spy();
var listener = listen(['a']);
var callback = listener();
listener.then(spy);
callback(null, 'b');
sinon.assert.calledWith(spy, null, ['a', 'b']);
},
'should append callback values to given values': function () {
var spy = sinon.spy();
var listener = listen(['a', 'b']);
var callbackA = listener();
var callbackB = listener();
listener.then(spy);
callbackB(null, 'd');
callbackA(null, 'c');
sinon.assert.calledWith(spy, null, ['a', 'b', 'c', 'd']);
},
'should not modify given values array': function () {
var values = [];
var listener = listen(values);
var callback = listener();
callback(null, 1);
assert.equal(0, values.length);
},
'should expose ErrorList': function () {
assert.strictEqual(listen.ErrorList, ErrorList);
}
});
/**
* listen.js
*
* Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
*
* @license MIT
*/
'use strict';
var test = require('utest');
var assert = require('assert');
var sinon = require('sinon');
var listen = require('../lib/listen');
test('listener', {
before: function () {
this.listener = listen();
this.clock = sinon.useFakeTimers();
},
after: function () {
this.clock.restore();
},
'should return callback function': function () {
var callback = this.listener();
assert.equal(typeof callback, 'function');
},
'should throw if called after then': function () {
this.listener.then(function () {});
var error;
try {
this.listener();
} catch (e) {
error = e;
}
assert.equal('Error', error.name);
assert.equal('Cannot be called after then', error.message);
},
'should err on timeout': function () {
var spy = sinon.spy();
this.listener(1000);
this.listener.then(spy);
this.clock.tick(999);
sinon.assert.notCalled(spy);
this.clock.tick(1);
sinon.assert.calledOnce(spy);
sinon.assert.calledWithMatch(spy, {
name : 'TimeoutError'
});
},
'should not set a timeout by default': function () {
var spy = sinon.spy();
this.listener();
this.listener.then(spy);
this.clock.tick(1);
sinon.assert.notCalled(spy);
},
'should not resolve if waiting for another callback': function () {
var spy = sinon.spy();
this.listener(1000);
this.listener();
this.listener.then(spy);
this.clock.tick(1000);
sinon.assert.notCalled(spy);
},
'should clear timeout': function () {
var spy = sinon.spy();
var callback1 = this.listener(250);
var callback2 = this.listener();
this.listener.then(spy);
callback1();
this.clock.tick(250);
callback2();
sinon.assert.calledOnce(spy);
sinon.assert.calledWith(spy, null);
},
'should ignore callback arguments after timeout': function () {
var spy = sinon.spy();
var callback1 = this.listener(500);
var callback2 = this.listener();
this.listener.then(spy);
this.clock.tick(500);
callback1(new TypeError());
callback2();
sinon.assert.calledOnce(spy);
sinon.assert.calledWithMatch(spy, {
name : 'TimeoutError'
});
},
'should invoke given function': function () {
var spy = sinon.spy();
var callback = this.listener(spy);
callback();
sinon.assert.calledOnce(spy);
},
'should pass error to callback': function () {
var spy = sinon.spy();
var callback = this.listener(spy);
var err = new Error();
callback(err);
sinon.assert.calledWith(spy, err);
},
'should pass null and value to callback': function () {
var spy = sinon.spy();
var callback = this.listener(spy);
callback(null, 'some value');
sinon.assert.calledWith(spy, null, 'some value');
},
'should allow to combine function and timeout arguments': function () {
var spy = sinon.spy();
var callback = this.listener(spy, 250);
this.clock.tick(250);
sinon.assert.calledWithMatch(spy, {
name : 'TimeoutError'
});
},
'should invoke given function before resolving the listener': function () {
var spy1 = sinon.spy();
var spy2 = sinon.spy();
var callback = this.listener(spy1);
this.listener.then(spy2);
callback();
sinon.assert.callOrder(spy1, spy2);
},
'should pass error thrown in given function to then': function () {
var err = new Error('ouch');
var callback = this.listener(sinon.stub().throws(err));
var spy = sinon.spy();
this.listener.then(spy);
callback();
sinon.assert.calledWith(spy, err);
},
'should combine error thrown in given function with err passed to callback':
function () {
var err1 = new Error('ouch');
var err2 = new Error('oh noes');
var callback = this.listener(sinon.stub().throws(err1));
var spy = sinon.spy();
this.listener.then(spy);
callback(err2);
sinon.assert.calledWithMatch(spy, {
name : 'ErrorList',
errors : [err1, err2]
});
},
'should not create an error list if the given function re-throws the error':
function () {
var err = new Error('ouch');
var callback = this.listener(function (e) { throw e; });
var spy = sinon.spy();
this.listener.then(spy);
callback(err);
sinon.assert.calledWith(spy, err);
}
});
/**
* listen.js
*
* Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
*
* @license MIT
*/
'use strict';
var test = require('utest');
var assert = require('assert');
var sinon = require('sinon');
var listen = require('../lib/listen');
test('push', {
before: function () {
this.listener = listen();
},
'should add value to values for then-callback': function () {
var spy = sinon.spy();
this.listener.push('a');
this.listener.push('b');
this.listener.then(spy);
sinon.assert.calledWith(spy, null, ['a', 'b']);
},
'should add value at second position if callback pending': function () {
var spy = sinon.spy();
var callback = this.listener();
this.listener.push('b');
this.listener.then(spy);
callback(null, 'a');
sinon.assert.calledWith(spy, null, ['a', 'b']);
},
'should throw if called after then': function () {
this.listener.then(function () {});
var error;
try {
this.listener.push(1);
} catch (e) {
error = e;
}
assert.equal('Error', error.name);
assert.equal('Cannot be called after then', error.message);
}
});
/**
* listen.js
*
* Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
*
* @license MIT
*/
'use strict';
var test = require('utest');
var assert = require('assert');
var sinon = require('sinon');
var listen = require('../lib/listen');
var ErrorList = require('../lib/error-list');
test('then', {
before: function () {
this.listener = listen();
this.then = this.listener.then;
},
'should require function argument': function () {
var re = /^TypeError: Function expected$/;
var then = this.then;
assert.throws(function () {
then(null);
}, re);
assert.throws(function () {
then(false);
}, re);
assert.throws(function () {
then({});
}, re);
assert.doesNotThrow(function () {
then(function () {});
});
},
'should invoke given function if no callbacks where created': function () {
var spy = sinon.spy();
this.then(spy);
sinon.assert.calledOnce(spy);
},
'should invoke given function with null and empty array': function () {
var spy = sinon.spy();
this.then(spy);
sinon.assert.calledWith(spy, null, []);
},
'should not invoke given function if callback was created': function () {
var spy = sinon.spy();
this.listener();
this.then(spy);
sinon.assert.notCalled(spy);
},
'should invoke given function if callback was already called': function () {
var spy = sinon.spy();
var callback = this.listener();
callback();
this.then(spy);
sinon.assert.calledOnce(spy);
},
'should invoke given function after callback was called': function () {
var spy = sinon.spy();
var callback = this.listener();
this.then(spy);
callback();
sinon.assert.calledOnce(spy);
},
'should invoke given function after two callbacks where called':
function () {
var spy = sinon.spy();
var callbackA = this.listener();
var callbackB = this.listener();
this.then(spy);
callbackA();
callbackB();
sinon.assert.calledOnce(spy);
},
'should invoke given function with null and empty array after callback':
function () {
var spy = sinon.spy();
var callback = this.listener();
this.then(spy);
callback(); // undefined value is ignored.
sinon.assert.calledWith(spy, null, []);
},
'should pass callback argument to given function': function () {
var spy = sinon.spy();
var callback = this.listener();
callback(null, 123);
this.then(spy);
sinon.assert.calledWith(spy, null, [123]);
},
'should pass arguments from multiple callback to given function':
function () {
var spy = sinon.spy();
var callbackA = this.listener();
var callbackB = this.listener();
callbackA(null, false);
callbackB(null, true);
this.then(spy);
sinon.assert.calledWith(spy, null, [false, true]);
},
'should pass callback arguments in order of callback creation':
function () {
var spy = sinon.spy();
var callbackA = this.listener();
var callbackB = this.listener();
callbackB(null, true);
callbackA(null, false);
this.then(spy);
sinon.assert.calledWith(spy, null, [false, true]);
},
'should not confuse argument order': function () {
var spy = sinon.spy();
var callbackA = this.listener();
callbackA(null, false);
var callbackB = this.listener();
callbackB(null, true);
this.then(spy);
sinon.assert.calledWith(spy, null, [false, true]);
},
'should not pass undefined from first value': function () {
var spy = sinon.spy();
var callbackA = this.listener();
var callbackB = this.listener();
var callbackC = this.listener();
callbackA();
callbackB(null, 'B');
callbackC(null, 'C');
this.then(spy);
sinon.assert.calledWith(spy, null, ['B', 'C']);
},
'should not pass undefined from second value': function () {
var spy = sinon.spy();
var callbackA = this.listener();
var callbackB = this.listener();
var callbackC = this.listener();
callbackA(null, 'A');
callbackB();
callbackC(null, 'C');
this.then(spy);
sinon.assert.calledWith(spy, null, ['A', 'C']);
},
'should not pass undefined from third value': function () {
var spy = sinon.spy();
var callbackA = this.listener();
var callbackB = this.listener();
var callbackC = this.listener();
callbackA(null, 'A');
callbackB(null, 'B');
callbackC();
this.then(spy);
sinon.assert.calledWith(spy, null, ['A', 'B']);
},
'should pass error to given function': function () {
var spy = sinon.spy();
var err = new RangeError();
var callback = this.listener();
callback(err);
this.then(spy);
sinon.assert.calledWith(spy, err);
},
'should pass errors as ErrorList to given function': function () {
var spy = sinon.spy();
var err1 = new RangeError();
var err2 = new TypeError();
var callbackA = this.listener();
var callbackB = this.listener();
this.then(spy);
callbackA(err1);
callbackB(err2);
var errorList = spy.firstCall.args[0];
assert.equal(errorList.name, 'ErrorList');
assert.deepEqual(errorList.errors, [err1, err2]);
},
'should throw if called again': function () {
var then = this.then;
var error;
then(function () {});
try {
then(function () {});
} catch (e) {
error = e;
}
assert.equal('Error', error.name);
assert.equal('Cannot be called more than once', error.message);
}
});
/**
* listen.js
*
* Copyright (c) 2012 Maximilian Antoni <mail@maxantoni.de>
*
* @license MIT
*/
'use strict';
var test = require('utest');
var assert = require('assert');
var TimeoutError = require('../lib/timeout-error');
test('timeout-error', {
'should be error': function () {
var error = new TimeoutError();
assert(error instanceof Error);
},
'should be named TimeoutError': function () {
var error = new TimeoutError([]);
assert.equal(error.name, 'TimeoutError');
}
});