brackt/app/lib/__tests__/afl-wildcard-reseed.test.ts

118 lines
4.1 KiB
TypeScript
Raw Normal View History

/**
* The AFL Wildcard winners are re-seeded into the Elimination Finals by ladder position
* (5th draws the lower-ranked winner, 6th the higher-ranked one) rather than crossing
* over from a fixed Wildcard match. These tests pin that mapping for every combination
* of results, and for either order of entry.
*/
import { describe, it, expect } from "vitest";
import {
resolveAflWildcardPlacements,
AFL_WILDCARD_DRAW,
AFL_ELIMINATION_HOSTS,
type AflWildcardResult,
} from "../afl-wildcard-reseed";
/** Both Wildcard games decided, addressed by the seed that won each. */
function bothDecided(match1Winner: 7 | 10, match2Winner: 8 | 9): AflWildcardResult[] {
return [
{ matchNumber: 1, winnerSlot: match1Winner === 7 ? 1 : 2 },
{ matchNumber: 2, winnerSlot: match2Winner === 8 ? 1 : 2 },
];
}
/** Elimination Finals match number each winning seed was sent to. */
function slotsBySeed(results: AflWildcardResult[]): Record<number, number> {
return Object.fromEntries(
resolveAflWildcardPlacements(results).map((p) => [p.seed, p.eliminationMatchNumber])
);
}
describe("AFL Wildcard draw constants", () => {
it("draws 7v10 and 8v9", () => {
expect(AFL_WILDCARD_DRAW[1]).toEqual([7, 10]);
expect(AFL_WILDCARD_DRAW[2]).toEqual([8, 9]);
});
it("hosts the Elimination Finals with seeds 5 and 6", () => {
expect(AFL_ELIMINATION_HOSTS[1]).toBe(5);
expect(AFL_ELIMINATION_HOSTS[2]).toBe(6);
});
});
describe("resolveAflWildcardPlacements", () => {
it("sends the higher-ranked winner to 6th and the lower to 5th (7 and 8 win)", () => {
expect(slotsBySeed(bothDecided(7, 8))).toEqual({ 7: 2, 8: 1 });
});
it("re-seeds when the lower seed wins the 7v10 game (10 and 8 win)", () => {
// The bug this replaces sent the 7v10 winner to 6th regardless, pairing 5th with
// 8th and handing 6th the weakest survivor.
expect(slotsBySeed(bothDecided(10, 8))).toEqual({ 8: 2, 10: 1 });
});
it("re-seeds when the lower seed wins the 8v9 game (7 and 9 win)", () => {
expect(slotsBySeed(bothDecided(7, 9))).toEqual({ 7: 2, 9: 1 });
});
it("re-seeds when both lower seeds win (10 and 9 win)", () => {
expect(slotsBySeed(bothDecided(10, 9))).toEqual({ 9: 2, 10: 1 });
});
it("places the 7v10 winner alone, since its rank is settled either way", () => {
// 7th outranks both possible 8v9 winners; 10th is outranked by both.
expect(slotsBySeed([
{ matchNumber: 1, winnerSlot: 1 },
{ matchNumber: 2, winnerSlot: null },
])).toEqual({ 7: 2 });
expect(slotsBySeed([
{ matchNumber: 1, winnerSlot: 2 },
{ matchNumber: 2, winnerSlot: null },
])).toEqual({ 10: 1 });
});
it("holds an 8v9 winner back until the 7v10 game is decided", () => {
// 8th and 9th both sit between 7th and 10th, so either slot is still possible.
expect(slotsBySeed([
{ matchNumber: 1, winnerSlot: null },
{ matchNumber: 2, winnerSlot: 1 },
])).toEqual({});
expect(slotsBySeed([
{ matchNumber: 1, winnerSlot: null },
{ matchNumber: 2, winnerSlot: 2 },
])).toEqual({});
});
it("places nothing while both games are undecided", () => {
expect(resolveAflWildcardPlacements([
{ matchNumber: 1, winnerSlot: null },
{ matchNumber: 2, winnerSlot: null },
])).toEqual([]);
});
it("gives the same answer whichever result is entered first", () => {
for (const m1 of [7, 10] as const) {
for (const m2 of [8, 9] as const) {
const final = slotsBySeed(bothDecided(m1, m2));
// Whatever a single result places must survive the second result unchanged.
const m1First = slotsBySeed([
{ matchNumber: 1, winnerSlot: m1 === 7 ? 1 : 2 },
{ matchNumber: 2, winnerSlot: null },
]);
for (const [seed, slot] of Object.entries(m1First)) {
expect(final[Number(seed)]).toBe(slot);
}
}
}
});
it("rejects a match number outside the Wildcard draw", () => {
expect(() => resolveAflWildcardPlacements([{ matchNumber: 3, winnerSlot: 1 }])).toThrow(
/Unknown AFL Wildcard Round match number 3/
);
});
});