import { describe, it, expect } from 'vitest'; import { advanceGrowth, GROWTH_THRESHOLDS } from './growth'; import { PLANT_TYPES } from './plants'; import type { PlantInstance } from './types'; const rosemary = PLANT_TYPES.rosemary; const yarrow = PLANT_TYPES.yarrow; const winterRose = PLANT_TYPES['winter-rose']; function plant(plantedAtTick: number, plantTypeId: PlantInstance['plantTypeId'] = 'rosemary'): PlantInstance { return { plantedAtTick, plantTypeId }; } describe('advanceGrowth (D-08, D-09; pure function of currentTick + duration)', () => { it('returns sprout at tick=plantedAtTick', () => { expect(advanceGrowth(plant(0), rosemary, 0)).toBe('sprout'); }); it('returns sprout just below the 33% mature threshold', () => { // 600 * 0.33 = 198. Tick 197 is below the threshold. expect(advanceGrowth(plant(0), rosemary, 197)).toBe('sprout'); }); it('returns mature at the 33% threshold (≥, not >)', () => { expect(advanceGrowth(plant(0), rosemary, 198)).toBe('mature'); }); it('returns mature just below the ready threshold', () => { expect(advanceGrowth(plant(0), rosemary, 599)).toBe('mature'); }); it('returns ready at the duration boundary (100%)', () => { expect(advanceGrowth(plant(0), rosemary, 600)).toBe('ready'); }); it('returns sprout when just planted (currentTick === plantedAtTick != 0)', () => { expect(advanceGrowth(plant(100), rosemary, 100)).toBe('sprout'); }); it('clamps negative deltas to sprout (Pitfall 1 — system-clock rewind defense)', () => { expect(advanceGrowth(plant(100), rosemary, 50)).toBe('sprout'); }); it('overgrowth stays at ready (no overflow stage)', () => { expect(advanceGrowth(plant(0), rosemary, 100000)).toBe('ready'); }); it('respects per-plant duration — yarrow at 900 ticks is ready', () => { // Yarrow 33% threshold = 297; 900 = ready. expect(advanceGrowth(plant(0), yarrow, 296)).toBe('sprout'); expect(advanceGrowth(plant(0), yarrow, 297)).toBe('mature'); expect(advanceGrowth(plant(0), yarrow, 899)).toBe('mature'); expect(advanceGrowth(plant(0), yarrow, 900)).toBe('ready'); }); it('respects per-plant duration — winter-rose at 1500 ticks is ready', () => { // 1500 * 0.33 = 495. expect(advanceGrowth(plant(0), winterRose, 494)).toBe('sprout'); expect(advanceGrowth(plant(0), winterRose, 495)).toBe('mature'); expect(advanceGrowth(plant(0), winterRose, 1499)).toBe('mature'); expect(advanceGrowth(plant(0), winterRose, 1500)).toBe('ready'); }); it('GROWTH_THRESHOLDS is frozen (no accidental mutation)', () => { expect(Object.isFrozen(GROWTH_THRESHOLDS)).toBe(true); }); });