67 lines
2.5 KiB
TypeScript
67 lines
2.5 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { CLASSES, type ClassId } from "../app/characterCatalog";
|
|
import {
|
|
COA_ABILITIES_BY_CLASS,
|
|
COA_CLASS_RESOURCES,
|
|
COA_TRIGGERED_ABILITIES_BY_SPELL_ID,
|
|
} from "./coaAbilityCatalog";
|
|
import {
|
|
COA_RUNTIME_ABILITIES_BY_CLASS,
|
|
COA_RUNTIME_CLASS_RESOURCES,
|
|
COA_RUNTIME_TRIGGERED_ABILITIES_BY_SPELL_ID,
|
|
} from "./coaAbilityRuntimeCatalog";
|
|
import generatedTalentRuntime from "./generated/talentRuntimeCatalog.json";
|
|
import {
|
|
TALENT_NODES,
|
|
allocateTalentPoint,
|
|
normalizeTalentRanks,
|
|
talentTreesForClass,
|
|
} from "./talentCatalog";
|
|
import {
|
|
runtimeAllocateTalentPoint,
|
|
runtimeNormalizeTalentRanks,
|
|
} from "./talentRuntimeCatalog";
|
|
|
|
describe("compact combat runtime catalogs", () => {
|
|
it("preserves every derived COA ability and resource profile", () => {
|
|
expect(COA_RUNTIME_ABILITIES_BY_CLASS).toEqual(COA_ABILITIES_BY_CLASS);
|
|
expect(COA_RUNTIME_CLASS_RESOURCES).toEqual(COA_CLASS_RESOURCES);
|
|
expect(COA_RUNTIME_TRIGGERED_ABILITIES_BY_SPELL_ID).toEqual(COA_TRIGGERED_ABILITIES_BY_SPELL_ID);
|
|
});
|
|
|
|
it("preserves every talent field used by runtime allocation and modifiers", () => {
|
|
const expected = TALENT_NODES.map((node) => ({
|
|
id: node.id,
|
|
treeId: node.treeId,
|
|
index: node.index,
|
|
row: node.row,
|
|
maxRank: node.maxRank,
|
|
name: node.name,
|
|
prerequisites: node.prerequisites,
|
|
rankDescriptions: node.rankDescriptions,
|
|
system: node.system,
|
|
abilityEssenceCost: node.abilityEssenceCost,
|
|
talentEssenceCost: node.talentEssenceCost,
|
|
requiredClassPoints: node.requiredClassPoints,
|
|
requiredSpecPoints: node.requiredSpecPoints,
|
|
requiredLevel: node.requiredLevel,
|
|
isPassive: node.isPassive,
|
|
}));
|
|
expect(generatedTalentRuntime.nodes).toEqual(JSON.parse(JSON.stringify(expected)));
|
|
});
|
|
|
|
it("matches normalization and first legal allocation for every playable class", () => {
|
|
for (const definition of CLASSES) {
|
|
const classId = definition.id as ClassId;
|
|
expect(runtimeNormalizeTalentRanks(classId, 80, {})).toEqual(normalizeTalentRanks(classId, 80, {}));
|
|
const node = talentTreesForClass(classId)
|
|
.flatMap((tree) => TALENT_NODES.filter((candidate) => candidate.treeId === tree.id))
|
|
.find((candidate) => allocateTalentPoint({}, classId, candidate.id, 80).ok);
|
|
if (!node) continue;
|
|
expect(runtimeAllocateTalentPoint({}, classId, node.id, 80)).toEqual(
|
|
allocateTalentPoint({}, classId, node.id, 80),
|
|
);
|
|
}
|
|
});
|
|
});
|