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