first commit
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import { test } from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname, join } from "node:path";
|
||||
import { ModIndexer } from "../out/indexer/indexer.js";
|
||||
import { CachedDirectoryWalker } from "../out/indexer/fileScanner.js";
|
||||
import { isReferenceAttribute, resolveReferenceTargets } from "../out/indexer/refs.js";
|
||||
import * as model from "../out/model/schemaModel.js";
|
||||
|
||||
const root = dirname(dirname(fileURLToPath(import.meta.url)));
|
||||
const project = join(root, "test", "fixtures", "minimod");
|
||||
const sdk = join(root, "test", "fixtures", "fakesdk");
|
||||
|
||||
async function buildIndex() {
|
||||
const indexer = new ModIndexer({
|
||||
projectDir: project,
|
||||
sdkDir: sdk,
|
||||
builtmodsDirs: [join(sdk, "builtmods")],
|
||||
indexSageXml: true,
|
||||
additionalDataSearchPaths: [],
|
||||
walker: new CachedDirectoryWalker(),
|
||||
});
|
||||
return indexer.build();
|
||||
}
|
||||
|
||||
test("definition resolution filters by the attribute's ref type", async () => {
|
||||
const idx = await buildIndex();
|
||||
const defs = idx.assetsById.get("sharedthing");
|
||||
assert.equal(defs.length, 2);
|
||||
const types = defs.map((d) => d.type).sort();
|
||||
assert.deepEqual(types, ["GameObject", "WeaponTemplate"]);
|
||||
|
||||
// WeaponName="SharedThing" on a WeaponTemplateRef attribute must only resolve
|
||||
// to the WeaponTemplate definition.
|
||||
const targets = resolveReferenceTargets(idx, "FireWeaponNugget", "WeaponName", "SharedThing");
|
||||
assert.equal(targets.length, 1);
|
||||
assert.equal(targets[0].def.type, "WeaponTemplate");
|
||||
assert.match(targets[0].def.file, /Refs\.xml/);
|
||||
|
||||
// A non-reference attribute must never resolve anything.
|
||||
const none = resolveReferenceTargets(idx, "FireWeaponNugget", "EditorName", "SharedThing");
|
||||
assert.equal(none.length, 0);
|
||||
|
||||
// inheritFrom filters to types assignable to the element itself.
|
||||
const inherit = resolveReferenceTargets(idx, "GameObject", "inheritFrom", "SharedThing");
|
||||
assert.equal(inherit.length, 1);
|
||||
assert.equal(inherit[0].def.type, "GameObject");
|
||||
});
|
||||
|
||||
test("the model knows a real WeaponTemplateRef attribute pair", () => {
|
||||
const attrs = model.attributesOfElement("FireWeaponNugget");
|
||||
const weapon = attrs.find((a) => a.name === "WeaponName");
|
||||
assert.equal(weapon?.refType, "WeaponTemplate");
|
||||
});
|
||||
|
||||
test("isReferenceAttribute distinguishes references from enums/paths", () => {
|
||||
// Include/@type and Include/@source must never be treated as references.
|
||||
assert.equal(isReferenceAttribute("Include", "type"), false);
|
||||
assert.equal(isReferenceAttribute("Include", "source"), false);
|
||||
// Typed references and inheritFrom are references.
|
||||
assert.equal(isReferenceAttribute("GameObject", "CommandSet"), true);
|
||||
assert.equal(isReferenceAttribute("GameObject", "inheritFrom"), true);
|
||||
assert.equal(isReferenceAttribute("FireWeaponNugget", "WeaponName"), true);
|
||||
});
|
||||
|
||||
test("untyped references (isRef without refType) resolve to any declared id", () => {
|
||||
// LocomotorSet/@Locomotor has type AssetReference: xas:isRef="true" with
|
||||
// no refType. It must be treated as a reference and match the id regardless
|
||||
// of the target asset type.
|
||||
const idx = {
|
||||
assetsById: new Map([
|
||||
[
|
||||
"alliedantivehiclevehicletech1locomotor",
|
||||
[
|
||||
{
|
||||
type: "LocomotorTemplate",
|
||||
id: "AlliedAntiVehicleVehicleTech1Locomotor",
|
||||
file: "Locomotor.xml",
|
||||
line: 5,
|
||||
origin: "project",
|
||||
},
|
||||
],
|
||||
],
|
||||
]),
|
||||
assets: new Map(),
|
||||
projectDir: ".",
|
||||
sdkDir: ".",
|
||||
defines: new Map(),
|
||||
files: new Map(),
|
||||
streams: [],
|
||||
manifests: new Map(),
|
||||
sourceCandidates: [],
|
||||
diagnostics: [],
|
||||
stats: {},
|
||||
};
|
||||
assert.equal(isReferenceAttribute("LocomotorSet", "Locomotor"), true);
|
||||
const targets = resolveReferenceTargets(idx, "LocomotorSet", "Locomotor", "AlliedAntiVehicleVehicleTech1Locomotor");
|
||||
assert.equal(targets.length, 1);
|
||||
assert.equal(targets[0].def.type, "LocomotorTemplate");
|
||||
// A non-reference attribute still returns nothing.
|
||||
assert.equal(resolveReferenceTargets(idx, "LocomotorSet", "EditorName", "X").length, 0);
|
||||
});
|
||||
Reference in New Issue
Block a user