1'use strict'; 2 3const common = require('../common'); 4const { 5 BroadcastChannel, 6 Worker, 7 receiveMessageOnPort 8} = require('worker_threads'); 9const assert = require('assert'); 10 11assert.throws(() => new BroadcastChannel(Symbol('test')), { 12 message: /Cannot convert a Symbol value to a string/ 13}); 14 15assert.throws(() => new BroadcastChannel(), { 16 message: /The "name" argument must be specified/ 17}); 18 19// These should all just work 20[undefined, 1, null, 'test', 1n, false, Infinity].forEach((i) => { 21 const bc = new BroadcastChannel(i); 22 assert.strictEqual(bc.name, `${i}`); 23 bc.close(); 24}); 25 26{ 27 // Empty postMessage throws 28 const bc = new BroadcastChannel('whatever'); 29 assert.throws(() => bc.postMessage(), { 30 message: /The "message" argument must be specified/ 31 }); 32 bc.close(); 33 // Calling close multiple times should not throw 34 bc.close(); 35 36 // Calling postMessage after close should throw 37 assert.throws(() => bc.postMessage(null), { 38 message: /BroadcastChannel is closed/ 39 }); 40} 41 42{ 43 const bc1 = new BroadcastChannel('channel1'); 44 const bc2 = new BroadcastChannel('channel1'); 45 const bc3 = new BroadcastChannel('channel1'); 46 const bc4 = new BroadcastChannel('channel2'); 47 assert.strictEqual(bc1.name, 'channel1'); 48 assert.strictEqual(bc2.name, 'channel1'); 49 assert.strictEqual(bc3.name, 'channel1'); 50 assert.strictEqual(bc4.name, 'channel2'); 51 bc1.addEventListener('message', common.mustCall((event) => { 52 assert.strictEqual(event.data, 'hello'); 53 bc1.close(); 54 bc2.close(); 55 bc4.close(); 56 })); 57 bc3.addEventListener('message', common.mustCall((event) => { 58 assert.strictEqual(event.data, 'hello'); 59 bc3.close(); 60 })); 61 bc2.addEventListener('message', common.mustNotCall()); 62 bc4.addEventListener('message', common.mustNotCall()); 63 bc2.postMessage('hello'); 64} 65 66{ 67 const bc1 = new BroadcastChannel('onmessage-channel1'); 68 const bc2 = new BroadcastChannel('onmessage-channel1'); 69 const bc3 = new BroadcastChannel('onmessage-channel1'); 70 const bc4 = new BroadcastChannel('onmessage-channel2'); 71 assert.strictEqual(bc1.name, 'onmessage-channel1'); 72 assert.strictEqual(bc2.name, 'onmessage-channel1'); 73 assert.strictEqual(bc3.name, 'onmessage-channel1'); 74 assert.strictEqual(bc4.name, 'onmessage-channel2'); 75 bc1.onmessage = common.mustCall((event) => { 76 assert.strictEqual(event.data, 'hello'); 77 bc1.close(); 78 bc2.close(); 79 bc4.close(); 80 }); 81 bc3.onmessage = common.mustCall((event) => { 82 assert.strictEqual(event.data, 'hello'); 83 bc3.close(); 84 }); 85 bc2.onmessage = common.mustNotCall(); 86 bc4.onmessage = common.mustNotCall(); 87 bc2.postMessage('hello'); 88} 89 90{ 91 const bc = new BroadcastChannel('worker1'); 92 new Worker(` 93 const assert = require('assert'); 94 const { BroadcastChannel } = require('worker_threads'); 95 const bc = new BroadcastChannel('worker1'); 96 bc.addEventListener('message', (event) => { 97 assert.strictEqual(event.data, 123); 98 // If this close() is not executed, the test should hang and timeout. 99 // If the test does hang and timeout in CI, then the first step should 100 // be to check that the two bc.close() calls are being made. 101 bc.close(); 102 }); 103 bc.postMessage(321); 104 `, { eval: true }); 105 bc.addEventListener('message', common.mustCall(({ data }) => { 106 assert.strictEqual(data, 321); 107 bc.postMessage(123); 108 bc.close(); 109 })); 110} 111 112{ 113 const bc1 = new BroadcastChannel('channel3'); 114 const bc2 = new BroadcastChannel('channel3'); 115 const bc3 = new BroadcastChannel('channel3'); 116 bc3.postMessage(new SharedArrayBuffer(10)); 117 let received = 0; 118 for (const bc of [bc1, bc2]) { 119 bc.addEventListener('message', common.mustCall(({ data }) => { 120 assert(data instanceof SharedArrayBuffer); 121 if (++received === 2) { 122 bc1.close(); 123 bc2.close(); 124 bc3.close(); 125 } 126 })); 127 } 128} 129 130{ 131 const bc1 = new BroadcastChannel('channel3'); 132 const mc = new MessageChannel(); 133 assert.throws(() => bc1.postMessage(mc), { 134 message: /Object that needs transfer was found/ 135 }); 136 assert.throws(() => bc1.postMessage(Symbol()), { 137 message: /Symbol\(\) could not be cloned/ 138 }); 139 bc1.close(); 140 assert.throws(() => bc1.postMessage(Symbol()), { 141 message: /BroadcastChannel is closed/ 142 }); 143} 144 145{ 146 const bc1 = new BroadcastChannel('channel4'); 147 const bc2 = new BroadcastChannel('channel4'); 148 bc1.postMessage('some data'); 149 assert.strictEqual(receiveMessageOnPort(bc2).message, 'some data'); 150 assert.strictEqual(receiveMessageOnPort(bc2), undefined); 151 bc1.close(); 152 bc2.close(); 153} 154 155{ 156 assert.throws(() => Reflect.get(BroadcastChannel.prototype, 'name', {}), { 157 code: 'ERR_INVALID_THIS', 158 }); 159 160 [ 161 'close', 162 'postMessage', 163 'ref', 164 'unref', 165 ].forEach((i) => { 166 assert.throws(() => Reflect.apply(BroadcastChannel.prototype[i], [], {}), { 167 code: 'ERR_INVALID_THIS', 168 }); 169 }); 170} 171