/** * @jest-environment node * * We need to use Node.js since the default "jsdom" environment results in a * "ReferenceError: TextDecoder is not defined" error. **/ import { readFileSync } from "fs"; import { CmMip, extractCmMips } from "../dist/cmMips.js"; import { LogObservable } from "../dist/Observable/LogObservable.js"; const logger = new LogObservable(); let onlyInternal: Uint8Array | undefined = undefined; let partlyExternal: Uint8Array | undefined = undefined; const emptyCmMips = new Uint8Array([ 0x77, // magic 0xee, 1, // version 0, 0, 0, 1, // suffix length 65, // suffix string ("A") 3, // format length 82, // format string ("RGB") 71, 66, 1, // averageR 2, // averageG 3, // averageB 4, // minWidth 0, 0, 0, 5, // minHeight 0, 0, 0, 0, // mipLevels 0, 0, 0, ]); beforeAll(() => { onlyInternal = new Uint8Array( readFileSync("./packages/web-utilities/__tests__/images/onlyInternal.cmmips") ); partlyExternal = new Uint8Array( readFileSync("./packages/web-utilities/__tests__/images/partlyExternal.cmmips") ); }); afterAll(() => { onlyInternal = undefined; partlyExternal = undefined; }); function checkBasics(mip: CmMip) { expect(mip).toBeDefined(); expect(mip.name).toBeTruthy(); expect(mip.suffix).toBeTruthy(); expect(mip.width).toBeGreaterThan(0); expect(mip.height).toBeGreaterThan(0); expect(mip.data?.length).toBeGreaterThan(0); } test("Default Mip from CmMips file with only internal images", () => { checkBasics(extractCmMips(onlyInternal, logger)); }); test("Default Mip from CmMips file with some external images", () => { checkBasics(extractCmMips(partlyExternal, logger)); }); test("Requesting exact Mip size", () => { const mip = extractCmMips(onlyInternal, logger, 16); checkBasics(mip); expect(mip.width).toEqual(16); expect(mip.height).toEqual(16); }); test("Requesting closest smaller Mip size", () => { const mip = extractCmMips(onlyInternal, logger, 15); checkBasics(mip); expect(mip.width).toEqual(8); expect(mip.height).toEqual(8); }); test("Requesting impossible Mip size", () => { // We should always get a Mip back, if there are any internal at all in the file. const mip = extractCmMips(onlyInternal, logger, 0); checkBasics(mip); expect(mip.width).toEqual(1); expect(mip.height).toEqual(1); }); test("Undefined array", () => { expect(extractCmMips(undefined, logger, 0)).toBeUndefined(); }); test("Wrong magic", () => { expect(extractCmMips(new Uint8Array([0x39, 0x30, 0, 0, 0, 0]), logger)).toBeUndefined(); }); test("Only header", () => { expect(extractCmMips(emptyCmMips, logger)).toBeUndefined(); }); test("Truncated data", () => { // Slice and Subarray will give internal buffers of different sizes. // Slice is safest and can therefor be considered the reference if the tests differ. const mip = extractCmMips(onlyInternal.subarray(0, 15), logger); expect(mip).toBeUndefined(); expect(extractCmMips(onlyInternal.slice(0, 15), logger)).toEqual(mip); }); test("Subarray with non-zero offset", () => { // Slice and Subarray will give internal buffers of different sizes and offsets. // Slice is safest and can therefor be considered the reference if the tests differ. const array = new Uint8Array(onlyInternal.length + 1); array.set(onlyInternal, 1); array[0] = 42; const mip = extractCmMips(array.subarray(1, array.length), logger); checkBasics(mip); expect(extractCmMips(array.slice(1, array.length), logger)).toEqual(mip); });