3 var common = require('./common');
4 var EventEmitter = require('../').EventEmitter;
5 var once = require('../').once;
6 var has = require('has');
7 var assert = require('assert');
13 function EventTargetMock() {
16 this.addEventListener = common.mustCall(this.addEventListener);
17 this.removeEventListener = common.mustCall(this.removeEventListener);
20 EventTargetMock.prototype.addEventListener = function addEventListener(name, listener, options) {
21 if (!(name in this.events)) {
22 this.events[name] = { listeners: [], options: options || {} }
24 this.events[name].listeners.push(listener);
27 EventTargetMock.prototype.removeEventListener = function removeEventListener(name, callback) {
28 if (!(name in this.events)) {
31 var event = this.events[name];
32 var stack = event.listeners;
34 for (var i = 0, l = stack.length; i < l; i++) {
35 if (stack[i] === callback) {
37 if (stack.length === 0) {
38 delete this.events[name];
45 EventTargetMock.prototype.dispatchEvent = function dispatchEvent(arg) {
46 if (!(arg.type in this.events)) {
50 var event = this.events[arg.type];
51 var stack = event.listeners.slice();
53 for (var i = 0, l = stack.length; i < l; i++) {
54 stack[i].call(null, arg);
55 if (event.options.once) {
56 this.removeEventListener(arg.type, stack[i]);
59 return !arg.defaultPrevented;
62 function onceAnEvent() {
63 var ee = new EventEmitter();
65 process.nextTick(function () {
66 ee.emit('myevent', 42);
69 return once(ee, 'myevent').then(function (args) {
71 assert.strictEqual(value, 42);
72 assert.strictEqual(ee.listenerCount('error'), 0);
73 assert.strictEqual(ee.listenerCount('myevent'), 0);
77 function onceAnEventWithTwoArgs() {
78 var ee = new EventEmitter();
80 process.nextTick(function () {
81 ee.emit('myevent', 42, 24);
84 return once(ee, 'myevent').then(function (value) {
85 assert.strictEqual(value.length, 2);
86 assert.strictEqual(value[0], 42);
87 assert.strictEqual(value[1], 24);
91 function catchesErrors() {
92 var ee = new EventEmitter();
94 var expected = new Error('kaboom');
96 process.nextTick(function () {
97 ee.emit('error', expected);
100 return once(ee, 'myevent').then(function () {
101 throw new Error('should reject')
103 assert.strictEqual(err, expected);
104 assert.strictEqual(ee.listenerCount('error'), 0);
105 assert.strictEqual(ee.listenerCount('myevent'), 0);
109 function stopListeningAfterCatchingError() {
110 var ee = new EventEmitter();
112 var expected = new Error('kaboom');
114 process.nextTick(function () {
115 ee.emit('error', expected);
116 ee.emit('myevent', 42, 24);
119 // process.on('multipleResolves', common.mustNotCall());
121 return once(ee, 'myevent').then(common.mustNotCall, function (err) {
122 // process.removeAllListeners('multipleResolves');
123 assert.strictEqual(err, expected);
124 assert.strictEqual(ee.listenerCount('error'), 0);
125 assert.strictEqual(ee.listenerCount('myevent'), 0);
129 function onceError() {
130 var ee = new EventEmitter();
132 var expected = new Error('kaboom');
133 process.nextTick(function () {
134 ee.emit('error', expected);
137 var promise = once(ee, 'error');
138 assert.strictEqual(ee.listenerCount('error'), 1);
139 return promise.then(function (args) {
141 assert.strictEqual(err, expected);
142 assert.strictEqual(ee.listenerCount('error'), 0);
143 assert.strictEqual(ee.listenerCount('myevent'), 0);
147 function onceWithEventTarget() {
148 var et = new EventTargetMock();
149 var event = new Event('myevent');
150 process.nextTick(function () {
151 et.dispatchEvent(event);
153 return once(et, 'myevent').then(function (args) {
155 assert.strictEqual(value, event);
156 assert.strictEqual(has(et.events, 'myevent'), false);
160 function onceWithEventTargetError() {
161 var et = new EventTargetMock();
162 var error = new Event('error');
163 process.nextTick(function () {
164 et.dispatchEvent(error);
166 return once(et, 'error').then(function (args) {
168 assert.strictEqual(err, error);
169 assert.strictEqual(has(et.events, 'error'), false);
173 function prioritizesEventEmitter() {
174 var ee = new EventEmitter();
175 ee.addEventListener = assert.fail;
176 ee.removeAllListeners = assert.fail;
177 process.nextTick(function () {
180 return once(ee, 'foo');
185 onceAnEventWithTwoArgs(),
187 stopListeningAfterCatchingError(),
189 onceWithEventTarget(),
190 onceWithEventTargetError(),
191 prioritizesEventEmitter()
194 var hasBrowserEventTarget = false;
196 hasBrowserEventTarget = typeof (new window.EventTarget().addEventListener) === 'function' &&
197 new window.Event('xyz').type === 'xyz';
200 if (hasBrowserEventTarget) {
201 var onceWithBrowserEventTarget = function onceWithBrowserEventTarget() {
202 var et = new window.EventTarget();
203 var event = new window.Event('myevent');
204 process.nextTick(function () {
205 et.dispatchEvent(event);
207 return once(et, 'myevent').then(function (args) {
209 assert.strictEqual(value, event);
210 assert.strictEqual(has(et.events, 'myevent'), false);
214 var onceWithBrowserEventTargetError = function onceWithBrowserEventTargetError() {
215 var et = new window.EventTarget();
216 var error = new window.Event('error');
217 process.nextTick(function () {
218 et.dispatchEvent(error);
220 return once(et, 'error').then(function (args) {
222 assert.strictEqual(err, error);
223 assert.strictEqual(has(et.events, 'error'), false);
227 common.test.comment('Testing with browser built-in EventTarget');
229 onceWithBrowserEventTarget(),
230 onceWithBrowserEventTargetError()
234 module.exports = Promise.all(allTests);