| 1 | import { describe, expect, it } from "vitest"; |
| 2 | import { ZIP_MAX_ENTRIES, ZipWriter, concat, tar, tarEnd, tarEntry, tarStart, zip, type ArchiveEntry } from "../../src/lib/archive.js"; |
| 3 | |
| 4 | const enc = new TextEncoder(); |
| 5 | const MTIME = Date.UTC(2024, 0, 2, 3, 4, 6) / 1000; |
| 6 | const entries: ArchiveEntry[] = [ |
| 7 | { path: "r-abc/", dir: true }, |
| 8 | { path: "r-abc/a.txt", mode: "100644", content: enc.encode("hello\n".repeat(100)) }, |
| 9 | { path: `r-abc/${"long/".repeat(30)}b`, mode: "100755", content: enc.encode("#!/bin/sh\n") }, |
| 10 | { path: "r-abc/l", mode: "120000", content: enc.encode("a.txt") }, |
| 11 | ]; |
| 12 | |
| 13 | describe("streaming archive writers", () => { |
| 14 | it("write the same tar piece by piece as in one go", () => { |
| 15 | const pieces = [...tarStart(MTIME, "abc"), ...entries.flatMap((e) => tarEntry(e, MTIME)), tarEnd()]; |
| 16 | expect(concat(pieces)).toEqual(tar(entries, MTIME, "abc")); |
| 17 | }); |
| 18 | |
| 19 | it("write the same zip piece by piece as in one go", async () => { |
| 20 | const w = new ZipWriter(MTIME); |
| 21 | const parts: Uint8Array[] = []; |
| 22 | for (const e of entries) parts.push(...(await w.entry(e))); |
| 23 | parts.push(...w.end("abc")); |
| 24 | expect(concat(parts)).toEqual(await zip(entries, MTIME, "abc")); |
| 25 | }); |
| 26 | |
| 27 | it("refuse more entries than classic zip can hold instead of writing a broken archive", async () => { |
| 28 | const w = new ZipWriter(MTIME); |
| 29 | const dir: ArchiveEntry = { path: "d/", dir: true }; |
| 30 | for (let i = 0; i < ZIP_MAX_ENTRIES; i++) await w.entry(dir); |
| 31 | await expect(w.entry(dir)).rejects.toBeInstanceOf(RangeError); |
| 32 | }); |
| 33 | }); |