mirror of
https://github.com/tiennm99/loldle.git
synced 2026-09-02 08:20:47 +00:00
classic-mode.js moves byte-for-byte. champion-data.js swaps the Next.js env-var fetch prefix for asset() from $app/paths, which resolves to /champions.json in dev and /loldle/champions.json in the deployed build. getChampionImageUrl keeps returning an absolute Data Dragon URL, unwrapped. Drops three exports with no callers: getAllChampions, getChampionByName, getGuessedNames. The characterization suite passes unchanged against the new location -- only import specifiers moved, no assertions touched.
164 lines
5.2 KiB
JavaScript
164 lines
5.2 KiB
JavaScript
import { describe, expect, it } from "vitest";
|
|
import { CLASSIC_ATTRIBUTES, compareChampions } from "$lib/classic-mode";
|
|
import { AATROX, AHRI, AKALI, BELVETH } from "./fixtures/champions";
|
|
|
|
/** Pull one attribute's comparison out of the 7-entry result array. */
|
|
function cell(guess, target, key) {
|
|
return compareChampions(guess, target).find((r) => r.key === key);
|
|
}
|
|
|
|
describe("CLASSIC_ATTRIBUTES", () => {
|
|
it("exposes 7 attributes with gender first and releaseDate last", () => {
|
|
expect(CLASSIC_ATTRIBUTES).toHaveLength(7);
|
|
expect(CLASSIC_ATTRIBUTES[0].key).toBe("gender");
|
|
expect(CLASSIC_ATTRIBUTES[6].key).toBe("releaseDate");
|
|
});
|
|
|
|
it("keeps the display order the grid header depends on", () => {
|
|
expect(CLASSIC_ATTRIBUTES.map((a) => a.key)).toEqual([
|
|
"gender",
|
|
"genre",
|
|
"attackType",
|
|
"resource",
|
|
"region",
|
|
"lane",
|
|
"releaseDate",
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("compareChampions — result shape", () => {
|
|
it("returns one entry per attribute, carrying label and type through", () => {
|
|
const results = compareChampions(AHRI, AATROX);
|
|
expect(results).toHaveLength(7);
|
|
expect(results[0]).toMatchObject({
|
|
key: "gender",
|
|
label: "Gender",
|
|
type: "exact",
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("compareChampions — exact", () => {
|
|
it("marks an identical value correct", () => {
|
|
expect(cell(AKALI, AHRI, "gender").result).toBe("correct");
|
|
});
|
|
|
|
it("marks a differing value wrong", () => {
|
|
expect(cell(AHRI, AATROX, "gender").result).toBe("wrong");
|
|
});
|
|
|
|
it("compares case-insensitively", () => {
|
|
const shouty = { ...AATROX, gender: "MALE" };
|
|
expect(cell(shouty, AATROX, "gender").result).toBe("correct");
|
|
});
|
|
|
|
it("treats a missing value as not matching a present one", () => {
|
|
expect(cell(BELVETH, AATROX, "resource").result).toBe("wrong");
|
|
});
|
|
});
|
|
|
|
describe("compareChampions — multi", () => {
|
|
it("marks identical sets correct", () => {
|
|
expect(cell(BELVETH, AATROX, "genre").result).toBe("correct");
|
|
});
|
|
|
|
it("marks intersecting sets partial", () => {
|
|
// AKALI lane "top,mid" overlaps AATROX lane "top"
|
|
expect(cell(AKALI, AATROX, "lane").result).toBe("partial");
|
|
});
|
|
|
|
it("marks disjoint sets wrong", () => {
|
|
expect(cell(AHRI, AATROX, "lane").result).toBe("wrong");
|
|
});
|
|
|
|
it("marks two empty sets correct", () => {
|
|
const a = { ...AATROX, lane: "" };
|
|
const b = { ...AATROX, lane: "" };
|
|
expect(cell(a, b, "lane").result).toBe("correct");
|
|
});
|
|
|
|
it("marks one empty set against a populated one wrong", () => {
|
|
const empty = { ...AATROX, lane: "" };
|
|
expect(cell(empty, AATROX, "lane").result).toBe("wrong");
|
|
});
|
|
|
|
it("ignores order and whitespace when comparing sets", () => {
|
|
const spaced = { ...AKALI, lane: " mid , top " };
|
|
expect(cell(spaced, AKALI, "lane").result).toBe("correct");
|
|
});
|
|
});
|
|
|
|
describe("compareChampions — year", () => {
|
|
it("marks the same year correct with no direction hint", () => {
|
|
const twin = { ...AHRI, releaseDate: 2013 };
|
|
const result = cell(twin, AATROX, "releaseDate");
|
|
expect(result.result).toBe("correct");
|
|
expect(result.direction).toBeUndefined();
|
|
});
|
|
|
|
it("points up when the guess is older than the target", () => {
|
|
expect(cell(AHRI, AATROX, "releaseDate")).toMatchObject({
|
|
result: "wrong",
|
|
direction: "up",
|
|
});
|
|
});
|
|
|
|
it("points down when the guess is newer than the target", () => {
|
|
expect(cell(BELVETH, AATROX, "releaseDate")).toMatchObject({
|
|
result: "wrong",
|
|
direction: "down",
|
|
});
|
|
});
|
|
|
|
it("gives no direction when either year is unparseable", () => {
|
|
const undated = { ...AHRI, releaseDate: "" };
|
|
const result = cell(undated, AATROX, "releaseDate");
|
|
expect(result.result).toBe("wrong");
|
|
expect(result.direction).toBeUndefined();
|
|
});
|
|
|
|
it("renders a missing year as ?", () => {
|
|
const undated = { ...AHRI, releaseDate: "" };
|
|
expect(cell(undated, AATROX, "releaseDate").guessValue).toBe("?");
|
|
});
|
|
|
|
it("passes the year through unformatted", () => {
|
|
expect(cell(AHRI, AATROX, "releaseDate")).toMatchObject({
|
|
guessValue: 2011,
|
|
targetValue: 2013,
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("compareChampions — value formatting", () => {
|
|
it("capitalizes gender", () => {
|
|
expect(cell(AATROX, AATROX, "gender").guessValue).toBe("Male");
|
|
});
|
|
|
|
it("renders attackType close as Melee and range as Ranged", () => {
|
|
expect(cell(AATROX, AATROX, "attackType").guessValue).toBe("Melee");
|
|
expect(cell(AHRI, AHRI, "attackType").guessValue).toBe("Ranged");
|
|
});
|
|
|
|
it("splits hyphenated regions into capitalized words", () => {
|
|
expect(cell(AKALI, AKALI, "region").guessValue).toBe("Shadow Isles");
|
|
});
|
|
|
|
it("title-cases comma lists and rejoins them with a space", () => {
|
|
expect(cell(AHRI, AHRI, "genre").guessValue).toBe("Mage, Assassin");
|
|
expect(cell(AKALI, AKALI, "lane").guessValue).toBe("Top, Mid");
|
|
});
|
|
|
|
it("renders an empty value as an em dash", () => {
|
|
expect(cell(BELVETH, BELVETH, "resource").guessValue).toBe("—");
|
|
});
|
|
|
|
it("formats the target value the same way as the guess value", () => {
|
|
expect(cell(AHRI, AKALI, "region")).toMatchObject({
|
|
guessValue: "Ionia",
|
|
targetValue: "Shadow Isles",
|
|
});
|
|
});
|
|
});
|