mirror of
https://github.com/jcwimer/wrestlingApp
synced 2026-04-12 00:09:32 +00:00
New stats page, scoreboard, and live scores pages.
This commit is contained in:
227
test/javascript/match_state/scoreboard_presenters.test.js
Normal file
227
test/javascript/match_state/scoreboard_presenters.test.js
Normal file
@@ -0,0 +1,227 @@
|
||||
import { describe, expect, it } from "vitest"
|
||||
import { getMatchStateConfig } from "match-state-config"
|
||||
import { buildInitialState } from "match-state-engine"
|
||||
import {
|
||||
boardColors,
|
||||
buildRunningTimerSnapshot,
|
||||
emptyBoardViewModel,
|
||||
currentClockText,
|
||||
detectRecentlyStoppedTimer,
|
||||
mainClockRunning,
|
||||
nextTimerBannerState,
|
||||
participantDisplayLabel,
|
||||
participantForColor,
|
||||
populatedBoardViewModel,
|
||||
timerBannerRenderState,
|
||||
timerBannerViewModel,
|
||||
timerIndicatorLabel
|
||||
} from "match-state-scoreboard-presenters"
|
||||
|
||||
describe("match state scoreboard presenters", () => {
|
||||
it("maps colors to participants and labels", () => {
|
||||
const state = {
|
||||
assignment: { w1: "red", w2: "green" },
|
||||
metadata: { w1Name: "Alpha", w2Name: "Bravo" }
|
||||
}
|
||||
|
||||
expect(participantForColor(state, "red")).toBe("w1")
|
||||
expect(participantForColor(state, "green")).toBe("w2")
|
||||
expect(participantDisplayLabel(state, "w1")).toBe("Red Alpha")
|
||||
expect(participantDisplayLabel(state, "w2")).toBe("Green Bravo")
|
||||
})
|
||||
|
||||
it("formats the current clock from running phase state", () => {
|
||||
const config = getMatchStateConfig("folkstyle_usa", "Bracket Round of 64")
|
||||
const state = buildInitialState(config)
|
||||
state.phaseIndex = 0
|
||||
state.clocksByPhase.period_1.running = true
|
||||
state.clocksByPhase.period_1.startedAt = 1_000
|
||||
state.clocksByPhase.period_1.remainingSeconds = 120
|
||||
|
||||
expect(currentClockText(config, state, (seconds) => `F-${seconds}`, 11_000)).toBe("F-110")
|
||||
expect(mainClockRunning(config, state)).toBe(true)
|
||||
})
|
||||
|
||||
it("builds timer indicator and banner view models from running timers", () => {
|
||||
const config = getMatchStateConfig("folkstyle_usa", "Bracket Round of 64")
|
||||
const state = buildInitialState(config)
|
||||
state.metadata = { w1Name: "Alpha", w2Name: "Bravo" }
|
||||
state.timers.w1.blood.running = true
|
||||
state.timers.w1.blood.startedAt = 1_000
|
||||
state.timers.w1.blood.remainingSeconds = 300
|
||||
|
||||
expect(timerIndicatorLabel(config, state, "w1", (seconds) => `F-${seconds}`, 21_000)).toBe("Blood: F-20")
|
||||
|
||||
const banner = timerBannerViewModel(config, state, { participantKey: "w1", timerKey: "blood", expiresAt: null }, (seconds) => `F-${seconds}`, 21_000)
|
||||
expect(banner).toEqual({
|
||||
color: "green",
|
||||
label: "Green Alpha Blood Running",
|
||||
clockText: "F-20"
|
||||
})
|
||||
})
|
||||
|
||||
it("detects recently stopped timers from the snapshot", () => {
|
||||
const state = {
|
||||
timers: {
|
||||
w1: { blood: { running: false } },
|
||||
w2: { injury: { running: true } }
|
||||
}
|
||||
}
|
||||
const snapshot = {
|
||||
"w1:blood": true,
|
||||
"w2:injury": true
|
||||
}
|
||||
|
||||
expect(detectRecentlyStoppedTimer(state, snapshot)).toEqual({ participantKey: "w1", timerKey: "blood" })
|
||||
expect(buildRunningTimerSnapshot(state)).toEqual({
|
||||
"w1:blood": false,
|
||||
"w2:injury": true
|
||||
})
|
||||
})
|
||||
|
||||
it("builds populated and empty board view models", () => {
|
||||
const config = getMatchStateConfig("folkstyle_usa", "Bracket Round of 64")
|
||||
const state = buildInitialState(config)
|
||||
state.metadata = {
|
||||
w1Name: "Alpha",
|
||||
w2Name: "Bravo",
|
||||
w1School: "School A",
|
||||
w2School: "School B",
|
||||
weightLabel: "106"
|
||||
}
|
||||
state.participantScores = { w1: 4, w2: 1 }
|
||||
state.assignment = { w1: "green", w2: "red" }
|
||||
|
||||
const populated = populatedBoardViewModel(
|
||||
config,
|
||||
state,
|
||||
{ w1_stat: "T3", w2_stat: "E1" },
|
||||
1001,
|
||||
(seconds) => `F-${seconds}`
|
||||
)
|
||||
|
||||
expect(populated).toMatchObject({
|
||||
isEmpty: false,
|
||||
redName: "Bravo",
|
||||
redSchool: "School B",
|
||||
redScore: "1",
|
||||
greenName: "Alpha",
|
||||
greenSchool: "School A",
|
||||
greenScore: "4",
|
||||
weightLabel: "Weight 106",
|
||||
boutLabel: "Bout 1001",
|
||||
redStats: "E1",
|
||||
greenStats: "T3"
|
||||
})
|
||||
|
||||
expect(emptyBoardViewModel(1002, "Last result")).toEqual({
|
||||
isEmpty: true,
|
||||
redName: "NO MATCH",
|
||||
redSchool: "",
|
||||
redScore: "0",
|
||||
redTimerIndicator: "",
|
||||
greenName: "NO MATCH",
|
||||
greenSchool: "",
|
||||
greenScore: "0",
|
||||
greenTimerIndicator: "",
|
||||
clockText: "-",
|
||||
phaseLabel: "No Match",
|
||||
weightLabel: "Weight -",
|
||||
boutLabel: "Bout 1002",
|
||||
redStats: "",
|
||||
greenStats: "",
|
||||
lastMatchResult: "Last result"
|
||||
})
|
||||
})
|
||||
|
||||
it("builds next timer banner state for running and recently stopped timers", () => {
|
||||
const runningState = {
|
||||
timers: {
|
||||
w1: { blood: { running: true } },
|
||||
w2: {}
|
||||
}
|
||||
}
|
||||
|
||||
expect(nextTimerBannerState(runningState, {})).toEqual({
|
||||
timerBannerState: {
|
||||
participantKey: "w1",
|
||||
timerKey: "blood",
|
||||
expiresAt: null
|
||||
},
|
||||
previousTimerSnapshot: {
|
||||
"w1:blood": true
|
||||
}
|
||||
})
|
||||
|
||||
const stoppedState = {
|
||||
timers: {
|
||||
w1: { blood: { running: false } },
|
||||
w2: {}
|
||||
}
|
||||
}
|
||||
|
||||
const stoppedResult = nextTimerBannerState(stoppedState, { "w1:blood": true }, 5_000)
|
||||
expect(stoppedResult).toEqual({
|
||||
timerBannerState: {
|
||||
participantKey: "w1",
|
||||
timerKey: "blood",
|
||||
expiresAt: 15_000
|
||||
},
|
||||
previousTimerSnapshot: {
|
||||
"w1:blood": false
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
it("builds board colors and timer banner render decisions", () => {
|
||||
expect(boardColors(true)).toEqual({
|
||||
red: "#000",
|
||||
center: "#000",
|
||||
green: "#000"
|
||||
})
|
||||
expect(boardColors(false)).toEqual({
|
||||
red: "#c91f1f",
|
||||
center: "#050505",
|
||||
green: "#1cab2d"
|
||||
})
|
||||
|
||||
const config = getMatchStateConfig("folkstyle_usa", "Bracket Round of 64")
|
||||
const state = buildInitialState(config)
|
||||
state.metadata = { w1Name: "Alpha", w2Name: "Bravo" }
|
||||
state.timers.w1.blood.running = true
|
||||
state.timers.w1.blood.startedAt = 1_000
|
||||
state.timers.w1.blood.remainingSeconds = 300
|
||||
|
||||
expect(timerBannerRenderState(
|
||||
config,
|
||||
state,
|
||||
{ participantKey: "w1", timerKey: "blood", expiresAt: null },
|
||||
(seconds) => `F-${seconds}`,
|
||||
11_000
|
||||
)).toEqual({
|
||||
timerBannerState: { participantKey: "w1", timerKey: "blood", expiresAt: null },
|
||||
visible: true,
|
||||
viewModel: {
|
||||
color: "green",
|
||||
label: "Green Alpha Blood Running",
|
||||
clockText: "F-10"
|
||||
}
|
||||
})
|
||||
|
||||
state.clocksByPhase.period_1.running = true
|
||||
state.clocksByPhase.period_1.startedAt = 1_000
|
||||
state.clocksByPhase.period_1.remainingSeconds = 120
|
||||
|
||||
expect(timerBannerRenderState(
|
||||
config,
|
||||
state,
|
||||
{ participantKey: "w1", timerKey: "blood", expiresAt: 20_000 },
|
||||
(seconds) => `F-${seconds}`,
|
||||
11_000
|
||||
)).toEqual({
|
||||
timerBannerState: null,
|
||||
visible: false,
|
||||
viewModel: null
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user