• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const {
6  BroadcastChannel,
7} = require('worker_threads');
8
9{
10  const c1 = new BroadcastChannel('eventType').unref();
11  const c2 = new BroadcastChannel('eventType');
12
13  c2.onmessage = common.mustCall((e) => {
14    assert(e instanceof MessageEvent);
15    assert.strictEqual(e.target, c2);
16    assert.strictEqual(e.type, 'message');
17    assert.strictEqual(e.data, 'hello world');
18    c2.close();
19  });
20  c1.postMessage('hello world');
21}
22
23{
24  // Messages are delivered in port creation order.
25  // TODO(@jasnell): The ordering here is different than
26  // what the browsers would implement due to the different
27  // dispatching algorithm under the covers. What's not
28  // immediately clear is whether the ordering is spec
29  // mandated. In this test, c1 should receive events
30  // first, then c2, then c3. In the Node.js dispatching
31  // algorithm this means the ordering is:
32  //    from c3    (c1 from c3)
33  //    done       (c1 from c2)
34  //    from c1    (c2 from c1)
35  //    from c3    (c2 from c3)
36  //    from c1    (c3 from c1)
37  //    done       (c3 from c2)
38  //
39  // Whereas in the browser-ordering (as illustrated in the
40  // Web Platform Tests) it would be:
41  //    from c1    (c2 from c1)
42  //    from c1    (c3 from c1)
43  //    from c3    (c1 from c3)
44  //    from c3    (c2 from c3)
45  //    done       (c1 from c2)
46  //    done       (c3 from c2)
47  const c1 = new BroadcastChannel('order');
48  const c2 = new BroadcastChannel('order');
49  const c3 = new BroadcastChannel('order');
50
51  const events = [];
52  let doneCount = 0;
53  const handler = common.mustCall((e) => {
54    events.push(e);
55    if (e.data === 'done') {
56      doneCount++;
57      if (doneCount === 2) {
58        assert.strictEqual(events.length, 6);
59        // TODO: Don't skip Windows once ordering is fixed per comment above.
60        // Right now, the ordering for Windows is unreliable.
61        if (!common.isWindows) {
62          assert.strictEqual(events[0].data, 'from c3');
63          assert.strictEqual(events[1].data, 'done');
64          assert.strictEqual(events[2].data, 'from c1');
65          assert.strictEqual(events[3].data, 'from c3');
66          assert.strictEqual(events[4].data, 'from c1');
67          assert.strictEqual(events[5].data, 'done');
68        }
69        c1.close();
70        c2.close();
71        c3.close();
72      }
73    }
74  }, 6);
75  c1.onmessage = handler;
76  c2.onmessage = handler;
77  c3.onmessage = handler;
78
79  c1.postMessage('from c1');
80  c3.postMessage('from c3');
81  c2.postMessage('done');
82}
83
84{
85  // Messages aren't delivered to a closed port
86  const c1 = new BroadcastChannel('closed1').unref();
87  const c2 = new BroadcastChannel('closed1');
88  const c3 = new BroadcastChannel('closed1');
89
90  c2.onmessage = common.mustNotCall();
91  c2.close();
92  c3.onmessage = common.mustCall(() => c3.close());
93  c1.postMessage('test');
94}
95
96{
97  // Messages aren't delivered to a port closed after calling postMessage.
98  const c1 = new BroadcastChannel('closed2').unref();
99  const c2 = new BroadcastChannel('closed2');
100  const c3 = new BroadcastChannel('closed2');
101
102  c2.onmessage = common.mustNotCall();
103  c3.onmessage = common.mustCall(() => c3.close());
104  c1.postMessage('test');
105  c2.close();
106}
107
108{
109  // Closing and creating channels during message delivery works correctly
110  const c1 = new BroadcastChannel('create-in-onmessage').unref();
111  const c2 = new BroadcastChannel('create-in-onmessage');
112
113  c2.onmessage = common.mustCall((e) => {
114    assert.strictEqual(e.data, 'first');
115    c2.close();
116    const c3 = new BroadcastChannel('create-in-onmessage');
117    c3.onmessage = common.mustCall((event) => {
118      assert.strictEqual(event.data, 'done');
119      c3.close();
120    });
121    c1.postMessage('done');
122  });
123  c1.postMessage('first');
124  c2.postMessage('second');
125}
126
127{
128  // TODO: Fix failure on Windows CI. Skipping for now.
129  if (!common.isWindows) {
130    // Closing a channel in onmessage prevents already queued tasks
131    // from firing onmessage events
132    const c1 = new BroadcastChannel('close-in-onmessage2').unref();
133    const c2 = new BroadcastChannel('close-in-onmessage2');
134    const c3 = new BroadcastChannel('close-in-onmessage2');
135    const events = [];
136    c1.onmessage = (e) => events.push('c1: ' + e.data);
137    c2.onmessage = (e) => events.push('c2: ' + e.data);
138    c3.onmessage = (e) => events.push('c3: ' + e.data);
139
140    // c2 closes itself when it receives the first message
141    c2.addEventListener('message', common.mustCall(() => c2.close()));
142
143    c3.addEventListener('message', common.mustCall((e) => {
144      if (e.data === 'done') {
145        assert.deepStrictEqual(events, [
146          'c2: first',
147          'c3: first',
148          'c3: done']);
149        c3.close();
150      }
151    }, 2));
152    c1.postMessage('first');
153    c1.postMessage('done');
154  }
155}
156