MinsoftK

9

Showing 1000 changed files with 0 additions and 4904 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

sauce_connect: true
loopback: airtap.local
browsers:
- name: chrome
version: latest
- name: firefox
version: latest
- name: safari
version: 9..latest
- name: iphone
version: latest
- name: ie
version: 9..latest
- name: microsoftedge
version: 13..latest
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/events
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
dist: xenial
os: linux
language: node_js
node_js:
- 'stable'
- 'lts/*'
- '0.12'
script:
- npm test
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_NODE_VERSION}" = "stable" ]; then npm run test:browsers; fi
addons:
sauce_connect: true
hosts:
- airtap.local
env:
global:
- secure: XcBiD8yReflut9q7leKsigDZ0mI3qTKH+QrNVY8DaqlomJOZw8aOrVuX9Jz12l86ZJ41nbxmKnRNkFzcVr9mbP9YaeTb3DpeOBWmvaoSfud9Wnc16VfXtc1FCcwDhSVcSiM3UtnrmFU5cH+Dw1LPh5PbfylYOS/nJxUvG0FFLqI=
- secure: jNWtEbqhUdQ0xXDHvCYfUbKYeJCi6a7B4LsrcxYCyWWn4NIgncE5x2YbB+FSUUFVYfz0dsn5RKP1oHB99f0laUEo18HBNkrAS/rtyOdVzcpJjbQ6kgSILGjnJD/Ty1B57Rcz3iyev5Y7bLZ6Y1FbDnk/i9/l0faOGz8vTC3Vdkc=
# 3.2.0
- Add `events.once` from Node.js 11.13.0.
To use this function, Promises must be supported in the environment. Use a polyfill like `es6-promise` if you support older browsers.
# 3.1.0 (2020-01-08)
`events` now matches the Node.js 11.12.0 API.
- pass through return value in wrapped `emitter.once()` listeners
Now, this works:
```js
emitter.once('myevent', function () { return 1; });
var listener = emitter.rawListeners('myevent')[0]
assert(listener() === 1);
```
Previously, `listener()` would return undefined regardless of the implementation.
Ported from https://github.com/nodejs/node/commit/acc506c2d2771dab8d7bba6d3452bc5180dff7cf
- Reduce code duplication in listener type check ([#67](https://github.com/Gozala/events/pull/67) by [@friederbluemle](https://github.com/friederbluemle)).
- Improve `emitter.once()` performance in some engines
# 3.0.0 (2018-05-25)
**This version drops support for IE8.** `events` no longer includes polyfills
for ES5 features. If you need to support older environments, use an ES5 shim
like [es5-shim](https://npmjs.com/package/es5-shim). Both the shim and sham
versions of es5-shim are necessary.
- Update to events code from Node.js 10.x
- (semver major) Adds `off()` method
- Port more tests from Node.js
- Switch browser tests to airtap, making things more reliable
# 2.1.0 (2018-05-25)
- add Emitter#rawListeners from Node.js v9.4
# 2.0.0 (2018-02-02)
- Update to events code from node.js 8.x
- Adds `prependListener()` and `prependOnceListener()`
- Adds `eventNames()` method
- (semver major) Unwrap `once()` listeners in `listeners()`
- copy tests from node.js
Note that this version doubles the gzipped size, jumping from 1.1KB to 2.1KB,
due to new methods and runtime performance improvements. Be aware of that when
upgrading.
# 1.1.1 (2016-06-22)
- add more context to errors if they are not instanceof Error
# 1.1.0 (2015-09-29)
- add Emitter#listerCount (to match node v4 api)
# 1.0.2 (2014-08-28)
- remove un-reachable code
- update devDeps
## 1.0.1 / 2014-05-11
- check for console.trace before using it
## 1.0.0 / 2013-12-10
- Update to latest events code from node.js 0.10
- copy tests from node.js
## 0.4.0 / 2011-07-03 ##
- Switching to graphquire@0.8.0
## 0.3.0 / 2011-07-03 ##
- Switching to URL based module require.
## 0.2.0 / 2011-06-10 ##
- Simplified package structure.
- Graphquire for dependency management.
## 0.1.1 / 2011-05-16 ##
- Unhandled errors are logged via console.error
## 0.1.0 / 2011-04-22 ##
- Initial release
MIT
Copyright Joyent, Inc. and other Node contributors.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.
# events [![Build Status](https://travis-ci.org/Gozala/events.png?branch=master)](https://travis-ci.org/Gozala/events)
> Node's event emitter for all engines.
This implements the Node.js [`events`][node.js docs] module for environments that do not have it, like browsers.
> `events` currently matches the **Node.js 11.13.0** API.
Note that the `events` module uses ES5 features. If you need to support very old browsers like IE8, use a shim like [`es5-shim`](https://www.npmjs.com/package/es5-shim). You need both the shim and the sham versions of `es5-shim`.
This module is maintained, but only by very few people. If you'd like to help, let us know in the [Maintainer Needed](https://github.com/Gozala/events/issues/43) issue!
## Install
You usually do not have to install `events` yourself! If your code runs in Node.js, `events` is built in. If your code runs in the browser, bundlers like [browserify](https://github.com/browserify/browserify) or [webpack](https://github.com/webpack/webpack) also include the `events` module.
But if none of those apply, with npm do:
```
npm install events
```
## Usage
```javascript
var EventEmitter = require('events')
var ee = new EventEmitter()
ee.on('message', function (text) {
console.log(text)
})
ee.emit('message', 'hello world')
```
## API
See the [Node.js EventEmitter docs][node.js docs]. `events` currently matches the Node.js 11.13.0 API.
## Contributing
PRs are very welcome! The main way to contribute to `events` is by porting features, bugfixes and tests from Node.js. Ideally, code contributions to this module are copy-pasted from Node.js and transpiled to ES5, rather than reimplemented from scratch. Matching the Node.js code as closely as possible makes maintenance simpler when new changes land in Node.js.
This module intends to provide exactly the same API as Node.js, so features that are not available in the core `events` module will not be accepted. Feature requests should instead be directed at [nodejs/node](https://github.com/nodejs/node) and will be added to this module once they are implemented in Node.js.
If there is a difference in behaviour between Node.js's `events` module and this module, please open an issue!
## License
[MIT](./LICENSE)
[node.js docs]: https://nodejs.org/dist/v11.13.0/docs/api/events.html
This diff is collapsed. Click to expand it.
{
"_from": "events@^3.0.0",
"_id": "events@3.2.0",
"_inBundle": false,
"_integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==",
"_location": "/events",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "events@^3.0.0",
"name": "events",
"escapedName": "events",
"rawSpec": "^3.0.0",
"saveSpec": null,
"fetchSpec": "^3.0.0"
},
"_requiredBy": [
"/node-libs-browser"
],
"_resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz",
"_shasum": "93b87c18f8efcd4202a461aec4dfc0556b639379",
"_spec": "events@^3.0.0",
"_where": "C:\\Users\\kkwan_000\\Desktop\\git\\2017110269\\minsung\\node_modules\\node-libs-browser",
"author": {
"name": "Irakli Gozalishvili",
"email": "rfobic@gmail.com",
"url": "http://jeditoolkit.com"
},
"bugs": {
"url": "http://github.com/Gozala/events/issues/"
},
"bundleDependencies": false,
"deprecated": false,
"description": "Node's event emitter for all engines.",
"devDependencies": {
"airtap": "^1.0.0",
"functions-have-names": "^1.2.1",
"has-symbols": "^1.0.1",
"isarray": "^2.0.5",
"tape": "^5.0.0"
},
"engines": {
"node": ">=0.8.x"
},
"homepage": "https://github.com/Gozala/events#readme",
"keywords": [
"events",
"eventEmitter",
"eventDispatcher",
"listeners"
],
"license": "MIT",
"main": "./events.js",
"name": "events",
"repository": {
"type": "git",
"url": "git://github.com/Gozala/events.git",
"web": "https://github.com/Gozala/events"
},
"scripts": {
"test": "node tests/index.js",
"test:browsers": "airtap -- tests/index.js"
},
"version": "3.2.0"
}
# Security Policy
## Supported Versions
Only the latest major version is supported at any given time.
## Reporting a Vulnerability
To report a security vulnerability, please use the
[Tidelift security contact](https://tidelift.com/security).
Tidelift will coordinate the fix and disclosure.
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('./common');
var assert = require('assert');
var EventEmitter = require('../');
{
var ee = new EventEmitter();
var events_new_listener_emitted = [];
var listeners_new_listener_emitted = [];
// Sanity check
assert.strictEqual(ee.addListener, ee.on);
ee.on('newListener', function(event, listener) {
// Don't track newListener listeners.
if (event === 'newListener')
return;
events_new_listener_emitted.push(event);
listeners_new_listener_emitted.push(listener);
});
var hello = common.mustCall(function(a, b) {
assert.strictEqual('a', a);
assert.strictEqual('b', b);
});
ee.once('newListener', function(name, listener) {
assert.strictEqual(name, 'hello');
assert.strictEqual(listener, hello);
var listeners = this.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
});
ee.on('hello', hello);
ee.once('foo', assert.fail);
assert.ok(Array.isArray(events_new_listener_emitted));
assert.strictEqual(events_new_listener_emitted.length, 2);
assert.strictEqual(events_new_listener_emitted[0], 'hello');
assert.strictEqual(events_new_listener_emitted[1], 'foo');
assert.ok(Array.isArray(listeners_new_listener_emitted));
assert.strictEqual(listeners_new_listener_emitted.length, 2);
assert.strictEqual(listeners_new_listener_emitted[0], hello);
assert.strictEqual(listeners_new_listener_emitted[1], assert.fail);
ee.emit('hello', 'a', 'b');
}
// just make sure that this doesn't throw:
{
var f = new EventEmitter();
f.setMaxListeners(0);
}
{
var listen1 = function() {};
var listen2 = function() {};
var ee = new EventEmitter();
ee.once('newListener', function() {
var listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
ee.once('newListener', function() {
var listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
});
ee.on('hello', listen2);
});
ee.on('hello', listen1);
// The order of listeners on an event is not always the order in which the
// listeners were added.
var listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 2);
assert.strictEqual(listeners[0], listen2);
assert.strictEqual(listeners[1], listen1);
}
// Verify that the listener must be a function
assert.throws(function() {
var ee = new EventEmitter();
ee.on('foo', null);
}, /^TypeError: The "listener" argument must be of type Function. Received type object$/);
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('./common');
var assert = require('assert');
var events = require('../');
// Redirect warning output to tape.
var consoleWarn = console.warn;
console.warn = common.test.comment;
common.test.on('end', function () {
console.warn = consoleWarn;
});
// default
{
var e = new events.EventEmitter();
for (var i = 0; i < 10; i++) {
e.on('default', common.mustNotCall());
}
assert.ok(!e._events['default'].hasOwnProperty('warned'));
e.on('default', common.mustNotCall());
assert.ok(e._events['default'].warned);
// specific
e.setMaxListeners(5);
for (var i = 0; i < 5; i++) {
e.on('specific', common.mustNotCall());
}
assert.ok(!e._events['specific'].hasOwnProperty('warned'));
e.on('specific', common.mustNotCall());
assert.ok(e._events['specific'].warned);
// only one
e.setMaxListeners(1);
e.on('only one', common.mustNotCall());
assert.ok(!e._events['only one'].hasOwnProperty('warned'));
e.on('only one', common.mustNotCall());
assert.ok(e._events['only one'].hasOwnProperty('warned'));
// unlimited
e.setMaxListeners(0);
for (var i = 0; i < 1000; i++) {
e.on('unlimited', common.mustNotCall());
}
assert.ok(!e._events['unlimited'].hasOwnProperty('warned'));
}
// process-wide
{
events.EventEmitter.defaultMaxListeners = 42;
var e = new events.EventEmitter();
for (var i = 0; i < 42; ++i) {
e.on('fortytwo', common.mustNotCall());
}
assert.ok(!e._events['fortytwo'].hasOwnProperty('warned'));
e.on('fortytwo', common.mustNotCall());
assert.ok(e._events['fortytwo'].hasOwnProperty('warned'));
delete e._events['fortytwo'].warned;
events.EventEmitter.defaultMaxListeners = 44;
e.on('fortytwo', common.mustNotCall());
assert.ok(!e._events['fortytwo'].hasOwnProperty('warned'));
e.on('fortytwo', common.mustNotCall());
assert.ok(e._events['fortytwo'].hasOwnProperty('warned'));
}
// but _maxListeners still has precedence over defaultMaxListeners
{
events.EventEmitter.defaultMaxListeners = 42;
var e = new events.EventEmitter();
e.setMaxListeners(1);
e.on('uno', common.mustNotCall());
assert.ok(!e._events['uno'].hasOwnProperty('warned'));
e.on('uno', common.mustNotCall());
assert.ok(e._events['uno'].hasOwnProperty('warned'));
// chainable
assert.strictEqual(e, e.setMaxListeners(1));
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var test = require('tape');
var assert = require('assert');
var noop = function() {};
var mustCallChecks = [];
function runCallChecks(exitCode) {
if (exitCode !== 0) return;
var failed = filter(mustCallChecks, function(context) {
if ('minimum' in context) {
context.messageSegment = 'at least ' + context.minimum;
return context.actual < context.minimum;
} else {
context.messageSegment = 'exactly ' + context.exact;
return context.actual !== context.exact;
}
});
for (var i = 0; i < failed.length; i++) {
var context = failed[i];
console.log('Mismatched %s function calls. Expected %s, actual %d.',
context.name,
context.messageSegment,
context.actual);
// IE8 has no .stack
if (context.stack) console.log(context.stack.split('\n').slice(2).join('\n'));
}
assert.strictEqual(failed.length, 0);
}
exports.mustCall = function(fn, exact) {
return _mustCallInner(fn, exact, 'exact');
};
function _mustCallInner(fn, criteria, field) {
if (typeof criteria == 'undefined') criteria = 1;
if (typeof fn === 'number') {
criteria = fn;
fn = noop;
} else if (fn === undefined) {
fn = noop;
}
if (typeof criteria !== 'number')
throw new TypeError('Invalid ' + field + ' value: ' + criteria);
var context = {
actual: 0,
stack: (new Error()).stack,
name: fn.name || '<anonymous>'
};
context[field] = criteria;
// add the exit listener only once to avoid listener leak warnings
if (mustCallChecks.length === 0) test.onFinish(function() { runCallChecks(0); });
mustCallChecks.push(context);
return function() {
context.actual++;
return fn.apply(this, arguments);
};
}
exports.mustNotCall = function(msg) {
return function mustNotCall() {
assert.fail(msg || 'function should not have been called');
};
};
function filter(arr, fn) {
if (arr.filter) return arr.filter(fn);
var filtered = [];
for (var i = 0; i < arr.length; i++) {
if (fn(arr[i], i, arr)) filtered.push(arr[i]);
}
return filtered
}
'use strict';
var assert = require('assert');
var EventEmitter = require('../');
var EE = new EventEmitter();
assert.throws(function () {
EE.emit('error', 'Accepts a string');
}, 'Error: Unhandled error. (Accepts a string)');
assert.throws(function () {
EE.emit('error', { message: 'Error!' });
}, 'Unhandled error. ([object Object])');
'use strict';
var EventEmitter = require('../');
var assert = require('assert');
var EE = new EventEmitter();
var m = function() {};
EE.on('foo', function() {});
assert.equal(1, EE.eventNames().length);
assert.equal('foo', EE.eventNames()[0]);
EE.on('bar', m);
assert.equal(2, EE.eventNames().length);
assert.equal('foo', EE.eventNames()[0]);
assert.equal('bar', EE.eventNames()[1]);
EE.removeListener('bar', m);
assert.equal(1, EE.eventNames().length);
assert.equal('foo', EE.eventNames()[0]);
if (typeof Symbol !== 'undefined') {
var s = Symbol('s');
EE.on(s, m);
assert.equal(2, EE.eventNames().length);
assert.equal('foo', EE.eventNames()[0]);
assert.equal(s, EE.eventNames()[1]);
EE.removeListener(s, m);
assert.equal(1, EE.eventNames().length);
assert.equal('foo', EE.eventNames()[0]);
}
'use strict';
var common = require('./common');
var EventEmitter = require('../').EventEmitter;
var once = require('../').once;
var assert = require('assert');
function onceAnEvent() {
var ee = new EventEmitter();
process.nextTick(function () {
ee.emit('myevent', 42);
});
return once(ee, 'myevent').then(function (args) {
var value = args[0]
assert.strictEqual(value, 42);
assert.strictEqual(ee.listenerCount('error'), 0);
assert.strictEqual(ee.listenerCount('myevent'), 0);
});
}
function onceAnEventWithTwoArgs() {
var ee = new EventEmitter();
process.nextTick(function () {
ee.emit('myevent', 42, 24);
});
return once(ee, 'myevent').then(function (value) {
assert.strictEqual(value.length, 2);
assert.strictEqual(value[0], 42);
assert.strictEqual(value[1], 24);
});
}
function catchesErrors() {
var ee = new EventEmitter();
var expected = new Error('kaboom');
var err;
process.nextTick(function () {
ee.emit('error', expected);
});
return once(ee, 'myevent').then(function () {
throw new Error('should reject')
}, function (err) {
assert.strictEqual(err, expected);
assert.strictEqual(ee.listenerCount('error'), 0);
assert.strictEqual(ee.listenerCount('myevent'), 0);
});
}
function stopListeningAfterCatchingError() {
var ee = new EventEmitter();
var expected = new Error('kaboom');
var err;
process.nextTick(function () {
ee.emit('error', expected);
ee.emit('myevent', 42, 24);
});
// process.on('multipleResolves', common.mustNotCall());
return once(ee, 'myevent').then(common.mustNotCall, function (err) {
// process.removeAllListeners('multipleResolves');
assert.strictEqual(err, expected);
assert.strictEqual(ee.listenerCount('error'), 0);
assert.strictEqual(ee.listenerCount('myevent'), 0);
});
}
function onceError() {
var ee = new EventEmitter();
var expected = new Error('kaboom');
process.nextTick(function () {
ee.emit('error', expected);
});
return once(ee, 'error').then(function (args) {
var err = args[0]
assert.strictEqual(err, expected);
assert.strictEqual(ee.listenerCount('error'), 0);
assert.strictEqual(ee.listenerCount('myevent'), 0);
});
}
Promise.all([
onceAnEvent(),
onceAnEventWithTwoArgs(),
catchesErrors(),
stopListeningAfterCatchingError(),
onceError()
]).catch(function (err) {
console.error(err.stack)
process.exit(1)
});
var test = require('tape');
var functionsHaveNames = require('functions-have-names');
var hasSymbols = require('has-symbols');
require('./legacy-compat');
var common = require('./common');
// we do this to easily wrap each file in a mocha test
// and also have browserify be able to statically analyze this file
var orig_require = require;
var require = function(file) {
test(file, function(t) {
// Store the tape object so tests can access it.
t.on('end', function () { delete common.test; });
common.test = t;
try { orig_require(file); } catch (err) { t.fail(err); }
t.end();
});
};
require('./add-listeners.js');
require('./check-listener-leaks.js');
require('./errors.js');
require('./events-list.js');
if (typeof Promise === 'function') {
require('./events-once.js');
} else {
// Promise support is not available.
test('./events-once.js', { skip: true }, function () {});
}
require('./listener-count.js');
require('./listeners-side-effects.js');
require('./listeners.js');
require('./max-listeners.js');
if (functionsHaveNames()) {
require('./method-names.js');
} else {
// Function.name is not supported in IE
test('./method-names.js', { skip: true }, function () {});
}
require('./modify-in-emit.js');
require('./num-args.js');
require('./once.js');
require('./prepend.js');
require('./set-max-listeners-side-effects.js');
require('./special-event-names.js');
require('./subclass.js');
if (hasSymbols()) {
require('./symbols.js');
} else {
// Symbol is not available.
test('./symbols.js', { skip: true }, function () {});
}
require('./remove-all-listeners.js');
require('./remove-listeners.js');
// sigh... life is hard
if (!global.console) {
console = {}
}
var fns = ['log', 'error', 'trace'];
for (var i=0 ; i<fns.length ; ++i) {
var fn = fns[i];
if (!console[fn]) {
console[fn] = function() {};
}
}
if (!Array.isArray) {
Array.isArray = require('isarray');
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
require('./common');
var assert = require('assert');
var EventEmitter = require('../');
var emitter = new EventEmitter();
emitter.on('foo', function() {});
emitter.on('foo', function() {});
emitter.on('baz', function() {});
// Allow any type
emitter.on(123, function() {});
assert.strictEqual(EventEmitter.listenerCount(emitter, 'foo'), 2);
assert.strictEqual(emitter.listenerCount('foo'), 2);
assert.strictEqual(emitter.listenerCount('bar'), 0);
assert.strictEqual(emitter.listenerCount('baz'), 1);
assert.strictEqual(emitter.listenerCount(123), 1);
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
require('./common');
var assert = require('assert');
var EventEmitter = require('../').EventEmitter;
var e = new EventEmitter();
var fl; // foo listeners
fl = e.listeners('foo');
assert.ok(Array.isArray(fl));
assert.strictEqual(fl.length, 0);
if (Object.create) assert.ok(!(e._events instanceof Object));
assert.strictEqual(Object.keys(e._events).length, 0);
e.on('foo', assert.fail);
fl = e.listeners('foo');
assert.strictEqual(e._events.foo, assert.fail);
assert.ok(Array.isArray(fl));
assert.strictEqual(fl.length, 1);
assert.strictEqual(fl[0], assert.fail);
e.listeners('bar');
e.on('foo', assert.ok);
fl = e.listeners('foo');
assert.ok(Array.isArray(e._events.foo));
assert.strictEqual(e._events.foo.length, 2);
assert.strictEqual(e._events.foo[0], assert.fail);
assert.strictEqual(e._events.foo[1], assert.ok);
assert.ok(Array.isArray(fl));
assert.strictEqual(fl.length, 2);
assert.strictEqual(fl[0], assert.fail);
assert.strictEqual(fl[1], assert.ok);
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
require('./common');
var assert = require('assert');
var events = require('../');
var util = require('util');
function listener() {}
function listener2() {}
function listener3() {
return 0;
}
function listener4() {
return 1;
}
function TestStream() {}
util.inherits(TestStream, events.EventEmitter);
{
var ee = new events.EventEmitter();
ee.on('foo', listener);
var fooListeners = ee.listeners('foo');
var listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 1);
assert.strictEqual(listeners[0], listener);
ee.removeAllListeners('foo');
listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
assert.ok(Array.isArray(fooListeners));
assert.strictEqual(fooListeners.length, 1);
assert.strictEqual(fooListeners[0], listener);
}
{
var ee = new events.EventEmitter();
ee.on('foo', listener);
var eeListenersCopy = ee.listeners('foo');
assert.ok(Array.isArray(eeListenersCopy));
assert.strictEqual(eeListenersCopy.length, 1);
assert.strictEqual(eeListenersCopy[0], listener);
var listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 1);
assert.strictEqual(listeners[0], listener);
eeListenersCopy.push(listener2);
listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 1);
assert.strictEqual(listeners[0], listener);
assert.strictEqual(eeListenersCopy.length, 2);
assert.strictEqual(eeListenersCopy[0], listener);
assert.strictEqual(eeListenersCopy[1], listener2);
}
{
var ee = new events.EventEmitter();
ee.on('foo', listener);
var eeListenersCopy = ee.listeners('foo');
ee.on('foo', listener2);
var listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 2);
assert.strictEqual(listeners[0], listener);
assert.strictEqual(listeners[1], listener2);
assert.ok(Array.isArray(eeListenersCopy));
assert.strictEqual(eeListenersCopy.length, 1);
assert.strictEqual(eeListenersCopy[0], listener);
}
{
var ee = new events.EventEmitter();
ee.once('foo', listener);
var listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 1);
assert.strictEqual(listeners[0], listener);
}
{
var ee = new events.EventEmitter();
ee.on('foo', listener);
ee.once('foo', listener2);
var listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 2);
assert.strictEqual(listeners[0], listener);
assert.strictEqual(listeners[1], listener2);
}
{
var ee = new events.EventEmitter();
ee._events = undefined;
var listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
}
{
var s = new TestStream();
var listeners = s.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
}
{
var ee = new events.EventEmitter();
ee.on('foo', listener);
var wrappedListener = ee.rawListeners('foo');
assert.strictEqual(wrappedListener.length, 1);
assert.strictEqual(wrappedListener[0], listener);
assert.notStrictEqual(wrappedListener, ee.rawListeners('foo'));
ee.once('foo', listener);
var wrappedListeners = ee.rawListeners('foo');
assert.strictEqual(wrappedListeners.length, 2);
assert.strictEqual(wrappedListeners[0], listener);
assert.notStrictEqual(wrappedListeners[1], listener);
assert.strictEqual(wrappedListeners[1].listener, listener);
assert.notStrictEqual(wrappedListeners, ee.rawListeners('foo'));
ee.emit('foo');
assert.strictEqual(wrappedListeners.length, 2);
assert.strictEqual(wrappedListeners[1].listener, listener);
}
{
var ee = new events.EventEmitter();
ee.once('foo', listener3);
ee.on('foo', listener4);
var rawListeners = ee.rawListeners('foo');
assert.strictEqual(rawListeners.length, 2);
assert.strictEqual(rawListeners[0](), 0);
var rawListener = ee.rawListeners('foo');
assert.strictEqual(rawListener.length, 1);
assert.strictEqual(rawListener[0](), 1);
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('./common');
var assert = require('assert');
var events = require('../');
var e = new events.EventEmitter();
var hasDefineProperty = !!Object.defineProperty;
try { Object.defineProperty({}, 'x', { value: 0 }); } catch (err) { hasDefineProperty = false }
e.on('maxListeners', common.mustCall());
// Should not corrupt the 'maxListeners' queue.
e.setMaxListeners(42);
var throwsObjs = [NaN, -1, 'and even this'];
var maxError = /^RangeError: The value of "n" is out of range\. It must be a non-negative number\./;
var defError = /^RangeError: The value of "defaultMaxListeners" is out of range\. It must be a non-negative number\./;
for (var i = 0; i < throwsObjs.length; i++) {
var obj = throwsObjs[i];
assert.throws(function() { e.setMaxListeners(obj); }, maxError);
if (hasDefineProperty) {
assert.throws(function() { events.defaultMaxListeners = obj; }, defError);
}
}
e.emit('maxListeners');
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
'use strict';
require('./common');
var assert = require('assert');
var events = require('../');
var E = events.EventEmitter.prototype;
assert.strictEqual(E.constructor.name, 'EventEmitter');
assert.strictEqual(E.on, E.addListener); // Same method.
assert.strictEqual(E.off, E.removeListener); // Same method.
Object.getOwnPropertyNames(E).forEach(function(name) {
if (name === 'constructor' || name === 'on' || name === 'off') return;
if (typeof E[name] !== 'function') return;
assert.strictEqual(E[name].name, name);
});
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
require('./common');
var assert = require('assert');
var events = require('../');
var callbacks_called = [];
var e = new events.EventEmitter();
function callback1() {
callbacks_called.push('callback1');
e.on('foo', callback2);
e.on('foo', callback3);
e.removeListener('foo', callback1);
}
function callback2() {
callbacks_called.push('callback2');
e.removeListener('foo', callback2);
}
function callback3() {
callbacks_called.push('callback3');
e.removeListener('foo', callback3);
}
e.on('foo', callback1);
assert.strictEqual(e.listeners('foo').length, 1);
e.emit('foo');
assert.strictEqual(e.listeners('foo').length, 2);
assert.ok(Array.isArray(callbacks_called));
assert.strictEqual(callbacks_called.length, 1);
assert.strictEqual(callbacks_called[0], 'callback1');
e.emit('foo');
assert.strictEqual(e.listeners('foo').length, 0);
assert.ok(Array.isArray(callbacks_called));
assert.strictEqual(callbacks_called.length, 3);
assert.strictEqual(callbacks_called[0], 'callback1');
assert.strictEqual(callbacks_called[1], 'callback2');
assert.strictEqual(callbacks_called[2], 'callback3');
e.emit('foo');
assert.strictEqual(e.listeners('foo').length, 0);
assert.ok(Array.isArray(callbacks_called));
assert.strictEqual(callbacks_called.length, 3);
assert.strictEqual(callbacks_called[0], 'callback1');
assert.strictEqual(callbacks_called[1], 'callback2');
assert.strictEqual(callbacks_called[2], 'callback3');
e.on('foo', callback1);
e.on('foo', callback2);
assert.strictEqual(e.listeners('foo').length, 2);
e.removeAllListeners('foo');
assert.strictEqual(e.listeners('foo').length, 0);
// Verify that removing callbacks while in emit allows emits to propagate to
// all listeners
callbacks_called = [];
e.on('foo', callback2);
e.on('foo', callback3);
assert.strictEqual(2, e.listeners('foo').length);
e.emit('foo');
assert.ok(Array.isArray(callbacks_called));
assert.strictEqual(callbacks_called.length, 2);
assert.strictEqual(callbacks_called[0], 'callback2');
assert.strictEqual(callbacks_called[1], 'callback3');
assert.strictEqual(0, e.listeners('foo').length);
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
require('./common');
var assert = require('assert');
var events = require('../');
var e = new events.EventEmitter();
var num_args_emitted = [];
e.on('numArgs', function() {
var numArgs = arguments.length;
num_args_emitted.push(numArgs);
});
e.on('foo', function() {
num_args_emitted.push(arguments.length);
});
e.on('foo', function() {
num_args_emitted.push(arguments.length);
});
e.emit('numArgs');
e.emit('numArgs', null);
e.emit('numArgs', null, null);
e.emit('numArgs', null, null, null);
e.emit('numArgs', null, null, null, null);
e.emit('numArgs', null, null, null, null, null);
e.emit('foo', null, null, null, null);
assert.ok(Array.isArray(num_args_emitted));
assert.strictEqual(num_args_emitted.length, 8);
assert.strictEqual(num_args_emitted[0], 0);
assert.strictEqual(num_args_emitted[1], 1);
assert.strictEqual(num_args_emitted[2], 2);
assert.strictEqual(num_args_emitted[3], 3);
assert.strictEqual(num_args_emitted[4], 4);
assert.strictEqual(num_args_emitted[5], 5);
assert.strictEqual(num_args_emitted[6], 4);
assert.strictEqual(num_args_emitted[6], 4);
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('./common');
var assert = require('assert');
var EventEmitter = require('../');
var e = new EventEmitter();
e.once('hello', common.mustCall());
e.emit('hello', 'a', 'b');
e.emit('hello', 'a', 'b');
e.emit('hello', 'a', 'b');
e.emit('hello', 'a', 'b');
function remove() {
assert.fail('once->foo should not be emitted');
}
e.once('foo', remove);
e.removeListener('foo', remove);
e.emit('foo');
e.once('e', common.mustCall(function() {
e.emit('e');
}));
e.once('e', common.mustCall());
e.emit('e');
// Verify that the listener must be a function
assert.throws(function() {
var ee = new EventEmitter();
ee.once('foo', null);
}, /^TypeError: The "listener" argument must be of type Function. Received type object$/);
{
// once() has different code paths based on the number of arguments being
// emitted. Verify that all of the cases are covered.
var maxArgs = 4;
for (var i = 0; i <= maxArgs; ++i) {
var ee = new EventEmitter();
var args = ['foo'];
for (var j = 0; j < i; ++j)
args.push(j);
ee.once('foo', common.mustCall(function() {
var params = Array.prototype.slice.call(arguments);
var restArgs = args.slice(1);
assert.ok(Array.isArray(params));
assert.strictEqual(params.length, restArgs.length);
for (var index = 0; index < params.length; index++) {
var param = params[index];
assert.strictEqual(param, restArgs[index]);
}
}));
EventEmitter.prototype.emit.apply(ee, args);
}
}
'use strict';
var common = require('./common');
var EventEmitter = require('../');
var assert = require('assert');
var myEE = new EventEmitter();
var m = 0;
// This one comes last.
myEE.on('foo', common.mustCall(function () {
assert.strictEqual(m, 2);
}));
// This one comes second.
myEE.prependListener('foo', common.mustCall(function () {
assert.strictEqual(m++, 1);
}));
// This one comes first.
myEE.prependOnceListener('foo',
common.mustCall(function () {
assert.strictEqual(m++, 0);
}));
myEE.emit('foo');
// Verify that the listener must be a function
assert.throws(function () {
var ee = new EventEmitter();
ee.prependOnceListener('foo', null);
}, 'TypeError: The "listener" argument must be of type Function. Received type object');
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('./common');
var assert = require('assert');
var events = require('../');
var test = require('tape');
function expect(expected) {
var actual = [];
test.onFinish(function() {
var sortedActual = actual.sort();
var sortedExpected = expected.sort();
assert.strictEqual(sortedActual.length, sortedExpected.length);
for (var index = 0; index < sortedActual.length; index++) {
var value = sortedActual[index];
assert.strictEqual(value, sortedExpected[index]);
}
});
function listener(name) {
actual.push(name);
}
return common.mustCall(listener, expected.length);
}
{
var ee = new events.EventEmitter();
var noop = common.mustNotCall();
ee.on('foo', noop);
ee.on('bar', noop);
ee.on('baz', noop);
ee.on('baz', noop);
var fooListeners = ee.listeners('foo');
var barListeners = ee.listeners('bar');
var bazListeners = ee.listeners('baz');
ee.on('removeListener', expect(['bar', 'baz', 'baz']));
ee.removeAllListeners('bar');
ee.removeAllListeners('baz');
var listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 1);
assert.strictEqual(listeners[0], noop);
listeners = ee.listeners('bar');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
listeners = ee.listeners('baz');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
// After calling removeAllListeners(),
// the old listeners array should stay unchanged.
assert.strictEqual(fooListeners.length, 1);
assert.strictEqual(fooListeners[0], noop);
assert.strictEqual(barListeners.length, 1);
assert.strictEqual(barListeners[0], noop);
assert.strictEqual(bazListeners.length, 2);
assert.strictEqual(bazListeners[0], noop);
assert.strictEqual(bazListeners[1], noop);
// After calling removeAllListeners(),
// new listeners arrays is different from the old.
assert.notStrictEqual(ee.listeners('bar'), barListeners);
assert.notStrictEqual(ee.listeners('baz'), bazListeners);
}
{
var ee = new events.EventEmitter();
ee.on('foo', common.mustNotCall());
ee.on('bar', common.mustNotCall());
// Expect LIFO order
ee.on('removeListener', expect(['foo', 'bar', 'removeListener']));
ee.on('removeListener', expect(['foo', 'bar']));
ee.removeAllListeners();
var listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
listeners = ee.listeners('bar');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
}
{
var ee = new events.EventEmitter();
ee.on('removeListener', common.mustNotCall());
// Check for regression where removeAllListeners() throws when
// there exists a 'removeListener' listener, but there exists
// no listeners for the provided event type.
assert.doesNotThrow(function () { ee.removeAllListeners(ee, 'foo') });
}
{
var ee = new events.EventEmitter();
var expectLength = 2;
ee.on('removeListener', function() {
assert.strictEqual(expectLength--, this.listeners('baz').length);
});
ee.on('baz', common.mustNotCall());
ee.on('baz', common.mustNotCall());
ee.on('baz', common.mustNotCall());
assert.strictEqual(ee.listeners('baz').length, expectLength + 1);
ee.removeAllListeners('baz');
assert.strictEqual(ee.listeners('baz').length, 0);
}
{
var ee = new events.EventEmitter();
assert.strictEqual(ee, ee.removeAllListeners());
}
{
var ee = new events.EventEmitter();
ee._events = undefined;
assert.strictEqual(ee, ee.removeAllListeners());
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('./common');
var assert = require('assert');
var EventEmitter = require('../');
var listener1 = function listener1() {};
var listener2 = function listener2() {};
{
var ee = new EventEmitter();
ee.on('hello', listener1);
ee.on('removeListener', common.mustCall(function(name, cb) {
assert.strictEqual(name, 'hello');
assert.strictEqual(cb, listener1);
}));
ee.removeListener('hello', listener1);
var listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
}
{
var ee = new EventEmitter();
ee.on('hello', listener1);
ee.on('removeListener', common.mustNotCall());
ee.removeListener('hello', listener2);
var listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 1);
assert.strictEqual(listeners[0], listener1);
}
{
var ee = new EventEmitter();
ee.on('hello', listener1);
ee.on('hello', listener2);
var listeners;
ee.once('removeListener', common.mustCall(function(name, cb) {
assert.strictEqual(name, 'hello');
assert.strictEqual(cb, listener1);
listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 1);
assert.strictEqual(listeners[0], listener2);
}));
ee.removeListener('hello', listener1);
listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 1);
assert.strictEqual(listeners[0], listener2);
ee.once('removeListener', common.mustCall(function(name, cb) {
assert.strictEqual(name, 'hello');
assert.strictEqual(cb, listener2);
listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
}));
ee.removeListener('hello', listener2);
listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
}
{
var ee = new EventEmitter();
function remove1() {
assert.fail('remove1 should not have been called');
}
function remove2() {
assert.fail('remove2 should not have been called');
}
ee.on('removeListener', common.mustCall(function(name, cb) {
if (cb !== remove1) return;
this.removeListener('quux', remove2);
this.emit('quux');
}, 2));
ee.on('quux', remove1);
ee.on('quux', remove2);
ee.removeListener('quux', remove1);
}
{
var ee = new EventEmitter();
ee.on('hello', listener1);
ee.on('hello', listener2);
var listeners;
ee.once('removeListener', common.mustCall(function(name, cb) {
assert.strictEqual(name, 'hello');
assert.strictEqual(cb, listener1);
listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 1);
assert.strictEqual(listeners[0], listener2);
ee.once('removeListener', common.mustCall(function(name, cb) {
assert.strictEqual(name, 'hello');
assert.strictEqual(cb, listener2);
listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
}));
ee.removeListener('hello', listener2);
listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
}));
ee.removeListener('hello', listener1);
listeners = ee.listeners('hello');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 0);
}
{
var ee = new EventEmitter();
var listener3 = common.mustCall(function() {
ee.removeListener('hello', listener4);
}, 2);
var listener4 = common.mustCall();
ee.on('hello', listener3);
ee.on('hello', listener4);
// listener4 will still be called although it is removed by listener 3.
ee.emit('hello');
// This is so because the interal listener array at time of emit
// was [listener3,listener4]
// Interal listener array [listener3]
ee.emit('hello');
}
{
var ee = new EventEmitter();
ee.once('hello', listener1);
ee.on('removeListener', common.mustCall(function(eventName, listener) {
assert.strictEqual(eventName, 'hello');
assert.strictEqual(listener, listener1);
}));
ee.emit('hello');
}
{
var ee = new EventEmitter();
assert.strictEqual(ee, ee.removeListener('foo', function() {}));
}
// Verify that the removed listener must be a function
assert.throws(function() {
var ee = new EventEmitter();
ee.removeListener('foo', null);
}, /^TypeError: The "listener" argument must be of type Function\. Received type object$/);
{
var ee = new EventEmitter();
var listener = function() {};
ee._events = undefined;
var e = ee.removeListener('foo', listener);
assert.strictEqual(e, ee);
}
{
var ee = new EventEmitter();
ee.on('foo', listener1);
ee.on('foo', listener2);
var listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 2);
assert.strictEqual(listeners[0], listener1);
assert.strictEqual(listeners[1], listener2);
ee.removeListener('foo', listener1);
assert.strictEqual(ee._events.foo, listener2);
ee.on('foo', listener1);
listeners = ee.listeners('foo');
assert.ok(Array.isArray(listeners));
assert.strictEqual(listeners.length, 2);
assert.strictEqual(listeners[0], listener2);
assert.strictEqual(listeners[1], listener1);
ee.removeListener('foo', listener1);
assert.strictEqual(ee._events.foo, listener2);
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
require('./common');
var assert = require('assert');
var events = require('../');
var e = new events.EventEmitter();
if (Object.create) assert.ok(!(e._events instanceof Object));
assert.strictEqual(Object.keys(e._events).length, 0);
e.setMaxListeners(5);
assert.strictEqual(Object.keys(e._events).length, 0);
'use strict';
var common = require('./common');
var EventEmitter = require('../');
var assert = require('assert');
var ee = new EventEmitter();
var handler = function() {};
assert.strictEqual(ee.eventNames().length, 0);
assert.strictEqual(ee._events.hasOwnProperty, undefined);
assert.strictEqual(ee._events.toString, undefined);
ee.on('__defineGetter__', handler);
ee.on('toString', handler);
ee.on('__proto__', handler);
assert.strictEqual(ee.eventNames()[0], '__defineGetter__');
assert.strictEqual(ee.eventNames()[1], 'toString');
assert.strictEqual(ee.listeners('__defineGetter__').length, 1);
assert.strictEqual(ee.listeners('__defineGetter__')[0], handler);
assert.strictEqual(ee.listeners('toString').length, 1);
assert.strictEqual(ee.listeners('toString')[0], handler);
// Only run __proto__ tests if that property can actually be set
if ({ __proto__: 'ok' }.__proto__ === 'ok') {
assert.strictEqual(ee.eventNames().length, 3);
assert.strictEqual(ee.eventNames()[2], '__proto__');
assert.strictEqual(ee.listeners('__proto__').length, 1);
assert.strictEqual(ee.listeners('__proto__')[0], handler);
ee.on('__proto__', common.mustCall(function(val) {
assert.strictEqual(val, 1);
}));
ee.emit('__proto__', 1);
process.on('__proto__', common.mustCall(function(val) {
assert.strictEqual(val, 1);
}));
process.emit('__proto__', 1);
} else {
console.log('# skipped __proto__')
}
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('./common');
var test = require('tape');
var assert = require('assert');
var EventEmitter = require('../').EventEmitter;
var util = require('util');
util.inherits(MyEE, EventEmitter);
function MyEE(cb) {
this.once(1, cb);
this.emit(1);
this.removeAllListeners();
EventEmitter.call(this);
}
var myee = new MyEE(common.mustCall());
util.inherits(ErrorEE, EventEmitter);
function ErrorEE() {
this.emit('error', new Error('blerg'));
}
assert.throws(function() {
new ErrorEE();
}, /blerg/);
test.onFinish(function() {
assert.ok(!(myee._events instanceof Object));
assert.strictEqual(Object.keys(myee._events).length, 0);
});
function MyEE2() {
EventEmitter.call(this);
}
MyEE2.prototype = new EventEmitter();
var ee1 = new MyEE2();
var ee2 = new MyEE2();
ee1.on('x', function() {});
assert.strictEqual(ee2.listenerCount('x'), 0);
'use strict';
var common = require('./common');
var EventEmitter = require('../');
var assert = require('assert');
var ee = new EventEmitter();
var foo = Symbol('foo');
var listener = common.mustCall();
ee.on(foo, listener);
assert.strictEqual(ee.listeners(foo).length, 1);
assert.strictEqual(ee.listeners(foo)[0], listener);
ee.emit(foo);
ee.removeAllListeners();
assert.strictEqual(ee.listeners(foo).length, 0);
ee.on(foo, listener);
assert.strictEqual(ee.listeners(foo).length, 1);
assert.strictEqual(ee.listeners(foo)[0], listener);
ee.removeListener(foo, listener);
assert.strictEqual(ee.listeners(foo).length, 0);
# http://editorconfig.org
root = true
[*]
# Use hard or soft tabs
indent_style = space
# Size of a single indent
indent_size = tab
# Number of columns representing a tab character
tab_width = 2
# Use line-feed as EOL indicator
end_of_line = lf
# Use UTF-8 character encoding for all files
charset = utf-8
# Remove any whitespace characters preceding newline characters
trim_trailing_whitespace = true
# Ensure file ends with a newline when saving
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
language: node_js
node_js:
- '0.12'
- '4'
- '6'
- '8'
- '10'
# Contributing to EventSource
If you add or fix something, add tests.
## Release process
Update `HISTORY.md`, Then:
npm outdated --depth 0 # See if you can upgrade something
npm run polyfill
git commit ...
npm version [major|minor|patch]
npm publish
# [1.0.7](https://github.com/EventSource/eventsource/compare/v1.0.6...v1.0.7)
* Add dispatchEvent to EventSource ([#101](https://github.com/EventSource/eventsource/pull/101) Ali Afroozeh)
* Added `checkServerIdentity` option ([#104](https://github.com/EventSource/eventsource/pull/104) cintolas)
* Surface request error message ([#107](https://github.com/EventSource/eventsource/pull/107) RasPhilCo)
# [1.0.6](https://github.com/EventSource/eventsource/compare/v1.0.5...v1.0.6)
* Fix issue where a unicode sequence split in two chunks would lead to invalid messages ([#108](https://github.com/EventSource/eventsource/pull/108) Espen Hovlandsdal)
* Change example to use `eventsource/ssestream` (Aslak Hellesøy)
# [1.0.5](https://github.com/EventSource/eventsource/compare/v1.0.4...v1.0.5)
* Check for `window` existing before polyfilling. ([#80](https://github.com/EventSource/eventsource/pull/80) Neftaly Hernandez)
# [1.0.4](https://github.com/EventSource/eventsource/compare/v1.0.2...v1.0.4)
* Pass withCredentials on to the XHR. ([#79](https://github.com/EventSource/eventsource/pull/79) Ken Mayer)
# [1.0.2](https://github.com/EventSource/eventsource/compare/v1.0.1...v1.0.2)
* Fix proxy not working when proxy and target URL uses different protocols. ([#76](https://github.com/EventSource/eventsource/pull/76) Espen Hovlandsdal)
* Make `close()` a prototype method instead of an instance method. ([#77](https://github.com/EventSource/eventsource/pull/77) Espen Hovlandsdal)
# [1.0.1](https://github.com/EventSource/eventsource/compare/v1.0.0...v1.0.1)
* Reconnect if server responds with HTTP 500, 502, 503 or 504. ([#74](https://github.com/EventSource/eventsource/pull/74) Vykintas Narmontas)
# [1.0.0](https://github.com/EventSource/eventsource/compare/v0.2.3...v1.0.0)
* Add missing `removeEventListener`-method. ([#51](https://github.com/EventSource/eventsource/pull/51) Yucheng Tu / Espen Hovlandsdal)
* Fix EventSource reconnecting on non-200 responses. ([af84476](https://github.com/EventSource/eventsource/commit/af84476b519a01e61b8c80727261df52ae40022c) Espen Hovlandsdal)
* Add ability to customize https options. ([#53](https://github.com/EventSource/eventsource/pull/53) Rafael Alfaro)
* Add readyState constants to EventSource instances. ([#66](https://github.com/EventSource/eventsource/pull/66) Espen Hovlandsdal)
# [0.2.3](https://github.com/EventSource/eventsource/compare/v0.2.2...v0.2.3)
* Fix `onConnectionClosed` firing multiple times resulting in multiple connections. ([#61](https://github.com/EventSource/eventsource/pull/61) Phil Strong / Duncan Wong)
* Remove unneeded isPlainObject check for headers. ([#64](https://github.com/EventSource/eventsource/pull/64) David Mark)
# [0.2.2](https://github.com/EventSource/eventsource/compare/v0.2.1...v0.2.2)
* Don't include test files in npm package. ([#56](https://github.com/EventSource/eventsource/pull/56) eanplatter)
# [0.2.1](https://github.com/EventSource/eventsource/compare/v0.2.0...v0.2.1)
* Fix `close()` for polyfill. ([#52](https://github.com/EventSource/eventsource/pull/52) brian-medendorp)
* Add http/https proxy function. ([#46](https://github.com/EventSource/eventsource/pull/46) Eric Lu)
* Fix reconnect for polyfill. Only disable reconnect when server status is 204. (Aslak Hellesøy).
* Drop support for Node 0.10.x and older (Aslak Hellesøy).
# [0.2.0](https://github.com/EventSource/eventsource/compare/v0.1.6...v0.2.0)
* Renamed repository to `eventsource` (since it's not just Node, but also browser polyfill). (Aslak Hellesøy).
* Compatibility with webpack/browserify. ([#44](https://github.com/EventSource/eventsource/pull/44) Adriano Raiano).
# [0.1.6](https://github.com/EventSource/eventsource/compare/v0.1.5...v0.1.6)
* Ignore headers without a value. ([#41](https://github.com/EventSource/eventsource/issues/41), [#43](https://github.com/EventSource/eventsource/pull/43) Adriano Raiano)
# [0.1.5](https://github.com/EventSource/eventsource/compare/v0.1.4...v0.1.5)
* Refactor tests to support Node.js 0.12.0 and Io.js 1.1.0. (Aslak Hellesøy)
# [0.1.4](https://github.com/EventSource/eventsource/compare/v0.1.3...master)
* Bugfix: Added missing origin property. ([#39](https://github.com/EventSource/eventsource/pull/39), [#38](https://github.com/EventSource/eventsource/issues/38) Arnout Kazemier)
* Expose `status` property on `error` events. ([#40](https://github.com/EventSource/eventsource/pull/40) Adriano Raiano)
# [0.1.3](https://github.com/EventSource/eventsource/compare/v0.1.2...v0.1.3)
* Bugfix: Made message properties enumerable. ([#37](https://github.com/EventSource/eventsource/pull/37) Golo Roden)
# [0.1.2](https://github.com/EventSource/eventsource/compare/v0.1.1...v0.1.2)
* Bugfix: Blank lines not read. ([#35](https://github.com/EventSource/eventsource/issues/35), [#36](https://github.com/EventSource/eventsource/pull/36) Lesterpig)
# [0.1.1](https://github.com/EventSource/eventsource/compare/v0.1.0...v0.1.1)
* Bugfix: Fix message type. ([#33](https://github.com/EventSource/eventsource/pull/33) Romain Gauthier)
# [0.1.0](https://github.com/EventSource/eventsource/compare/v0.0.10...v0.1.0)
* Bugfix: High CPU usage by replacing Jison with port of WebKit's parser. ([#25](https://github.com/EventSource/eventsource/issues/25), [#32](https://github.com/EventSource/eventsource/pull/32), [#18](https://github.com/EventSource/eventsource/issues/18) qqueue)
* Reformatted all code to 2 spaces.
# [0.0.10](https://github.com/EventSource/eventsource/compare/v0.0.9...v0.0.10)
* Provide `Event` argument on `open` and `error` event ([#30](https://github.com/EventSource/eventsource/issues/30), [#31](https://github.com/EventSource/eventsource/pull/31) Donghwan Kim)
* Expose `lastEventId` on messages. ([#28](https://github.com/EventSource/eventsource/pull/28) mbieser)
# [0.0.9](https://github.com/EventSource/eventsource/compare/v0.0.8...v0.0.9)
* Bugfix: old "last-event-id" used on reconnect ([#27](https://github.com/EventSource/eventsource/pull/27) Aslak Hellesøy)
# [0.0.8](https://github.com/EventSource/eventsource/compare/v0.0.7...v0.0.8)
* Bugfix: EventSource still reconnected when closed ([#24](https://github.com/EventSource/eventsource/pull/24) FrozenCow)
* Allow unauthorized HTTPS connections by setting `rejectUnauthorized` to false. (Aslak Hellesøy)
# [0.0.7](https://github.com/EventSource/eventsource/compare/v0.0.6...v0.0.7)
* Explicitly raise an error when server returns http 403 and don't continue ([#20](https://github.com/EventSource/eventsource/pull/20) Scott Moak)
* Added ability to send custom http headers to server ([#21](https://github.com/EventSource/eventsource/pull/21), [#9](https://github.com/EventSource/eventsource/issues/9) Scott Moak)
* Fix Unicode support to cope with Javascript Unicode size limitations ([#23](https://github.com/EventSource/eventsource/pull/23), [#22](https://github.com/EventSource/eventsource/issues/22) Devon Adkisson)
* Graceful handling of parse errors ([#19](https://github.com/EventSource/eventsource/issues/19) Aslak Hellesøy)
* Switched from testing with Nodeunit to Mocha (Aslak Hellesøy)
# [0.0.6](https://github.com/EventSource/eventsource/compare/v0.0.5...v0.0.6)
* Add Accept: text/event-stream header ([#17](https://github.com/EventSource/eventsource/pull/17) William Wicks)
# [0.0.5](https://github.com/EventSource/eventsource/compare/v0.0.4...v0.0.5)
* Add no-cache and https support ([#10](https://github.com/EventSource/eventsource/pull/10) Einar Otto Stangvik)
* Ensure that Last-Event-ID is sent to the server for reconnects, as defined in the spec ([#8](https://github.com/EventSource/eventsource/pull/8) Einar Otto Stangvik)
* Verify that CR and CRLF are accepted alongside LF ([#7](https://github.com/EventSource/eventsource/pull/7) Einar Otto Stangvik)
* Emit 'open' event ([#4](https://github.com/EventSource/eventsource/issues/4) Einar Otto Stangvik)
# [0.0.4](https://github.com/EventSource/eventsource/compare/v0.0.3...v0.0.4)
* Automatic reconnect every second if the server is down. Reconnect interval can be set with `reconnectInterval` (not in W3C spec). (Aslak Hellesøy)
# [0.0.3](https://github.com/EventSource/eventsource/compare/v0.0.2...v0.0.3)
* Jison based eventstream parser ([#2](https://github.com/EventSource/eventsource/pull/2) Einar Otto Stangvik)
# [0.0.2](https://github.com/EventSource/eventsource/compare/v0.0.1...v0.0.2)
* Use native EventListener (Aslak Hellesøy)
# 0.0.1
* First release
The MIT License
Copyright (c) EventSource GitHub organisation
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# EventSource [![npm version](http://img.shields.io/npm/v/eventsource.svg?style=flat-square)](http://browsenpm.org/package/eventsource)[![Build Status](http://img.shields.io/travis/EventSource/eventsource/master.svg?style=flat-square)](https://travis-ci.org/EventSource/eventsource)[![NPM Downloads](https://img.shields.io/npm/dm/eventsource.svg?style=flat-square)](http://npm-stat.com/charts.html?package=eventsource&from=2015-09-01)[![Dependencies](https://img.shields.io/david/EventSource/eventsource.svg?style=flat-square)](https://david-dm.org/EventSource/eventsource)
This library is a pure JavaScript implementation of the [EventSource](https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events) client. The API aims to be W3C compatible.
You can use it with Node.js or as a browser polyfill for
[browsers that don't have native `EventSource` support](http://caniuse.com/#feat=eventsource).
## Install
npm install eventsource
## Example
npm install
node ./example/sse-server.js
node ./example/sse-client.js # Node.js client
open http://localhost:8080 # Browser client - both native and polyfill
curl http://localhost:8080/sse # Enjoy the simplicity of SSE
## Browser Polyfill
Just add `example/eventsource-polyfill.js` file to your web page:
```html
<script src=/eventsource-polyfill.js></script>
```
Now you will have two global constructors:
```javascript
window.EventSourcePolyfill
window.EventSource // Unchanged if browser has defined it. Otherwise, same as window.EventSourcePolyfill
```
If you're using [webpack](https://webpack.github.io/) or [browserify](http://browserify.org/)
you can of course build your own. (The `example/eventsource-polyfill.js` is built with webpack).
## Extensions to the W3C API
### Setting HTTP request headers
You can define custom HTTP headers for the initial HTTP request. This can be useful for e.g. sending cookies
or to specify an initial `Last-Event-ID` value.
HTTP headers are defined by assigning a `headers` attribute to the optional `eventSourceInitDict` argument:
```javascript
var eventSourceInitDict = {headers: {'Cookie': 'test=test'}};
var es = new EventSource(url, eventSourceInitDict);
```
### Allow unauthorized HTTPS requests
By default, https requests that cannot be authorized will cause the connection to fail and an exception
to be emitted. You can override this behaviour, along with other https options:
```javascript
var eventSourceInitDict = {https: {rejectUnauthorized: false}};
var es = new EventSource(url, eventSourceInitDict);
```
Note that for Node.js < v0.10.x this option has no effect - unauthorized HTTPS requests are *always* allowed.
### HTTP status code on error events
Unauthorized and redirect error status codes (for example 401, 403, 301, 307) are available in the `status` property in the error event.
```javascript
es.onerror = function (err) {
if (err) {
if (err.status === 401 || err.status === 403) {
console.log('not authorized');
}
}
};
```
### HTTP/HTTPS proxy
You can define a `proxy` option for the HTTP request to be used. This is typically useful if you are behind a corporate firewall.
```javascript
var es = new EventSource(url, {proxy: 'http://your.proxy.com'});
```
## License
MIT-licensed. See LICENSE
This diff could not be displayed because it is too large.
<!DOCTYPE html>
<html>
<head>
<style>
.col {
float:left;
width:50%;
left:50%;
}
</style>
</head>
<body>
<div class=col>
<h2>EventSource</h2>
<ul id=es-messages>
</ul>
</div>
<div class=col>
<h2>EventSourcePolyfill</h2>
<ul id=es-polyfill-messages>
</ul>
</div>
<script src=/eventsource-polyfill.js></script>
<script>
function subscribe(es, ul) {
es.addEventListener('server-time', function (e) {
var li = document.createElement("LI");
li.appendChild(document.createTextNode(e.data));
ul.appendChild(li);
});
}
subscribe(new EventSource('/sse'), document.getElementById('es-messages'));
subscribe(new EventSourcePolyfill('/sse'), document.getElementById('es-polyfill-messages'));
</script>
</body>
var EventSource = require('..')
var es = new EventSource('http://localhost:8080/sse')
es.addEventListener('server-time', function (e) {
console.log(e.data)
})
const express = require('express')
const serveStatic = require('serve-static')
const SseStream = require('ssestream')
const app = express()
app.use(serveStatic(__dirname))
app.get('/sse', (req, res) => {
console.log('new connection')
const sseStream = new SseStream(req)
sseStream.pipe(res)
const pusher = setInterval(() => {
sseStream.write({
event: 'server-time',
data: new Date().toTimeString()
})
}, 1000)
res.on('close', () => {
console.log('lost connection')
clearInterval(pusher)
sseStream.unpipe(res)
})
})
app.listen(8080, (err) => {
if (err) throw err
console.log('server ready on http://localhost:8080')
})
var EventSource = require('./eventsource')
if (typeof window === 'object') {
window.EventSourcePolyfill = EventSource
if (!window.EventSource) window.EventSource = EventSource
module.exports = window.EventSource
} else {
module.exports = EventSource
}
This diff is collapsed. Click to expand it.
{
"_from": "eventsource@^1.0.7",
"_id": "eventsource@1.0.7",
"_inBundle": false,
"_integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==",
"_location": "/eventsource",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "eventsource@^1.0.7",
"name": "eventsource",
"escapedName": "eventsource",
"rawSpec": "^1.0.7",
"saveSpec": null,
"fetchSpec": "^1.0.7"
},
"_requiredBy": [
"/sockjs-client"
],
"_resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz",
"_shasum": "8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0",
"_spec": "eventsource@^1.0.7",
"_where": "C:\\Users\\kkwan_000\\Desktop\\git\\2017110269\\minsung\\node_modules\\sockjs-client",
"author": {
"name": "Aslak Hellesøy",
"email": "aslak.hellesoy@gmail.com"
},
"bugs": {
"url": "http://github.com/EventSource/eventsource/issues"
},
"bundleDependencies": false,
"dependencies": {
"original": "^1.0.0"
},
"deprecated": false,
"description": "W3C compliant EventSource client for Node.js and browser (polyfill)",
"devDependencies": {
"buffer-from": "^1.1.1",
"express": "^4.15.3",
"mocha": "^3.5.3",
"nyc": "^11.2.1",
"serve-static": "^1.12.3",
"ssestream": "^1.0.0",
"standard": "^10.0.2",
"webpack": "^3.5.6"
},
"directories": {
"lib": "./lib"
},
"engines": {
"node": ">=0.12.0"
},
"homepage": "http://github.com/EventSource/eventsource",
"keywords": [
"eventsource",
"http",
"streaming",
"sse",
"polyfill"
],
"license": "MIT",
"licenses": [
{
"type": "MIT",
"url": "http://github.com/EventSource/eventsource/raw/master/LICENSE"
}
],
"main": "./lib/eventsource",
"name": "eventsource",
"repository": {
"type": "git",
"url": "git://github.com/EventSource/eventsource.git"
},
"scripts": {
"coverage": "nyc --reporter=html --reporter=text _mocha --reporter spec",
"polyfill": "webpack lib/eventsource-polyfill.js example/eventsource-polyfill.js",
"postpublish": "git push && git push --tags",
"test": "mocha --reporter spec && standard"
},
"standard": {
"ignore": [
"example/eventsource-polyfill.js"
]
},
"version": "1.0.7"
}
This diff could not be displayed because it is too large.
The MIT License (MIT)
Copyright (c) 2017 crypto-browserify contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# EVP\_BytesToKey
[![NPM Package](https://img.shields.io/npm/v/evp_bytestokey.svg?style=flat-square)](https://www.npmjs.org/package/evp_bytestokey)
[![Build Status](https://img.shields.io/travis/crypto-browserify/EVP_BytesToKey.svg?branch=master&style=flat-square)](https://travis-ci.org/crypto-browserify/EVP_BytesToKey)
[![Dependency status](https://img.shields.io/david/crypto-browserify/EVP_BytesToKey.svg?style=flat-square)](https://david-dm.org/crypto-browserify/EVP_BytesToKey#info=dependencies)
[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)
The insecure [key derivation algorithm from OpenSSL.][1]
**WARNING: DO NOT USE, except for compatibility reasons.**
MD5 is insecure.
Use at least `scrypt` or `pbkdf2-hmac-sha256` instead.
## API
`EVP_BytesToKey(password, salt, keyLen, ivLen)`
* `password` - `Buffer`, password used to derive the key data.
* `salt` - 8 byte `Buffer` or `null`, salt is used as a salt in the derivation.
* `keyBits` - `number`, key length in **bits**.
* `ivLen` - `number`, iv length in bytes.
*Returns*: `{ key: Buffer, iv: Buffer }`
## Examples
MD5 with `aes-256-cbc`:
```js
const crypto = require('crypto')
const EVP_BytesToKey = require('evp_bytestokey')
const result = EVP_BytesToKey(
'my-secret-password',
null,
32,
16
)
// =>
// { key: <Buffer e3 4f 96 f3 86 24 82 7c c2 5d ff 23 18 6f 77 72 54 45 7f 49 d4 be 4b dd 4f 6e 1b cc 92 a4 27 33>,
// iv: <Buffer 85 71 9a bf ae f4 1e 74 dd 46 b6 13 79 56 f5 5b> }
const cipher = crypto.createCipheriv('aes-256-cbc', result.key, result.iv)
```
## LICENSE [MIT](LICENSE)
[1]: https://wiki.openssl.org/index.php/Manual:EVP_BytesToKey(3)
[2]: https://nodejs.org/api/crypto.html#crypto_class_hash
var Buffer = require('safe-buffer').Buffer
var MD5 = require('md5.js')
/* eslint-disable camelcase */
function EVP_BytesToKey (password, salt, keyBits, ivLen) {
if (!Buffer.isBuffer(password)) password = Buffer.from(password, 'binary')
if (salt) {
if (!Buffer.isBuffer(salt)) salt = Buffer.from(salt, 'binary')
if (salt.length !== 8) throw new RangeError('salt should be Buffer with 8 byte length')
}
var keyLen = keyBits / 8
var key = Buffer.alloc(keyLen)
var iv = Buffer.alloc(ivLen || 0)
var tmp = Buffer.alloc(0)
while (keyLen > 0 || ivLen > 0) {
var hash = new MD5()
hash.update(tmp)
hash.update(password)
if (salt) hash.update(salt)
tmp = hash.digest()
var used = 0
if (keyLen > 0) {
var keyStart = key.length - keyLen
used = Math.min(keyLen, tmp.length)
tmp.copy(key, keyStart, 0, used)
keyLen -= used
}
if (used < tmp.length && ivLen > 0) {
var ivStart = iv.length - ivLen
var length = Math.min(ivLen, tmp.length - used)
tmp.copy(iv, ivStart, used, used + length)
ivLen -= length
}
}
tmp.fill(0)
return { key: key, iv: iv }
}
module.exports = EVP_BytesToKey
{
"_from": "evp_bytestokey@^1.0.0",
"_id": "evp_bytestokey@1.0.3",
"_inBundle": false,
"_integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
"_location": "/evp_bytestokey",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "evp_bytestokey@^1.0.0",
"name": "evp_bytestokey",
"escapedName": "evp_bytestokey",
"rawSpec": "^1.0.0",
"saveSpec": null,
"fetchSpec": "^1.0.0"
},
"_requiredBy": [
"/browserify-aes",
"/browserify-cipher",
"/parse-asn1"
],
"_resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
"_shasum": "7fcbdb198dc71959432efe13842684e0525acb02",
"_spec": "evp_bytestokey@^1.0.0",
"_where": "C:\\Users\\kkwan_000\\Desktop\\git\\2017110269\\minsung\\node_modules\\browserify-cipher",
"author": {
"name": "Calvin Metcalf",
"email": "calvin.metcalf@gmail.com"
},
"bugs": {
"url": "https://github.com/crypto-browserify/EVP_BytesToKey/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Kirill Fomichev",
"email": "fanatid@ya.ru"
}
],
"dependencies": {
"md5.js": "^1.3.4",
"safe-buffer": "^5.1.1"
},
"deprecated": false,
"description": "The insecure key derivation algorithm from OpenSSL",
"devDependencies": {
"bindings": "^1.2.1",
"nan": "^2.4.0",
"nyc": "^8.1.0",
"standard": "^8.0.0",
"tape": "^4.6.0"
},
"files": [
"index.js"
],
"gypfile": false,
"homepage": "https://github.com/crypto-browserify/EVP_BytesToKey",
"keywords": [
"crypto",
"openssl"
],
"license": "MIT",
"main": "index.js",
"name": "evp_bytestokey",
"repository": {
"type": "git",
"url": "git+https://github.com/crypto-browserify/EVP_BytesToKey.git"
},
"scripts": {
"coverage": "nyc tape test/*.js",
"lint": "standard",
"test": "npm run lint && npm run unit",
"test:prepare": "node-gyp rebuild",
"unit": "tape test/*.js"
},
"version": "1.0.3"
}
{
// --------------------------------------------------------------------
// JSHint Configuration, Strict Edition
// --------------------------------------------------------------------
//
// This is a options template for [JSHint][1], using [JSHint example][2]
// and [Ory Band's example][3] as basis and setting config values to
// be most strict:
//
// * set all enforcing options to true
// * set all relaxing options to false
// * set all environment options to false, except the browser value
// * set all JSLint legacy options to false
//
// [1]: http://www.jshint.com/
// [2]: https://github.com/jshint/node-jshint/blob/master/example/config.json
// [3]: https://github.com/oryband/dotfiles/blob/master/jshintrc
//
// @author http://michael.haschke.biz/
// @license http://unlicense.org/
// == Enforcing Options ===============================================
//
// These options tell JSHint to be more strict towards your code. Use
// them if you want to allow only a safe subset of JavaScript, very
// useful when your codebase is shared with a big number of developers
// with different skill levels.
"bitwise" : true, // Prohibit bitwise operators (&, |, ^, etc.).
"curly" : true, // Require {} for every new block or scope.
"eqeqeq" : true, // Require triple equals i.e. `===`.
"forin" : true, // Tolerate `for in` loops without `hasOwnPrototype`.
"immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );`
"latedef" : true, // Prohibit variable use before definition.
"newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`.
"noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`.
"noempty" : true, // Prohibit use of empty blocks.
"nonew" : true, // Prohibit use of constructors for side-effects.
"plusplus" : true, // Prohibit use of `++` & `--`.
"regexp" : true, // Prohibit `.` and `[^...]` in regular expressions.
"undef" : true, // Require all non-global variables be declared before they are used.
"strict" : false, // Require `use strict` pragma in every file.
"trailing" : true, // Prohibit trailing whitespaces.
// == Relaxing Options ================================================
//
// These options allow you to suppress certain types of warnings. Use
// them only if you are absolutely positive that you know what you are
// doing.
"asi" : false, // Tolerate Automatic Semicolon Insertion (no semicolons).
"boss" : false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments.
"debug" : false, // Allow debugger statements e.g. browser breakpoints.
"eqnull" : false, // Tolerate use of `== null`.
"es5" : false, // Allow EcmaScript 5 syntax.
"esnext" : false, // Allow ES.next specific features such as `const` and `let`.
"evil" : false, // Tolerate use of `eval`.
"expr" : false, // Tolerate `ExpressionStatement` as Programs.
"funcscope" : false, // Tolerate declarations of variables inside of control structures while accessing them later from the outside.
"globalstrict" : false, // Allow global "use strict" (also enables 'strict').
"iterator" : false, // Allow usage of __iterator__ property.
"lastsemic" : false, // Tolerat missing semicolons when the it is omitted for the last statement in a one-line block.
"laxbreak" : false, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons.
"laxcomma" : false, // Suppress warnings about comma-first coding style.
"loopfunc" : false, // Allow functions to be defined within loops.
"multistr" : false, // Tolerate multi-line strings.
"onecase" : false, // Tolerate switches with just one case.
"proto" : false, // Tolerate __proto__ property. This property is deprecated.
"regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`.
"scripturl" : false, // Tolerate script-targeted URLs.
"smarttabs" : false, // Tolerate mixed tabs and spaces when the latter are used for alignmnent only.
"shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`.
"sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`.
"supernew" : false, // Tolerate `new function () { ... };` and `new Object;`.
"validthis" : false, // Tolerate strict violations when the code is running in strict mode and you use this in a non-constructor function.
// == Environments ====================================================
//
// These options pre-define global variables that are exposed by
// popular JavaScript libraries and runtime environments—such as
// browser or node.js.
"browser" : false, // Standard browser globals e.g. `window`, `document`.
"couch" : false, // Enable globals exposed by CouchDB.
"devel" : false, // Allow development statements e.g. `console.log();`.
"dojo" : false, // Enable globals exposed by Dojo Toolkit.
"jquery" : false, // Enable globals exposed by jQuery JavaScript library.
"mootools" : false, // Enable globals exposed by MooTools JavaScript framework.
"node" : true, // Enable globals available when code is running inside of the NodeJS runtime environment.
"nonstandard" : false, // Define non-standard but widely adopted globals such as escape and unescape.
"prototypejs" : false, // Enable globals exposed by Prototype JavaScript framework.
"rhino" : false, // Enable globals available when your code is running inside of the Rhino runtime environment.
"wsh" : false, // Enable globals available when your code is running as a script for the Windows Script Host.
// == JSLint Legacy ===================================================
//
// These options are legacy from JSLint. Aside from bug fixes they will
// not be improved in any way and might be removed at any point.
"nomen" : false, // Prohibit use of initial or trailing underbars in names.
"onevar" : false, // Allow only one `var` statement per function.
"passfail" : false, // Stop on first error.
"white" : false, // Check against strict whitespace and indentation rules.
// == Undocumented Options ============================================
//
// While I've found these options in [example1][2] and [example2][3]
// they are not described in the [JSHint Options documentation][4].
//
// [4]: http://www.jshint.com/options/
"maxerr" : 100, // Maximum errors before stopping.
"predef" : [ // Extra globals.
//"exampleVar",
//"anotherCoolGlobal",
//"iLoveDouglas"
],
"indent" : 2, // Specify indentation spacing
"maxlen" : 100 // The maximum number of characters in a line.
}
\ No newline at end of file
language: node_js
node_js:
- 'node'
after_success:
- npm run jsdoc
- cat artifacts/coverage/lcov.info | node_modules/coveralls/bin/coveralls.js
notifications:
slack:
secure: k4kpAZcA1Mu7LHs58m4JkMbGtpWPI8BPYqmqKVfHBE21daaqRYgpHOiLyWiFhv83xkiOWWfDAS2svvS2h2jDmaRzieVBlonQlhGgDEu123Mobvi8nUxeu6bNxoFSRwKXVx8uTCGKmzwqWz870Y6d7+TUQnMhhdl0GRB2tqAhY0A=
deploy:
- provider: s3
access_key_id:
secure: IQXPBnuNyREtmNN+W9bONLok5lFO9+JzQ3n5nK/uRHTuYDgS4ZbKJwaJ1dRNS6Zb8qAgVyIq8FBVa4olbvH6sfxGwVluwY0ujskvgA5hOMEpyjJ5zQx5+boWDTz9wNdMUe4ImygJjcpTjn33wMu9arFLMyIQdKysrlfU1HlRWB0=
secret_access_key:
secure: lIFQHzB5Sfzi0BmYM/b8PzEtdwOUQjtTPBGdTjX09b7OFVsb3M4FROaAsaTMrbZ+L6TyLD9fDBJMPHW7xZTnrZG1zcKIjZITT25Ec/2YQ9CCdAdbr+NobKrjaJ6dIcF2NKcUaRQQvRE9E8uC/KVveWGEC7ITtv0yssuADNSdcOU=
bucket: tsertkov-artifacts
local-dir: artifacts
upload-dir: exec-sh/master
acl: public_read
skip_cleanup: true
region: eu-central-1
endpoint: s3.eu-central-1.amazonaws.com
on:
branch: master
- provider: s3
access_key_id:
secure: IQXPBnuNyREtmNN+W9bONLok5lFO9+JzQ3n5nK/uRHTuYDgS4ZbKJwaJ1dRNS6Zb8qAgVyIq8FBVa4olbvH6sfxGwVluwY0ujskvgA5hOMEpyjJ5zQx5+boWDTz9wNdMUe4ImygJjcpTjn33wMu9arFLMyIQdKysrlfU1HlRWB0=
secret_access_key:
secure: lIFQHzB5Sfzi0BmYM/b8PzEtdwOUQjtTPBGdTjX09b7OFVsb3M4FROaAsaTMrbZ+L6TyLD9fDBJMPHW7xZTnrZG1zcKIjZITT25Ec/2YQ9CCdAdbr+NobKrjaJ6dIcF2NKcUaRQQvRE9E8uC/KVveWGEC7ITtv0yssuADNSdcOU=
bucket: tsertkov-artifacts
local-dir: artifacts
upload-dir: exec-sh/develop
acl: public_read
skip_cleanup: true
region: eu-central-1
endpoint: s3.eu-central-1.amazonaws.com
on:
branch: develop
The MIT License (MIT)
Copyright (c) 2014 Aleksandr Tsertkov <tsertkov@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# exec-sh
[![NPM](https://nodei.co/npm/exec-sh.png)](https://nodei.co/npm/exec-sh/)
[![NPM Downloads](https://img.shields.io/npm/dm/exec-sh.svg)](https://www.npmjs.com/package/exec-sh)
[![Build Status](https://travis-ci.org/tsertkov/exec-sh.svg?branch=master)](https://travis-ci.org/tsertkov/exec-sh)
[![Coverage Status](https://img.shields.io/coveralls/tsertkov/exec-sh.svg)](https://coveralls.io/r/tsertkov/exec-sh?branch=master)
[![David Status](https://david-dm.org/tsertkov/exec-sh.png)](https://david-dm.org/tsertkov/exec-sh)
> Execute shell command forwarding all stdio streams.
## Features
exec-sh is a wrapper for [`child_process.spawn`](http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options) with some improvements:
- Cross platform command execution:
- Windows: `cmd /C COMMAND`
- others: `sh -c COMMAND`
- Fowrards all stdio streams to current terminal (by default):
- `execSh("bash")`
- `execsh("echo -n Say: && read i && echo Said:$i")`
- stdout and stderr are passed to callback when available
- `execSh("pwd", console.log)`
## Showcase
```javascript
// JavaScript
execSh("echo hello exec-sh && bash", { cwd: "/home" }, function(err){
if (err) {
console.log("Exit code: ", err.code);
}
});
```
```sh
# Terminal output: interactive bash session
hello exec-sh
bash-3.2$ pwd
/home
bash-3.2$ exit 99
exit
Exit code: 99
```
## Usage
```javascript
var execSh = require("../");
// run interactive bash shell
execSh("echo lorem && bash", { cwd: "/home" }, function(err){
if (err) {
console.log("Exit code: ", err.code);
return;
}
// collect streams output
var child = execSh(["bash -c id", "echo lorem >&2"], true,
function(err, stdout, stderr){
console.log("error: ", err);
console.log("stdout: ", stdout);
console.log("stderr: ", stderr);
});
});
```
## Promise Interface
```javascript
var execShPromise = require("exec-sh").promise;
// run interactive bash shell
const run = async () => {
let out;
try {
out = await execShPromise('pwd', true);
} catch (e) {
console.log('Error: ', e);
console.log('Stderr: ', e.stderr);
console.log('Stdout: ', e.stdout);
return e;
}
console.log('out: ', out.stdout, out.stderr);
}
run();
```
## Public API
### `execSh(command, [options], [callback])`
Execute shell command forwarding all stdio.
**Parameters:**
- `command {String|Array}` - The command to run, or array of commands
- `[options] {Object|TRUE}` - Options object passed directly to [`child_process.spawn`](http://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options), when `TRUE` then `{ stdio: null }` used
- `[callback] {Function}` - `callback(err, stdout, stderr)`
- `err {Error|NULL}` - Error object. Has `code` property containing last command exit code when available
- `stdout {String|NULL}` - aggregated stdout or `NULL` if not available
- `stderr {String|NULL}` - aggregated stderr or `NULL` if not available
**Return Values:**
Returns [ChildProcess](http://nodejs.org/api/child_process.html#child_process_class_childprocess) object.
## Private API
Complete API Documentation including private and public methods is generated from source code by JSDoc tool and is [available here](https://s3.eu-central-1.amazonaws.com/tsertkov-artifacts/exec-sh/master/jsdoc/index.html).
## Code Coverage
Code coverage report for all files is [available here](https://s3.eu-central-1.amazonaws.com/tsertkov-artifacts/exec-sh/master/coverage/index.html).
## Scripts
- `npm test` - run tests
- `npm run jsdoc` - build jsdoc
- `npm run dev` - run tests continuously
## License
The MIT License (MIT)
var execSh = require('../')
// run interactive bash shell
execSh('echo ola && bash', { cwd: '/home' }, function (err) {
if (err) {
console.log('Exit code: ', err.code)
return
}
// collect streams output
execSh(['bash -c id', 'echo olaola >&2'], true,
function (err, stdout, stderr) {
console.log('error: ', err)
console.log('stdout: ', stdout)
console.log('stderr: ', stderr)
})
})
var cp = require('child_process')
var defSpawnOptions = { stdio: 'inherit' }
/**
* @summary Get shell program meta for current platform
* @private
* @returns {Object}
*/
function getShell () {
if (process.platform === 'win32') {
return { cmd: 'cmd', arg: '/C' }
} else {
return { cmd: 'sh', arg: '-c' }
}
}
/**
* Callback is called with the output when the process terminates. Output is
* available when true is passed as options argument or stdio: null set
* within given options.
*
* @summary Execute shell command forwarding all stdio
* @param {String|Array} command
* @param {Object|TRUE} [options] spawn() options or TRUE to set stdio: null
* @param {Function} [callback]
* @returns {ChildProcess}
*/
function execSh (command, options, callback) {
if (Array.isArray(command)) {
command = command.join(';')
}
if (options === true) {
options = { stdio: null }
}
if (typeof options === 'function') {
callback = options
options = defSpawnOptions
} else {
options = options || {}
options = Object.assign({}, defSpawnOptions, options)
callback = callback || function () {}
}
var child
var stdout = ''
var stderr = ''
var shell = getShell()
try {
child = cp.spawn(shell.cmd, [shell.arg, command], options)
} catch (e) {
callback(e, stdout, stderr)
return
}
if (child.stdout) {
child.stdout.on('data', function (data) {
stdout += data
})
}
if (child.stderr) {
child.stderr.on('data', function (data) {
stderr += data
})
}
child.on('close', function (code) {
if (code) {
var e = new Error('Shell command exit with non zero code: ' + code)
e.code = code
callback(e, stdout, stderr)
} else {
callback(null, stdout, stderr)
}
})
return child
}
execSh.promise = function (command, options) {
return new Promise(function (resolve, reject) {
execSh(command, options, function (err, stdout, stderr) {
if (err) {
err.stdout = stdout
err.stderr = stderr
return reject(err)
}
resolve({
stderr: stderr,
stdout: stdout
})
})
})
}
module.exports = execSh
{
"_from": "exec-sh@^0.3.2",
"_id": "exec-sh@0.3.4",
"_inBundle": false,
"_integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==",
"_location": "/exec-sh",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "exec-sh@^0.3.2",
"name": "exec-sh",
"escapedName": "exec-sh",
"rawSpec": "^0.3.2",
"saveSpec": null,
"fetchSpec": "^0.3.2"
},
"_requiredBy": [
"/@cnakazawa/watch",
"/sane"
],
"_resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz",
"_shasum": "3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5",
"_spec": "exec-sh@^0.3.2",
"_where": "C:\\Users\\kkwan_000\\Desktop\\git\\2017110269\\minsung\\node_modules\\sane",
"author": {
"name": "Aleksandr Tsertkov",
"email": "tsertkov@gmail.com"
},
"bugs": {
"url": "https://github.com/tsertkov/exec-sh/issues"
},
"bundleDependencies": false,
"dependencies": {},
"deprecated": false,
"description": "Execute shell command forwarding all stdio.",
"devDependencies": {
"coveralls": "^3.0.7",
"jsdoc": "^3.6.3",
"jshint": "^2.10.3",
"mocha": "^6.2.2",
"nyc": "^14.1.1",
"sinon": "^7.5.0",
"standard": "^14.3.1"
},
"homepage": "https://github.com/tsertkov/exec-sh#readme",
"keywords": [
"exec",
"spawn",
"terminal",
"console",
"shell",
"command",
"child_process"
],
"license": "MIT",
"main": "lib/exec-sh.js",
"name": "exec-sh",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/tsertkov/exec-sh.git"
},
"scripts": {
"cover-test": "nyc --reporter=html --report-dir=artifacts/coverage mocha",
"dev": "mocha --reporter spec --watch",
"jsdoc": "jsdoc --private --destination artifacts/jsdoc lib/",
"lint": "standard --verbose **/*.js",
"test": "npm run lint && npm run cover-test"
},
"version": "0.3.4"
}
/* global describe, it, beforeEach, afterEach */
var execSh = require('..')
var assert = require('assert')
var sinon = require('sinon')
var cp = require('child_process')
describe('exec-sh', function () {
describe('module.exports', function () {
it('should export a single function', function () {
assert.strictEqual(typeof execSh, 'function')
})
it('should export promise interface', function () {
assert.strictEqual(typeof execSh.promise, 'function')
})
})
describe('#execSh() arguments', function () {
var spawn, exitCode, stream
stream = {
on: function (e, c) {
if (e === 'data') {
// execute callback two times to check if stream
// aggregation works correctly
c('1')
c('2')
}
}
}
beforeEach(function () {
exitCode = 0
spawn = sinon.stub(cp, 'spawn')
spawn.returns({
spawn_return: true,
on: function (e, c) {
if (e === 'close') {
c(exitCode)
}
},
stdout: stream,
stderr: stream
})
})
afterEach(function () {
cp.spawn.restore()
})
it('should pass command to spawn function', function () {
execSh('command')
sinon.assert.calledOnce(spawn)
assert.strictEqual('command', spawn.getCall(0).args[1][1])
})
it('should accept array of commands to run', function () {
execSh(['command1', 'command2'])
sinon.assert.calledOnce(spawn)
assert.strictEqual('command1;command2', spawn.getCall(0).args[1][1])
})
it('should accept true as options argument', function () {
execSh('command', true)
sinon.assert.calledOnce(spawn)
assert.strictEqual(spawn.getCall(0).args[2].stdio, null)
})
it('should merge defaults with options', function () {
var options = { key: 'value' }
var expectedOptions = {
key: 'value',
stdio: 'inherit'
}
execSh('command', options)
assert.deepStrictEqual(spawn.getCall(0).args[2], expectedOptions)
})
it('should allow overriding default options', function () {
var options = { foo: 'bar', stdio: null }
var expectedOptions = {
foo: 'bar',
stdio: null
}
execSh('command', options)
assert.deepStrictEqual(spawn.getCall(0).args[2], expectedOptions)
})
it('should allow passing nested environment options', function () {
var options = {
env: {
key1: 'value 1',
key2: 'value 2'
}
}
var expectedOptions = {
env: {
key1: 'value 1',
key2: 'value 2'
},
stdio: 'inherit'
}
execSh('command', options)
assert.deepStrictEqual(spawn.getCall(0).args[2], expectedOptions)
})
it("should accept optional 'callback' parameter", function () {
var callback = sinon.spy()
execSh('command', callback)
execSh('command', { key: 'value' }, callback)
sinon.assert.callCount(callback, 2)
})
it("should use 'cmd /C' command prefix on windows", function () {
var platform = process.platform
Object.defineProperty(process, 'platform', { value: 'win32' })
execSh('command')
Object.defineProperty(process, 'platform', { value: platform })
sinon.assert.calledOnce(spawn)
assert.strictEqual(spawn.getCall(0).args[0], 'cmd')
})
it("should use 'sh -c' command prefix on *nix", function () {
var platform = process.platform
process.platform = 'linux'
execSh('command')
process.platform = platform
sinon.assert.calledOnce(spawn)
assert.strictEqual(spawn.getCall(0).args[1][0], '-c')
assert.strictEqual(spawn.getCall(0).args[0], 'sh')
})
it('should return spawn() result', function () {
assert(execSh('command').spawn_return)
})
it('should aggregate stdoout and stderr', function (done) {
execSh('command', function (_err, stdout, stderr) {
assert.strictEqual(stdout, '12')
assert.strictEqual(stderr, '12')
done()
})
})
it('should catch exceptions thrown by spawn', function (done) {
spawn.throws()
execSh('command', function (err, stdout, stderr) {
assert(err instanceof Error)
done()
})
})
it('should return empty stdout and stderr when spawn throws', function (done) {
spawn.throws()
stream = null
execSh('command', function (_err, stdout, stderr) {
assert.strictEqual(stderr, '')
assert.strictEqual(stdout, '')
done()
})
})
it('should run callback with error when shell exit with non-zero code', function (done) {
exitCode = 1
execSh('command', function (err) {
assert(err instanceof Error)
assert.strictEqual(exitCode, err.code)
done()
})
})
it('promise interface: should return promise', function () {
assert(execSh.promise('command') instanceof Promise)
})
it('promise interface: should resolve with stderr and stdout', function (done) {
execSh.promise('command').then(function (data) {
assert.ok('stdout' in data)
assert.ok('stderr' in data)
done()
})
})
it('promise interface: should reject promise when exceptions thrown by spawn', function (done) {
spawn.throws()
execSh.promise('command').catch(function (err) {
assert(err instanceof Error)
done()
})
})
})
})
'use strict';
const path = require('path');
const childProcess = require('child_process');
const crossSpawn = require('cross-spawn');
const stripEof = require('strip-eof');
const npmRunPath = require('npm-run-path');
const isStream = require('is-stream');
const _getStream = require('get-stream');
const pFinally = require('p-finally');
const onExit = require('signal-exit');
const errname = require('./lib/errname');
const stdio = require('./lib/stdio');
const TEN_MEGABYTES = 1000 * 1000 * 10;
function handleArgs(cmd, args, opts) {
let parsed;
opts = Object.assign({
extendEnv: true,
env: {}
}, opts);
if (opts.extendEnv) {
opts.env = Object.assign({}, process.env, opts.env);
}
if (opts.__winShell === true) {
delete opts.__winShell;
parsed = {
command: cmd,
args,
options: opts,
file: cmd,
original: {
cmd,
args
}
};
} else {
parsed = crossSpawn._parse(cmd, args, opts);
}
opts = Object.assign({
maxBuffer: TEN_MEGABYTES,
buffer: true,
stripEof: true,
preferLocal: true,
localDir: parsed.options.cwd || process.cwd(),
encoding: 'utf8',
reject: true,
cleanup: true
}, parsed.options);
opts.stdio = stdio(opts);
if (opts.preferLocal) {
opts.env = npmRunPath.env(Object.assign({}, opts, {cwd: opts.localDir}));
}
if (opts.detached) {
// #115
opts.cleanup = false;
}
if (process.platform === 'win32' && path.basename(parsed.command) === 'cmd.exe') {
// #116
parsed.args.unshift('/q');
}
return {
cmd: parsed.command,
args: parsed.args,
opts,
parsed
};
}
function handleInput(spawned, input) {
if (input === null || input === undefined) {
return;
}
if (isStream(input)) {
input.pipe(spawned.stdin);
} else {
spawned.stdin.end(input);
}
}
function handleOutput(opts, val) {
if (val && opts.stripEof) {
val = stripEof(val);
}
return val;
}
function handleShell(fn, cmd, opts) {
let file = '/bin/sh';
let args = ['-c', cmd];
opts = Object.assign({}, opts);
if (process.platform === 'win32') {
opts.__winShell = true;
file = process.env.comspec || 'cmd.exe';
args = ['/s', '/c', `"${cmd}"`];
opts.windowsVerbatimArguments = true;
}
if (opts.shell) {
file = opts.shell;
delete opts.shell;
}
return fn(file, args, opts);
}
function getStream(process, stream, {encoding, buffer, maxBuffer}) {
if (!process[stream]) {
return null;
}
let ret;
if (!buffer) {
// TODO: Use `ret = util.promisify(stream.finished)(process[stream]);` when targeting Node.js 10
ret = new Promise((resolve, reject) => {
process[stream]
.once('end', resolve)
.once('error', reject);
});
} else if (encoding) {
ret = _getStream(process[stream], {
encoding,
maxBuffer
});
} else {
ret = _getStream.buffer(process[stream], {maxBuffer});
}
return ret.catch(err => {
err.stream = stream;
err.message = `${stream} ${err.message}`;
throw err;
});
}
function makeError(result, options) {
const {stdout, stderr} = result;
let err = result.error;
const {code, signal} = result;
const {parsed, joinedCmd} = options;
const timedOut = options.timedOut || false;
if (!err) {
let output = '';
if (Array.isArray(parsed.opts.stdio)) {
if (parsed.opts.stdio[2] !== 'inherit') {
output += output.length > 0 ? stderr : `\n${stderr}`;
}
if (parsed.opts.stdio[1] !== 'inherit') {
output += `\n${stdout}`;
}
} else if (parsed.opts.stdio !== 'inherit') {
output = `\n${stderr}${stdout}`;
}
err = new Error(`Command failed: ${joinedCmd}${output}`);
err.code = code < 0 ? errname(code) : code;
}
err.stdout = stdout;
err.stderr = stderr;
err.failed = true;
err.signal = signal || null;
err.cmd = joinedCmd;
err.timedOut = timedOut;
return err;
}
function joinCmd(cmd, args) {
let joinedCmd = cmd;
if (Array.isArray(args) && args.length > 0) {
joinedCmd += ' ' + args.join(' ');
}
return joinedCmd;
}
module.exports = (cmd, args, opts) => {
const parsed = handleArgs(cmd, args, opts);
const {encoding, buffer, maxBuffer} = parsed.opts;
const joinedCmd = joinCmd(cmd, args);
let spawned;
try {
spawned = childProcess.spawn(parsed.cmd, parsed.args, parsed.opts);
} catch (err) {
return Promise.reject(err);
}
let removeExitHandler;
if (parsed.opts.cleanup) {
removeExitHandler = onExit(() => {
spawned.kill();
});
}
let timeoutId = null;
let timedOut = false;
const cleanup = () => {
if (timeoutId) {
clearTimeout(timeoutId);
timeoutId = null;
}
if (removeExitHandler) {
removeExitHandler();
}
};
if (parsed.opts.timeout > 0) {
timeoutId = setTimeout(() => {
timeoutId = null;
timedOut = true;
spawned.kill(parsed.opts.killSignal);
}, parsed.opts.timeout);
}
const processDone = new Promise(resolve => {
spawned.on('exit', (code, signal) => {
cleanup();
resolve({code, signal});
});
spawned.on('error', err => {
cleanup();
resolve({error: err});
});
if (spawned.stdin) {
spawned.stdin.on('error', err => {
cleanup();
resolve({error: err});
});
}
});
function destroy() {
if (spawned.stdout) {
spawned.stdout.destroy();
}
if (spawned.stderr) {
spawned.stderr.destroy();
}
}
const handlePromise = () => pFinally(Promise.all([
processDone,
getStream(spawned, 'stdout', {encoding, buffer, maxBuffer}),
getStream(spawned, 'stderr', {encoding, buffer, maxBuffer})
]).then(arr => {
const result = arr[0];
result.stdout = arr[1];
result.stderr = arr[2];
if (result.error || result.code !== 0 || result.signal !== null) {
const err = makeError(result, {
joinedCmd,
parsed,
timedOut
});
// TODO: missing some timeout logic for killed
// https://github.com/nodejs/node/blob/master/lib/child_process.js#L203
// err.killed = spawned.killed || killed;
err.killed = err.killed || spawned.killed;
if (!parsed.opts.reject) {
return err;
}
throw err;
}
return {
stdout: handleOutput(parsed.opts, result.stdout),
stderr: handleOutput(parsed.opts, result.stderr),
code: 0,
failed: false,
killed: false,
signal: null,
cmd: joinedCmd,
timedOut: false
};
}), destroy);
crossSpawn._enoent.hookChildProcess(spawned, parsed.parsed);
handleInput(spawned, parsed.opts.input);
spawned.then = (onfulfilled, onrejected) => handlePromise().then(onfulfilled, onrejected);
spawned.catch = onrejected => handlePromise().catch(onrejected);
return spawned;
};
// TODO: set `stderr: 'ignore'` when that option is implemented
module.exports.stdout = (...args) => module.exports(...args).then(x => x.stdout);
// TODO: set `stdout: 'ignore'` when that option is implemented
module.exports.stderr = (...args) => module.exports(...args).then(x => x.stderr);
module.exports.shell = (cmd, opts) => handleShell(module.exports, cmd, opts);
module.exports.sync = (cmd, args, opts) => {
const parsed = handleArgs(cmd, args, opts);
const joinedCmd = joinCmd(cmd, args);
if (isStream(parsed.opts.input)) {
throw new TypeError('The `input` option cannot be a stream in sync mode');
}
const result = childProcess.spawnSync(parsed.cmd, parsed.args, parsed.opts);
result.code = result.status;
if (result.error || result.status !== 0 || result.signal !== null) {
const err = makeError(result, {
joinedCmd,
parsed
});
if (!parsed.opts.reject) {
return err;
}
throw err;
}
return {
stdout: handleOutput(parsed.opts, result.stdout),
stderr: handleOutput(parsed.opts, result.stderr),
code: 0,
failed: false,
signal: null,
cmd: joinedCmd,
timedOut: false
};
};
module.exports.shellSync = (cmd, opts) => handleShell(module.exports.sync, cmd, opts);
'use strict';
// Older verions of Node.js might not have `util.getSystemErrorName()`.
// In that case, fall back to a deprecated internal.
const util = require('util');
let uv;
if (typeof util.getSystemErrorName === 'function') {
module.exports = util.getSystemErrorName;
} else {
try {
uv = process.binding('uv');
if (typeof uv.errname !== 'function') {
throw new TypeError('uv.errname is not a function');
}
} catch (err) {
console.error('execa/lib/errname: unable to establish process.binding(\'uv\')', err);
uv = null;
}
module.exports = code => errname(uv, code);
}
// Used for testing the fallback behavior
module.exports.__test__ = errname;
function errname(uv, code) {
if (uv) {
return uv.errname(code);
}
if (!(code < 0)) {
throw new Error('err >= 0');
}
return `Unknown system error ${code}`;
}
'use strict';
const alias = ['stdin', 'stdout', 'stderr'];
const hasAlias = opts => alias.some(x => Boolean(opts[x]));
module.exports = opts => {
if (!opts) {
return null;
}
if (opts.stdio && hasAlias(opts)) {
throw new Error(`It's not possible to provide \`stdio\` in combination with one of ${alias.map(x => `\`${x}\``).join(', ')}`);
}
if (typeof opts.stdio === 'string') {
return opts.stdio;
}
const stdio = opts.stdio || [];
if (!Array.isArray(stdio)) {
throw new TypeError(`Expected \`stdio\` to be of type \`string\` or \`Array\`, got \`${typeof stdio}\``);
}
const result = [];
const len = Math.max(stdio.length, alias.length);
for (let i = 0; i < len; i++) {
let value = null;
if (stdio[i] !== undefined) {
value = stdio[i];
} else if (opts[alias[i]] !== undefined) {
value = opts[alias[i]];
}
result[i] = value;
}
return result;
};
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
{
"_from": "execa@^1.0.0",
"_id": "execa@1.0.0",
"_inBundle": false,
"_integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
"_location": "/execa",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "execa@^1.0.0",
"name": "execa",
"escapedName": "execa",
"rawSpec": "^1.0.0",
"saveSpec": null,
"fetchSpec": "^1.0.0"
},
"_requiredBy": [
"/default-gateway",
"/sane"
],
"_resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
"_shasum": "c6236a5bb4df6d6f15e88e7f017798216749ddd8",
"_spec": "execa@^1.0.0",
"_where": "C:\\Users\\kkwan_000\\Desktop\\git\\2017110269\\minsung\\node_modules\\sane",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"bugs": {
"url": "https://github.com/sindresorhus/execa/issues"
},
"bundleDependencies": false,
"dependencies": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
},
"deprecated": false,
"description": "A better `child_process`",
"devDependencies": {
"ava": "*",
"cat-names": "^1.0.2",
"coveralls": "^3.0.1",
"delay": "^3.0.0",
"is-running": "^2.0.0",
"nyc": "^13.0.1",
"tempfile": "^2.0.0",
"xo": "*"
},
"engines": {
"node": ">=6"
},
"files": [
"index.js",
"lib"
],
"homepage": "https://github.com/sindresorhus/execa#readme",
"keywords": [
"exec",
"child",
"process",
"execute",
"fork",
"execfile",
"spawn",
"file",
"shell",
"bin",
"binary",
"binaries",
"npm",
"path",
"local"
],
"license": "MIT",
"name": "execa",
"nyc": {
"reporter": [
"text",
"lcov"
],
"exclude": [
"**/fixtures/**",
"**/test.js",
"**/test/**"
]
},
"repository": {
"type": "git",
"url": "git+https://github.com/sindresorhus/execa.git"
},
"scripts": {
"test": "xo && nyc ava"
},
"version": "1.0.0"
}
# execa [![Build Status: Linux](https://travis-ci.org/sindresorhus/execa.svg?branch=master)](https://travis-ci.org/sindresorhus/execa) [![Build status: Windows](https://ci.appveyor.com/api/projects/status/x5ajamxtjtt93cqv/branch/master?svg=true)](https://ci.appveyor.com/project/sindresorhus/execa/branch/master) [![Coverage Status](https://coveralls.io/repos/github/sindresorhus/execa/badge.svg?branch=master)](https://coveralls.io/github/sindresorhus/execa?branch=master)
> A better [`child_process`](https://nodejs.org/api/child_process.html)
## Why
- Promise interface.
- [Strips EOF](https://github.com/sindresorhus/strip-eof) from the output so you don't have to `stdout.trim()`.
- Supports [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)) binaries cross-platform.
- [Improved Windows support.](https://github.com/IndigoUnited/node-cross-spawn#why)
- Higher max buffer. 10 MB instead of 200 KB.
- [Executes locally installed binaries by name.](#preferlocal)
- [Cleans up spawned processes when the parent process dies.](#cleanup)
## Install
```
$ npm install execa
```
<a href="https://www.patreon.com/sindresorhus">
<img src="https://c5.patreon.com/external/logo/become_a_patron_button@2x.png" width="160">
</a>
## Usage
```js
const execa = require('execa');
(async () => {
const {stdout} = await execa('echo', ['unicorns']);
console.log(stdout);
//=> 'unicorns'
})();
```
Additional examples:
```js
const execa = require('execa');
(async () => {
// Pipe the child process stdout to the current stdout
execa('echo', ['unicorns']).stdout.pipe(process.stdout);
// Run a shell command
const {stdout} = await execa.shell('echo unicorns');
//=> 'unicorns'
// Catching an error
try {
await execa.shell('exit 3');
} catch (error) {
console.log(error);
/*
{
message: 'Command failed: /bin/sh -c exit 3'
killed: false,
code: 3,
signal: null,
cmd: '/bin/sh -c exit 3',
stdout: '',
stderr: '',
timedOut: false
}
*/
}
})();
// Catching an error with a sync method
try {
execa.shellSync('exit 3');
} catch (error) {
console.log(error);
/*
{
message: 'Command failed: /bin/sh -c exit 3'
code: 3,
signal: null,
cmd: '/bin/sh -c exit 3',
stdout: '',
stderr: '',
timedOut: false
}
*/
}
```
## API
### execa(file, [arguments], [options])
Execute a file.
Think of this as a mix of `child_process.execFile` and `child_process.spawn`.
Returns a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess), which is enhanced to also be a `Promise` for a result `Object` with `stdout` and `stderr` properties.
### execa.stdout(file, [arguments], [options])
Same as `execa()`, but returns only `stdout`.
### execa.stderr(file, [arguments], [options])
Same as `execa()`, but returns only `stderr`.
### execa.shell(command, [options])
Execute a command through the system shell. Prefer `execa()` whenever possible, as it's both faster and safer.
Returns a [`child_process` instance](https://nodejs.org/api/child_process.html#child_process_class_childprocess).
The `child_process` instance is enhanced to also be promise for a result object with `stdout` and `stderr` properties.
### execa.sync(file, [arguments], [options])
Execute a file synchronously.
Returns the same result object as [`child_process.spawnSync`](https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options).
This method throws an `Error` if the command fails.
### execa.shellSync(file, [options])
Execute a command synchronously through the system shell.
Returns the same result object as [`child_process.spawnSync`](https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options).
### options
Type: `Object`
#### cwd
Type: `string`<br>
Default: `process.cwd()`
Current working directory of the child process.
#### env
Type: `Object`<br>
Default: `process.env`
Environment key-value pairs. Extends automatically from `process.env`. Set `extendEnv` to `false` if you don't want this.
#### extendEnv
Type: `boolean`<br>
Default: `true`
Set to `false` if you don't want to extend the environment variables when providing the `env` property.
#### argv0
Type: `string`
Explicitly set the value of `argv[0]` sent to the child process. This will be set to `command` or `file` if not specified.
#### stdio
Type: `string[]` `string`<br>
Default: `pipe`
Child's [stdio](https://nodejs.org/api/child_process.html#child_process_options_stdio) configuration.
#### detached
Type: `boolean`
Prepare child to run independently of its parent process. Specific behavior [depends on the platform](https://nodejs.org/api/child_process.html#child_process_options_detached).
#### uid
Type: `number`
Sets the user identity of the process.
#### gid
Type: `number`
Sets the group identity of the process.
#### shell
Type: `boolean` `string`<br>
Default: `false`
If `true`, runs `command` inside of a shell. Uses `/bin/sh` on UNIX and `cmd.exe` on Windows. A different shell can be specified as a string. The shell should understand the `-c` switch on UNIX or `/d /s /c` on Windows.
#### stripEof
Type: `boolean`<br>
Default: `true`
[Strip EOF](https://github.com/sindresorhus/strip-eof) (last newline) from the output.
#### preferLocal
Type: `boolean`<br>
Default: `true`
Prefer locally installed binaries when looking for a binary to execute.<br>
If you `$ npm install foo`, you can then `execa('foo')`.
#### localDir
Type: `string`<br>
Default: `process.cwd()`
Preferred path to find locally installed binaries in (use with `preferLocal`).
#### input
Type: `string` `Buffer` `stream.Readable`
Write some input to the `stdin` of your binary.<br>
Streams are not allowed when using the synchronous methods.
#### reject
Type: `boolean`<br>
Default: `true`
Setting this to `false` resolves the promise with the error instead of rejecting it.
#### cleanup
Type: `boolean`<br>
Default: `true`
Keep track of the spawned process and `kill` it when the parent process exits.
#### encoding
Type: `string`<br>
Default: `utf8`
Specify the character encoding used to decode the `stdout` and `stderr` output.
#### timeout
Type: `number`<br>
Default: `0`
If timeout is greater than `0`, the parent will send the signal identified by the `killSignal` property (the default is `SIGTERM`) if the child runs longer than timeout milliseconds.
#### buffer
Type: `boolean`<br>
Default: `true`
Buffer the output from the spawned process. When buffering is disabled you must consume the output of the `stdout` and `stderr` streams because the promise will not be resolved/rejected until they have completed.
#### maxBuffer
Type: `number`<br>
Default: `10000000` (10MB)
Largest amount of data in bytes allowed on `stdout` or `stderr`.
#### killSignal
Type: `string` `number`<br>
Default: `SIGTERM`
Signal value to be used when the spawned process will be killed.
#### stdin
Type: `string` `number` `Stream` `undefined` `null`<br>
Default: `pipe`
Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio).
#### stdout
Type: `string` `number` `Stream` `undefined` `null`<br>
Default: `pipe`
Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio).
#### stderr
Type: `string` `number` `Stream` `undefined` `null`<br>
Default: `pipe`
Same options as [`stdio`](https://nodejs.org/dist/latest-v6.x/docs/api/child_process.html#child_process_options_stdio).
#### windowsVerbatimArguments
Type: `boolean`<br>
Default: `false`
If `true`, no quoting or escaping of arguments is done on Windows. Ignored on other platforms. This is set to `true` automatically when the `shell` option is `true`.
## Tips
### Save and pipe output from a child process
Let's say you want to show the output of a child process in real-time while also saving it to a variable.
```js
const execa = require('execa');
const getStream = require('get-stream');
const stream = execa('echo', ['foo']).stdout;
stream.pipe(process.stdout);
getStream(stream).then(value => {
console.log('child output:', value);
});
```
## License
MIT © [Sindre Sorhus](https://sindresorhus.com)
{
"curly": true,
"eqeqeq": true,
"immed": true,
"latedef": "nofunc",
"newcap": true,
"noarg": true,
"sub": true,
"undef": true,
"unused": true,
"boss": true,
"eqnull": true,
"node": true
}
language: node_js
node_js:
- 0.8
- '0.10'
before_script:
- npm install -g grunt-cli
'use strict';
module.exports = function(grunt) {
// Project configuration.
grunt.initConfig({
nodeunit: {
files: ['test/**/*_test.js'],
},
jshint: {
options: {
jshintrc: '.jshintrc'
},
gruntfile: {
src: 'Gruntfile.js'
},
lib: {
src: ['lib/**/*.js']
},
test: {
src: ['test/**/*.js']
},
},
watch: {
gruntfile: {
files: '<%= jshint.gruntfile.src %>',
tasks: ['jshint:gruntfile']
},
lib: {
files: '<%= jshint.lib.src %>',
tasks: ['jshint:lib', 'nodeunit']
},
test: {
files: '<%= jshint.test.src %>',
tasks: ['jshint:test', 'nodeunit']
},
},
});
// These plugins provide necessary tasks.
grunt.loadNpmTasks('grunt-contrib-nodeunit');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-watch');
// Default task.
grunt.registerTask('default', ['jshint', 'nodeunit']);
};
Copyright (c) 2013 "Cowboy" Ben Alman
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
# exit [![Build Status](https://secure.travis-ci.org/cowboy/node-exit.png?branch=master)](http://travis-ci.org/cowboy/node-exit)
A replacement for process.exit that ensures stdio are fully drained before exiting.
To make a long story short, if `process.exit` is called on Windows, script output is often truncated when pipe-redirecting `stdout` or `stderr`. This module attempts to work around this issue by waiting until those streams have been completely drained before actually calling `process.exit`.
See [Node.js issue #3584](https://github.com/joyent/node/issues/3584) for further reference.
Tested in OS X 10.8, Windows 7 on Node.js 0.8.25 and 0.10.18.
Based on some code by [@vladikoff](https://github.com/vladikoff).
## Getting Started
Install the module with: `npm install exit`
```javascript
var exit = require('exit');
// These lines should appear in the output, EVEN ON WINDOWS.
console.log("omg");
console.error("yay");
// process.exit(5);
exit(5);
// These lines shouldn't appear in the output.
console.log("wtf");
console.error("bro");
```
## Don't believe me? Try it for yourself.
In Windows, clone the repo and cd to the `test\fixtures` directory. The only difference between [log.js](test/fixtures/log.js) and [log-broken.js](test/fixtures/log-broken.js) is that the former uses `exit` while the latter calls `process.exit` directly.
This test was done using cmd.exe, but you can see the same results using `| grep "std"` in either PowerShell or git-bash.
```
C:\node-exit\test\fixtures>node log.js 0 10 stdout stderr 2>&1 | find "std"
stdout 0
stderr 0
stdout 1
stderr 1
stdout 2
stderr 2
stdout 3
stderr 3
stdout 4
stderr 4
stdout 5
stderr 5
stdout 6
stderr 6
stdout 7
stderr 7
stdout 8
stderr 8
stdout 9
stderr 9
C:\node-exit\test\fixtures>node log-broken.js 0 10 stdout stderr 2>&1 | find "std"
C:\node-exit\test\fixtures>
```
## Contributing
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint and test your code using [Grunt](http://gruntjs.com/).
## Release History
2013-11-26 - v0.1.2 - Fixed a bug with hanging processes.
2013-09-26 - v0.1.1 - Fixed some bugs. It seems to actually work now!
2013-09-20 - v0.1.0 - Initial release.
## License
Copyright (c) 2013 "Cowboy" Ben Alman
Licensed under the MIT license.
/*
* exit
* https://github.com/cowboy/node-exit
*
* Copyright (c) 2013 "Cowboy" Ben Alman
* Licensed under the MIT license.
*/
'use strict';
module.exports = function exit(exitCode, streams) {
if (!streams) { streams = [process.stdout, process.stderr]; }
var drainCount = 0;
// Actually exit if all streams are drained.
function tryToExit() {
if (drainCount === streams.length) {
process.exit(exitCode);
}
}
streams.forEach(function(stream) {
// Count drained streams now, but monitor non-drained streams.
if (stream.bufferSize === 0) {
drainCount++;
} else {
stream.write('', 'utf-8', function() {
drainCount++;
tryToExit();
});
}
// Prevent further writing.
stream.write = function() {};
});
// If all streams were already drained, exit now.
tryToExit();
// In Windows, when run as a Node.js child process, a script utilizing
// this library might just exit with a 0 exit code, regardless. This code,
// despite the fact that it looks a bit crazy, appears to fix that.
process.on('exit', function() {
process.exit(exitCode);
});
};
{
"_from": "exit@^0.1.2",
"_id": "exit@0.1.2",
"_inBundle": false,
"_integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
"_location": "/exit",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "exit@^0.1.2",
"name": "exit",
"escapedName": "exit",
"rawSpec": "^0.1.2",
"saveSpec": null,
"fetchSpec": "^0.1.2"
},
"_requiredBy": [
"/@jest/core",
"/@jest/reporters",
"/jest-runner",
"/jest-runtime",
"/jest/jest-cli"
],
"_resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
"_shasum": "0632638f8d877cc82107d30a0fff1a17cba1cd0c",
"_spec": "exit@^0.1.2",
"_where": "C:\\Users\\kkwan_000\\Desktop\\git\\2017110269\\minsung\\node_modules\\@jest\\core",
"author": {
"name": "\"Cowboy\" Ben Alman",
"url": "http://benalman.com/"
},
"bugs": {
"url": "https://github.com/cowboy/node-exit/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "A replacement for process.exit that ensures stdio are fully drained before exiting.",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-jshint": "~0.6.4",
"grunt-contrib-nodeunit": "~0.2.0",
"grunt-contrib-watch": "~0.5.3",
"which": "~1.0.5"
},
"engines": {
"node": ">= 0.8.0"
},
"homepage": "https://github.com/cowboy/node-exit",
"keywords": [
"exit",
"process",
"stdio",
"stdout",
"stderr",
"drain",
"flush",
"3584"
],
"licenses": [
{
"type": "MIT",
"url": "https://github.com/cowboy/node-exit/blob/master/LICENSE-MIT"
}
],
"main": "lib/exit",
"name": "exit",
"repository": {
"type": "git",
"url": "git://github.com/cowboy/node-exit.git"
},
"scripts": {
"test": "grunt nodeunit"
},
"version": "0.1.2"
}
'use strict';
/*
======== A Handy Little Nodeunit Reference ========
https://github.com/caolan/nodeunit
Test methods:
test.expect(numAssertions)
test.done()
Test assertions:
test.ok(value, [message])
test.equal(actual, expected, [message])
test.notEqual(actual, expected, [message])
test.deepEqual(actual, expected, [message])
test.notDeepEqual(actual, expected, [message])
test.strictEqual(actual, expected, [message])
test.notStrictEqual(actual, expected, [message])
test.throws(block, [error], [message])
test.doesNotThrow(block, [error], [message])
test.ifError(value)
*/
var fs = require('fs');
var exec = require('child_process').exec;
var _which = require('which').sync;
function which(command) {
try {
_which(command);
return command;
} catch (err) {
return false;
}
}
// Look for grep first (any OS). If not found (but on Windows) look for find,
// which is Windows' horribly crippled grep alternative.
var grep = which('grep') || process.platform === 'win32' && which('find');
exports['exit'] = {
setUp: function(done) {
this.origCwd = process.cwd();
process.chdir('test/fixtures');
done();
},
tearDown: function(done) {
process.chdir(this.origCwd);
done();
},
'grep': function(test) {
test.expect(1);
// Many unit tests depend on this.
test.ok(grep, 'A suitable "grep" or "find" program was not found in the PATH.');
test.done();
},
// The rest of the tests are built dynamically, to keep things sane.
};
// A few helper functions.
function normalizeLineEndings(s) {
return s.replace(/\r?\n/g, '\n');
}
// Capture command output, normalizing captured stdout to unix file endings.
function run(command, callback) {
exec(command, function(error, stdout) {
callback(error ? error.code : 0, normalizeLineEndings(stdout));
});
}
// Read a fixture file, normalizing file contents to unix file endings.
function fixture(filename) {
return normalizeLineEndings(String(fs.readFileSync(filename)));
}
function buildTests() {
// Build individual unit tests for command output.
var counts = [10, 100, 1000];
var outputs = [' stdout stderr', ' stdout', ' stderr'];
var pipes = ['', ' | ' + grep + ' "std"'];
counts.forEach(function(count) {
outputs.forEach(function(output) {
pipes.forEach(function(pipe) {
var command = 'node log.js 0 ' + count + output + ' 2>&1' + pipe;
exports['exit']['output (' + command + ')'] = function(test) {
test.expect(2);
run(command, function(code, actual) {
var expected = fixture(count + output.replace(/ /g, '-') + '.txt');
// Sometimes, the actual file lines are out of order on Windows.
// But since the point of this lib is to drain the buffer and not
// guarantee output order, we only test the length.
test.equal(actual.length, expected.length, 'should be the same length.');
// The "fail" lines in log.js should NOT be output!
test.ok(actual.indexOf('fail') === -1, 'should not output after exit is called.');
test.done();
});
};
});
});
});
// Build individual unit tests for exit codes.
var codes = [0, 1, 123];
codes.forEach(function(code) {
var command = 'node log.js ' + code + ' 10 stdout stderr';
exports['exit']['exit code (' + command + ')'] = function(test) {
test.expect(1);
run(command, function(actual) {
// The specified exit code should be passed through.
test.equal(actual, code, 'should exit with ' + code + ' error code.');
test.done();
});
};
});
}
// Don't bother building tests if grep wasn't found, otherwise everything will
// fail and the error will get lost.
if (grep) {
buildTests();
}
stderr 0
stderr 1
stderr 2
stderr 3
stderr 4
stderr 5
stderr 6
stderr 7
stderr 8
stderr 9
stdout 0
stderr 0
stdout 1
stdout 2
stderr 1
stdout 3
stderr 2
stderr 3
stdout 4
stderr 4
stdout 5
stderr 5
stdout 6
stderr 6
stdout 7
stderr 7
stdout 8
stderr 8
stdout 9
stderr 9
stdout 0
stdout 1
stdout 2
stdout 3
stdout 4
stdout 5
stdout 6
stdout 7
stdout 8
stdout 9
stderr 0
stderr 1
stderr 2
stderr 3
stderr 4
stderr 5
stderr 6
stderr 7
stderr 8
stderr 9
stderr 10
stderr 11
stderr 12
stderr 13
stderr 14
stderr 15
stderr 16
stderr 17
stderr 18
stderr 19
stderr 20
stderr 21
stderr 22
stderr 23
stderr 24
stderr 25
stderr 26
stderr 27
stderr 28
stderr 29
stderr 30
stderr 31
stderr 32
stderr 33
stderr 34
stderr 35
stderr 36
stderr 37
stderr 38
stderr 39
stderr 40
stderr 41
stderr 42
stderr 43
stderr 44
stderr 45
stderr 46
stderr 47
stderr 48
stderr 49
stderr 50
stderr 51
stderr 52
stderr 53
stderr 54
stderr 55
stderr 56
stderr 57
stderr 58
stderr 59
stderr 60
stderr 61
stderr 62
stderr 63
stderr 64
stderr 65
stderr 66
stderr 67
stderr 68
stderr 69
stderr 70
stderr 71
stderr 72
stderr 73
stderr 74
stderr 75
stderr 76
stderr 77
stderr 78
stderr 79
stderr 80
stderr 81
stderr 82
stderr 83
stderr 84
stderr 85
stderr 86
stderr 87
stderr 88
stderr 89
stderr 90
stderr 91
stderr 92
stderr 93
stderr 94
stderr 95
stderr 96
stderr 97
stderr 98
stderr 99
stdout 0
stderr 0
stdout 1
stderr 1
stdout 2
stderr 2
stdout 3
stderr 3
stdout 4
stderr 4
stdout 5
stderr 5
stdout 6
stderr 6
stdout 7
stderr 7
stdout 8
stderr 8
stdout 9
stderr 9
stdout 10
stderr 10
stdout 11
stderr 11
stdout 12
stderr 12
stdout 13
stderr 13
stdout 14
stderr 14
stdout 15
stderr 15
stdout 16
stderr 16
stdout 17
stderr 17
stdout 18
stderr 18
stdout 19
stderr 19
stdout 20
stderr 20
stdout 21
stderr 21
stdout 22
stderr 22
stdout 23
stderr 23
stdout 24
stderr 24
stdout 25
stderr 25
stdout 26
stderr 26
stdout 27
stderr 27
stdout 28
stderr 28
stdout 29
stderr 29
stdout 30
stderr 30
stdout 31
stderr 31
stdout 32
stderr 32
stdout 33
stderr 33
stdout 34
stderr 34
stdout 35
stderr 35
stdout 36
stderr 36
stdout 37
stderr 37
stdout 38
stderr 38
stdout 39
stderr 39
stdout 40
stderr 40
stdout 41
stderr 41
stdout 42
stderr 42
stdout 43
stderr 43
stdout 44
stderr 44
stdout 45
stderr 45
stdout 46
stderr 46
stdout 47
stderr 47
stdout 48
stderr 48
stdout 49
stderr 49
stdout 50
stderr 50
stdout 51
stderr 51
stdout 52
stderr 52
stdout 53
stderr 53
stdout 54
stderr 54
stdout 55
stderr 55
stdout 56
stderr 56
stdout 57
stderr 57
stdout 58
stderr 58
stdout 59
stderr 59
stdout 60
stderr 60
stdout 61
stderr 61
stdout 62
stderr 62
stdout 63
stderr 63
stdout 64
stderr 64
stdout 65
stderr 65
stdout 66
stderr 66
stdout 67
stderr 67
stdout 68
stderr 68
stdout 69
stderr 69
stdout 70
stderr 70
stdout 71
stderr 71
stdout 72
stderr 72
stdout 73
stderr 73
stdout 74
stderr 74
stdout 75
stderr 75
stdout 76
stderr 76
stdout 77
stderr 77
stdout 78
stderr 78
stdout 79
stderr 79
stdout 80
stderr 80
stdout 81
stderr 81
stdout 82
stderr 82
stdout 83
stderr 83
stdout 84
stderr 84
stdout 85
stderr 85
stdout 86
stderr 86
stdout 87
stderr 87
stdout 88
stderr 88
stdout 89
stderr 89
stdout 90
stderr 90
stdout 91
stderr 91
stdout 92
stderr 92
stdout 93
stderr 93
stdout 94
stderr 94
stdout 95
stderr 95
stdout 96
stderr 96
stdout 97
stderr 97
stdout 98
stderr 98
stdout 99
stderr 99
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.