mirror of
https://github.com/tiennm99/gsd-framework.git
synced 2026-05-14 04:58:22 +00:00
feat(01-01): set up test infrastructure with Vitest
- Add package.json with Vitest, jsdom, Vite, and Preact dependencies - Configure Vitest with jsdom environment for component testing - Create test stubs for billStore (PEOPLE-01, PEOPLE-02, PEOPLE-03, PEOPLE-04) - Create test stubs for currency utilities (dollarsToCents, centsToDollars, formatCurrency) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import { describe, it, expect, beforeEach } from 'vitest';
|
||||
import { createBillStore } from '../src/store/billStore.js';
|
||||
|
||||
describe('BillStore', () => {
|
||||
let store;
|
||||
|
||||
beforeEach(() => {
|
||||
store = createBillStore();
|
||||
});
|
||||
|
||||
describe('addPerson (PEOPLE-01)', () => {
|
||||
it('adds person with valid name', () => {
|
||||
const result = store.addPerson('Alice');
|
||||
expect(result.success).toBe(true);
|
||||
expect(store.people.value).toHaveLength(1);
|
||||
expect(store.people.value[0].name).toBe('Alice');
|
||||
});
|
||||
|
||||
it('rejects empty name', () => {
|
||||
const result = store.addPerson('');
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it('trims whitespace from name', () => {
|
||||
const result = store.addPerson(' Bob ');
|
||||
expect(result.success).toBe(true);
|
||||
expect(store.people.value[0].name).toBe('Bob');
|
||||
});
|
||||
});
|
||||
|
||||
describe('addItem (PEOPLE-02)', () => {
|
||||
it('adds item with name and price', () => {
|
||||
const result = store.addItem('Pizza', '15.99');
|
||||
expect(result.success).toBe(true);
|
||||
expect(store.items.value[0].priceCents).toBe(1599);
|
||||
});
|
||||
|
||||
it('rejects empty item name', () => {
|
||||
const result = store.addItem('', '10.00');
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it('rejects negative price', () => {
|
||||
const result = store.addItem('Item', '-5.00');
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
|
||||
it('rejects non-numeric price', () => {
|
||||
const result = store.addItem('Item', 'abc');
|
||||
expect(result.success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setAssignment (PEOPLE-03, PEOPLE-04)', () => {
|
||||
it('assigns item to one person', () => {
|
||||
store.addPerson('Alice');
|
||||
const personId = store.people.value[0].id;
|
||||
store.addItem('Salad', '10.00');
|
||||
const itemId = store.items.value[0].id;
|
||||
|
||||
store.setAssignment(itemId, [personId]);
|
||||
expect(store.getAssignedPeople(itemId)).toEqual([personId]);
|
||||
});
|
||||
|
||||
it('assigns item to multiple people (shared)', () => {
|
||||
store.addPerson('Alice');
|
||||
store.addPerson('Bob');
|
||||
const [id1, id2] = store.people.value.map(p => p.id);
|
||||
store.addItem('Nachos', '12.00');
|
||||
const itemId = store.items.value[0].id;
|
||||
|
||||
store.setAssignment(itemId, [id1, id2]);
|
||||
expect(store.getAssignedPeople(itemId)).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('returns empty array for unassigned item', () => {
|
||||
store.addItem('Standalone', '5.00');
|
||||
const itemId = store.items.value[0].id;
|
||||
|
||||
expect(store.getAssignedPeople(itemId)).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,51 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { dollarsToCents, centsToDollars, formatCurrency } from '../src/utils/currency.js';
|
||||
|
||||
describe('currency utilities', () => {
|
||||
describe('dollarsToCents', () => {
|
||||
it('converts decimal string to cents', () => {
|
||||
expect(dollarsToCents('15.99')).toBe(1599);
|
||||
});
|
||||
|
||||
it('converts integer string to cents', () => {
|
||||
expect(dollarsToCents('20')).toBe(2000);
|
||||
});
|
||||
|
||||
it('handles single decimal place', () => {
|
||||
expect(dollarsToCents('10.5')).toBe(1050);
|
||||
});
|
||||
|
||||
it('handles zero', () => {
|
||||
expect(dollarsToCents('0')).toBe(0);
|
||||
});
|
||||
|
||||
it('rounds floating point precision', () => {
|
||||
// 10.99 * 100 = 1098.9999... in JS
|
||||
expect(dollarsToCents('10.99')).toBe(1099);
|
||||
});
|
||||
});
|
||||
|
||||
describe('centsToDollars', () => {
|
||||
it('converts cents to dollar string', () => {
|
||||
expect(centsToDollars(1599)).toBe('15.99');
|
||||
});
|
||||
|
||||
it('handles zero', () => {
|
||||
expect(centsToDollars(0)).toBe('0.00');
|
||||
});
|
||||
|
||||
it('pads single digit cents', () => {
|
||||
expect(centsToDollars(1050)).toBe('10.50');
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatCurrency', () => {
|
||||
it('formats cents as dollar string with $ prefix', () => {
|
||||
expect(formatCurrency(1599)).toBe('$15.99');
|
||||
});
|
||||
|
||||
it('formats zero', () => {
|
||||
expect(formatCurrency(0)).toBe('$0.00');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user