From bef3b8072e56bc74e4619336e0a5f9a99a399844 Mon Sep 17 00:00:00 2001 From: Boriss Nazarovs Date: Sat, 27 Aug 2016 19:00:50 +0300 Subject: [PATCH 1/4] Added type definition for eventemitter3-1.2.0 --- eventemitter3/eventemitter3-1.2.0-tests.ts | 113 ++++++++++++++++++ .../eventemitter3-1.2.0-tests.ts.tscparams | 1 + eventemitter3/eventemitter3-1.2.0.d.ts | 107 +++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 eventemitter3/eventemitter3-1.2.0-tests.ts create mode 100644 eventemitter3/eventemitter3-1.2.0-tests.ts.tscparams create mode 100644 eventemitter3/eventemitter3-1.2.0.d.ts diff --git a/eventemitter3/eventemitter3-1.2.0-tests.ts b/eventemitter3/eventemitter3-1.2.0-tests.ts new file mode 100644 index 0000000000..517b8afd72 --- /dev/null +++ b/eventemitter3/eventemitter3-1.2.0-tests.ts @@ -0,0 +1,113 @@ +/// +'use strict'; + +import EventEmitter from 'eventemitter3'; + +const eventName = 'test'; +const eventSymbol: symbol = Symbol('test'); +const fn = () => console.log(1); + +// Extending EventEmitter +class TestEmitter extends EventEmitter { + constructor() { + super(); + } +} + +const ee: TestEmitter = new TestEmitter(); + +// EventEmitter.prefixed +// should be boolean or string static property +const prefix = EventEmitter.prefixed; +if (typeof prefix === 'boolean') { + console.log(prefix.valueOf()); +} else { + console.log(prefix.length); +} + +// EventEmitter.eventNames() +// should return array of strings or symbols +ee.eventNames().every((event) => { + if (typeof event === 'symbol') { + return false; + } else { + return event.length > 0; + } +}); + +// EventEmitter.listeners() +// should return array of functions +ee.listeners(eventName).map((listener) => { + return listener.bind(this); +}); +// should accept symbol as event name +ee.listeners(eventSymbol).map((listener) => { + return listener.bind(this); +}); +// should return boolean with 'exists' flag +const hasListeners: boolean = ee.listeners(eventName, true); + +// EventEmitter.emit() +// should support any number of arguments +ee.emit(eventName, 1, true, {}, [], 'test', Symbol(), null); +// should accept symbol as event name +ee.emit(eventSymbol); + +// EventEmitter.addListener() and EventEmitter.on() +// should accept function +ee.on(eventName, fn); +ee.addListener(eventName, fn); +// should accept optional context argument +ee.on(eventName, fn, this); +ee.addListener(eventName, fn, this); +// should accept symbol as event name +ee.on(eventSymbol, fn); +ee.addListener(eventSymbol, fn); +// should support fluent interface +ee.on(eventSymbol, fn).on(eventName, fn); +ee.addListener(eventSymbol, fn).addListener(eventName, fn); + +// EventEmitter.once() +// should accept event name and function +ee.once(eventName, fn); +// should accept optional context argument +ee.once(eventName, fn, this); +ee.once(eventName, fn, {}); +// should accept symbol as event name +ee.once(eventSymbol, fn); +// should support fluent interface +ee.once(eventSymbol, fn).once(eventName, fn); + +// EventEmitter.removeListener() and EventEmitter.off() +// should accept event name +ee.removeListener(eventName); +ee.off(eventName); +// should accept optional function +ee.removeListener(eventName, fn); +ee.off(eventName, fn); +// should accept optional context argument +ee.removeListener(eventName, fn, {}); +ee.off(eventName, fn, {}); +// should accept optional boolean flag for removing listeners added with `EventEmitter.once()` +ee.removeListener(eventName, fn, null, true); +ee.off(eventName, fn, null, true); +// should accept symbol as event name +ee.removeListener(eventSymbol); +ee.off(eventSymbol); +// should support fluent interface +ee.removeListener(eventName).removeListener(eventSymbol); +ee.off(eventName).off(eventSymbol); + +// EventEmitter.removeAllListeners() +// should not require any arguments +ee.removeAllListeners(); +// should accept optional event name +ee.removeAllListeners(eventName); +// should accept symbol as event name +ee.removeAllListeners(eventSymbol); +// should support fluent interface +ee.removeAllListeners(eventName).removeAllListeners(eventSymbol); + +// EventEmitter.setMaxListeners() +// should support fluent interface +ee.setMaxListeners().setMaxListeners(); diff --git a/eventemitter3/eventemitter3-1.2.0-tests.ts.tscparams b/eventemitter3/eventemitter3-1.2.0-tests.ts.tscparams new file mode 100644 index 0000000000..a0aefcf79a --- /dev/null +++ b/eventemitter3/eventemitter3-1.2.0-tests.ts.tscparams @@ -0,0 +1 @@ +--target es6 --allowSyntheticDefaultImports --noImplicitAny diff --git a/eventemitter3/eventemitter3-1.2.0.d.ts b/eventemitter3/eventemitter3-1.2.0.d.ts new file mode 100644 index 0000000000..ca43aa6c95 --- /dev/null +++ b/eventemitter3/eventemitter3-1.2.0.d.ts @@ -0,0 +1,107 @@ +// Type definitions for EventEmitter3 1.2.0 +// Project: https://github.com/primus/eventemitter3 +// Definitions by: Boriss Nazarovs +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped + +declare module 'eventemitter3' { + /** + * Minimal EventEmitter interface that is molded against the Node.js + * EventEmitter interface. + */ + class EventEmitter { + constructor(); + + /** + * Return an array listing the events for which the emitter has registered listeners. + * + * @returns {(string|symbol)[]} + */ + eventNames(): (string|symbol)[]; + + /** + * Return the listeners registered for a given event. + * + * @param {(string|symbol)} event The event name. + * @returns {Function[]} + */ + listeners(event: string|symbol): Function[]; + + /** + * Check if there listeners for a given event. + * If `exists` argument is not `true` lists listeners. + * + * @param {(string|symbol)} event The event name. + * @param {boolean} exists Only check if there are listeners. + * @returns {boolean} + */ + listeners(event: string|symbol, exists: boolean): boolean; + + /** + * Calls each of the listeners registered for a given event. + * + * @param {(string|symbol)} event The event name. + * @param {...*} args Arguments that are passed to registered listeners + * @returns {boolean} `true` if the event had listeners, else `false`. + */ + emit(event: string|symbol, ...args: any[]): boolean; + + /** + * Add a listener for a given event. + * + * @param {(string|symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + */ + on(event: string|symbol, fn: Function, context?: any): EventEmitter; + + /** + * Add a one-time listener for a given event. + * + * @param {(string|symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. + */ + once(event: string|symbol, fn: Function, context?: any): EventEmitter; + + /** + * Remove the listeners of a given event. + * + * @param {(string|symbol)} event The event name. + * @param {Function} fn Only remove the listeners that match this function. + * @param {*} context Only remove the listeners that have this context. + * @param {boolean} once Only remove one-time listeners. + * @returns {EventEmitter} `this`. + */ + removeListener(event: string|symbol, fn?: Function, context?: any, once?: boolean): EventEmitter; + + /** + * Remove all listeners, or those of the specified event. + * + * @param {(string|symbol)} event The event name. + * @returns {EventEmitter} `this`. + */ + removeAllListeners(event?: string|symbol): EventEmitter; + + /** + * Alias method for `removeListener` + */ + off(event: string|symbol, fn?: Function, context?: any, once?: boolean): EventEmitter; + + /** + * Alias method for `on` + */ + addListener(event: string|symbol, fn: Function, context?: any): EventEmitter; + + /** + * This function doesn't apply anymore. + * @deprecated + */ + setMaxListeners(): EventEmitter; + + static prefixed: string|boolean; + } + + export = EventEmitter; +} From 6ed248d516f1c83b05806be67ece4853b69be792 Mon Sep 17 00:00:00 2001 From: Boriss Nazarovs Date: Thu, 1 Sep 2016 23:52:01 +0300 Subject: [PATCH 2/4] Merged eventemitter3-1.2.0 typings with main typing file --- eventemitter3/eventemitter3-1.2.0-tests.ts | 113 --- eventemitter3/eventemitter3-1.2.0.d.ts | 107 --- eventemitter3/eventemitter3-tests.ts | 673 +++--------------- ...arams => eventemitter3-tests.ts.tscparams} | 0 eventemitter3/eventemitter3.d.ts | 128 ++-- 5 files changed, 157 insertions(+), 864 deletions(-) delete mode 100644 eventemitter3/eventemitter3-1.2.0-tests.ts delete mode 100644 eventemitter3/eventemitter3-1.2.0.d.ts rename eventemitter3/{eventemitter3-1.2.0-tests.ts.tscparams => eventemitter3-tests.ts.tscparams} (100%) diff --git a/eventemitter3/eventemitter3-1.2.0-tests.ts b/eventemitter3/eventemitter3-1.2.0-tests.ts deleted file mode 100644 index 517b8afd72..0000000000 --- a/eventemitter3/eventemitter3-1.2.0-tests.ts +++ /dev/null @@ -1,113 +0,0 @@ -/// -'use strict'; - -import EventEmitter from 'eventemitter3'; - -const eventName = 'test'; -const eventSymbol: symbol = Symbol('test'); -const fn = () => console.log(1); - -// Extending EventEmitter -class TestEmitter extends EventEmitter { - constructor() { - super(); - } -} - -const ee: TestEmitter = new TestEmitter(); - -// EventEmitter.prefixed -// should be boolean or string static property -const prefix = EventEmitter.prefixed; -if (typeof prefix === 'boolean') { - console.log(prefix.valueOf()); -} else { - console.log(prefix.length); -} - -// EventEmitter.eventNames() -// should return array of strings or symbols -ee.eventNames().every((event) => { - if (typeof event === 'symbol') { - return false; - } else { - return event.length > 0; - } -}); - -// EventEmitter.listeners() -// should return array of functions -ee.listeners(eventName).map((listener) => { - return listener.bind(this); -}); -// should accept symbol as event name -ee.listeners(eventSymbol).map((listener) => { - return listener.bind(this); -}); -// should return boolean with 'exists' flag -const hasListeners: boolean = ee.listeners(eventName, true); - -// EventEmitter.emit() -// should support any number of arguments -ee.emit(eventName, 1, true, {}, [], 'test', Symbol(), null); -// should accept symbol as event name -ee.emit(eventSymbol); - -// EventEmitter.addListener() and EventEmitter.on() -// should accept function -ee.on(eventName, fn); -ee.addListener(eventName, fn); -// should accept optional context argument -ee.on(eventName, fn, this); -ee.addListener(eventName, fn, this); -// should accept symbol as event name -ee.on(eventSymbol, fn); -ee.addListener(eventSymbol, fn); -// should support fluent interface -ee.on(eventSymbol, fn).on(eventName, fn); -ee.addListener(eventSymbol, fn).addListener(eventName, fn); - -// EventEmitter.once() -// should accept event name and function -ee.once(eventName, fn); -// should accept optional context argument -ee.once(eventName, fn, this); -ee.once(eventName, fn, {}); -// should accept symbol as event name -ee.once(eventSymbol, fn); -// should support fluent interface -ee.once(eventSymbol, fn).once(eventName, fn); - -// EventEmitter.removeListener() and EventEmitter.off() -// should accept event name -ee.removeListener(eventName); -ee.off(eventName); -// should accept optional function -ee.removeListener(eventName, fn); -ee.off(eventName, fn); -// should accept optional context argument -ee.removeListener(eventName, fn, {}); -ee.off(eventName, fn, {}); -// should accept optional boolean flag for removing listeners added with `EventEmitter.once()` -ee.removeListener(eventName, fn, null, true); -ee.off(eventName, fn, null, true); -// should accept symbol as event name -ee.removeListener(eventSymbol); -ee.off(eventSymbol); -// should support fluent interface -ee.removeListener(eventName).removeListener(eventSymbol); -ee.off(eventName).off(eventSymbol); - -// EventEmitter.removeAllListeners() -// should not require any arguments -ee.removeAllListeners(); -// should accept optional event name -ee.removeAllListeners(eventName); -// should accept symbol as event name -ee.removeAllListeners(eventSymbol); -// should support fluent interface -ee.removeAllListeners(eventName).removeAllListeners(eventSymbol); - -// EventEmitter.setMaxListeners() -// should support fluent interface -ee.setMaxListeners().setMaxListeners(); diff --git a/eventemitter3/eventemitter3-1.2.0.d.ts b/eventemitter3/eventemitter3-1.2.0.d.ts deleted file mode 100644 index ca43aa6c95..0000000000 --- a/eventemitter3/eventemitter3-1.2.0.d.ts +++ /dev/null @@ -1,107 +0,0 @@ -// Type definitions for EventEmitter3 1.2.0 -// Project: https://github.com/primus/eventemitter3 -// Definitions by: Boriss Nazarovs -// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped - -declare module 'eventemitter3' { - /** - * Minimal EventEmitter interface that is molded against the Node.js - * EventEmitter interface. - */ - class EventEmitter { - constructor(); - - /** - * Return an array listing the events for which the emitter has registered listeners. - * - * @returns {(string|symbol)[]} - */ - eventNames(): (string|symbol)[]; - - /** - * Return the listeners registered for a given event. - * - * @param {(string|symbol)} event The event name. - * @returns {Function[]} - */ - listeners(event: string|symbol): Function[]; - - /** - * Check if there listeners for a given event. - * If `exists` argument is not `true` lists listeners. - * - * @param {(string|symbol)} event The event name. - * @param {boolean} exists Only check if there are listeners. - * @returns {boolean} - */ - listeners(event: string|symbol, exists: boolean): boolean; - - /** - * Calls each of the listeners registered for a given event. - * - * @param {(string|symbol)} event The event name. - * @param {...*} args Arguments that are passed to registered listeners - * @returns {boolean} `true` if the event had listeners, else `false`. - */ - emit(event: string|symbol, ...args: any[]): boolean; - - /** - * Add a listener for a given event. - * - * @param {(string|symbol)} event The event name. - * @param {Function} fn The listener function. - * @param {*} [context=this] The context to invoke the listener with. - * @returns {EventEmitter} `this`. - */ - on(event: string|symbol, fn: Function, context?: any): EventEmitter; - - /** - * Add a one-time listener for a given event. - * - * @param {(string|symbol)} event The event name. - * @param {Function} fn The listener function. - * @param {*} [context=this] The context to invoke the listener with. - * @returns {EventEmitter} `this`. - */ - once(event: string|symbol, fn: Function, context?: any): EventEmitter; - - /** - * Remove the listeners of a given event. - * - * @param {(string|symbol)} event The event name. - * @param {Function} fn Only remove the listeners that match this function. - * @param {*} context Only remove the listeners that have this context. - * @param {boolean} once Only remove one-time listeners. - * @returns {EventEmitter} `this`. - */ - removeListener(event: string|symbol, fn?: Function, context?: any, once?: boolean): EventEmitter; - - /** - * Remove all listeners, or those of the specified event. - * - * @param {(string|symbol)} event The event name. - * @returns {EventEmitter} `this`. - */ - removeAllListeners(event?: string|symbol): EventEmitter; - - /** - * Alias method for `removeListener` - */ - off(event: string|symbol, fn?: Function, context?: any, once?: boolean): EventEmitter; - - /** - * Alias method for `on` - */ - addListener(event: string|symbol, fn: Function, context?: any): EventEmitter; - - /** - * This function doesn't apply anymore. - * @deprecated - */ - setMaxListeners(): EventEmitter; - - static prefixed: string|boolean; - } - - export = EventEmitter; -} diff --git a/eventemitter3/eventemitter3-tests.ts b/eventemitter3/eventemitter3-tests.ts index 6c5733bec7..895dc7f54b 100644 --- a/eventemitter3/eventemitter3-tests.ts +++ b/eventemitter3/eventemitter3-tests.ts @@ -1,586 +1,113 @@ /// -/// -/// 'use strict'; -import EventEmitter = require('eventemitter3'); -import util = require('util'); -import * as EventEmitter3ImportedAsES6Module from 'eventemitter3'; +import EventEmitter from 'eventemitter3'; -declare namespace Assume { - interface Class { - new(...args: any[]): T; - } - - interface Assume { - equals(compare: T): Assume; - equal(compare: T): Assume; - eqls(compare: T): Assume; - is: Assume; - deep: Assume; - to: Assume; - either(arr: T[]): Assume; - instanceOf(clazz: Class): Assume; - a(typeofString: string): Assume; - } - - export function assume(input: T): Assume; -} - -let assume = Assume.assume; - -class EventEmitterTest { - v: EventEmitter3.EventEmitter; +const eventName = 'test'; +const eventSymbol: symbol = Symbol('test'); +const fn = () => console.log(1); +// Extending EventEmitter +class TestEmitter extends EventEmitter { constructor() { - this.v = new EventEmitter(); - this.v = new EventEmitter3ImportedAsES6Module(); - - // Some methods are missing or incompatible with current implementation (v4.2.x) of NodeJS.EventEmitter - // (e.g. getMaxListenters or listeners) - // var n: NodeJS.EventEmitter = this.v; - } - - listeners() { - var v1: Function[] = this.v.listeners('click'); - } - - emit() { - var v1: boolean = this.v.emit('click'); - var v2: boolean = this.v.emit('click', 1); - var v3: boolean = this.v.emit('click', 1, '1'); - var v4: boolean = this.v.emit('click', 1, '1', true); - var v5: boolean = this.v.emit('click', 1, '1', true, new Date()); - } - - on() { - var fn = () => console.log(1); - var v1: EventEmitter3.EventEmitter = this.v.on('click', fn); - var v2: EventEmitter3.EventEmitter = this.v.on('click', fn, this); - } - - once() { - var fn = () => console.log(1); - var v1: EventEmitter3.EventEmitter = this.v.once('click', fn); - var v2: EventEmitter3.EventEmitter = this.v.once('click', fn, this); - } - - removeListener() { - var fn = () => console.log(1); - var v1: EventEmitter3.EventEmitter = this.v.removeListener('click', fn); - var v2: EventEmitter3.EventEmitter = this.v.removeListener('click', fn, true); - } - - removeAllListeners() { - var v1: EventEmitter3.EventEmitter = this.v.removeAllListeners('click'); - } - - off() { - var fn = () => console.log(1); - var v1: EventEmitter3.EventEmitter = this.v.off('click', fn); - var v2: EventEmitter3.EventEmitter = this.v.off('click', fn, true); - } - - addListener() { - var fn = () => console.log(1); - var v1: EventEmitter3.EventEmitter = this.v.addListener('click', fn); - var v2: EventEmitter3.EventEmitter = this.v.addListener('click', fn, this); - } - - setMaxListeners() { - var v1: EventEmitter3.EventEmitter = this.v.setMaxListeners(); + super(); } } +const ee: TestEmitter = new TestEmitter(); -describe('EventEmitter', function tests() { - 'use strict'; +// EventEmitter.prefixed +// should be boolean or string static property +const prefix = EventEmitter.prefixed; +if (typeof prefix === 'boolean') { + console.log(prefix.valueOf()); +} else { + console.log(prefix.length); +} - it('exposes a `prefixed` property', function () { - assume(EventEmitter.prefixed).is.either([false, '~']); - }); - - it('inherits when used with require(util).inherits', function () { - class Beast extends EventEmitter { - /* rawr, i'm a beast */ +// EventEmitter.eventNames() +// should return array of strings or symbols +ee.eventNames().every((event) => { + if (typeof event === 'symbol') { + return false; + } else { + return event.length > 0; } - - class BeastES6 extends EventEmitter3ImportedAsES6Module { - /* rawr, i'm a beast */ - } - - util.inherits(Beast, EventEmitter); - - var moop = new Beast() - , meap = new Beast(); - - assume(moop).is.instanceOf(Beast); - assume(moop).is.instanceOf(EventEmitter); - - moop.listeners(); - meap.listeners(); - - moop.on('data', function () { - throw new Error('I should not emit'); - }); - - meap.emit('data', 'rawr'); - meap.removeListener('foo'); - meap.removeAllListeners(); - }); - - describe('EventEmitter#emit', function () { - it('should return false when there are not events to emit', function () { - var e = new EventEmitter(); - - assume(e.emit('foo')).equals(false); - assume(e.emit('bar')).equals(false); - }); - - it('emits with context', function (done) { - var context = { bar: 'baz' } - , e = new EventEmitter(); - - e.on('foo', function (bar: string) { - assume(bar).equals('bar'); - assume(this).equals(context); - - done(); - }, context).emit('foo', 'bar'); - }); - - it('emits with context, multiple arguments (force apply)', function (done) { - var context = { bar: 'baz' } - , e = new EventEmitter(); - - e.on('foo', function (bar: string) { - assume(bar).equals('bar'); - assume(this).equals(context); - - done(); - }, context).emit('foo', 'bar', 1,2,3,4,5,6,7,8,9,0); - }); - - it('can emit the function with multiple arguments', function () { - var e = new EventEmitter(); - - for(var i = 0; i < 100; i++) { - (function (j: number) { - for (var i = 0, args: number[] = []; i < j; i++) { - args.push(j); - } - - e.once('args', function () { - assume(arguments.length).equals(args.length); - }); - - e.emit.apply(e, (['args'] as any[]).concat(args)); - })(i); - } - }); - - it('can emit the function with multiple arguments, multiple listeners', function () { - var e = new EventEmitter(); - - for(var i = 0; i < 100; i++) { - (function (j: number) { - for (var i = 0, args: number[] = []; i < j; i++) { - args.push(j); - } - - e.once('args', function () { - assume(arguments.length).equals(args.length); - }); - - e.once('args', function () { - assume(arguments.length).equals(args.length); - }); - - e.once('args', function () { - assume(arguments.length).equals(args.length); - }); - - e.once('args', function () { - assume(arguments.length).equals(args.length); - }); - - e.emit.apply(e, (['args'] as any[]).concat(args)); - })(i); - } - }); - - it('emits with context, multiple listeners (force loop)', function () { - var e = new EventEmitter(); - - e.on('foo', function (bar: string) { - assume(this).eqls({ foo: 'bar' }); - assume(bar).equals('bar'); - }, { foo: 'bar' }); - - e.on('foo', function (bar: string) { - assume(this).eqls({ bar: 'baz' }); - assume(bar).equals('bar'); - }, { bar: 'baz' }); - - e.emit('foo', 'bar'); - }); - - it('emits with different contexts', function () { - var e = new EventEmitter() - , pattern = ''; - - function writer() { - pattern += this; - } - - e.on('write', writer, 'foo'); - e.on('write', writer, 'baz'); - e.once('write', writer, 'bar'); - e.once('write', writer, 'banana'); - - e.emit('write'); - assume(pattern).equals('foobazbarbanana'); - }); - - it('should return true when there are events to emit', function (done) { - var e = new EventEmitter(); - - e.on('foo', function () { - process.nextTick(done); - }); - - assume(e.emit('foo')).equals(true); - assume(e.emit('foob')).equals(false); - }); - - it('receives the emitted events', function (done) { - var e = new EventEmitter(); - - e.on('data', function (a: string, b: EventEmitter3.EventEmitter, c: Date, d: void, undef: void) { - assume(a).equals('foo'); - assume(b).equals(e); - assume(c).is.instanceOf(Date); - assume(undef).equals(undefined); - assume(arguments.length).equals(3); - - done(); - }); - - e.emit('data', 'foo', e, new Date()); - }); - - it('emits to all event listeners', function () { - var e = new EventEmitter() - , pattern: string[] = []; - - e.on('foo', function () { - pattern.push('foo1'); - }); - - e.on('foo', function () { - pattern.push('foo2'); - }); - - e.emit('foo'); - - assume(pattern.join(';')).equals('foo1;foo2'); - }); - - (function each(keys: string[]) { - var key = keys.shift(); - - if (!key) return; - - it('can store event which is a known property: '+ key, function (next) { - var e = new EventEmitter(); - - e.on(key, function (key: string) { - assume(key).equals(key); - next(); - }).emit(key, key); - }); - - each(keys); - })([ - 'hasOwnProperty', - 'constructor', - '__proto__', - 'toString', - 'toValue', - 'unwatch', - 'watch' - ]); - }); - - describe('EventEmitter#listeners', function () { - it('returns an empty array if no listeners are specified', function () { - var e = new EventEmitter(); - - assume(e.listeners('foo')).is.a('array'); - assume(e.listeners('foo').length).equals(0); - }); - - it('returns an array of function', function () { - var e = new EventEmitter(); - - function foo() {} - - e.on('foo', foo); - assume(e.listeners('foo')).is.a('array'); - assume(e.listeners('foo').length).equals(1); - assume(e.listeners('foo')).deep.equals([foo]); - }); - - it('is not vulnerable to modifications', function () { - var e = new EventEmitter(); - - function foo() {} - - e.on('foo', foo); - - assume(e.listeners('foo')).deep.equals([foo]); - - e.listeners('foo').length = 0; - assume(e.listeners('foo')).deep.equals([foo]); - }); - - it('can return a boolean as indication if listeners exist', function () { - var e = new EventEmitter(); - - function foo() {} - - e.once('once', foo); - e.once('multiple', foo); - e.once('multiple', foo); - e.on('on', foo); - e.on('multi', foo); - e.on('multi', foo); - - assume(e.listeners('foo', true)).equals(false); - assume(e.listeners('multiple', true)).equals(true); - assume(e.listeners('on', true)).equals(true); - assume(e.listeners('multi', true)).equals(true); - - e.removeAllListeners(); - - assume(e.listeners('multiple', true)).equals(false); - assume(e.listeners('on', true)).equals(false); - assume(e.listeners('multi', true)).equals(false); - }); - }); - - describe('EventEmitter#once', function () { - it('only emits it once', function () { - var e = new EventEmitter() - , calls = 0; - - e.once('foo', function () { - calls++; - }); - - e.emit('foo'); - e.emit('foo'); - e.emit('foo'); - e.emit('foo'); - e.emit('foo'); - - assume(e.listeners('foo').length).equals(0); - assume(calls).equals(1); - }); - - it('only emits once if emits are nested inside the listener', function () { - var e = new EventEmitter() - , calls = 0; - - e.once('foo', function () { - calls++; - e.emit('foo'); - }); - - e.emit('foo'); - assume(e.listeners('foo').length).equals(0); - assume(calls).equals(1); - }); - - it('only emits once for multiple events', function () { - var e = new EventEmitter() - , multi = 0 - , foo = 0 - , bar = 0; - - e.once('foo', function () { - foo++; - }); - - e.once('foo', function () { - bar++; - }); - - e.on('foo', function () { - multi++; - }); - - e.emit('foo'); - e.emit('foo'); - e.emit('foo'); - e.emit('foo'); - e.emit('foo'); - - assume(e.listeners('foo').length).equals(1); - assume(multi).equals(5); - assume(foo).equals(1); - assume(bar).equals(1); - }); - - it('only emits once with context', function (done) { - var context = { foo: 'bar' } - , e = new EventEmitter(); - - e.once('foo', function (bar: string) { - assume(this).equals(context); - assume(bar).equals('bar'); - - done(); - }, context).emit('foo', 'bar'); - }); - }); - - describe('EventEmitter#removeListener', function () { - it('should only remove the event with the specified function', function () { - var e = new EventEmitter(); - - function bar() {} - e.on('foo', function () {}); - e.on('bar', function () {}); - e.on('bar', bar); - - assume(e.removeListener('foo', bar)).equals(e); - assume(e.listeners('foo').length).equals(1); - assume(e.listeners('bar').length).equals(2); - - assume(e.removeListener('foo')).equals(e); - assume(e.listeners('foo').length).equals(0); - assume(e.listeners('bar').length).equals(2); - - assume(e.removeListener('bar', bar)).equals(e); - assume(e.listeners('bar').length).equals(1); - assume(e.removeListener('bar')).equals(e); - assume(e.listeners('bar').length).equals(0); - }); - - it('should only remove once events when using the once flag', function () { - var e = new EventEmitter(); - - function foo() {} - e.on('foo', foo); - - assume(e.removeListener('foo', function () {}, undefined, true)).equals(e); - assume(e.listeners('foo').length).equals(1); - assume(e.removeListener('foo', foo, undefined, true)).equals(e); - assume(e.listeners('foo').length).equals(1); - assume(e.removeListener('foo', foo)).equals(e); - assume(e.listeners('foo').length).equals(0); - - e.on('foo', foo); - e.once('foo', foo); - - assume(e.removeListener('foo', function () {}, undefined, true)).equals(e); - assume(e.listeners('foo').length).equals(2); - assume(e.removeListener('foo', foo, undefined, true)).equals(e); - assume(e.listeners('foo').length).equals(1); - - e.once('foo', foo); - - assume(e.removeListener('foo', foo)).equals(e); - assume(e.listeners('foo').length).equals(0); - }); - - it('should only remove listeners matching the correct context', function () { - var e = new EventEmitter() - , context = { foo: 'bar' }; - - function foo() {} - function bar() {} - e.on('foo', foo, context); - - assume(e.listeners('foo').length).equals(1); - assume(e.removeListener('foo', function () {}, context)).equals(e); - assume(e.listeners('foo').length).equals(1); - assume(e.removeListener('foo', foo, { baz: 'quux' })).equals(e); - assume(e.listeners('foo').length).equals(1); - assume(e.removeListener('foo', foo, context)).equals(e); - assume(e.listeners('foo').length).equals(0); - - e.on('foo', foo, context); - e.on('foo', bar); - - assume(e.listeners('foo').length).equals(2); - assume(e.removeListener('foo', foo, { baz: 'quux' })).equals(e); - assume(e.listeners('foo').length).equals(2); - assume(e.removeListener('foo', foo, context)).equals(e); - assume(e.listeners('foo').length).equals(1); - assume(e.listeners('foo')[0]).equals(bar); - - e.on('foo', foo, context); - - assume(e.listeners('foo').length).equals(2); - assume(e.removeAllListeners('foo')).equals(e); - assume(e.listeners('foo').length).equals(0); - }); - }); - - describe('EventEmitter#removeAllListeners', function () { - it('removes all events for the specified events', function () { - var e = new EventEmitter(); - - e.on('foo', function () { throw new Error('oops'); }); - e.on('foo', function () { throw new Error('oops'); }); - e.on('bar', function () { throw new Error('oops'); }); - e.on('aaa', function () { throw new Error('oops'); }); - - assume(e.removeAllListeners('foo')).equals(e); - assume(e.listeners('foo').length).equals(0); - assume(e.listeners('bar').length).equals(1); - assume(e.listeners('aaa').length).equals(1); - - assume(e.removeAllListeners('bar')).equals(e); - assume(e.removeAllListeners('aaa')).equals(e); - - assume(e.emit('foo')).equals(false); - assume(e.emit('bar')).equals(false); - assume(e.emit('aaa')).equals(false); - }); - - it('just nukes the fuck out of everything', function () { - var e = new EventEmitter(); - - e.on('foo', function () { throw new Error('oops'); }); - e.on('foo', function () { throw new Error('oops'); }); - e.on('bar', function () { throw new Error('oops'); }); - e.on('aaa', function () { throw new Error('oops'); }); - - assume(e.removeAllListeners()).equals(e); - assume(e.listeners('foo').length).equals(0); - assume(e.listeners('bar').length).equals(0); - assume(e.listeners('aaa').length).equals(0); - - assume(e.emit('foo')).equals(false); - assume(e.emit('bar')).equals(false); - assume(e.emit('aaa')).equals(false); - }); - }); - - describe('#setMaxListeners', function () { - it('is a function', function () { - var e = new EventEmitter(); - - assume(e.setMaxListeners).is.a('function'); - }); - - it('returns self when called', function () { - var e = new EventEmitter(); - - assume(e.setMaxListeners()).to.equal(e); - }); - }); }); + +// EventEmitter.listeners() +// should return array of functions +ee.listeners(eventName).map((listener) => { + return listener.bind(this); +}); +// should accept symbol as event name +ee.listeners(eventSymbol).map((listener) => { + return listener.bind(this); +}); +// should return boolean with 'exists' flag +const hasListeners: boolean = ee.listeners(eventName, true); + +// EventEmitter.emit() +// should support any number of arguments +ee.emit(eventName, 1, true, {}, [], 'test', Symbol(), null); +// should accept symbol as event name +ee.emit(eventSymbol); + +// EventEmitter.addListener() and EventEmitter.on() +// should accept function +ee.on(eventName, fn); +ee.addListener(eventName, fn); +// should accept optional context argument +ee.on(eventName, fn, this); +ee.addListener(eventName, fn, this); +// should accept symbol as event name +ee.on(eventSymbol, fn); +ee.addListener(eventSymbol, fn); +// should support fluent interface +ee.on(eventSymbol, fn).on(eventName, fn); +ee.addListener(eventSymbol, fn).addListener(eventName, fn); + +// EventEmitter.once() +// should accept event name and function +ee.once(eventName, fn); +// should accept optional context argument +ee.once(eventName, fn, this); +ee.once(eventName, fn, {}); +// should accept symbol as event name +ee.once(eventSymbol, fn); +// should support fluent interface +ee.once(eventSymbol, fn).once(eventName, fn); + +// EventEmitter.removeListener() and EventEmitter.off() +// should accept event name +ee.removeListener(eventName); +ee.off(eventName); +// should accept optional function +ee.removeListener(eventName, fn); +ee.off(eventName, fn); +// should accept optional context argument +ee.removeListener(eventName, fn, {}); +ee.off(eventName, fn, {}); +// should accept optional boolean flag for removing listeners added with `EventEmitter.once()` +ee.removeListener(eventName, fn, null, true); +ee.off(eventName, fn, null, true); +// should accept symbol as event name +ee.removeListener(eventSymbol); +ee.off(eventSymbol); +// should support fluent interface +ee.removeListener(eventName).removeListener(eventSymbol); +ee.off(eventName).off(eventSymbol); + +// EventEmitter.removeAllListeners() +// should not require any arguments +ee.removeAllListeners(); +// should accept optional event name +ee.removeAllListeners(eventName); +// should accept symbol as event name +ee.removeAllListeners(eventSymbol); +// should support fluent interface +ee.removeAllListeners(eventName).removeAllListeners(eventSymbol); + +// EventEmitter.setMaxListeners() +// should support fluent interface +ee.setMaxListeners().setMaxListeners(); diff --git a/eventemitter3/eventemitter3-1.2.0-tests.ts.tscparams b/eventemitter3/eventemitter3-tests.ts.tscparams similarity index 100% rename from eventemitter3/eventemitter3-1.2.0-tests.ts.tscparams rename to eventemitter3/eventemitter3-tests.ts.tscparams diff --git a/eventemitter3/eventemitter3.d.ts b/eventemitter3/eventemitter3.d.ts index 0d692b8247..ad71b1d49b 100644 --- a/eventemitter3/eventemitter3.d.ts +++ b/eventemitter3/eventemitter3.d.ts @@ -1,123 +1,109 @@ -// Type definitions for EventEmitter3 1.1.1 +// Type definitions for EventEmitter3 1.2.0 // Project: https://github.com/primus/eventemitter3 -// Definitions by: Yuichi Murata , Leon Yu +// Definitions by: Yuichi Murata , Leon Yu , Boriss Nazarovs // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped declare namespace EventEmitter3 { - interface EventEmitter3Static { - new (): EventEmitter; - prefixed: string | boolean; - } + /** + * Minimal EventEmitter interface that is molded against the Node.js + * EventEmitter interface. + */ class EventEmitter { - /** - * Minimal EventEmitter interface that is molded against the Node.js - * EventEmitter interface. - * - * @constructor - * @api public - */ constructor(); /** - * Return a list of assigned event listeners. + * Return an array listing the events for which the emitter has registered listeners. * - * @param {String} event The events that should be listed. - * @returns {Array} - * @api public + * @returns {(string|symbol)[]} */ - listeners(event?: string): Function[]; + eventNames(): (string|symbol)[]; /** - * Return a list of assigned event listeners. + * Return the listeners registered for a given event. * - * @param {String} event The events that should be listed. - * @param {Boolean} exists We only need to know if there are listeners. - * @returns {Boolean} - * @api public + * @param {(string|symbol)} event The event name. + * @returns {Function[]} */ - listeners(event: string, param: boolean): boolean; + listeners(event: string|symbol): Function[]; /** - * Emit an event to all registered event listeners. + * Check if there listeners for a given event. + * If `exists` argument is not `true` lists listeners. * - * @param {String} event The name of the event. - * @returns {Boolean} Indication if we've emitted an event. - * @api public + * @param {(string|symbol)} event The event name. + * @param {boolean} exists Only check if there are listeners. + * @returns {boolean} */ - emit(event: string, ...args: any[]): boolean; + listeners(event: string|symbol, exists: boolean): boolean; /** - * Register a new EventListener for the given event. + * Calls each of the listeners registered for a given event. * - * @param {String} event Name of the event. - * @param {Function} fn Callback function. - * @param {Mixed} [context=this] The context of the function. - * @api public + * @param {(string|symbol)} event The event name. + * @param {...*} args Arguments that are passed to registered listeners + * @returns {boolean} `true` if the event had listeners, else `false`. */ - on(event: string, fn: Function, context?: any): EventEmitter; + emit(event: string|symbol, ...args: any[]): boolean; /** - * Add an EventListener that's only called once. + * Add a listener for a given event. * - * @param {String} event Name of the event. - * @param {Function} fn Callback function. - * @param {Mixed} [context=this] The context of the function. - * @api public + * @param {(string|symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. */ - once(event: string, fn: Function, context?: any): EventEmitter; + on(event: string|symbol, fn: Function, context?: any): EventEmitter; /** - * Remove event listeners. + * Add a one-time listener for a given event. * - * @param {String} event The event we want to remove. - * @param {Function} fn The listener that we need to find. - * @param {Mixed} context Only remove listeners matching this context. - * @param {Boolean} once Only remove once listeners. - * @api public + * @param {(string|symbol)} event The event name. + * @param {Function} fn The listener function. + * @param {*} [context=this] The context to invoke the listener with. + * @returns {EventEmitter} `this`. */ - removeListener(event: string, fn?: Function, context?: any, once?: boolean): EventEmitter; + once(event: string|symbol, fn: Function, context?: any): EventEmitter; /** - * Remove all listeners or only the listeners for the specified event. + * Remove the listeners of a given event. * - * @param {String} event The event want to remove all listeners for. - * @api public + * @param {(string|symbol)} event The event name. + * @param {Function} fn Only remove the listeners that match this function. + * @param {*} context Only remove the listeners that have this context. + * @param {boolean} once Only remove one-time listeners. + * @returns {EventEmitter} `this`. */ - removeAllListeners(event?: string): EventEmitter; + removeListener(event: string|symbol, fn?: Function, context?: any, once?: boolean): EventEmitter; /** - * Remove event listeners. + * Remove all listeners, or those of the specified event. * - * @param {String} event The event we want to remove. - * @param {Function} fn The listener that we need to find. - * @param {Mixed} context Only remove listeners matching this context. - * @param {Boolean} once Only remove once listeners. - * @api public + * @param {(string|symbol)} event The event name. + * @returns {EventEmitter} `this`. */ - off(event: string, fn?: Function, context?: any, once?: boolean): EventEmitter; + removeAllListeners(event?: string|symbol): EventEmitter; /** - * Register a new EventListener for the given event. - * - * @param {String} event Name of the event. - * @param {Function} fn Callback function. - * @param {Mixed} [context=this] The context of the function. - * @api public + * Alias method for `removeListener` */ - addListener(event: string, fn: Function, context?: any): EventEmitter; + off(event: string|symbol, fn?: Function, context?: any, once?: boolean): EventEmitter; + + /** + * Alias method for `on` + */ + addListener(event: string|symbol, fn: Function, context?: any): EventEmitter; /** * This function doesn't apply anymore. * @deprecated */ setMaxListeners(): EventEmitter; + + static prefixed: string|boolean; } } declare module 'eventemitter3' { - // - // Expose the module. - // - var EventEmitter3: EventEmitter3.EventEmitter3Static; - export = EventEmitter3; + export = EventEmitter3.EventEmitter; } From d240f0ad0289e58d73701b8b5667cd973b60a69f Mon Sep 17 00:00:00 2001 From: Boriss Nazarovs Date: Fri, 2 Sep 2016 00:01:37 +0300 Subject: [PATCH 3/4] Added support for fluent interface in classes extending EventEmitter --- eventemitter3/eventemitter3-tests.ts | 18 +++++++++++------- eventemitter3/eventemitter3.d.ts | 14 +++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/eventemitter3/eventemitter3-tests.ts b/eventemitter3/eventemitter3-tests.ts index 895dc7f54b..8af197a80c 100644 --- a/eventemitter3/eventemitter3-tests.ts +++ b/eventemitter3/eventemitter3-tests.ts @@ -12,6 +12,10 @@ class TestEmitter extends EventEmitter { constructor() { super(); } + + test() { + return this; + } } const ee: TestEmitter = new TestEmitter(); @@ -64,8 +68,8 @@ ee.addListener(eventName, fn, this); ee.on(eventSymbol, fn); ee.addListener(eventSymbol, fn); // should support fluent interface -ee.on(eventSymbol, fn).on(eventName, fn); -ee.addListener(eventSymbol, fn).addListener(eventName, fn); +ee.on(eventSymbol, fn).test(); +ee.addListener(eventSymbol, fn).test(); // EventEmitter.once() // should accept event name and function @@ -76,7 +80,7 @@ ee.once(eventName, fn, {}); // should accept symbol as event name ee.once(eventSymbol, fn); // should support fluent interface -ee.once(eventSymbol, fn).once(eventName, fn); +ee.once(eventSymbol, fn).test(); // EventEmitter.removeListener() and EventEmitter.off() // should accept event name @@ -95,8 +99,8 @@ ee.off(eventName, fn, null, true); ee.removeListener(eventSymbol); ee.off(eventSymbol); // should support fluent interface -ee.removeListener(eventName).removeListener(eventSymbol); -ee.off(eventName).off(eventSymbol); +ee.removeListener(eventName).test(); +ee.off(eventName).test(); // EventEmitter.removeAllListeners() // should not require any arguments @@ -106,8 +110,8 @@ ee.removeAllListeners(eventName); // should accept symbol as event name ee.removeAllListeners(eventSymbol); // should support fluent interface -ee.removeAllListeners(eventName).removeAllListeners(eventSymbol); +ee.removeAllListeners(eventName).test(); // EventEmitter.setMaxListeners() // should support fluent interface -ee.setMaxListeners().setMaxListeners(); +ee.setMaxListeners().test(); diff --git a/eventemitter3/eventemitter3.d.ts b/eventemitter3/eventemitter3.d.ts index ad71b1d49b..96af62c94b 100644 --- a/eventemitter3/eventemitter3.d.ts +++ b/eventemitter3/eventemitter3.d.ts @@ -53,7 +53,7 @@ declare namespace EventEmitter3 { * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. */ - on(event: string|symbol, fn: Function, context?: any): EventEmitter; + on(event: string|symbol, fn: Function, context?: any): this; /** * Add a one-time listener for a given event. @@ -63,7 +63,7 @@ declare namespace EventEmitter3 { * @param {*} [context=this] The context to invoke the listener with. * @returns {EventEmitter} `this`. */ - once(event: string|symbol, fn: Function, context?: any): EventEmitter; + once(event: string|symbol, fn: Function, context?: any): this; /** * Remove the listeners of a given event. @@ -74,7 +74,7 @@ declare namespace EventEmitter3 { * @param {boolean} once Only remove one-time listeners. * @returns {EventEmitter} `this`. */ - removeListener(event: string|symbol, fn?: Function, context?: any, once?: boolean): EventEmitter; + removeListener(event: string|symbol, fn?: Function, context?: any, once?: boolean): this; /** * Remove all listeners, or those of the specified event. @@ -82,23 +82,23 @@ declare namespace EventEmitter3 { * @param {(string|symbol)} event The event name. * @returns {EventEmitter} `this`. */ - removeAllListeners(event?: string|symbol): EventEmitter; + removeAllListeners(event?: string|symbol): this; /** * Alias method for `removeListener` */ - off(event: string|symbol, fn?: Function, context?: any, once?: boolean): EventEmitter; + off(event: string|symbol, fn?: Function, context?: any, once?: boolean): this; /** * Alias method for `on` */ - addListener(event: string|symbol, fn: Function, context?: any): EventEmitter; + addListener(event: string|symbol, fn: Function, context?: any): this; /** * This function doesn't apply anymore. * @deprecated */ - setMaxListeners(): EventEmitter; + setMaxListeners(): this; static prefixed: string|boolean; } From 6151d69fadae62c9a4636a0736b0820b53f44e44 Mon Sep 17 00:00:00 2001 From: Boriss Nazarovs Date: Sat, 24 Sep 2016 14:37:30 +0300 Subject: [PATCH 4/4] Updated import in tests to use standard TypeScript import syntax --- eventemitter3/eventemitter3-tests.ts | 4 ++-- eventemitter3/eventemitter3-tests.ts.tscparams | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eventemitter3/eventemitter3-tests.ts b/eventemitter3/eventemitter3-tests.ts index 8af197a80c..77d84093cf 100644 --- a/eventemitter3/eventemitter3-tests.ts +++ b/eventemitter3/eventemitter3-tests.ts @@ -1,10 +1,10 @@ /// 'use strict'; -import EventEmitter from 'eventemitter3'; +import EventEmitter = require('eventemitter3'); const eventName = 'test'; -const eventSymbol: symbol = Symbol('test'); +const eventSymbol = Symbol('test'); const fn = () => console.log(1); // Extending EventEmitter diff --git a/eventemitter3/eventemitter3-tests.ts.tscparams b/eventemitter3/eventemitter3-tests.ts.tscparams index a0aefcf79a..30c9419a57 100644 --- a/eventemitter3/eventemitter3-tests.ts.tscparams +++ b/eventemitter3/eventemitter3-tests.ts.tscparams @@ -1 +1 @@ ---target es6 --allowSyntheticDefaultImports --noImplicitAny +-m commonjs