Files
workinf_Blender_Wasm/web/tests/unit/render-image-comparison.test.mjs
mes123456 0fe8d2bb56
Some checks are pending
M6 deployable RC / quick (push) Waiting to run
M6 deployable RC / chromium (push) Blocked by required conditions
M6 deployable RC / release (push) Blocked by required conditions
Advance M8-M11 parity workflows
2026-08-17 04:37:07 -04:00

66 lines
2.9 KiB
JavaScript

import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import test from "node:test";
import ts from "typescript";
const root = path.resolve(import.meta.dirname, "../../..");
const sourcePath = path.join(root, "web/protocol/render-image-comparison.ts");
const source = fs.readFileSync(sourcePath, "utf8").replace('import type { ErrorCode } from "./error";\n', "");
const transpiled = ts.transpileModule(source, {
compilerOptions: { module: ts.ModuleKind.ES2022, target: ts.ScriptTarget.ES2022 },
fileName: sourcePath,
reportDiagnostics: true,
});
assert.deepEqual(transpiled.diagnostics, []);
const comparison = await import("data:text/javascript;base64," + Buffer.from(transpiled.outputText).toString("base64"));
const thresholds = {
maxMeanAbsoluteError: 8,
maxRootMeanSquaredError: 16,
maxP95ChannelError: 16,
maxBadPixelRatio: 0.1,
badPixelChannelError: 32,
foregroundDeltaFromReferenceBackground: 32,
minForegroundIntersectionOverUnion: 0.8,
maxAlphaCoverageDeltaRatio: 0,
};
function frame(width = 4, height = 4) {
const pixels = new Uint8Array(width * height * 4);
for (let index = 0; index < pixels.length; index += 4) pixels.set([64, 64, 64, 255], index);
for (const pixel of [5, 6, 9, 10]) pixels.set([0, 0, 0, 255], pixel * 4);
return pixels;
}
test("M11-04 reports every explainable metric for identical SRGB8 frames", () => {
const reference = frame();
const report = comparison.compareRenderImages(reference, reference.slice(), 4, 4, thresholds);
assert.equal(report.status, "READY");
assert.deepEqual(
[report.meanAbsoluteError, report.rootMeanSquaredError, report.p95ChannelError, report.badPixelRatio],
[0, 0, 0, 0],
);
assert.equal(report.foregroundIntersectionOverUnion, 1);
assert.equal(report.checks.length, 6);
assert.equal(report.errorCode, null);
});
test("M11-04 rejects a non-empty but compositionally wrong frame", () => {
const reference = frame();
const wrong = frame();
for (let index = 0; index < wrong.length; index += 4) wrong.set([64, 64, 64, 255], index);
wrong.set([255, 0, 0, 255], 0);
const report = comparison.compareRenderImages(reference, wrong, 4, 4, thresholds);
assert.equal(report.status, "BLOCKED");
assert.equal(report.errorCode, "RENDER_REFERENCE_MISMATCH");
assert.ok(report.foregroundIntersectionOverUnion < thresholds.minForegroundIntersectionOverUnion);
assert.ok(report.checks.some((item) => !item.passed));
});
test("M11-04 rejects invalid dimensions, byte lengths and thresholds", () => {
assert.throws(() => comparison.compareRenderImages(frame(), frame(), 0, 4, thresholds), /INVALID_ARGUMENT/);
assert.throws(() => comparison.compareRenderImages(frame(), frame().subarray(1), 4, 4, thresholds), /INVALID_ARGUMENT/);
assert.throws(() => comparison.compareRenderImages(frame(), frame(), 4, 4, { ...thresholds, maxBadPixelRatio: 2 }), /INVALID_ARGUMENT/);
});