11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst {
61cb0ef41Sopenharmony_ci  BroadcastChannel,
71cb0ef41Sopenharmony_ci} = require('worker_threads');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci{
101cb0ef41Sopenharmony_ci  const c1 = new BroadcastChannel('eventType').unref();
111cb0ef41Sopenharmony_ci  const c2 = new BroadcastChannel('eventType');
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci  c2.onmessage = common.mustCall((e) => {
141cb0ef41Sopenharmony_ci    assert(e instanceof MessageEvent);
151cb0ef41Sopenharmony_ci    assert.strictEqual(e.target, c2);
161cb0ef41Sopenharmony_ci    assert.strictEqual(e.type, 'message');
171cb0ef41Sopenharmony_ci    assert.strictEqual(e.data, 'hello world');
181cb0ef41Sopenharmony_ci    c2.close();
191cb0ef41Sopenharmony_ci  });
201cb0ef41Sopenharmony_ci  c1.postMessage('hello world');
211cb0ef41Sopenharmony_ci}
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci{
241cb0ef41Sopenharmony_ci  // Messages are delivered in port creation order.
251cb0ef41Sopenharmony_ci  // TODO(@jasnell): The ordering here is different than
261cb0ef41Sopenharmony_ci  // what the browsers would implement due to the different
271cb0ef41Sopenharmony_ci  // dispatching algorithm under the covers. What's not
281cb0ef41Sopenharmony_ci  // immediately clear is whether the ordering is spec
291cb0ef41Sopenharmony_ci  // mandated. In this test, c1 should receive events
301cb0ef41Sopenharmony_ci  // first, then c2, then c3. In the Node.js dispatching
311cb0ef41Sopenharmony_ci  // algorithm this means the ordering is:
321cb0ef41Sopenharmony_ci  //    from c3    (c1 from c3)
331cb0ef41Sopenharmony_ci  //    done       (c1 from c2)
341cb0ef41Sopenharmony_ci  //    from c1    (c2 from c1)
351cb0ef41Sopenharmony_ci  //    from c3    (c2 from c3)
361cb0ef41Sopenharmony_ci  //    from c1    (c3 from c1)
371cb0ef41Sopenharmony_ci  //    done       (c3 from c2)
381cb0ef41Sopenharmony_ci  //
391cb0ef41Sopenharmony_ci  // Whereas in the browser-ordering (as illustrated in the
401cb0ef41Sopenharmony_ci  // Web Platform Tests) it would be:
411cb0ef41Sopenharmony_ci  //    from c1    (c2 from c1)
421cb0ef41Sopenharmony_ci  //    from c1    (c3 from c1)
431cb0ef41Sopenharmony_ci  //    from c3    (c1 from c3)
441cb0ef41Sopenharmony_ci  //    from c3    (c2 from c3)
451cb0ef41Sopenharmony_ci  //    done       (c1 from c2)
461cb0ef41Sopenharmony_ci  //    done       (c3 from c2)
471cb0ef41Sopenharmony_ci  const c1 = new BroadcastChannel('order');
481cb0ef41Sopenharmony_ci  const c2 = new BroadcastChannel('order');
491cb0ef41Sopenharmony_ci  const c3 = new BroadcastChannel('order');
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  const events = [];
521cb0ef41Sopenharmony_ci  let doneCount = 0;
531cb0ef41Sopenharmony_ci  const handler = common.mustCall((e) => {
541cb0ef41Sopenharmony_ci    events.push(e);
551cb0ef41Sopenharmony_ci    if (e.data === 'done') {
561cb0ef41Sopenharmony_ci      doneCount++;
571cb0ef41Sopenharmony_ci      if (doneCount === 2) {
581cb0ef41Sopenharmony_ci        assert.strictEqual(events.length, 6);
591cb0ef41Sopenharmony_ci        // TODO: Don't skip Windows once ordering is fixed per comment above.
601cb0ef41Sopenharmony_ci        // Right now, the ordering for Windows is unreliable.
611cb0ef41Sopenharmony_ci        if (!common.isWindows) {
621cb0ef41Sopenharmony_ci          assert.strictEqual(events[0].data, 'from c3');
631cb0ef41Sopenharmony_ci          assert.strictEqual(events[1].data, 'done');
641cb0ef41Sopenharmony_ci          assert.strictEqual(events[2].data, 'from c1');
651cb0ef41Sopenharmony_ci          assert.strictEqual(events[3].data, 'from c3');
661cb0ef41Sopenharmony_ci          assert.strictEqual(events[4].data, 'from c1');
671cb0ef41Sopenharmony_ci          assert.strictEqual(events[5].data, 'done');
681cb0ef41Sopenharmony_ci        }
691cb0ef41Sopenharmony_ci        c1.close();
701cb0ef41Sopenharmony_ci        c2.close();
711cb0ef41Sopenharmony_ci        c3.close();
721cb0ef41Sopenharmony_ci      }
731cb0ef41Sopenharmony_ci    }
741cb0ef41Sopenharmony_ci  }, 6);
751cb0ef41Sopenharmony_ci  c1.onmessage = handler;
761cb0ef41Sopenharmony_ci  c2.onmessage = handler;
771cb0ef41Sopenharmony_ci  c3.onmessage = handler;
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ci  c1.postMessage('from c1');
801cb0ef41Sopenharmony_ci  c3.postMessage('from c3');
811cb0ef41Sopenharmony_ci  c2.postMessage('done');
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci{
851cb0ef41Sopenharmony_ci  // Messages aren't delivered to a closed port
861cb0ef41Sopenharmony_ci  const c1 = new BroadcastChannel('closed1').unref();
871cb0ef41Sopenharmony_ci  const c2 = new BroadcastChannel('closed1');
881cb0ef41Sopenharmony_ci  const c3 = new BroadcastChannel('closed1');
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci  c2.onmessage = common.mustNotCall();
911cb0ef41Sopenharmony_ci  c2.close();
921cb0ef41Sopenharmony_ci  c3.onmessage = common.mustCall(() => c3.close());
931cb0ef41Sopenharmony_ci  c1.postMessage('test');
941cb0ef41Sopenharmony_ci}
951cb0ef41Sopenharmony_ci
961cb0ef41Sopenharmony_ci{
971cb0ef41Sopenharmony_ci  // Messages aren't delivered to a port closed after calling postMessage.
981cb0ef41Sopenharmony_ci  const c1 = new BroadcastChannel('closed2').unref();
991cb0ef41Sopenharmony_ci  const c2 = new BroadcastChannel('closed2');
1001cb0ef41Sopenharmony_ci  const c3 = new BroadcastChannel('closed2');
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci  c2.onmessage = common.mustNotCall();
1031cb0ef41Sopenharmony_ci  c3.onmessage = common.mustCall(() => c3.close());
1041cb0ef41Sopenharmony_ci  c1.postMessage('test');
1051cb0ef41Sopenharmony_ci  c2.close();
1061cb0ef41Sopenharmony_ci}
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ci{
1091cb0ef41Sopenharmony_ci  // Closing and creating channels during message delivery works correctly
1101cb0ef41Sopenharmony_ci  const c1 = new BroadcastChannel('create-in-onmessage').unref();
1111cb0ef41Sopenharmony_ci  const c2 = new BroadcastChannel('create-in-onmessage');
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci  c2.onmessage = common.mustCall((e) => {
1141cb0ef41Sopenharmony_ci    assert.strictEqual(e.data, 'first');
1151cb0ef41Sopenharmony_ci    c2.close();
1161cb0ef41Sopenharmony_ci    const c3 = new BroadcastChannel('create-in-onmessage');
1171cb0ef41Sopenharmony_ci    c3.onmessage = common.mustCall((event) => {
1181cb0ef41Sopenharmony_ci      assert.strictEqual(event.data, 'done');
1191cb0ef41Sopenharmony_ci      c3.close();
1201cb0ef41Sopenharmony_ci    });
1211cb0ef41Sopenharmony_ci    c1.postMessage('done');
1221cb0ef41Sopenharmony_ci  });
1231cb0ef41Sopenharmony_ci  c1.postMessage('first');
1241cb0ef41Sopenharmony_ci  c2.postMessage('second');
1251cb0ef41Sopenharmony_ci}
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci{
1281cb0ef41Sopenharmony_ci  // TODO: Fix failure on Windows CI. Skipping for now.
1291cb0ef41Sopenharmony_ci  if (!common.isWindows) {
1301cb0ef41Sopenharmony_ci    // Closing a channel in onmessage prevents already queued tasks
1311cb0ef41Sopenharmony_ci    // from firing onmessage events
1321cb0ef41Sopenharmony_ci    const c1 = new BroadcastChannel('close-in-onmessage2').unref();
1331cb0ef41Sopenharmony_ci    const c2 = new BroadcastChannel('close-in-onmessage2');
1341cb0ef41Sopenharmony_ci    const c3 = new BroadcastChannel('close-in-onmessage2');
1351cb0ef41Sopenharmony_ci    const events = [];
1361cb0ef41Sopenharmony_ci    c1.onmessage = (e) => events.push('c1: ' + e.data);
1371cb0ef41Sopenharmony_ci    c2.onmessage = (e) => events.push('c2: ' + e.data);
1381cb0ef41Sopenharmony_ci    c3.onmessage = (e) => events.push('c3: ' + e.data);
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci    // c2 closes itself when it receives the first message
1411cb0ef41Sopenharmony_ci    c2.addEventListener('message', common.mustCall(() => c2.close()));
1421cb0ef41Sopenharmony_ci
1431cb0ef41Sopenharmony_ci    c3.addEventListener('message', common.mustCall((e) => {
1441cb0ef41Sopenharmony_ci      if (e.data === 'done') {
1451cb0ef41Sopenharmony_ci        assert.deepStrictEqual(events, [
1461cb0ef41Sopenharmony_ci          'c2: first',
1471cb0ef41Sopenharmony_ci          'c3: first',
1481cb0ef41Sopenharmony_ci          'c3: done']);
1491cb0ef41Sopenharmony_ci        c3.close();
1501cb0ef41Sopenharmony_ci      }
1511cb0ef41Sopenharmony_ci    }, 2));
1521cb0ef41Sopenharmony_ci    c1.postMessage('first');
1531cb0ef41Sopenharmony_ci    c1.postMessage('done');
1541cb0ef41Sopenharmony_ci  }
1551cb0ef41Sopenharmony_ci}
156