import { describe, expect, it } from 'vitest' import { computeDerivedCount, effectiveCount, recentlyPlantedIds, type EditorPlanting } from './plantings' function plop(over: Partial): EditorPlanting { return { id: 0, objectId: 1, plantId: 1, xCm: 0, yCm: 0, radiusCm: 5, count: null, derivedCount: 1, label: null, plantedAt: null, version: 1, ...over, } } describe('recentlyPlantedIds', () => { it('returns unique plant ids, newest planted first', () => { const got = recentlyPlantedIds([ plop({ id: 1, plantId: 10, plantedAt: '2026-05-01' }), plop({ id: 2, plantId: 20, plantedAt: '2026-07-01' }), plop({ id: 3, plantId: 10, plantedAt: '2026-06-01' }), // dup plant, later ]) // 20 (Jul) before 10 (its most recent plop is Jun); 10 appears once. expect(got).toEqual([20, 10]) }) it('breaks a same-day tie by newer plop id, and sorts undated last', () => { const got = recentlyPlantedIds([ plop({ id: 5, plantId: 30, plantedAt: null }), plop({ id: 6, plantId: 40, plantedAt: '2026-07-01' }), plop({ id: 7, plantId: 50, plantedAt: '2026-07-01' }), ]) expect(got).toEqual([50, 40, 30]) // id 7 > 6 on the same day; undated 30 last }) it('is empty for no plantings', () => { expect(recentlyPlantedIds([])).toEqual([]) }) }) describe('computeDerivedCount', () => { it('mirrors the server formula max(1, round(π·r²/spacing²))', () => { expect(computeDerivedCount(10, 10)).toBe(3) // π·100/100 = 3.14 → 3 expect(computeDerivedCount(50, 10)).toBe(79) // π·2500/100 = 78.5 → 79 expect(computeDerivedCount(30, 15)).toBe(13) // π·900/225 = 12.57 → 13 }) it('floors at 1 for tiny / non-positive inputs', () => { expect(computeDerivedCount(0.1, 10)).toBe(1) expect(computeDerivedCount(0, 10)).toBe(1) expect(computeDerivedCount(10, 0)).toBe(1) }) it('caps like the server', () => { expect(computeDerivedCount(10_000, 0.1)).toBe(1_000_000) }) }) describe('effectiveCount', () => { it('prefers the override, else the derived value', () => { expect(effectiveCount({ count: 12, derivedCount: 79 })).toBe(12) expect(effectiveCount({ count: null, derivedCount: 79 })).toBe(79) }) })