Page MenuHomePhorge

streams-compression.js
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

streams-compression.js

import { test, testThrows, summary } from './helpers.js';
console.log('CompressionStream / DecompressionStream Tests\n');
test('CS typeof', typeof CompressionStream, 'function');
test('CS toStringTag', Object.prototype.toString.call(new CompressionStream('gzip')), '[object CompressionStream]');
testThrows('CS requires new', () => CompressionStream('gzip'));
testThrows('CS requires format', () => new CompressionStream());
testThrows('CS rejects invalid format', () => new CompressionStream('invalid'));
const cs0 = new CompressionStream('gzip');
test('CS readable is ReadableStream', cs0.readable instanceof ReadableStream, true);
test('CS writable is WritableStream', cs0.writable instanceof WritableStream, true);
test('DS typeof', typeof DecompressionStream, 'function');
test('DS toStringTag', Object.prototype.toString.call(new DecompressionStream('gzip')), '[object DecompressionStream]');
testThrows('DS requires new', () => DecompressionStream('gzip'));
testThrows('DS requires format', () => new DecompressionStream());
testThrows('DS rejects invalid format', () => new DecompressionStream('invalid'));
const ds0 = new DecompressionStream('gzip');
test('DS readable is ReadableStream', ds0.readable instanceof ReadableStream, true);
test('DS writable is WritableStream', ds0.writable instanceof WritableStream, true);
const csBrotli = new CompressionStream('brotli');
test('CS brotli toStringTag', Object.prototype.toString.call(csBrotli), '[object CompressionStream]');
async function collectStream(readable) {
const reader = readable.getReader();
const chunks = [];
while (true) {
const { value, done } = await reader.read();
if (done) break;
chunks.push(value);
}
let total = 0;
for (const c of chunks) total += c.byteLength;
const result = new Uint8Array(total);
let offset = 0;
for (const c of chunks) {
result.set(c, offset);
offset += c.byteLength;
}
return result;
}
async function testGzipRoundTrip() {
const input = new TextEncoder().encode('Hello, compression world!');
const cs = new CompressionStream('gzip');
const writer = cs.writable.getWriter();
writer.write(input);
writer.close();
const compressed = await collectStream(cs.readable);
test('gzip compressed is smaller or has gzip header', compressed[0], 0x1f);
test('gzip compressed header byte 2', compressed[1], 0x8b);
const ds = new DecompressionStream('gzip');
const writer2 = ds.writable.getWriter();
writer2.write(compressed);
writer2.close();
const decompressed = await collectStream(ds.readable);
test('gzip roundtrip length', decompressed.length, input.length);
test('gzip roundtrip value', new TextDecoder().decode(decompressed), 'Hello, compression world!');
}
async function testDeflateRoundTrip() {
const input = new TextEncoder().encode('Deflate test data');
const cs = new CompressionStream('deflate');
const writer = cs.writable.getWriter();
writer.write(input);
writer.close();
const compressed = await collectStream(cs.readable);
test('deflate compressed length > 0', compressed.length > 0, true);
const ds = new DecompressionStream('deflate');
const writer2 = ds.writable.getWriter();
writer2.write(compressed);
writer2.close();
const decompressed = await collectStream(ds.readable);
test('deflate roundtrip', new TextDecoder().decode(decompressed), 'Deflate test data');
}
async function testDeflateRawRoundTrip() {
const input = new TextEncoder().encode('Raw deflate test');
const cs = new CompressionStream('deflate-raw');
const writer = cs.writable.getWriter();
writer.write(input);
writer.close();
const compressed = await collectStream(cs.readable);
test('deflate-raw compressed length > 0', compressed.length > 0, true);
const ds = new DecompressionStream('deflate-raw');
const writer2 = ds.writable.getWriter();
writer2.write(compressed);
writer2.close();
const decompressed = await collectStream(ds.readable);
test('deflate-raw roundtrip', new TextDecoder().decode(decompressed), 'Raw deflate test');
}
async function testBrotliRoundTrip() {
const input = new TextEncoder().encode('brotli stream test data');
const cs = new CompressionStream('brotli');
const writer = cs.writable.getWriter();
writer.write(input);
writer.close();
const compressed = await collectStream(cs.readable);
test('brotli compressed length > 0', compressed.length > 0, true);
const ds = new DecompressionStream('brotli');
const writer2 = ds.writable.getWriter();
writer2.write(compressed);
writer2.close();
const reader = ds.readable.getReader();
const first = await reader.read();
test('brotli decompressed chunk is Uint8Array', first.value.constructor, Uint8Array);
test('brotli roundtrip', new TextDecoder().decode(first.value), 'brotli stream test data');
}
async function testPipeThrough() {
const input = 'pipe through compression test';
const encoded = new TextEncoder().encode(input);
const rs = new ReadableStream({
start(c) {
c.enqueue(encoded);
c.close();
}
});
const compressed = await collectStream(rs.pipeThrough(new CompressionStream('gzip')));
const rs2 = new ReadableStream({
start(c) {
c.enqueue(compressed);
c.close();
}
});
const decompressed = await collectStream(rs2.pipeThrough(new DecompressionStream('gzip')));
test('pipeThrough roundtrip', new TextDecoder().decode(decompressed), input);
}
async function testMultipleChunks() {
const cs = new CompressionStream('gzip');
const writer = cs.writable.getWriter();
writer.write(new TextEncoder().encode('chunk1 '));
writer.write(new TextEncoder().encode('chunk2 '));
writer.write(new TextEncoder().encode('chunk3'));
writer.close();
const compressed = await collectStream(cs.readable);
const ds = new DecompressionStream('gzip');
const writer2 = ds.writable.getWriter();
writer2.write(compressed);
writer2.close();
const decompressed = await collectStream(ds.readable);
test('multi-chunk roundtrip', new TextDecoder().decode(decompressed), 'chunk1 chunk2 chunk3');
}
async function testLargeData() {
const str = 'x'.repeat(100000);
const input = new TextEncoder().encode(str);
const cs = new CompressionStream('gzip');
const writer = cs.writable.getWriter();
writer.write(input);
writer.close();
const compressed = await collectStream(cs.readable);
test('large data compresses', compressed.length < input.length, true);
const ds = new DecompressionStream('gzip');
const writer2 = ds.writable.getWriter();
writer2.write(compressed);
writer2.close();
const decompressed = await collectStream(ds.readable);
test('large data roundtrip length', decompressed.length, input.length);
}
await testGzipRoundTrip();
await testDeflateRoundTrip();
await testDeflateRawRoundTrip();
await testBrotliRoundTrip();
await testPipeThrough();
await testMultipleChunks();
await testLargeData();
summary();

File Metadata

Mime Type
application/javascript
Expires
Fri, Apr 3, 7:32 PM (1 d, 23 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
521309
Default Alt Text
streams-compression.js (6 KB)

Event Timeline