sendou.ink/app/modules/analyzer/abilityChunksCalc.test.ts
William Lam 94ddd3031b
Ability chunk calculation now properly takes Ability Doubler into account (#1186)
* Issue 1180: ability chunk section now properly ignores Ability Doubler in its calculations
- Build Analyzer also no longer shows Ability Doubler as an Ability Chunk entry, nor does it show the Ability Chunks accordion if Ability Doubler is the only selected ability in the build

* Prettier formatting

* Now handles edge case for subabilities on Clothing gear with Ability Doubler
2022-12-07 19:07:29 +02:00

169 lines
5.1 KiB
TypeScript

import { suite } from "uvu";
import * as assert from "uvu/assert";
import type { BuildAbilitiesTupleWithUnknown } from "../in-game-lists";
import type { AbilityWithUnknown } from "../in-game-lists/types";
import { getAbilityChunksMapAsArray } from "./abilityChunksCalc";
// Utility function that performs an order-agnostic check to see
// if the abilityChunksArray contains all elements from the expected output.
function validateAbilityChunksArray(
abilityChunksArray: [AbilityWithUnknown, number][],
expectedOutput: (string | number)[][]
) {
for (const output of expectedOutput) {
const typedOutput = output as [AbilityWithUnknown, number];
const isFoundInAbilityChunksArray = abilityChunksArray.filter(
(result) => JSON.stringify(result) === JSON.stringify(typedOutput)
).length;
const errorString = `${JSON.stringify(
typedOutput
)} was not found in the actual output.\nExpected output: ${JSON.stringify(
expectedOutput
)}\nActual Output: ${JSON.stringify(abilityChunksArray)}`;
assert.ok(isFoundInAbilityChunksArray, errorString);
}
}
const GetAbilityChunksMapAsArray = suite("getAbilityChunksMapAsArray()");
GetAbilityChunksMapAsArray("Empty build results in an empty array", () => {
const emptyBuild = [
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
] as unknown as BuildAbilitiesTupleWithUnknown;
const abilityChunksArray = getAbilityChunksMapAsArray(emptyBuild);
assert.equal(abilityChunksArray, [], "Ability chunks array is not empty.");
});
GetAbilityChunksMapAsArray(
"Ability Doubler ability does not count towards Ability Chunks",
() => {
const buildWithOnlyAbilityDoubler = [
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
["AD", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
] as unknown as BuildAbilitiesTupleWithUnknown;
const abilityChunksArray = getAbilityChunksMapAsArray(
buildWithOnlyAbilityDoubler
);
assert.equal(abilityChunksArray, [], "Ability chunks array is not empty.");
}
);
GetAbilityChunksMapAsArray(
"Main Ability stackable ability chunk calculation is correct",
() => {
const build = [
["ISS", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
["ISM", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
] as unknown as BuildAbilitiesTupleWithUnknown;
const expectedOutput = [
["ISM", 45],
["ISS", 45],
];
const abilityChunksArray = getAbilityChunksMapAsArray(build);
validateAbilityChunksArray(abilityChunksArray, expectedOutput);
}
);
GetAbilityChunksMapAsArray(
"Ninja Squid ability chunk calculation is correct (for a primary slot-only ability)",
() => {
const build = [
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
["NS", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
] as unknown as BuildAbilitiesTupleWithUnknown;
const expectedOutput = [
["RSU", 15],
["IRU", 15],
["SSU", 15],
];
const abilityChunksArray = getAbilityChunksMapAsArray(build);
validateAbilityChunksArray(abilityChunksArray, expectedOutput);
}
);
GetAbilityChunksMapAsArray(
"Ability chunk calculation is correct for a real build. Each gear has 1, 2 or 3 ability chunks of same type",
() => {
const slayerBuild = [
["LDE", "SSU", "SSU", "SSU"],
["NS", "QR", "QR", "ISM"],
["SJ", "SSU", "RES", "QSJ"],
] as unknown as BuildAbilitiesTupleWithUnknown;
const expectedOutput = [
["SSU", 85],
["IRU", 30],
["QR", 30],
["ISM", 25],
["QSJ", 25],
["IA", 15],
["ISS", 15],
["RSU", 15],
["SRU", 15],
["RES", 10],
];
const abilityChunksArray = getAbilityChunksMapAsArray(slayerBuild);
validateAbilityChunksArray(abilityChunksArray, expectedOutput);
}
);
GetAbilityChunksMapAsArray(
"Ability chunk calculation is correct for a real build (Splatling)",
() => {
const splatlingBuild = [
["RSU", "QSJ", "SSU", "RSU"],
["RSU", "ISM", "ISM", "RSU"],
["OS", "SSU", "SSU", "RES"],
] as unknown as BuildAbilitiesTupleWithUnknown;
const expectedOutput = [
["RSU", 110],
["SSU", 40],
["ISM", 30],
["BRU", 15],
["IRU", 15],
["SPU", 15],
["QSJ", 10],
["RES", 10],
];
const abilityChunksArray = getAbilityChunksMapAsArray(splatlingBuild);
validateAbilityChunksArray(abilityChunksArray, expectedOutput);
}
);
GetAbilityChunksMapAsArray(
"Sub abilities chunk calculation with Ability Doubler in Clothing slot is correct",
() => {
const build = [
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
["AD", "SSU", "SSU", "ISM"],
["UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"],
] as unknown as BuildAbilitiesTupleWithUnknown;
const expectedOutput = [
["SSU", 9],
["ISM", 3],
];
const abilityChunksArray = getAbilityChunksMapAsArray(build);
validateAbilityChunksArray(abilityChunksArray, expectedOutput);
}
);
GetAbilityChunksMapAsArray.run();