Files
workinf_Blender_Wasm/web/tests/unit/sequencer-codec-probe.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

69 lines
3.8 KiB
JavaScript

import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { pathToFileURL } from "node:url";
import test from "node:test";
import ts from "typescript";
const repoRoot = path.resolve(import.meta.dirname, "../../..");
const temporary = fs.mkdtempSync(path.join(os.tmpdir(), "sequencer-codec-probe-unit-"));
function transpile(sourceName, outputName, replacements = []) {
const sourcePath = path.join(repoRoot, "web/protocol", sourceName);
const result = ts.transpileModule(fs.readFileSync(sourcePath, "utf8"), {
compilerOptions: { module: ts.ModuleKind.ES2022, target: ts.ScriptTarget.ES2022 },
fileName: sourcePath,
reportDiagnostics: true,
});
assert.deepEqual(result.diagnostics, []);
fs.writeFileSync(path.join(temporary, outputName), replacements.reduce((value, [from, to]) => value.replaceAll(from, to), result.outputText));
}
transpile("capability-gates.ts", "capability-gates.mjs");
transpile("asset-path.ts", "asset-path.mjs");
transpile("sequencer.ts", "sequencer.mjs", [
['from "./capability-gates"', 'from "./capability-gates.mjs"'],
['from "./asset-path"', 'from "./asset-path.mjs"'],
]);
const sequencer = await import(pathToFileURL(path.join(temporary, "sequencer.mjs")));
const requests = [
{ schemaVersion: 1, stripType: "IMAGE", mimeType: "image/png", byteLength: 261, sourceSha256: "a".repeat(64) },
{ schemaVersion: 1, stripType: "SOUND", mimeType: "audio/wav", byteLength: 16_044, sourceSha256: "b".repeat(64) },
{ schemaVersion: 1, stripType: "MOVIE", mimeType: "video/mp4", byteLength: 1_484, sourceSha256: "c".repeat(64) },
];
const ready = [
{ backend: "IMAGE_BITMAP", decoded: { width: 8, height: 8 } },
{ backend: "WEB_AUDIO", decoded: { sampleRate: 8_000, channels: 1, durationFrames: 8_000 } },
{ backend: "HTML_MEDIA", decoded: { width: 16, height: 16, durationMicros: 1_000_000 } },
];
test("M11-09 gates IMAGE, SOUND and MOVIE only with identity-bound ready probe receipts", () => {
for (const [index, request] of requests.entries()) {
assert.deepEqual(sequencer.parseSequencerCodecProbeRequest(request), request);
const result = { ...request, status: "READY", backend: ready[index].backend, reason: null, decoded: ready[index].decoded };
assert.equal(sequencer.gateSequencerCodec(request, result).status, "READY");
}
});
test("M11-09 rejects extension fields, family mismatch, forged backend and source drift", () => {
assert.throws(() => sequencer.parseSequencerCodecProbeRequest({ ...requests[0], sourcePath: "image.mp4" }), { code: "SEQUENCER_SCHEMA_INVALID" });
assert.throws(() => sequencer.parseSequencerCodecProbeRequest({ ...requests[0], mimeType: "video/mp4" }), { code: "SEQUENCER_SCHEMA_INVALID" });
const forged = { ...requests[0], status: "READY", backend: "HTML_MEDIA", reason: null, decoded: { width: 8, height: 8 } };
assert.deepEqual(sequencer.gateSequencerCodec(requests[0], forged).issues.map((issue) => issue.code), ["SEQUENCER_CODEC_UNSUPPORTED"]);
const drift = { ...requests[0], sourceSha256: "d".repeat(64), status: "READY", backend: "IMAGE_BITMAP", reason: null, decoded: { width: 8, height: 8 } };
assert.deepEqual(sequencer.gateSequencerCodec(requests[0], drift).issues.map((issue) => issue.code), ["SEQUENCER_CODEC_UNSUPPORTED"]);
});
test("M11-09 keeps runtime unavailability and decode failure blocked", () => {
for (const [index, request] of requests.entries()) {
const result = { ...request, status: "BLOCKED", backend: ready[index].backend, reason: "DECODE_FAILED", decoded: null };
const gate = sequencer.gateSequencerCodec(request, result);
assert.equal(gate.status, "BLOCKED");
assert.deepEqual(gate.issues.map((issue) => issue.code), ["SEQUENCER_CODEC_UNSUPPORTED"]);
}
});
test.after(() => fs.rmSync(temporary, { recursive: true, force: true }));