import { describe, expect, it } from 'vitest'; import { parseCents, parseSize, priceInput, unitPriceCents } from './groceries'; import { cheapestStores, formatCents } from '../groceries'; describe('groceries helpers', () => { it('parses prices into cents', () => { expect(parseCents('1,79')).toBe(179); expect(parseCents('€ 2.5')).toBe(250); expect(parseCents('3')).toBe(300); expect(parseCents('abc')).toBeNull(); expect(parseCents('1,234')).toBeNull(); }); it('parses pack sizes', () => { expect(parseSize('1 L')).toEqual({ amount: 1, unit: 'l' }); expect(parseSize('6 x 1 L')).toEqual({ amount: 6, unit: 'l' }); expect(parseSize('500 g')).toEqual({ amount: 0.5, unit: 'kg' }); expect(parseSize('750ml')).toEqual({ amount: 0.75, unit: 'l' }); expect(parseSize('4 stuks')).toEqual({ amount: 4, unit: 'piece' }); expect(parseSize('1,5 liter')).toEqual({ amount: 1.5, unit: 'l' }); expect(parseSize('a bunch')).toBeNull(); }); it('computes unit prices', () => { expect(unitPriceCents(479, 6)).toBe(80); expect(unitPriceCents(100, null)).toBeNull(); }); it('validates price input', () => { expect(priceInput.safeParse({ price: '1,29' }).data?.price).toBe(129); expect(priceInput.safeParse({ price: 'x' }).success).toBe(false); expect(priceInput.safeParse({ price: '1', url: '' }).success).toBe(true); }); it('finds the cheapest store', () => { const p = (storeId: number, priceCents: number, unitPriceCents: number | null) => ({ storeId, priceCents, unitPriceCents, promo: false, observedAt: new Date() }); expect([...cheapestStores([p(1, 179, 179), p(2, 129, 129)])]).toEqual([2]); expect([...cheapestStores([p(1, 479, 80), p(2, 129, 129)])]).toEqual([1]); expect([...cheapestStores([p(1, 479, null), p(2, 129, 129)])]).toEqual([2]); expect(cheapestStores([p(1, 100, null)]).size).toBe(0); expect(formatCents(179).replace(/\s/g, ' ')).toBe('€ 1,79'); }); });