1// Flags: --expose-internals --no-warnings 2'use strict'; 3 4const common = require('../common'); 5const { 6 Event, 7 NodeEventTarget, 8} = require('internal/event_target'); 9 10const { 11 deepStrictEqual, 12 ok, 13 strictEqual, 14 throws, 15} = require('assert'); 16 17const { on } = require('events'); 18 19{ 20 const eventTarget = new NodeEventTarget(); 21 strictEqual(eventTarget.listenerCount('foo'), 0); 22 deepStrictEqual(eventTarget.eventNames(), []); 23 24 const ev1 = common.mustCall(function(event) { 25 strictEqual(event.type, 'foo'); 26 strictEqual(this, eventTarget); 27 }, 2); 28 29 const ev2 = { 30 handleEvent: common.mustCall(function(event) { 31 strictEqual(event.type, 'foo'); 32 strictEqual(this, ev2); 33 }) 34 }; 35 36 eventTarget.addEventListener('foo', ev1); 37 eventTarget.addEventListener('foo', ev2, { once: true }); 38 strictEqual(eventTarget.listenerCount('foo'), 2); 39 ok(eventTarget.dispatchEvent(new Event('foo'))); 40 strictEqual(eventTarget.listenerCount('foo'), 1); 41 eventTarget.dispatchEvent(new Event('foo')); 42 43 eventTarget.removeEventListener('foo', ev1); 44 strictEqual(eventTarget.listenerCount('foo'), 0); 45 eventTarget.dispatchEvent(new Event('foo')); 46} 47 48{ 49 const eventTarget = new NodeEventTarget(); 50 strictEqual(eventTarget.listenerCount('foo'), 0); 51 deepStrictEqual(eventTarget.eventNames(), []); 52 53 const ev1 = common.mustCall((event) => { 54 strictEqual(event.type, 'foo'); 55 }, 2); 56 57 const ev2 = { 58 handleEvent: common.mustCall((event) => { 59 strictEqual(event.type, 'foo'); 60 }) 61 }; 62 63 strictEqual(eventTarget.on('foo', ev1), eventTarget); 64 strictEqual(eventTarget.once('foo', ev2, { once: true }), eventTarget); 65 strictEqual(eventTarget.listenerCount('foo'), 2); 66 eventTarget.dispatchEvent(new Event('foo')); 67 strictEqual(eventTarget.listenerCount('foo'), 1); 68 eventTarget.dispatchEvent(new Event('foo')); 69 70 strictEqual(eventTarget.off('foo', ev1), eventTarget); 71 strictEqual(eventTarget.listenerCount('foo'), 0); 72 eventTarget.dispatchEvent(new Event('foo')); 73} 74 75{ 76 const eventTarget = new NodeEventTarget(); 77 strictEqual(eventTarget.listenerCount('foo'), 0); 78 deepStrictEqual(eventTarget.eventNames(), []); 79 80 const ev1 = common.mustCall((event) => { 81 strictEqual(event.type, 'foo'); 82 }, 2); 83 84 const ev2 = { 85 handleEvent: common.mustCall((event) => { 86 strictEqual(event.type, 'foo'); 87 }) 88 }; 89 90 eventTarget.addListener('foo', ev1); 91 eventTarget.once('foo', ev2, { once: true }); 92 strictEqual(eventTarget.listenerCount('foo'), 2); 93 eventTarget.dispatchEvent(new Event('foo')); 94 strictEqual(eventTarget.listenerCount('foo'), 1); 95 eventTarget.dispatchEvent(new Event('foo')); 96 97 eventTarget.removeListener('foo', ev1); 98 strictEqual(eventTarget.listenerCount('foo'), 0); 99 eventTarget.dispatchEvent(new Event('foo')); 100} 101 102{ 103 const eventTarget = new NodeEventTarget(); 104 strictEqual(eventTarget.listenerCount('foo'), 0); 105 deepStrictEqual(eventTarget.eventNames(), []); 106 107 // Won't actually be called. 108 const ev1 = () => {}; 109 110 // Won't actually be called. 111 const ev2 = { handleEvent() {} }; 112 113 eventTarget.addListener('foo', ev1); 114 eventTarget.addEventListener('foo', ev1); 115 eventTarget.once('foo', ev2, { once: true }); 116 eventTarget.once('foo', ev2, { once: false }); 117 eventTarget.on('bar', ev1); 118 strictEqual(eventTarget.listenerCount('foo'), 2); 119 strictEqual(eventTarget.listenerCount('bar'), 1); 120 deepStrictEqual(eventTarget.eventNames(), ['foo', 'bar']); 121 strictEqual(eventTarget.removeAllListeners('foo'), eventTarget); 122 strictEqual(eventTarget.listenerCount('foo'), 0); 123 strictEqual(eventTarget.listenerCount('bar'), 1); 124 deepStrictEqual(eventTarget.eventNames(), ['bar']); 125 strictEqual(eventTarget.removeAllListeners(), eventTarget); 126 strictEqual(eventTarget.listenerCount('foo'), 0); 127 strictEqual(eventTarget.listenerCount('bar'), 0); 128 deepStrictEqual(eventTarget.eventNames(), []); 129} 130 131{ 132 const target = new NodeEventTarget(); 133 134 process.on('warning', common.mustCall((warning) => { 135 ok(warning instanceof Error); 136 strictEqual(warning.name, 'MaxListenersExceededWarning'); 137 strictEqual(warning.target, target); 138 strictEqual(warning.count, 2); 139 strictEqual(warning.type, 'foo'); 140 ok(warning.message.includes( 141 '2 foo listeners added to NodeEventTarget')); 142 })); 143 144 strictEqual(target.getMaxListeners(), NodeEventTarget.defaultMaxListeners); 145 target.setMaxListeners(1); 146 target.on('foo', () => {}); 147 target.on('foo', () => {}); 148} 149{ 150 // Test NodeEventTarget emit 151 const emitter = new NodeEventTarget(); 152 emitter.addEventListener('foo', common.mustCall((e) => { 153 strictEqual(e.type, 'foo'); 154 strictEqual(e.detail, 'bar'); 155 ok(e instanceof Event); 156 }), { once: true }); 157 emitter.once('foo', common.mustCall((e, droppedAdditionalArgument) => { 158 strictEqual(e, 'bar'); 159 strictEqual(droppedAdditionalArgument, undefined); 160 })); 161 emitter.emit('foo', 'bar', 'baz'); 162} 163{ 164 // Test NodeEventTarget emit unsupported usage 165 const emitter = new NodeEventTarget(); 166 throws(() => { 167 emitter.emit(); 168 }, /ERR_INVALID_ARG_TYPE/); 169} 170 171(async () => { 172 // test NodeEventTarget async-iterability 173 const emitter = new NodeEventTarget(); 174 const interval = setInterval(() => { 175 emitter.dispatchEvent(new Event('foo')); 176 }, 0); 177 let count = 0; 178 for await (const [ item ] of on(emitter, 'foo')) { 179 count++; 180 strictEqual(item.type, 'foo'); 181 if (count > 5) { 182 break; 183 } 184 } 185 clearInterval(interval); 186})().then(common.mustCall()); 187