123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- '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);
|