mirror of https://github.com/nodejs/node.git
156 lines
4.7 KiB
JavaScript
156 lines
4.7 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
const assert = require('assert');
|
|
const {
|
|
BroadcastChannel,
|
|
} = require('worker_threads');
|
|
|
|
{
|
|
const c1 = new BroadcastChannel('eventType').unref();
|
|
const c2 = new BroadcastChannel('eventType');
|
|
|
|
c2.onmessage = common.mustCall((e) => {
|
|
assert(e instanceof MessageEvent);
|
|
assert.strictEqual(e.target, c2);
|
|
assert.strictEqual(e.type, 'message');
|
|
assert.strictEqual(e.data, 'hello world');
|
|
c2.close();
|
|
});
|
|
c1.postMessage('hello world');
|
|
}
|
|
|
|
{
|
|
// Messages are delivered in port creation order.
|
|
// TODO(@jasnell): The ordering here is different than
|
|
// what the browsers would implement due to the different
|
|
// dispatching algorithm under the covers. What's not
|
|
// immediately clear is whether the ordering is spec
|
|
// mandated. In this test, c1 should receive events
|
|
// first, then c2, then c3. In the Node.js dispatching
|
|
// algorithm this means the ordering is:
|
|
// from c3 (c1 from c3)
|
|
// done (c1 from c2)
|
|
// from c1 (c2 from c1)
|
|
// from c3 (c2 from c3)
|
|
// from c1 (c3 from c1)
|
|
// done (c3 from c2)
|
|
//
|
|
// Whereas in the browser-ordering (as illustrated in the
|
|
// Web Platform Tests) it would be:
|
|
// from c1 (c2 from c1)
|
|
// from c1 (c3 from c1)
|
|
// from c3 (c1 from c3)
|
|
// from c3 (c2 from c3)
|
|
// done (c1 from c2)
|
|
// done (c3 from c2)
|
|
const c1 = new BroadcastChannel('order');
|
|
const c2 = new BroadcastChannel('order');
|
|
const c3 = new BroadcastChannel('order');
|
|
|
|
const events = [];
|
|
let doneCount = 0;
|
|
const handler = common.mustCall((e) => {
|
|
events.push(e);
|
|
if (e.data === 'done') {
|
|
doneCount++;
|
|
if (doneCount === 2) {
|
|
assert.strictEqual(events.length, 6);
|
|
// TODO: Don't skip Windows once ordering is fixed per comment above.
|
|
// Right now, the ordering for Windows is unreliable.
|
|
if (!common.isWindows) {
|
|
assert.strictEqual(events[0].data, 'from c3');
|
|
assert.strictEqual(events[1].data, 'done');
|
|
assert.strictEqual(events[2].data, 'from c1');
|
|
assert.strictEqual(events[3].data, 'from c3');
|
|
assert.strictEqual(events[4].data, 'from c1');
|
|
assert.strictEqual(events[5].data, 'done');
|
|
}
|
|
c1.close();
|
|
c2.close();
|
|
c3.close();
|
|
}
|
|
}
|
|
}, 6);
|
|
c1.onmessage = handler;
|
|
c2.onmessage = handler;
|
|
c3.onmessage = handler;
|
|
|
|
c1.postMessage('from c1');
|
|
c3.postMessage('from c3');
|
|
c2.postMessage('done');
|
|
}
|
|
|
|
{
|
|
// Messages aren't delivered to a closed port
|
|
const c1 = new BroadcastChannel('closed1').unref();
|
|
const c2 = new BroadcastChannel('closed1');
|
|
const c3 = new BroadcastChannel('closed1');
|
|
|
|
c2.onmessage = common.mustNotCall();
|
|
c2.close();
|
|
c3.onmessage = common.mustCall(() => c3.close());
|
|
c1.postMessage('test');
|
|
}
|
|
|
|
{
|
|
// Messages aren't delivered to a port closed after calling postMessage.
|
|
const c1 = new BroadcastChannel('closed2').unref();
|
|
const c2 = new BroadcastChannel('closed2');
|
|
const c3 = new BroadcastChannel('closed2');
|
|
|
|
c2.onmessage = common.mustNotCall();
|
|
c3.onmessage = common.mustCall(() => c3.close());
|
|
c1.postMessage('test');
|
|
c2.close();
|
|
}
|
|
|
|
{
|
|
// Closing and creating channels during message delivery works correctly
|
|
const c1 = new BroadcastChannel('create-in-onmessage').unref();
|
|
const c2 = new BroadcastChannel('create-in-onmessage');
|
|
|
|
c2.onmessage = common.mustCall((e) => {
|
|
assert.strictEqual(e.data, 'first');
|
|
c2.close();
|
|
const c3 = new BroadcastChannel('create-in-onmessage');
|
|
c3.onmessage = common.mustCall((event) => {
|
|
assert.strictEqual(event.data, 'done');
|
|
c3.close();
|
|
});
|
|
c1.postMessage('done');
|
|
});
|
|
c1.postMessage('first');
|
|
c2.postMessage('second');
|
|
}
|
|
|
|
{
|
|
// TODO: Fix failure on Windows CI. Skipping for now.
|
|
if (!common.isWindows) {
|
|
// Closing a channel in onmessage prevents already queued tasks
|
|
// from firing onmessage events
|
|
const c1 = new BroadcastChannel('close-in-onmessage2').unref();
|
|
const c2 = new BroadcastChannel('close-in-onmessage2');
|
|
const c3 = new BroadcastChannel('close-in-onmessage2');
|
|
const events = [];
|
|
c1.onmessage = (e) => events.push('c1: ' + e.data);
|
|
c2.onmessage = (e) => events.push('c2: ' + e.data);
|
|
c3.onmessage = (e) => events.push('c3: ' + e.data);
|
|
|
|
// c2 closes itself when it receives the first message
|
|
c2.addEventListener('message', common.mustCall(() => c2.close()));
|
|
|
|
c3.addEventListener('message', common.mustCall((e) => {
|
|
if (e.data === 'done') {
|
|
assert.deepStrictEqual(events, [
|
|
'c2: first',
|
|
'c3: first',
|
|
'c3: done']);
|
|
c3.close();
|
|
}
|
|
}, 2));
|
|
c1.postMessage('first');
|
|
c1.postMessage('done');
|
|
}
|
|
}
|