Files
healer-man/scripts/runewaker-pipeline/lib/origin-native-material-provenance.test.mjs
T
2026-10-06 22:25:34 -04:00

99 lines
4.6 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import { buildOriginNativeMaterialProvenance } from "./origin-native-material-provenance.mjs";
const resources = [
"model\\dungeon\\the_origin\\act_precipice_01.ros",
"model\\dungeon\\the_origin\\act_precipice_02.ros",
"model\\element\\wailing_mountains\\prop\\waterfall\\act_waterfall02.ros",
"model\\element\\elves_island\\vegetation\\gaint_tree_a.ros",
"model\\element\\weeping_coast\\vegetation\\n_tree_02.ros",
"model\\dungeon\\the_origin\\tree_01_01.ros",
"model\\dungeon\\the_origin\\act_cocoon_01.ros",
];
function fixture() {
const conversionReports = new Map();
const stagedOverrides = resources.map((resource, index) => {
const sha256 = String(index + 1).padStart(64, "0");
conversionReports.set(resource.toLowerCase(), {
source: { model: resource, resourceSha256: sha256 },
visual: {
materials: {
nativeAlpha: {
sourceModel: resource,
sourceResourceSha256: sha256,
materials: [{ sourceModel: resource, sourceResourceSha256: sha256, materialIndex: 1 }],
},
},
},
});
return { resource, file: `staging/${index}/visual.glb`, placements: index + 1 };
});
return {
conversionReports,
assembly: {
sourceWdbSha256: "a".repeat(64),
sourceWdbReportSha256: "b".repeat(64),
primaryResource: "model\\dungeon\\the_origin\\cathedral_01_b.ros",
primarySourceSha256: "c".repeat(64),
staticPlacementCount: 693,
uniqueResourceCount: 220,
dynamicPlacementCount: 0,
resources: stagedOverrides.map((override, index) => ({
resource: override.resource.replaceAll("\\", "/"),
placementCount: override.placements,
sourceSha256: String(index + 1).padStart(64, "0"),
})),
stagedOverrides,
assembledVisual: { sha256: "d".repeat(64) },
},
semantics: {
khrMaterialsUnlit: [{ sourceModel: resources[2], sourceResourceSha256: String(3).padStart(64, "0") }],
nativeAdditiveMaterials: [{ sourceModel: resources[0], sourceResourceSha256: String(1).padStart(64, "0"), alphaMode: "BLEND" }],
materialCounts: { total: 2 },
sharedMapLightingPair: { note: "same map, different native lighting identity" },
},
metadata: {
title: "The Origin",
entry: { x: 1, y: 2, z: 3 },
sourceTerrain: { resource: "terrain/source.wdb", chunkCount: 4 },
nativeTerrain: { report: "terrain-report.json", sourceSha256: "e".repeat(64) },
assets: [{ role: "visual", sha256: "old-visual-hash" }],
nativeMaterialAlpha: { report: "old-report.json", resources: [] },
},
};
}
test("joins staged Origin overrides by authoritative native ROS identity while retaining current metadata", () => {
const data = fixture();
const originalEntry = structuredClone(data.metadata.entry);
const originalSourceTerrain = structuredClone(data.metadata.sourceTerrain);
const originalNativeTerrain = structuredClone(data.metadata.nativeTerrain);
const originalAssets = structuredClone(data.metadata.assets);
const output = buildOriginNativeMaterialProvenance(data);
assert.equal(output.alphaReport.resources.length, resources.length);
assert.equal(output.alphaReport.resources[2].nativeAlpha.materials[0].sourceModel, resources[2]);
assert.equal(output.metadata.nativeMaterialAlpha.resources[6].placements, 7);
assert.equal(output.metadata.nativeMaterialSemantics.unlitMaterialCount, 1);
assert.equal(output.metadata.nativeMaterialSemantics.additiveMaterialCount, 1);
assert.deepEqual(output.metadata.entry, originalEntry);
assert.deepEqual(output.metadata.sourceTerrain, originalSourceTerrain);
assert.deepEqual(output.metadata.nativeTerrain, originalNativeTerrain);
assert.deepEqual(output.metadata.assets, originalAssets);
assert.equal(data.metadata.nativeMaterialAlpha.report, "old-report.json");
});
test("rejects conversion evidence whose ROS identity or source hash does not match its placement override", () => {
const data = fixture();
const first = data.assembly.stagedOverrides[0].resource.toLowerCase();
data.conversionReports.get(first).visual.materials.nativeAlpha.sourceResourceSha256 = "not-a-sha";
assert.throws(() => buildOriginNativeMaterialProvenance(data), /Invalid native source hash/);
});
test("rejects staged source hashes that disagree with authoritative assembly resource rows", () => {
const data = fixture();
data.assembly.resources[0].sourceSha256 = "f".repeat(64);
assert.throws(() => buildOriginNativeMaterialProvenance(data), /does not match the authoritative assembly row/);
});