109 lines
3.6 KiB
JavaScript
109 lines
3.6 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import {
|
|
buildNativeCollisionAuditArguments,
|
|
validateNativeCoreCandidateProvenance,
|
|
} from "./lib/native-core-candidate-provenance.mjs";
|
|
|
|
const hash = (letter) => letter.repeat(64);
|
|
|
|
function fixture() {
|
|
const placement = {
|
|
guid: "A-B-C",
|
|
resource: "model\\dungeon\\sample.ros",
|
|
translation: [1, 2, 3],
|
|
rotation: [0, 0, 0, 1],
|
|
scale: [1, 1, 1],
|
|
};
|
|
const recipe = {
|
|
slug: "sample-dungeon",
|
|
source: { model: "model/dungeon/sample.ros", wdb: "Resource/wdb/dungeon/sample.wdb" },
|
|
};
|
|
const sourceModelSha256 = hash("a");
|
|
const sourceWdbSha256 = hash("b");
|
|
const exportReportSha256 = hash("c");
|
|
return {
|
|
slug: recipe.slug,
|
|
recipe,
|
|
recipeSha256: hash("d"),
|
|
primaryPlacement: placement,
|
|
importMetadata: {
|
|
dungeonId: recipe.slug,
|
|
source: {
|
|
model: recipe.source.model,
|
|
modelSha256: sourceModelSha256,
|
|
wdb: recipe.source.wdb,
|
|
wdbSha256: sourceWdbSha256,
|
|
},
|
|
},
|
|
actualSourceModelSha256: sourceModelSha256,
|
|
actualSourceWdbSha256: sourceWdbSha256,
|
|
wdbReport: { descriptors: [{
|
|
...placement,
|
|
resource: "model/dungeon/sample.ros",
|
|
translation: [...placement.translation],
|
|
rotation: [...placement.rotation],
|
|
scale: [...placement.scale],
|
|
}] },
|
|
wdbReportSha256: hash("e"),
|
|
exportReport: { sourceModel: "model/dungeon/sample.ros" },
|
|
exportReportSha256,
|
|
conversionReportSha256: hash("f"),
|
|
nativeCollisionReport: {
|
|
sourceModel: "model/dungeon/sample.ros",
|
|
collisionMode: "respect-options",
|
|
queryMasks: { ignoreEntityCollisionOption: false },
|
|
nativeCollisionTriangleCount: 12,
|
|
enabledNativeCollisionTriangleCount: 12,
|
|
renderMeshFallbackTriangleCount: 0,
|
|
},
|
|
nativeCollisionReportSha256: hash("1"),
|
|
nativeCollisionObjSha256: hash("2"),
|
|
nativeCollisionFlagsSha256: hash("3"),
|
|
};
|
|
}
|
|
|
|
test("native-core provenance accepts one exact ROS/WDB/export/query source chain", () => {
|
|
const provenance = validateNativeCoreCandidateProvenance(fixture());
|
|
assert.equal(provenance.nativeEnabledTriangleCount, 12);
|
|
assert.equal(provenance.primaryPlacementGuid, "A-B-C");
|
|
assert.equal(provenance.recipeSha256, hash("d"));
|
|
});
|
|
|
|
test("native-core provenance rejects changed source cache hashes", () => {
|
|
const input = fixture();
|
|
input.actualSourceModelSha256 = hash("9");
|
|
assert.throws(() => validateNativeCoreCandidateProvenance(input), /Imported source ROS hash/);
|
|
});
|
|
|
|
test("native-core provenance rejects a different WDB primary descriptor", () => {
|
|
const input = fixture();
|
|
input.wdbReport.descriptors[0].translation[0] += 0.01;
|
|
assert.throws(() => validateNativeCoreCandidateProvenance(input), /primary WDB descriptor/);
|
|
});
|
|
|
|
test("native-core provenance rejects option-blind or render-fallback collision reports", () => {
|
|
for (const update of [
|
|
(report) => { report.queryMasks.ignoreEntityCollisionOption = true; },
|
|
(report) => { report.renderMeshFallbackTriangleCount = 1; },
|
|
(report) => { report.enabledNativeCollisionTriangleCount -= 1; },
|
|
]) {
|
|
const input = fixture();
|
|
update(input.nativeCollisionReport);
|
|
assert.throws(() => validateNativeCoreCandidateProvenance(input));
|
|
}
|
|
});
|
|
|
|
test("native collision extractor arguments use JSON-safe forward-slash paths", () => {
|
|
assert.deepEqual(buildNativeCollisionAuditArguments({
|
|
resourceRoot: "F:\\Runewaker\\Resource",
|
|
sourceModel: "model\\dungeon\\sample.ros",
|
|
reportPath: "F:\\work\\query-report.json",
|
|
}), [
|
|
"F:/Runewaker/Resource",
|
|
"model/dungeon/sample.ros",
|
|
"F:/work/query-report.json",
|
|
"respect-options",
|
|
]);
|
|
});
|