/** * Money Value Object Unit Tests */ import { Money } from './money.vo'; describe('Money Value Object', () => { describe('create', () => { it('should create money with valid amount and currency', () => { const money = Money.create(100, 'USD'); expect(money.getAmount()).toBe(100); expect(money.getCurrency()).toBe('USD'); }); it('should round to 2 decimal places', () => { const money = Money.create(100.999, 'USD'); expect(money.getAmount()).toBe(101); }); it('should throw error for negative amount', () => { expect(() => Money.create(-100, 'USD')).toThrow('Amount cannot be negative'); }); it('should throw error for invalid currency', () => { expect(() => Money.create(100, 'XXX')).toThrow('Invalid currency code'); }); it('should normalize currency to uppercase', () => { const money = Money.create(100, 'usd'); expect(money.getCurrency()).toBe('USD'); }); }); describe('zero', () => { it('should create zero amount', () => { const money = Money.zero('USD'); expect(money.getAmount()).toBe(0); expect(money.isZero()).toBe(true); }); }); describe('add', () => { it('should add two money amounts', () => { const money1 = Money.create(100, 'USD'); const money2 = Money.create(50, 'USD'); const result = money1.add(money2); expect(result.getAmount()).toBe(150); }); it('should throw error for currency mismatch', () => { const money1 = Money.create(100, 'USD'); const money2 = Money.create(50, 'EUR'); expect(() => money1.add(money2)).toThrow('Currency mismatch'); }); }); describe('subtract', () => { it('should subtract two money amounts', () => { const money1 = Money.create(100, 'USD'); const money2 = Money.create(30, 'USD'); const result = money1.subtract(money2); expect(result.getAmount()).toBe(70); }); it('should throw error for negative result', () => { const money1 = Money.create(50, 'USD'); const money2 = Money.create(100, 'USD'); expect(() => money1.subtract(money2)).toThrow('negative amount'); }); }); describe('multiply', () => { it('should multiply money amount', () => { const money = Money.create(100, 'USD'); const result = money.multiply(2); expect(result.getAmount()).toBe(200); }); it('should throw error for negative multiplier', () => { const money = Money.create(100, 'USD'); expect(() => money.multiply(-2)).toThrow('Multiplier cannot be negative'); }); }); describe('divide', () => { it('should divide money amount', () => { const money = Money.create(100, 'USD'); const result = money.divide(2); expect(result.getAmount()).toBe(50); }); it('should throw error for zero divisor', () => { const money = Money.create(100, 'USD'); expect(() => money.divide(0)).toThrow('Divisor must be positive'); }); }); describe('comparisons', () => { it('should compare greater than', () => { const money1 = Money.create(100, 'USD'); const money2 = Money.create(50, 'USD'); expect(money1.isGreaterThan(money2)).toBe(true); expect(money2.isGreaterThan(money1)).toBe(false); }); it('should compare less than', () => { const money1 = Money.create(50, 'USD'); const money2 = Money.create(100, 'USD'); expect(money1.isLessThan(money2)).toBe(true); expect(money2.isLessThan(money1)).toBe(false); }); it('should compare equality', () => { const money1 = Money.create(100, 'USD'); const money2 = Money.create(100, 'USD'); const money3 = Money.create(50, 'USD'); expect(money1.isEqualTo(money2)).toBe(true); expect(money1.isEqualTo(money3)).toBe(false); }); }); describe('format', () => { it('should format USD with $ symbol', () => { const money = Money.create(100.5, 'USD'); expect(money.format()).toBe('$100.50'); }); it('should format EUR with € symbol', () => { const money = Money.create(100.5, 'EUR'); expect(money.format()).toBe('€100.50'); }); }); });