node/test/parallel/test-worker-broadcastchannel-wpt.js
Rich Trott d1e4d34afa test: skip flaky parts of broadcastchannel test on Windows
The feature was added recently and is experimental. This will need to be
fixed before it can be released as stable (in my opinion at least). But
for now, this gets us to a green CI without skipping the parts of the
test that are working on Windows.

PR-URL: https://github.com/nodejs/node/pull/36386
Reviewed-By: Beth Griggs <bgriggs@redhat.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
2020-12-04 08:19:37 -08:00

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');
}
}