MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 170 lines 5.0 kB view raw
1import { test, testDeep, testThrows, summary } from './helpers.js'; 2 3console.log('ReadableStream / DefaultController / DefaultReader Tests\n'); 4 5test('RS typeof', typeof ReadableStream, 'function'); 6test('RS toStringTag', Object.prototype.toString.call(new ReadableStream()), '[object ReadableStream]'); 7 8const rs = new ReadableStream(); 9test('RS locked initially false', rs.locked, false); 10 11testThrows('RS requires new', () => ReadableStream()); 12testThrows('RS rejects null source', () => new ReadableStream(null)); 13testThrows('RS rejects invalid type', () => new ReadableStream({ type: 'invalid' })); 14testThrows('RS rejects null type', () => new ReadableStream({ type: null })); 15 16const rs2 = new ReadableStream({ type: undefined }); 17test('RS accepts undefined type', rs2.locked, false); 18 19let startCalled = false; 20let startController = null; 21const rs3 = new ReadableStream({ 22 start(c) { startCalled = true; startController = c; } 23}); 24test('start called synchronously', startCalled, true); 25test('controller has desiredSize', startController.desiredSize, 1); 26test('controller toStringTag', Object.prototype.toString.call(startController), '[object ReadableStreamDefaultController]'); 27 28testThrows('controller cannot be constructed', () => new ReadableStreamDefaultController()); 29 30const rs4 = new ReadableStream({ 31 start(c) { c.enqueue('a'); c.enqueue('b'); c.close(); } 32}); 33 34const reader = rs4.getReader(); 35test('locked after getReader', rs4.locked, true); 36test('reader toStringTag', Object.prototype.toString.call(reader), '[object ReadableStreamDefaultReader]'); 37 38testThrows('cannot get second reader', () => rs4.getReader()); 39testThrows('getReader rejects unknown mode', () => new ReadableStream().getReader({ mode: 'potato' })); 40 41async function testReadSequence() { 42 const r1 = await reader.read(); 43 test('read 1 value', r1.value, 'a'); 44 test('read 1 done', r1.done, false); 45 46 const r2 = await reader.read(); 47 test('read 2 value', r2.value, 'b'); 48 test('read 2 done', r2.done, false); 49 50 const r3 = await reader.read(); 51 test('read 3 done', r3.done, true); 52 test('read 3 value', r3.value, undefined); 53} 54 55async function testClosedPromise() { 56 const rs = new ReadableStream({ 57 start(c) { c.close(); } 58 }); 59 const reader = rs.getReader(); 60 await reader.closed; 61 test('closed resolves on close', true, true); 62} 63 64async function testCancel() { 65 let cancelReason = null; 66 const rs = new ReadableStream({ 67 cancel(reason) { cancelReason = reason; } 68 }); 69 await rs.cancel('test reason'); 70 test('cancel passes reason', cancelReason, 'test reason'); 71} 72 73async function testPullBackpressure() { 74 let pullCount = 0; 75 const rs = new ReadableStream({ 76 pull(c) { 77 pullCount++; 78 c.enqueue(pullCount); 79 } 80 }, { highWaterMark: 1 }); 81 82 await new Promise(r => setTimeout(r, 50)); 83 test('pull called once at start', pullCount, 1); 84 85 const reader = rs.getReader(); 86 const r1 = await reader.read(); 87 test('pull backpressure value', r1.value, 1); 88 89 await new Promise(r => setTimeout(r, 50)); 90 test('pull called again after read', pullCount, 2); 91} 92 93async function testReleaseLock() { 94 const rs = new ReadableStream({ 95 start(c) { c.enqueue('x'); } 96 }); 97 const reader = rs.getReader(); 98 reader.releaseLock(); 99 test('locked false after release', rs.locked, false); 100 101 const reader2 = rs.getReader(); 102 const r = await reader2.read(); 103 test('new reader can read', r.value, 'x'); 104} 105 106async function testDesiredSize() { 107 let ctrl; 108 new ReadableStream({ 109 start(c) { 110 ctrl = c; 111 } 112 }); 113 await new Promise(r => setTimeout(r, 0)); 114 test('desiredSize initially 1', ctrl.desiredSize, 1); 115 ctrl.enqueue('a'); 116 test('desiredSize after enqueue', ctrl.desiredSize, 0); 117 ctrl.close(); 118 test('desiredSize after close', ctrl.desiredSize, 0); 119} 120 121async function testErrorStream() { 122 const err = new Error('boom'); 123 const rs = new ReadableStream({ 124 start(c) { c.error(err); } 125 }); 126 const reader = rs.getReader(); 127 try { 128 await reader.read(); 129 test('errored stream should reject read', false, true); 130 } catch (e) { 131 test('errored stream rejects with error', e, err); 132 } 133} 134 135async function testCustomStrategy() { 136 const rs = new ReadableStream({ 137 start(c) { 138 c.enqueue(new Uint8Array(10)); 139 c.enqueue(new Uint8Array(20)); 140 } 141 }, { 142 highWaterMark: 64, 143 size(chunk) { return chunk.byteLength; } 144 }); 145 146 const reader = rs.getReader(); 147 const r1 = await reader.read(); 148 test('custom strategy chunk size', r1.value.byteLength, 10); 149} 150 151async function testSubclass() { 152 class MyStream extends ReadableStream { 153 myMethod() { return 42; } 154 } 155 const ms = new MyStream({ start(c) { c.close(); } }); 156 test('subclass instanceof', ms instanceof ReadableStream, true); 157 test('subclass method', ms.myMethod(), 42); 158} 159 160await testReadSequence(); 161await testClosedPromise(); 162await testCancel(); 163await testPullBackpressure(); 164await testReleaseLock(); 165await testDesiredSize(); 166await testErrorStream(); 167await testCustomStrategy(); 168await testSubclass(); 169 170summary();