[Tests] add unit-tests for battle-stat.ts (#2752)

* add test coverage for battle-stat.getBattleStatName()

* add test coverage for battle-stat

* apply mockI18next() to status-effect.test.ts

* add testUtils jsdocs and optimize imports
This commit is contained in:
flx-sta 2024-07-05 08:30:48 -07:00 committed by GitHub
parent 42304070a0
commit c5886bc2a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 210 additions and 38 deletions

View File

@ -0,0 +1,149 @@
import {
BattleStat,
getBattleStatLevelChangeDescription,
getBattleStatName,
} from "#app/data/battle-stat.js";
import { describe, expect, it } from "vitest";
import { arrayOfRange, mockI18next } from "./utils/testUtils";
const TEST_BATTLE_STAT = -99 as unknown as BattleStat;
const TEST_POKEMON = "Testmon";
const TEST_STAT = "Teststat";
describe("battle-stat", () => {
describe("getBattleStatName", () => {
it("should return the correct name for each BattleStat", () => {
mockI18next();
expect(getBattleStatName(BattleStat.ATK)).toBe("pokemonInfo:Stat.ATK");
expect(getBattleStatName(BattleStat.DEF)).toBe("pokemonInfo:Stat.DEF");
expect(getBattleStatName(BattleStat.SPATK)).toBe(
"pokemonInfo:Stat.SPATK"
);
expect(getBattleStatName(BattleStat.SPDEF)).toBe(
"pokemonInfo:Stat.SPDEF"
);
expect(getBattleStatName(BattleStat.SPD)).toBe("pokemonInfo:Stat.SPD");
expect(getBattleStatName(BattleStat.ACC)).toBe("pokemonInfo:Stat.ACC");
expect(getBattleStatName(BattleStat.EVA)).toBe("pokemonInfo:Stat.EVA");
});
it("should fall back to ??? for an unknown BattleStat", () => {
expect(getBattleStatName(TEST_BATTLE_STAT)).toBe("???");
});
});
describe("getBattleStatLevelChangeDescription", () => {
it("should return battle:statRose for +1", () => {
mockI18next();
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
1,
true
);
expect(message).toBe("battle:statRose");
});
it("should return battle:statSharplyRose for +2", () => {
mockI18next();
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
2,
true
);
expect(message).toBe("battle:statSharplyRose");
});
it("should return battle:statRoseDrastically for +3 to +6", () => {
mockI18next();
arrayOfRange(3, 6).forEach((n) => {
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
n,
true
);
expect(message).toBe("battle:statRoseDrastically");
});
});
it("should return battle:statWontGoAnyHigher for 7 or higher", () => {
mockI18next();
arrayOfRange(7, 10).forEach((n) => {
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
n,
true
);
expect(message).toBe("battle:statWontGoAnyHigher");
});
});
it("should return battle:statFell for -1", () => {
mockI18next();
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
1,
false
);
expect(message).toBe("battle:statFell");
});
it("should return battle:statHarshlyFell for -2", () => {
mockI18next();
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
2,
false
);
expect(message).toBe("battle:statHarshlyFell");
});
it("should return battle:statSeverelyFell for -3 to -6", () => {
mockI18next();
arrayOfRange(3, 6).forEach((n) => {
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
n,
false
);
expect(message).toBe("battle:statSeverelyFell");
});
});
it("should return battle:statWontGoAnyLower for -7 or lower", () => {
mockI18next();
arrayOfRange(7, 10).forEach((n) => {
const message = getBattleStatLevelChangeDescription(
TEST_POKEMON,
TEST_STAT,
n,
false
);
expect(message).toBe("battle:statWontGoAnyLower");
});
});
});
});

View File

@ -7,9 +7,9 @@ import {
getStatusEffectObtainText, getStatusEffectObtainText,
getStatusEffectOverlapText, getStatusEffectOverlapText,
} from "#app/data/status-effect"; } from "#app/data/status-effect";
import i18next, { ParseKeys } from "i18next"; import i18next from "i18next";
import { mockI18next } from "../utils/testUtils";
const tMock = (key: ParseKeys) => key;
const pokemonName = "PKM"; const pokemonName = "PKM";
const sourceText = "SOURCE"; const sourceText = "SOURCE";
@ -22,7 +22,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.NONE; const statusEffect = StatusEffect.NONE;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:none.obtain"); expect(text).toBe("statusEffect:none.obtain");
@ -32,7 +32,7 @@ describe("status-effect", () => {
}); });
it("should return the source-obtain text", () => { it("should return the source-obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName, sourceText); const text = getStatusEffectObtainText(statusEffect, pokemonName, sourceText);
expect(text).toBe("statusEffect:none.obtainSource"); expect(text).toBe("statusEffect:none.obtainSource");
@ -42,25 +42,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:none.activation"); expect(text).toBe("statusEffect:none.activation");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:none.overlap"); expect(text).toBe("statusEffect:none.overlap");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:none.heal"); expect(text).toBe("statusEffect:none.heal");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:none.description"); expect(text).toBe("statusEffect:none.description");
}); });
@ -70,7 +70,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.POISON; const statusEffect = StatusEffect.POISON;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:poison.obtain"); expect(text).toBe("statusEffect:poison.obtain");
@ -80,25 +80,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:poison.activation"); expect(text).toBe("statusEffect:poison.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:poison.description"); expect(text).toBe("statusEffect:poison.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:poison.heal"); expect(text).toBe("statusEffect:poison.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:poison.overlap"); expect(text).toBe("statusEffect:poison.overlap");
}); });
@ -108,7 +108,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.TOXIC; const statusEffect = StatusEffect.TOXIC;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:toxic.obtain"); expect(text).toBe("statusEffect:toxic.obtain");
@ -118,25 +118,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:toxic.activation"); expect(text).toBe("statusEffect:toxic.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:toxic.description"); expect(text).toBe("statusEffect:toxic.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:toxic.heal"); expect(text).toBe("statusEffect:toxic.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:toxic.overlap"); expect(text).toBe("statusEffect:toxic.overlap");
}); });
@ -146,7 +146,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.PARALYSIS; const statusEffect = StatusEffect.PARALYSIS;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:paralysis.obtain"); expect(text).toBe("statusEffect:paralysis.obtain");
@ -156,25 +156,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:paralysis.activation"); expect(text).toBe("statusEffect:paralysis.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:paralysis.description"); expect(text).toBe("statusEffect:paralysis.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:paralysis.heal"); expect(text).toBe("statusEffect:paralysis.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:paralysis.overlap"); expect(text).toBe("statusEffect:paralysis.overlap");
}); });
@ -184,7 +184,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.SLEEP; const statusEffect = StatusEffect.SLEEP;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:sleep.obtain"); expect(text).toBe("statusEffect:sleep.obtain");
@ -194,25 +194,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:sleep.activation"); expect(text).toBe("statusEffect:sleep.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:sleep.description"); expect(text).toBe("statusEffect:sleep.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:sleep.heal"); expect(text).toBe("statusEffect:sleep.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:sleep.overlap"); expect(text).toBe("statusEffect:sleep.overlap");
}); });
@ -222,7 +222,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.FREEZE; const statusEffect = StatusEffect.FREEZE;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:freeze.obtain"); expect(text).toBe("statusEffect:freeze.obtain");
@ -232,25 +232,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:freeze.activation"); expect(text).toBe("statusEffect:freeze.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:freeze.description"); expect(text).toBe("statusEffect:freeze.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:freeze.heal"); expect(text).toBe("statusEffect:freeze.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:freeze.overlap"); expect(text).toBe("statusEffect:freeze.overlap");
}); });
@ -260,7 +260,7 @@ describe("status-effect", () => {
const statusEffect = StatusEffect.BURN; const statusEffect = StatusEffect.BURN;
it("should return the obtain text", () => { it("should return the obtain text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectObtainText(statusEffect, pokemonName); const text = getStatusEffectObtainText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:burn.obtain"); expect(text).toBe("statusEffect:burn.obtain");
@ -270,25 +270,25 @@ describe("status-effect", () => {
}); });
it("should return the activation text", () => { it("should return the activation text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectActivationText(statusEffect, pokemonName); const text = getStatusEffectActivationText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:burn.activation"); expect(text).toBe("statusEffect:burn.activation");
}); });
it("should return the descriptor", () => { it("should return the descriptor", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectDescriptor(statusEffect); const text = getStatusEffectDescriptor(statusEffect);
expect(text).toBe("statusEffect:burn.description"); expect(text).toBe("statusEffect:burn.description");
}); });
it("should return the heal text", () => { it("should return the heal text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectHealText(statusEffect, pokemonName); const text = getStatusEffectHealText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:burn.heal"); expect(text).toBe("statusEffect:burn.heal");
}); });
it("should return the overlap text", () => { it("should return the overlap text", () => {
vi.spyOn(i18next, "t").mockImplementation(tMock); mockI18next();
const text = getStatusEffectOverlapText(statusEffect, pokemonName); const text = getStatusEffectOverlapText(statusEffect, pokemonName);
expect(text).toBe("statusEffect:burn.overlap"); expect(text).toBe("statusEffect:burn.overlap");
}); });

View File

@ -0,0 +1,23 @@
import i18next, { type ParseKeys } from "i18next";
import { vi } from "vitest";
/**
* Sets up the i18next mock.
* Includes a i18next.t mocked implementation only returning the raw key (`(key) => key`)
*
* @returns A spy/mock of i18next
*/
export function mockI18next() {
return vi.spyOn(i18next, "t").mockImplementation((key: ParseKeys) => key);
}
/**
* Creates an array of range `start - end`
*
* @param start start number e.g. 1
* @param end end number e.g. 10
* @returns an array of numbers
*/
export function arrayOfRange(start: integer, end: integer) {
return Array.from({ length: end - start }, (_v, k) => k + start);
}