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 185 lines 6.9 kB view raw
1import { test, testThrows, summary } from './helpers.js'; 2 3console.log('CompressionStream / DecompressionStream Tests\n'); 4 5test('CS typeof', typeof CompressionStream, 'function'); 6test('CS toStringTag', Object.prototype.toString.call(new CompressionStream('gzip')), '[object CompressionStream]'); 7 8testThrows('CS requires new', () => CompressionStream('gzip')); 9testThrows('CS requires format', () => new CompressionStream()); 10testThrows('CS rejects invalid format', () => new CompressionStream('invalid')); 11 12const cs0 = new CompressionStream('gzip'); 13test('CS readable is ReadableStream', cs0.readable instanceof ReadableStream, true); 14test('CS writable is WritableStream', cs0.writable instanceof WritableStream, true); 15 16test('DS typeof', typeof DecompressionStream, 'function'); 17test('DS toStringTag', Object.prototype.toString.call(new DecompressionStream('gzip')), '[object DecompressionStream]'); 18 19testThrows('DS requires new', () => DecompressionStream('gzip')); 20testThrows('DS requires format', () => new DecompressionStream()); 21testThrows('DS rejects invalid format', () => new DecompressionStream('invalid')); 22 23const ds0 = new DecompressionStream('gzip'); 24test('DS readable is ReadableStream', ds0.readable instanceof ReadableStream, true); 25test('DS writable is WritableStream', ds0.writable instanceof WritableStream, true); 26 27const csBrotli = new CompressionStream('brotli'); 28test('CS brotli toStringTag', Object.prototype.toString.call(csBrotli), '[object CompressionStream]'); 29 30async function collectStream(readable) { 31 const reader = readable.getReader(); 32 const chunks = []; 33 while (true) { 34 const { value, done } = await reader.read(); 35 if (done) break; 36 chunks.push(value); 37 } 38 let total = 0; 39 for (const c of chunks) total += c.byteLength; 40 const result = new Uint8Array(total); 41 let offset = 0; 42 for (const c of chunks) { 43 result.set(c, offset); 44 offset += c.byteLength; 45 } 46 return result; 47} 48 49async function testGzipRoundTrip() { 50 const input = new TextEncoder().encode('Hello, compression world!'); 51 const cs = new CompressionStream('gzip'); 52 const writer = cs.writable.getWriter(); 53 writer.write(input); 54 writer.close(); 55 const compressed = await collectStream(cs.readable); 56 test('gzip compressed is smaller or has gzip header', compressed[0], 0x1f); 57 test('gzip compressed header byte 2', compressed[1], 0x8b); 58 59 const ds = new DecompressionStream('gzip'); 60 const writer2 = ds.writable.getWriter(); 61 writer2.write(compressed); 62 writer2.close(); 63 const decompressed = await collectStream(ds.readable); 64 test('gzip roundtrip length', decompressed.length, input.length); 65 test('gzip roundtrip value', new TextDecoder().decode(decompressed), 'Hello, compression world!'); 66} 67 68async function testDeflateRoundTrip() { 69 const input = new TextEncoder().encode('Deflate test data'); 70 const cs = new CompressionStream('deflate'); 71 const writer = cs.writable.getWriter(); 72 writer.write(input); 73 writer.close(); 74 const compressed = await collectStream(cs.readable); 75 test('deflate compressed length > 0', compressed.length > 0, true); 76 77 const ds = new DecompressionStream('deflate'); 78 const writer2 = ds.writable.getWriter(); 79 writer2.write(compressed); 80 writer2.close(); 81 const decompressed = await collectStream(ds.readable); 82 test('deflate roundtrip', new TextDecoder().decode(decompressed), 'Deflate test data'); 83} 84 85async function testDeflateRawRoundTrip() { 86 const input = new TextEncoder().encode('Raw deflate test'); 87 const cs = new CompressionStream('deflate-raw'); 88 const writer = cs.writable.getWriter(); 89 writer.write(input); 90 writer.close(); 91 const compressed = await collectStream(cs.readable); 92 test('deflate-raw compressed length > 0', compressed.length > 0, true); 93 94 const ds = new DecompressionStream('deflate-raw'); 95 const writer2 = ds.writable.getWriter(); 96 writer2.write(compressed); 97 writer2.close(); 98 const decompressed = await collectStream(ds.readable); 99 test('deflate-raw roundtrip', new TextDecoder().decode(decompressed), 'Raw deflate test'); 100} 101 102async function testBrotliRoundTrip() { 103 const input = new TextEncoder().encode('brotli stream test data'); 104 const cs = new CompressionStream('brotli'); 105 const writer = cs.writable.getWriter(); 106 writer.write(input); 107 writer.close(); 108 const compressed = await collectStream(cs.readable); 109 test('brotli compressed length > 0', compressed.length > 0, true); 110 111 const ds = new DecompressionStream('brotli'); 112 const writer2 = ds.writable.getWriter(); 113 writer2.write(compressed); 114 writer2.close(); 115 const reader = ds.readable.getReader(); 116 const first = await reader.read(); 117 test('brotli decompressed chunk is Uint8Array', first.value.constructor, Uint8Array); 118 test('brotli roundtrip', new TextDecoder().decode(first.value), 'brotli stream test data'); 119} 120 121async function testPipeThrough() { 122 const input = 'pipe through compression test'; 123 const encoded = new TextEncoder().encode(input); 124 const rs = new ReadableStream({ 125 start(c) { 126 c.enqueue(encoded); 127 c.close(); 128 } 129 }); 130 const compressed = await collectStream(rs.pipeThrough(new CompressionStream('gzip'))); 131 132 const rs2 = new ReadableStream({ 133 start(c) { 134 c.enqueue(compressed); 135 c.close(); 136 } 137 }); 138 const decompressed = await collectStream(rs2.pipeThrough(new DecompressionStream('gzip'))); 139 test('pipeThrough roundtrip', new TextDecoder().decode(decompressed), input); 140} 141 142async function testMultipleChunks() { 143 const cs = new CompressionStream('gzip'); 144 const writer = cs.writable.getWriter(); 145 writer.write(new TextEncoder().encode('chunk1 ')); 146 writer.write(new TextEncoder().encode('chunk2 ')); 147 writer.write(new TextEncoder().encode('chunk3')); 148 writer.close(); 149 const compressed = await collectStream(cs.readable); 150 151 const ds = new DecompressionStream('gzip'); 152 const writer2 = ds.writable.getWriter(); 153 writer2.write(compressed); 154 writer2.close(); 155 const decompressed = await collectStream(ds.readable); 156 test('multi-chunk roundtrip', new TextDecoder().decode(decompressed), 'chunk1 chunk2 chunk3'); 157} 158 159async function testLargeData() { 160 const str = 'x'.repeat(100000); 161 const input = new TextEncoder().encode(str); 162 const cs = new CompressionStream('gzip'); 163 const writer = cs.writable.getWriter(); 164 writer.write(input); 165 writer.close(); 166 const compressed = await collectStream(cs.readable); 167 test('large data compresses', compressed.length < input.length, true); 168 169 const ds = new DecompressionStream('gzip'); 170 const writer2 = ds.writable.getWriter(); 171 writer2.write(compressed); 172 writer2.close(); 173 const decompressed = await collectStream(ds.readable); 174 test('large data roundtrip length', decompressed.length, input.length); 175} 176 177await testGzipRoundTrip(); 178await testDeflateRoundTrip(); 179await testDeflateRawRoundTrip(); 180await testBrotliRoundTrip(); 181await testPipeThrough(); 182await testMultipleChunks(); 183await testLargeData(); 184 185summary();