154 lines
4.1 KiB
TypeScript
154 lines
4.1 KiB
TypeScript
import { describe, it, expect, beforeEach } from 'vitest'
|
|
import { useDefensiveSetup } from '~/composables/useDefensiveSetup'
|
|
|
|
describe('useDefensiveSetup', () => {
|
|
beforeEach(() => {
|
|
const { reset } = useDefensiveSetup()
|
|
reset()
|
|
})
|
|
|
|
describe('singleton behavior', () => {
|
|
it('returns the same state across multiple calls', () => {
|
|
/**
|
|
* The composable is a module-level singleton — multiple calls to
|
|
* useDefensiveSetup() should return refs pointing to the same state.
|
|
*/
|
|
const a = useDefensiveSetup()
|
|
const b = useDefensiveSetup()
|
|
|
|
a.toggleHold(1)
|
|
expect(b.isHeld(1)).toBe(true)
|
|
expect(b.holdRunnersArray.value).toEqual([1])
|
|
})
|
|
})
|
|
|
|
describe('toggleHold', () => {
|
|
it('adds a base when not held', () => {
|
|
const { toggleHold, isHeld } = useDefensiveSetup()
|
|
|
|
toggleHold(1)
|
|
expect(isHeld(1)).toBe(true)
|
|
})
|
|
|
|
it('removes a base when already held', () => {
|
|
const { toggleHold, isHeld } = useDefensiveSetup()
|
|
|
|
toggleHold(2)
|
|
expect(isHeld(2)).toBe(true)
|
|
|
|
toggleHold(2)
|
|
expect(isHeld(2)).toBe(false)
|
|
})
|
|
|
|
it('can hold multiple bases independently', () => {
|
|
const { toggleHold, isHeld, holdRunnersArray } = useDefensiveSetup()
|
|
|
|
toggleHold(1)
|
|
toggleHold(3)
|
|
|
|
expect(isHeld(1)).toBe(true)
|
|
expect(isHeld(2)).toBe(false)
|
|
expect(isHeld(3)).toBe(true)
|
|
expect(holdRunnersArray.value).toEqual([1, 3])
|
|
})
|
|
})
|
|
|
|
describe('holdRunnersArray', () => {
|
|
it('returns sorted array of held base numbers', () => {
|
|
/**
|
|
* holdRunnersArray should always be sorted so the output is
|
|
* deterministic regardless of toggle order.
|
|
*/
|
|
const { toggleHold, holdRunnersArray } = useDefensiveSetup()
|
|
|
|
toggleHold(3)
|
|
toggleHold(1)
|
|
expect(holdRunnersArray.value).toEqual([1, 3])
|
|
})
|
|
|
|
it('returns empty array when nothing is held', () => {
|
|
const { holdRunnersArray } = useDefensiveSetup()
|
|
expect(holdRunnersArray.value).toEqual([])
|
|
})
|
|
})
|
|
|
|
describe('reset', () => {
|
|
it('clears all hold state and resets depths to defaults', () => {
|
|
const { toggleHold, infieldDepth, outfieldDepth, holdRunnersArray, reset } = useDefensiveSetup()
|
|
|
|
toggleHold(1)
|
|
toggleHold(2)
|
|
infieldDepth.value = 'infield_in'
|
|
outfieldDepth.value = 'shallow'
|
|
|
|
reset()
|
|
|
|
expect(holdRunnersArray.value).toEqual([])
|
|
expect(infieldDepth.value).toBe('normal')
|
|
expect(outfieldDepth.value).toBe('normal')
|
|
})
|
|
})
|
|
|
|
describe('syncFromDecision', () => {
|
|
it('sets all state from a DefensiveDecision object', () => {
|
|
const { syncFromDecision, infieldDepth, outfieldDepth, holdRunnersArray } = useDefensiveSetup()
|
|
|
|
syncFromDecision({
|
|
infield_depth: 'corners_in',
|
|
outfield_depth: 'shallow',
|
|
hold_runners: [1, 3],
|
|
})
|
|
|
|
expect(infieldDepth.value).toBe('corners_in')
|
|
expect(outfieldDepth.value).toBe('shallow')
|
|
expect(holdRunnersArray.value).toEqual([1, 3])
|
|
})
|
|
|
|
it('clears previously held runners not in new decision', () => {
|
|
const { toggleHold, syncFromDecision, isHeld } = useDefensiveSetup()
|
|
|
|
toggleHold(1)
|
|
toggleHold(2)
|
|
toggleHold(3)
|
|
|
|
syncFromDecision({
|
|
infield_depth: 'normal',
|
|
outfield_depth: 'normal',
|
|
hold_runners: [2],
|
|
})
|
|
|
|
expect(isHeld(1)).toBe(false)
|
|
expect(isHeld(2)).toBe(true)
|
|
expect(isHeld(3)).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('getDecision', () => {
|
|
it('returns a valid DefensiveDecision from current state', () => {
|
|
const { toggleHold, infieldDepth, getDecision } = useDefensiveSetup()
|
|
|
|
infieldDepth.value = 'infield_in'
|
|
toggleHold(1)
|
|
toggleHold(3)
|
|
|
|
const decision = getDecision()
|
|
|
|
expect(decision).toEqual({
|
|
infield_depth: 'infield_in',
|
|
outfield_depth: 'normal',
|
|
hold_runners: [1, 3],
|
|
})
|
|
})
|
|
|
|
it('returns defaults when nothing has been set', () => {
|
|
const { getDecision } = useDefensiveSetup()
|
|
|
|
expect(getDecision()).toEqual({
|
|
infield_depth: 'normal',
|
|
outfield_depth: 'normal',
|
|
hold_runners: [],
|
|
})
|
|
})
|
|
})
|
|
})
|