|
|
'use strict';
var common = require('./common'); var EventEmitter = require('../').EventEmitter; var once = require('../').once; var has = require('has'); var assert = require('assert');
function Event(type) { this.type = type; }
function EventTargetMock() { this.events = {};
this.addEventListener = common.mustCall(this.addEventListener); this.removeEventListener = common.mustCall(this.removeEventListener); }
EventTargetMock.prototype.addEventListener = function addEventListener(name, listener, options) { if (!(name in this.events)) { this.events[name] = { listeners: [], options: options || {} } } this.events[name].listeners.push(listener); };
EventTargetMock.prototype.removeEventListener = function removeEventListener(name, callback) { if (!(name in this.events)) { return; } var event = this.events[name]; var stack = event.listeners;
for (var i = 0, l = stack.length; i < l; i++) { if (stack[i] === callback) { stack.splice(i, 1); if (stack.length === 0) { delete this.events[name]; } return; } } };
EventTargetMock.prototype.dispatchEvent = function dispatchEvent(arg) { if (!(arg.type in this.events)) { return true; }
var event = this.events[arg.type]; var stack = event.listeners.slice();
for (var i = 0, l = stack.length; i < l; i++) { stack[i].call(null, arg); if (event.options.once) { this.removeEventListener(arg.type, stack[i]); } } return !arg.defaultPrevented; };
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); });
var promise = once(ee, 'error'); assert.strictEqual(ee.listenerCount('error'), 1); return promise.then(function (args) { var err = args[0] assert.strictEqual(err, expected); assert.strictEqual(ee.listenerCount('error'), 0); assert.strictEqual(ee.listenerCount('myevent'), 0); }); }
function onceWithEventTarget() { var et = new EventTargetMock(); var event = new Event('myevent'); process.nextTick(function () { et.dispatchEvent(event); }); return once(et, 'myevent').then(function (args) { var value = args[0]; assert.strictEqual(value, event); assert.strictEqual(has(et.events, 'myevent'), false); }); }
function onceWithEventTargetError() { var et = new EventTargetMock(); var error = new Event('error'); process.nextTick(function () { et.dispatchEvent(error); }); return once(et, 'error').then(function (args) { var err = args[0]; assert.strictEqual(err, error); assert.strictEqual(has(et.events, 'error'), false); }); }
function prioritizesEventEmitter() { var ee = new EventEmitter(); ee.addEventListener = assert.fail; ee.removeAllListeners = assert.fail; process.nextTick(function () { ee.emit('foo'); }); return once(ee, 'foo'); }
var allTests = [ onceAnEvent(), onceAnEventWithTwoArgs(), catchesErrors(), stopListeningAfterCatchingError(), onceError(), onceWithEventTarget(), onceWithEventTargetError(), prioritizesEventEmitter() ];
var hasBrowserEventTarget = false; try { hasBrowserEventTarget = typeof (new window.EventTarget().addEventListener) === 'function' && new window.Event('xyz').type === 'xyz'; } catch (err) {}
if (hasBrowserEventTarget) { var onceWithBrowserEventTarget = function onceWithBrowserEventTarget() { var et = new window.EventTarget(); var event = new window.Event('myevent'); process.nextTick(function () { et.dispatchEvent(event); }); return once(et, 'myevent').then(function (args) { var value = args[0]; assert.strictEqual(value, event); assert.strictEqual(has(et.events, 'myevent'), false); }); }
var onceWithBrowserEventTargetError = function onceWithBrowserEventTargetError() { var et = new window.EventTarget(); var error = new window.Event('error'); process.nextTick(function () { et.dispatchEvent(error); }); return once(et, 'error').then(function (args) { var err = args[0]; assert.strictEqual(err, error); assert.strictEqual(has(et.events, 'error'), false); }); }
common.test.comment('Testing with browser built-in EventTarget'); allTests.push([ onceWithBrowserEventTarget(), onceWithBrowserEventTargetError() ]); }
module.exports = Promise.all(allTests);
|