From c3e91f92f1aac7bb95b1499de4f662b43701ef06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9e=20Kooi?= Date: Thu, 24 May 2018 16:55:14 +0200 Subject: [PATCH] Add events-list and special-event-names test; more robust Reflect polyfills --- events.js | 26 +++++++++++++++++---- tests/events-list.js | 28 ++++++++++++++++++++++ tests/index.js | 2 ++ tests/special-event-names.js | 45 ++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 tests/events-list.js create mode 100644 tests/special-event-names.js diff --git a/events.js b/events.js index bcf4698..6dbc6eb 100644 --- a/events.js +++ b/events.js @@ -21,15 +21,31 @@ 'use strict'; -function ReflectApply(target, receiver, args) { - return Function.prototype.apply.call(target, receiver, args); -} -function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target); +var R = typeof Reflect === 'object' ? Reflect : null +var ReflectApply = R && typeof R.apply === 'function' + ? R.apply + : function ReflectApply(target, receiver, args) { + return Function.prototype.apply.call(target, receiver, args); + } + +var ReflectOwnKeys +if (R && typeof R.ownKeys === 'function') { + ReflectOwnKeys = R.ownKeys +} else if (Object.getOwnPropertySymbols) { + ReflectOwnKeys = function ReflectOwnKeys(target) { + return Object.getOwnPropertyNames(target) + .concat(Object.getOwnPropertySymbols(target)); + }; +} else { + ReflectOwnKeys = function ReflectOwnKeys(target) { + return Object.getOwnPropertyNames(target); + }; } + function ProcessEmitWarning(warning) { if (console && console.warn) console.warn(warning); } + var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { return value !== value; } diff --git a/tests/events-list.js b/tests/events-list.js new file mode 100644 index 0000000..08aa621 --- /dev/null +++ b/tests/events-list.js @@ -0,0 +1,28 @@ +'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]); +} diff --git a/tests/index.js b/tests/index.js index a8e6a40..2e5efcb 100644 --- a/tests/index.js +++ b/tests/index.js @@ -15,6 +15,7 @@ var require = function(file) { require('./add-listeners.js'); require('./check-listener-leaks.js'); require('./errors.js'); +require('./events-list.js'); require('./listener-count.js'); require('./listeners-side-effects.js'); require('./listeners.js'); @@ -30,6 +31,7 @@ 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 (typeof Symbol === 'function') { require('./symbols.js'); diff --git a/tests/special-event-names.js b/tests/special-event-names.js new file mode 100644 index 0000000..a2f0b74 --- /dev/null +++ b/tests/special-event-names.js @@ -0,0 +1,45 @@ +'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__') +}