import { describe, expect, it } from "vitest"; import { applyBinaryTemplate, deleteBytes, findBytePattern, insertBytes, interpretBytes, parseSearchPattern, replaceByteRange, validateBookmarks, } from "../../src/core/workbench"; describe("byte workbench primitives", () => { it("edits checked ranges without mutating the source", () => { const source = Uint8Array.from([1, 2, 3, 4]); expect([ ...replaceByteRange(source, 1, 2, Uint8Array.from([9, 8])), ]).toEqual([1, 9, 8, 4]); expect([...insertBytes(source, 2, Uint8Array.from([7]))]).toEqual([ 1, 2, 7, 3, 4, ]); expect([...deleteBytes(source, 1, 2)]).toEqual([1, 4]); expect([...source]).toEqual([1, 2, 3, 4]); expect(() => deleteBytes(source, 3, 2)).toThrow(/Edit range/u); }); it("searches exact and wildcard byte patterns with a bounded result set", () => { const bytes = new TextEncoder().encode("hello hallo hello"); const pattern = parseSearchPattern("68 ?? 6c 6c 6f", "hex"); expect(findBytePattern(bytes, pattern).offsets).toEqual([0, 6, 12]); expect( findBytePattern(bytes, parseSearchPattern("hello", "utf8"), { maximumMatches: 1, }), ).toMatchObject({ offsets: [0], truncated: true }); }); it("interprets typed values with explicit byte order", () => { const bytes = Uint8Array.from([1, 2, 3, 4, 0, 0, 0, 0]); const little = interpretBytes(bytes, 0, "little"); const big = interpretBytes(bytes, 0, "big"); expect(little.find((item) => item.type === "unsigned 32-bit")?.value).toBe( "67305985", ); expect(big.find((item) => item.type === "unsigned 32-bit")?.value).toBe( "16909060", ); }); it("applies built-in templates and validates bookmark ranges", () => { const png = Uint8Array.from([ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0, 0, 0, 13, 0x49, 0x48, 0x44, 0x52, 0, 0, 0, 2, 0, 0, 0, 3, ]); const result = applyBinaryTemplate(png, "png-header"); expect(result.recognized).toBe(true); expect(result.fields.find((field) => field.name === "width")?.value).toBe( "2", ); expect( validateBookmarks( [{ id: "ihdr", name: "IHDR", offset: 8, length: 16 }], png.length, ), ).toHaveLength(1); expect(() => validateBookmarks( [{ id: "bad", name: "Bad", offset: 23, length: 2 }], png.length, ), ).toThrow(/Bookmark range/u); }); });