115 lines
5.0 KiB
JavaScript
115 lines
5.0 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import path from "node:path";
|
|
import test from "node:test";
|
|
import {
|
|
collectRealmSpellIds,
|
|
expandCoaSpellIds,
|
|
resolveCoaSourcePaths,
|
|
sharedRealmSpellIds,
|
|
} from "./coa-source-policy.mjs";
|
|
|
|
test("CoA payload closure includes effect-168 links, cycles and absent IDs without overlay fallback", () => {
|
|
const buffer = Buffer.alloc(20 + 3 * 234 * 4);
|
|
buffer.write("WDBC");
|
|
buffer.writeUInt32LE(3, 4);
|
|
buffer.writeUInt32LE(234, 8);
|
|
buffer.writeUInt32LE(234 * 4, 12);
|
|
const write = (row, field, value) => buffer.writeUInt32LE(value, 20 + (row * 234 + field) * 4);
|
|
write(0, 0, 100);
|
|
write(0, 71, 168);
|
|
write(0, 110, 200);
|
|
write(1, 0, 200);
|
|
write(1, 116, 300);
|
|
write(2, 0, 300);
|
|
write(2, 116, 100);
|
|
write(2, 117, 400);
|
|
assert.deepEqual([...expandCoaSpellIds(buffer, [100])], [100, 200, 300, 400]);
|
|
assert.throws(() => expandCoaSpellIds(Buffer.from("invalid"), [100]), /234-field/);
|
|
});
|
|
|
|
test("CoA source resolution selects global patch-T and patch-M while classic keeps Area52 priority", () => {
|
|
const root = path.resolve("fixture/client-current");
|
|
const legacy = path.resolve("fixture/legacy");
|
|
const exists = new Set([
|
|
path.join(root, "area-52", "patch-D", "DBFilesClient", "Spell.dbc"),
|
|
path.join(root, "area-52", "patch-D", "DBFilesClient", "SkillLineAbility.dbc"),
|
|
path.join(root, "patch-T", "DBFilesClient", "Spell.dbc"),
|
|
path.join(root, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
|
path.join(legacy, "patch-T", "DBFilesClient", "Spell.dbc"),
|
|
path.join(legacy, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
|
]);
|
|
const sources = resolveCoaSourcePaths({
|
|
extractedClientRoot: root,
|
|
legacyExtractedRoot: legacy,
|
|
exists: (candidate) => exists.has(candidate),
|
|
});
|
|
|
|
assert.equal(sources.classicSpellDbcPath, path.join(root, "area-52", "patch-D", "DBFilesClient", "Spell.dbc"));
|
|
assert.equal(sources.classicSkillLineAbilityDbcPath, path.join(root, "area-52", "patch-D", "DBFilesClient", "SkillLineAbility.dbc"));
|
|
assert.equal(sources.coaSpellDbcPath, path.join(root, "patch-T", "DBFilesClient", "Spell.dbc"));
|
|
assert.equal(sources.coaSkillLineAbilityDbcPath, path.join(root, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"));
|
|
});
|
|
|
|
test("CoA sources fall back only to global legacy files, never Area52", () => {
|
|
const root = path.resolve("fixture/client-current");
|
|
const legacy = path.resolve("fixture/legacy");
|
|
const exists = new Set([
|
|
path.join(root, "area-52", "patch-D", "DBFilesClient", "Spell.dbc"),
|
|
path.join(root, "area-52", "patch-D", "DBFilesClient", "SkillLineAbility.dbc"),
|
|
path.join(legacy, "patch-T", "DBFilesClient", "Spell.dbc"),
|
|
path.join(legacy, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
|
]);
|
|
const sources = resolveCoaSourcePaths({
|
|
extractedClientRoot: root,
|
|
legacyExtractedRoot: legacy,
|
|
exists: (candidate) => exists.has(candidate),
|
|
});
|
|
|
|
assert.equal(sources.coaSpellDbcPath, path.join(legacy, "patch-T", "DBFilesClient", "Spell.dbc"));
|
|
assert.equal(sources.coaSkillLineAbilityDbcPath, path.join(legacy, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"));
|
|
});
|
|
|
|
test("classic SkillLineAbility follows the selected Spell.dbc when that sibling exists", () => {
|
|
const root = path.resolve("fixture/client-current");
|
|
const legacy = path.resolve("fixture/legacy");
|
|
const exists = new Set([
|
|
path.join(root, "area-52", "patch-D", "DBFilesClient", "SkillLineAbility.dbc"),
|
|
path.join(root, "patch-T", "DBFilesClient", "Spell.dbc"),
|
|
path.join(root, "patch-T", "DBFilesClient", "SkillLineAbility.dbc"),
|
|
path.join(root, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
|
path.join(legacy, "patch-T", "DBFilesClient", "Spell.dbc"),
|
|
path.join(legacy, "patch-M", "DBFilesClient", "SkillLineAbility.dbc"),
|
|
]);
|
|
const sources = resolveCoaSourcePaths({
|
|
extractedClientRoot: root,
|
|
legacyExtractedRoot: legacy,
|
|
exists: (candidate) => exists.has(candidate),
|
|
});
|
|
|
|
assert.equal(sources.classicSpellDbcPath, path.join(root, "patch-T", "DBFilesClient", "Spell.dbc"));
|
|
assert.equal(sources.classicSkillLineAbilityDbcPath, path.join(root, "patch-T", "DBFilesClient", "SkillLineAbility.dbc"));
|
|
});
|
|
|
|
test("realm spell ownership protects classic references and includes CoA tree ranks", () => {
|
|
const { classicIds, coaIds } = collectRealmSpellIds({
|
|
classicClassIds: [11],
|
|
coaClassIds: [27],
|
|
classSpellRows: [
|
|
{ id: 100, classId: 11 },
|
|
{ id: 200, classId: 27 },
|
|
{ id: 300, classId: 27 },
|
|
{ id: 400, classId: 11 },
|
|
{ id: 400, classId: 27 },
|
|
],
|
|
classicRankCandidates: [{ id: 101 }],
|
|
coaRankCandidates: [{ id: 201 }],
|
|
coaEntrySpellIds: [300, 301],
|
|
});
|
|
|
|
assert.deepEqual([...classicIds].sort(), [100, 101, 400]);
|
|
assert.deepEqual([...coaIds].sort(), [200, 201, 300, 301, 400]);
|
|
assert.ok(classicIds.has(100) && coaIds.has(300) && classicIds.has(400) && coaIds.has(400));
|
|
assert.deepEqual(sharedRealmSpellIds(classicIds, coaIds), [400]);
|
|
assert.deepEqual(sharedRealmSpellIds(new Set([401]), new Set([401])), [401]);
|
|
});
|