Files
website/src/lib/server/groceries.test.ts

46 lines
1.9 KiB
TypeScript

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');
});
});