11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ciconst common = require('../common'); 31cb0ef41Sopenharmony_ciconst assert = require('assert'); 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_ciconst { MessageChannel, MessagePort } = require('worker_threads'); 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci{ 81cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 91cb0ef41Sopenharmony_ci assert(port1 instanceof MessagePort); 101cb0ef41Sopenharmony_ci assert(port2 instanceof MessagePort); 111cb0ef41Sopenharmony_ci 121cb0ef41Sopenharmony_ci const input = { a: 1 }; 131cb0ef41Sopenharmony_ci port1.postMessage(input); 141cb0ef41Sopenharmony_ci port2.on('message', common.mustCall((received) => { 151cb0ef41Sopenharmony_ci assert.deepStrictEqual(received, input); 161cb0ef41Sopenharmony_ci port2.close(common.mustCall()); 171cb0ef41Sopenharmony_ci })); 181cb0ef41Sopenharmony_ci} 191cb0ef41Sopenharmony_ci{ 201cb0ef41Sopenharmony_ci // Test emitting non-message events on a port 211cb0ef41Sopenharmony_ci const { port2 } = new MessageChannel(); 221cb0ef41Sopenharmony_ci port2.addEventListener('foo', common.mustCall((received) => { 231cb0ef41Sopenharmony_ci assert.strictEqual(received.type, 'foo'); 241cb0ef41Sopenharmony_ci assert.strictEqual(received.detail, 'bar'); 251cb0ef41Sopenharmony_ci })); 261cb0ef41Sopenharmony_ci port2.on('foo', common.mustCall((received) => { 271cb0ef41Sopenharmony_ci assert.strictEqual(received, 'bar'); 281cb0ef41Sopenharmony_ci })); 291cb0ef41Sopenharmony_ci port2.emit('foo', 'bar'); 301cb0ef41Sopenharmony_ci} 311cb0ef41Sopenharmony_ci{ 321cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci port1.onmessage = common.mustCall((message) => { 351cb0ef41Sopenharmony_ci assert.strictEqual(message.data, 4); 361cb0ef41Sopenharmony_ci assert.strictEqual(message.target, port1); 371cb0ef41Sopenharmony_ci assert.deepStrictEqual(message.ports, []); 381cb0ef41Sopenharmony_ci port2.close(common.mustCall()); 391cb0ef41Sopenharmony_ci }); 401cb0ef41Sopenharmony_ci 411cb0ef41Sopenharmony_ci port1.postMessage(2); 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ci port2.onmessage = common.mustCall((message) => { 441cb0ef41Sopenharmony_ci port2.postMessage(message.data * 2); 451cb0ef41Sopenharmony_ci }); 461cb0ef41Sopenharmony_ci} 471cb0ef41Sopenharmony_ci 481cb0ef41Sopenharmony_ci{ 491cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 501cb0ef41Sopenharmony_ci 511cb0ef41Sopenharmony_ci const input = { a: 1 }; 521cb0ef41Sopenharmony_ci port1.postMessage(input); 531cb0ef41Sopenharmony_ci // Check that the message still gets delivered if `port2` has its 541cb0ef41Sopenharmony_ci // `on('message')` handler attached at a later point in time. 551cb0ef41Sopenharmony_ci setImmediate(() => { 561cb0ef41Sopenharmony_ci port2.on('message', common.mustCall((received) => { 571cb0ef41Sopenharmony_ci assert.deepStrictEqual(received, input); 581cb0ef41Sopenharmony_ci port2.close(common.mustCall()); 591cb0ef41Sopenharmony_ci })); 601cb0ef41Sopenharmony_ci }); 611cb0ef41Sopenharmony_ci} 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci{ 641cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci const input = { a: 1 }; 671cb0ef41Sopenharmony_ci 681cb0ef41Sopenharmony_ci const dummy = common.mustNotCall(); 691cb0ef41Sopenharmony_ci // Check that the message still gets delivered if `port2` has its 701cb0ef41Sopenharmony_ci // `on('message')` handler attached at a later point in time, even if a 711cb0ef41Sopenharmony_ci // listener was removed previously. 721cb0ef41Sopenharmony_ci port2.addListener('message', dummy); 731cb0ef41Sopenharmony_ci setImmediate(() => { 741cb0ef41Sopenharmony_ci port2.removeListener('message', dummy); 751cb0ef41Sopenharmony_ci port1.postMessage(input); 761cb0ef41Sopenharmony_ci setImmediate(() => { 771cb0ef41Sopenharmony_ci port2.on('message', common.mustCall((received) => { 781cb0ef41Sopenharmony_ci assert.deepStrictEqual(received, input); 791cb0ef41Sopenharmony_ci port2.close(common.mustCall()); 801cb0ef41Sopenharmony_ci })); 811cb0ef41Sopenharmony_ci }); 821cb0ef41Sopenharmony_ci }); 831cb0ef41Sopenharmony_ci} 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci{ 861cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 871cb0ef41Sopenharmony_ci port2.on('message', common.mustCall(6)); 881cb0ef41Sopenharmony_ci port1.postMessage(1, null); 891cb0ef41Sopenharmony_ci port1.postMessage(2, undefined); 901cb0ef41Sopenharmony_ci port1.postMessage(3, []); 911cb0ef41Sopenharmony_ci port1.postMessage(4, {}); 921cb0ef41Sopenharmony_ci port1.postMessage(5, { transfer: undefined }); 931cb0ef41Sopenharmony_ci port1.postMessage(6, { transfer: [] }); 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_ci const err = { 961cb0ef41Sopenharmony_ci constructor: TypeError, 971cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 981cb0ef41Sopenharmony_ci message: 'Optional transferList argument must be an iterable' 991cb0ef41Sopenharmony_ci }; 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, 0), err); 1021cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, false), err); 1031cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, 'X'), err); 1041cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, Symbol('X')), err); 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci const err2 = { 1071cb0ef41Sopenharmony_ci constructor: TypeError, 1081cb0ef41Sopenharmony_ci code: 'ERR_INVALID_ARG_TYPE', 1091cb0ef41Sopenharmony_ci message: 'Optional options.transfer argument must be an iterable' 1101cb0ef41Sopenharmony_ci }; 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, { transfer: null }), err2); 1131cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, { transfer: 0 }), err2); 1141cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, { transfer: false }), err2); 1151cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, { transfer: {} }), err2); 1161cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, { 1171cb0ef41Sopenharmony_ci transfer: { [Symbol.iterator]() { return {}; } } 1181cb0ef41Sopenharmony_ci }), err2); 1191cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, { 1201cb0ef41Sopenharmony_ci transfer: { [Symbol.iterator]() { return { next: 42 }; } } 1211cb0ef41Sopenharmony_ci }), err2); 1221cb0ef41Sopenharmony_ci assert.throws(() => port1.postMessage(5, { 1231cb0ef41Sopenharmony_ci transfer: { [Symbol.iterator]() { return { next: null }; } } 1241cb0ef41Sopenharmony_ci }), err2); 1251cb0ef41Sopenharmony_ci port1.close(); 1261cb0ef41Sopenharmony_ci} 1271cb0ef41Sopenharmony_ci 1281cb0ef41Sopenharmony_ci{ 1291cb0ef41Sopenharmony_ci // Make sure these ArrayBuffers end up detached, i.e. are actually being 1301cb0ef41Sopenharmony_ci // transferred because the transfer list provides them. 1311cb0ef41Sopenharmony_ci const { port1, port2 } = new MessageChannel(); 1321cb0ef41Sopenharmony_ci port2.on('message', common.mustCall((msg) => { 1331cb0ef41Sopenharmony_ci assert.strictEqual(msg.ab.byteLength, 10); 1341cb0ef41Sopenharmony_ci }, 4)); 1351cb0ef41Sopenharmony_ci 1361cb0ef41Sopenharmony_ci { 1371cb0ef41Sopenharmony_ci const ab = new ArrayBuffer(10); 1381cb0ef41Sopenharmony_ci port1.postMessage({ ab }, [ ab ]); 1391cb0ef41Sopenharmony_ci assert.strictEqual(ab.byteLength, 0); 1401cb0ef41Sopenharmony_ci } 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci { 1431cb0ef41Sopenharmony_ci const ab = new ArrayBuffer(10); 1441cb0ef41Sopenharmony_ci port1.postMessage({ ab }, { transfer: [ ab ] }); 1451cb0ef41Sopenharmony_ci assert.strictEqual(ab.byteLength, 0); 1461cb0ef41Sopenharmony_ci } 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci { 1491cb0ef41Sopenharmony_ci const ab = new ArrayBuffer(10); 1501cb0ef41Sopenharmony_ci port1.postMessage({ ab }, (function*() { yield ab; })()); 1511cb0ef41Sopenharmony_ci assert.strictEqual(ab.byteLength, 0); 1521cb0ef41Sopenharmony_ci } 1531cb0ef41Sopenharmony_ci 1541cb0ef41Sopenharmony_ci { 1551cb0ef41Sopenharmony_ci const ab = new ArrayBuffer(10); 1561cb0ef41Sopenharmony_ci port1.postMessage({ ab }, { 1571cb0ef41Sopenharmony_ci transfer: (function*() { yield ab; })() 1581cb0ef41Sopenharmony_ci }); 1591cb0ef41Sopenharmony_ci assert.strictEqual(ab.byteLength, 0); 1601cb0ef41Sopenharmony_ci } 1611cb0ef41Sopenharmony_ci 1621cb0ef41Sopenharmony_ci port1.close(); 1631cb0ef41Sopenharmony_ci} 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci{ 1661cb0ef41Sopenharmony_ci // Test MessageEvent#ports 1671cb0ef41Sopenharmony_ci const c1 = new MessageChannel(); 1681cb0ef41Sopenharmony_ci const c2 = new MessageChannel(); 1691cb0ef41Sopenharmony_ci c1.port1.postMessage({ port: c2.port2 }, [ c2.port2 ]); 1701cb0ef41Sopenharmony_ci c1.port2.addEventListener('message', common.mustCall((ev) => { 1711cb0ef41Sopenharmony_ci assert.strictEqual(ev.ports.length, 1); 1721cb0ef41Sopenharmony_ci assert.strictEqual(ev.ports[0].constructor, MessagePort); 1731cb0ef41Sopenharmony_ci c1.port1.close(); 1741cb0ef41Sopenharmony_ci c2.port1.close(); 1751cb0ef41Sopenharmony_ci })); 1761cb0ef41Sopenharmony_ci} 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_ci{ 1791cb0ef41Sopenharmony_ci assert.deepStrictEqual( 1801cb0ef41Sopenharmony_ci Object.getOwnPropertyNames(MessagePort.prototype).sort(), 1811cb0ef41Sopenharmony_ci [ 1821cb0ef41Sopenharmony_ci 'close', 'constructor', 'hasRef', 'onmessage', 'onmessageerror', 1831cb0ef41Sopenharmony_ci 'postMessage', 'ref', 'start', 'unref', 1841cb0ef41Sopenharmony_ci ]); 1851cb0ef41Sopenharmony_ci} 186