2024-01-01 14:58:21 -05:00
|
|
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
2023-06-24 10:12:08 -04:00
|
|
|
|
2024-07-25 01:30:28 -04:00
|
|
|
import { assert, assertEquals } from "@std/assert";
|
|
|
|
import { fromFileUrl, relative } from "@std/path";
|
2023-06-24 10:12:08 -04:00
|
|
|
import {
|
2023-12-31 06:53:09 -05:00
|
|
|
brotliCompress,
|
2023-06-24 10:12:08 -04:00
|
|
|
brotliCompressSync,
|
|
|
|
brotliDecompressSync,
|
2024-08-02 10:44:32 -04:00
|
|
|
constants,
|
2024-11-13 09:37:45 -05:00
|
|
|
crc32,
|
2023-06-24 10:12:08 -04:00
|
|
|
createBrotliCompress,
|
|
|
|
createBrotliDecompress,
|
2023-08-11 07:42:35 -04:00
|
|
|
createDeflate,
|
2024-11-06 09:12:24 -05:00
|
|
|
gzip,
|
2024-01-03 08:33:51 -05:00
|
|
|
gzipSync,
|
|
|
|
unzipSync,
|
2023-06-24 10:12:08 -04:00
|
|
|
} from "node:zlib";
|
|
|
|
import { Buffer } from "node:buffer";
|
|
|
|
import { createReadStream, createWriteStream } from "node:fs";
|
2024-02-07 11:23:32 -05:00
|
|
|
import { Readable } from "node:stream";
|
|
|
|
import { buffer } from "node:stream/consumers";
|
2023-06-24 10:12:08 -04:00
|
|
|
|
|
|
|
Deno.test("brotli compression sync", () => {
|
|
|
|
const buf = Buffer.from("hello world");
|
|
|
|
const compressed = brotliCompressSync(buf);
|
|
|
|
const decompressed = brotliDecompressSync(compressed);
|
|
|
|
assertEquals(decompressed.toString(), "hello world");
|
|
|
|
});
|
|
|
|
|
2023-12-31 06:53:09 -05:00
|
|
|
Deno.test("brotli compression async", async () => {
|
|
|
|
const buf = Buffer.from("hello world");
|
|
|
|
const compressed: Buffer = await new Promise((resolve) =>
|
|
|
|
brotliCompress(buf, (_, res) => {
|
|
|
|
return resolve(res);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
assertEquals(compressed instanceof Buffer, true);
|
|
|
|
const decompressed = brotliDecompressSync(compressed);
|
|
|
|
assertEquals(decompressed.toString(), "hello world");
|
|
|
|
});
|
|
|
|
|
2024-06-20 01:01:53 -04:00
|
|
|
Deno.test("gzip compression sync", () => {
|
2024-01-03 08:33:51 -05:00
|
|
|
const buf = Buffer.from("hello world");
|
|
|
|
const compressed = gzipSync(buf);
|
|
|
|
const decompressed = unzipSync(compressed);
|
|
|
|
assertEquals(decompressed.toString(), "hello world");
|
|
|
|
});
|
|
|
|
|
2024-03-21 13:01:11 -04:00
|
|
|
Deno.test("brotli compression", {
|
|
|
|
ignore: true,
|
|
|
|
}, async () => {
|
2024-03-01 15:48:09 -05:00
|
|
|
const promise = Promise.withResolvers<void>();
|
2023-06-24 10:12:08 -04:00
|
|
|
const compress = createBrotliCompress();
|
|
|
|
const filePath = relative(
|
|
|
|
Deno.cwd(),
|
|
|
|
fromFileUrl(new URL("./testdata/lorem_ipsum.txt", import.meta.url)),
|
|
|
|
);
|
|
|
|
const input = createReadStream(filePath);
|
|
|
|
const output = createWriteStream("lorem_ipsum.txt.br");
|
|
|
|
|
|
|
|
const stream = input.pipe(compress).pipe(output);
|
|
|
|
|
|
|
|
stream.on("finish", () => {
|
|
|
|
const decompress = createBrotliDecompress();
|
|
|
|
const input2 = createReadStream("lorem_ipsum.txt.br");
|
|
|
|
const output2 = createWriteStream("lorem_ipsum.txt");
|
|
|
|
|
|
|
|
const stream2 = input2.pipe(decompress).pipe(output2);
|
2024-03-01 15:48:09 -05:00
|
|
|
stream2.on("close", () => promise.resolve());
|
2023-06-24 10:12:08 -04:00
|
|
|
});
|
|
|
|
|
2024-03-01 15:48:09 -05:00
|
|
|
await Promise.all([
|
|
|
|
promise.promise,
|
|
|
|
new Promise((r) => stream.on("close", r)),
|
|
|
|
]);
|
|
|
|
|
2023-06-24 10:12:08 -04:00
|
|
|
const content = Deno.readTextFileSync("lorem_ipsum.txt");
|
2024-03-21 13:01:11 -04:00
|
|
|
assert(content.startsWith("Lorem ipsum dolor sit amet"), content);
|
2023-06-24 10:12:08 -04:00
|
|
|
try {
|
|
|
|
Deno.removeSync("lorem_ipsum.txt.br");
|
|
|
|
} catch {
|
|
|
|
// pass
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
Deno.removeSync("lorem_ipsum.txt");
|
|
|
|
} catch {
|
|
|
|
// pass
|
|
|
|
}
|
|
|
|
});
|
2023-08-11 07:42:35 -04:00
|
|
|
|
2023-09-07 23:41:33 -04:00
|
|
|
Deno.test("brotli end-to-end with 4097 bytes", () => {
|
|
|
|
const a = "a".repeat(4097);
|
|
|
|
const compressed = brotliCompressSync(a);
|
|
|
|
const decompressed = brotliDecompressSync(compressed);
|
|
|
|
assertEquals(decompressed.toString(), a);
|
|
|
|
});
|
|
|
|
|
2023-08-11 07:42:35 -04:00
|
|
|
Deno.test(
|
|
|
|
"zlib create deflate with dictionary",
|
|
|
|
async () => {
|
2023-11-22 06:11:20 -05:00
|
|
|
const { promise, resolve } = Promise.withResolvers<void>();
|
2023-08-11 07:42:35 -04:00
|
|
|
const handle = createDeflate({
|
|
|
|
dictionary: Buffer.alloc(0),
|
|
|
|
});
|
|
|
|
|
2023-11-22 06:11:20 -05:00
|
|
|
handle.on("close", () => resolve());
|
2023-08-11 07:42:35 -04:00
|
|
|
handle.end();
|
|
|
|
handle.destroy();
|
|
|
|
|
|
|
|
await promise;
|
|
|
|
},
|
|
|
|
);
|
2023-12-13 11:58:56 -05:00
|
|
|
|
|
|
|
Deno.test(
|
|
|
|
"zlib flush i32",
|
|
|
|
function () {
|
|
|
|
const handle = createDeflate({
|
|
|
|
// @ts-expect-error: passing non-int flush value
|
|
|
|
flush: "",
|
|
|
|
});
|
|
|
|
|
|
|
|
handle.end();
|
|
|
|
handle.destroy();
|
|
|
|
},
|
|
|
|
);
|
2023-12-31 06:50:37 -05:00
|
|
|
|
|
|
|
Deno.test("should work with dataview", () => {
|
|
|
|
const buf = Buffer.from("hello world");
|
2024-08-02 10:23:21 -04:00
|
|
|
const compressed = brotliCompressSync(new DataView(buf.buffer));
|
2023-12-31 06:50:37 -05:00
|
|
|
const decompressed = brotliDecompressSync(compressed);
|
|
|
|
assertEquals(decompressed.toString(), "hello world");
|
|
|
|
});
|
|
|
|
|
|
|
|
Deno.test("should work with a buffer from an encoded string", () => {
|
|
|
|
const encoder = new TextEncoder();
|
|
|
|
const buffer = encoder.encode("hello world");
|
|
|
|
const buf = Buffer.from(buffer);
|
|
|
|
const compressed = brotliCompressSync(buf);
|
|
|
|
const decompressed = brotliDecompressSync(compressed);
|
|
|
|
assertEquals(decompressed.toString(), "hello world");
|
|
|
|
});
|
2024-01-03 08:33:51 -05:00
|
|
|
|
2024-08-02 10:44:32 -04:00
|
|
|
// https://github.com/denoland/deno/issues/24572
|
|
|
|
Deno.test("Brotli quality 10 doesn't panic", () => {
|
|
|
|
const e = brotliCompressSync("abc", {
|
|
|
|
params: {
|
|
|
|
[constants.BROTLI_PARAM_QUALITY]: 10,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
assertEquals(
|
|
|
|
new Uint8Array(e.buffer),
|
|
|
|
new Uint8Array([11, 1, 128, 97, 98, 99, 3]),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2024-01-03 08:33:51 -05:00
|
|
|
Deno.test(
|
|
|
|
"zlib compression with dataview",
|
|
|
|
() => {
|
|
|
|
const buf = Buffer.from("hello world");
|
2024-08-02 10:23:21 -04:00
|
|
|
const compressed = gzipSync(new DataView(buf.buffer));
|
2024-01-03 08:33:51 -05:00
|
|
|
const decompressed = unzipSync(compressed);
|
|
|
|
assertEquals(decompressed.toString(), "hello world");
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2024-06-20 01:01:53 -04:00
|
|
|
Deno.test("zlib compression with an encoded string", () => {
|
2024-01-03 08:33:51 -05:00
|
|
|
const encoder = new TextEncoder();
|
|
|
|
const buffer = encoder.encode("hello world");
|
|
|
|
const compressed = gzipSync(buffer);
|
|
|
|
const decompressed = unzipSync(compressed);
|
|
|
|
assertEquals(decompressed.toString(), "hello world");
|
|
|
|
});
|
2024-02-07 11:23:32 -05:00
|
|
|
|
|
|
|
Deno.test("brotli large chunk size", async () => {
|
|
|
|
const input = new Uint8Array(1000000);
|
|
|
|
for (let i = 0; i < input.length; i++) {
|
|
|
|
input[i] = Math.random() * 256;
|
|
|
|
}
|
|
|
|
const output = await buffer(
|
|
|
|
Readable.from([input])
|
|
|
|
.pipe(createBrotliCompress())
|
|
|
|
.pipe(createBrotliDecompress()),
|
|
|
|
);
|
|
|
|
assertEquals(output.length, input.length);
|
|
|
|
});
|
2024-03-12 07:53:31 -04:00
|
|
|
|
|
|
|
Deno.test("brotli decompress flush restore size", async () => {
|
|
|
|
const input = new Uint8Array(1000000);
|
|
|
|
const output = await buffer(
|
|
|
|
Readable.from([input])
|
|
|
|
.pipe(createBrotliCompress())
|
|
|
|
.pipe(createBrotliDecompress()),
|
|
|
|
);
|
|
|
|
assertEquals(output.length, input.length);
|
|
|
|
});
|
2024-08-11 04:56:30 -04:00
|
|
|
|
|
|
|
Deno.test("createBrotliCompress params", async () => {
|
|
|
|
const compress = createBrotliCompress({
|
|
|
|
params: {
|
|
|
|
[constants.BROTLI_PARAM_QUALITY]: 11,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
const input = new Uint8Array(10000);
|
|
|
|
for (let i = 0; i < input.length; i++) {
|
|
|
|
input[i] = Math.random() * 256;
|
|
|
|
}
|
|
|
|
const output = await buffer(
|
|
|
|
Readable.from([input])
|
|
|
|
.pipe(compress)
|
|
|
|
.pipe(createBrotliDecompress()),
|
|
|
|
);
|
|
|
|
assertEquals(output.length, input.length);
|
|
|
|
});
|
2024-11-06 09:12:24 -05:00
|
|
|
|
|
|
|
Deno.test("gzip() and gzipSync() accept ArrayBuffer", async () => {
|
|
|
|
const deffered = Promise.withResolvers<void>();
|
|
|
|
const buf = new ArrayBuffer(0);
|
|
|
|
let output: Buffer;
|
|
|
|
gzip(buf, (_err, data) => {
|
|
|
|
output = data;
|
|
|
|
deffered.resolve();
|
|
|
|
});
|
|
|
|
await deffered.promise;
|
|
|
|
assert(output! instanceof Buffer);
|
|
|
|
const outputSync = gzipSync(buf);
|
|
|
|
assert(outputSync instanceof Buffer);
|
|
|
|
});
|
2024-11-13 09:37:45 -05:00
|
|
|
|
|
|
|
Deno.test("crc32()", () => {
|
|
|
|
assertEquals(crc32("hello world"), 222957957);
|
|
|
|
});
|