import { cn, formatNumber, formatCurrency, debounce, throttle, randomBetween, lerp, clamp } from './utils'; describe('utils', () => { describe('cn', () => { it('should merge class names correctly', () => { expect(cn('foo', 'bar')).toBe('foo bar'); }); it('should handle conditional classes', () => { expect(cn('foo', false && 'bar', 'baz')).toBe('foo baz'); }); it('should handle empty input', () => { expect(cn()).toBe(''); }); }); describe('formatNumber', () => { it('should format numbers with Chinese locale', () => { expect(formatNumber(1234567)).toBe('1,234,567'); }); it('should handle decimal numbers', () => { expect(formatNumber(1234.56)).toBe('1,234.56'); }); it('should handle zero', () => { expect(formatNumber(0)).toBe('0'); }); }); describe('formatCurrency', () => { it('should format numbers as CNY currency', () => { expect(formatCurrency(1234.56)).toBe('¥1,234.56'); }); it('should handle large numbers', () => { expect(formatCurrency(1000000)).toBe('¥1,000,000.00'); }); it('should handle zero', () => { expect(formatCurrency(0)).toBe('¥0.00'); }); }); describe('debounce', () => { beforeEach(() => { jest.useFakeTimers(); }); afterEach(() => { jest.useRealTimers(); }); it('should delay function execution', () => { const mockFn = jest.fn(); const debouncedFn = debounce(mockFn, 100); debouncedFn(); expect(mockFn).not.toHaveBeenCalled(); jest.advanceTimersByTime(100); expect(mockFn).toHaveBeenCalledTimes(1); }); it('should cancel previous calls', () => { const mockFn = jest.fn(); const debouncedFn = debounce(mockFn, 100); debouncedFn(); jest.advanceTimersByTime(50); debouncedFn(); jest.advanceTimersByTime(100); expect(mockFn).toHaveBeenCalledTimes(1); }); }); describe('throttle', () => { beforeEach(() => { jest.useFakeTimers(); }); afterEach(() => { jest.useRealTimers(); }); it('should limit function execution rate', () => { const mockFn = jest.fn(); const throttledFn = throttle(mockFn, 100); throttledFn(); throttledFn(); throttledFn(); expect(mockFn).toHaveBeenCalledTimes(1); jest.advanceTimersByTime(100); throttledFn(); expect(mockFn).toHaveBeenCalledTimes(2); }); }); describe('randomBetween', () => { it('should generate number in range', () => { const result = randomBetween(1, 10); expect(result).toBeGreaterThanOrEqual(1); expect(result).toBeLessThanOrEqual(10); }); it('should handle negative numbers', () => { const result = randomBetween(-10, -1); expect(result).toBeGreaterThanOrEqual(-10); expect(result).toBeLessThanOrEqual(-1); }); }); describe('lerp', () => { it('should interpolate between values', () => { expect(lerp(0, 10, 0.5)).toBe(5); expect(lerp(0, 100, 0.25)).toBe(25); }); it('should handle edge cases', () => { expect(lerp(0, 10, 0)).toBe(0); expect(lerp(0, 10, 1)).toBe(10); }); }); describe('clamp', () => { it('should clamp values within range', () => { expect(clamp(5, 0, 10)).toBe(5); expect(clamp(-5, 0, 10)).toBe(0); expect(clamp(15, 0, 10)).toBe(10); }); it('should handle equal min and max', () => { expect(clamp(5, 5, 5)).toBe(5); }); }); });