char/avril
(wip) why'd you have to go and make things so complicaaaaated?
git clone https://git.t4t.associates/char/avril
688e96e
main
1mod common; 2 3# [ test ] 4fn self_messages_clone_synchronously_and_dispatch_in_fifo_tasks () { 5let output = common:: run ( 6r#" 7const seen = []; 8if (postMessage.name !== 'postMessage' || postMessage.length !== 1) throw Error('Function surface'); 9try {new postMessage(1); throw Error('Constructible postMessage');} 10catch (error) {if (!(error instanceof TypeError)) throw error;} 11onmessage = function (event) { 12if (this !== self || event.target !== self || !event.isTrusted || 13!(event instanceof MessageEvent) || event.source !== null || 14event.origin !== '' || !Object.isFrozen(event.ports)) throw Error('Message event'); 15seen.push(event.data.value); 16queueMicrotask(() => seen.push('microtask')); 17}; 18const value = {value: 1}; 19postMessage(value); 20value.value = 9; 21postMessage({value: 2}, {}); 22queueMicrotask(() => seen.push('before')); 23addEventListener('message', event => { 24if (event.data.value === 2) { 25if (seen.join() !== 'before,1,microtask,2') throw Error(seen.join()); 26console.log('self messages'); 27} 28}); 29try { postMessage(() => {}); throw Error('Clone accepted'); } 30catch (error) { if (error.name !== 'DataCloneError') throw error; } 31try { postMessage(); throw Error('Missing argument'); } 32catch (error) { if (!(error instanceof TypeError)) throw error; } 33"# , 34& [], 35); 36assert_eq! ( output. stdout , b"self messages\n" ); 37} 38 39# [ test ] 40fn self_messages_transfer_buffers_ports_and_streams () { 41let output = common:: run ( 42r#" 43const channel = new MessageChannel(), buffer = new Uint8Array([4, 5]).buffer; 44const stream = new ReadableStream({start(controller) {controller.enqueue('stream'); controller.close();}}); 45const portPost = MessagePort.prototype.postMessage; 46const answer = new Promise((resolve, reject) => { 47onmessage = async event => { 48try { 49if (event.data.port !== event.ports[0] || event.data.again !== event.data.port || 50new Uint8Array(event.data.buffer).join() !== '4,5') throw Error('Transfer graph'); 51const reply = new Promise(resolve => channel.port1.onmessage = e => resolve(e.data)); 52portPost.call(event.data.port, 'reply'); 53if (await reply !== 'reply' || (await event.data.stream.getReader().read()).value !== 'stream') throw Error('Transferred value'); 54event.data.port.close(); channel.port1.close(); 55resolve(); 56} catch (error) {reject(error);} 57}; 58}); 59const post = postMessage; 60globalThis.structuredClone = () => {throw Error('Guest clone');}; 61MessagePort.prototype.postMessage = () => {throw Error('Guest port');}; 62post({buffer, port: channel.port2, again: channel.port2, stream}, {transfer: [buffer, channel.port2, stream]}); 63if (buffer.byteLength !== 0 || !stream.locked) throw Error('Transfer not synchronous'); 64await answer; 65onmessage = null; 66if (onmessage !== null || onmessageerror !== null) throw Error('Handlers'); 67console.log('transfers'); 68"# , 69& [], 70); 71assert_eq! ( output. stdout , b"transfers\n" ); 72}