import assert from "node:assert/strict"; import test from "node:test"; import { inspectNativeWaterDxt1Dds } from "./native-water-dds.mjs"; function ddsFixture({ width = 8, height = 8, mipCount = 3, trailingBytes = 0, fourCC = "DXT1" } = {}) { const mipSizes = []; let mipWidth = width; let mipHeight = height; for (let level = 0; level < mipCount; level += 1) { mipSizes.push(Math.ceil(mipWidth / 4) * Math.ceil(mipHeight / 4) * 8); mipWidth = Math.max(1, Math.floor(mipWidth / 2)); mipHeight = Math.max(1, Math.floor(mipHeight / 2)); } const bytes = Buffer.alloc(128 + mipSizes.reduce((sum, size) => sum + size, 0) + trailingBytes); bytes.write("DDS ", 0, "ascii"); bytes.writeUInt32LE(124, 4); bytes.writeUInt32LE(height, 12); bytes.writeUInt32LE(width, 16); bytes.writeUInt32LE(mipCount, 28); bytes.writeUInt32LE(32, 76); bytes.write(fourCC, 84, "ascii"); for (let index = 128; index < bytes.length; index += 1) bytes[index] = index & 0xff; return bytes; } test("native water DDS inspection hashes each declared mip and confirms exact consumption", () => { const result = inspectNativeWaterDxt1Dds(ddsFixture()); assert.equal(result.formatFourCC, "DXT1"); assert.equal(result.width, 8); assert.equal(result.height, 8); assert.equal(result.mipCount, 3); assert.equal(result.exactMipChainConsumption, true); assert.deepEqual(result.mips.map(({ width, height, byteLength }) => ({ width, height, byteLength })), [ { width: 8, height: 8, byteLength: 32 }, { width: 4, height: 4, byteLength: 8 }, { width: 2, height: 2, byteLength: 8 }, ]); assert.ok(result.mips.every((mip) => /^[a-f\d]{64}$/.test(mip.sha256))); }); test("native water DDS inspection rejects truncated, trailing and non-DXT1 data", () => { const complete = ddsFixture(); assert.throws(() => inspectNativeWaterDxt1Dds(complete.subarray(0, complete.length - 1)), /truncated/); assert.throws(() => inspectNativeWaterDxt1Dds(ddsFixture({ trailingBytes: 1 })), /trailing bytes/); assert.throws(() => inspectNativeWaterDxt1Dds(ddsFixture({ fourCC: "DXT5" })), /Unsupported native water frame format/); });