/** * 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 { 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/ ); }); });