|
| 1 | +import { describe, it, expect } from 'vitest'; |
| 2 | +import { formatDate, timeAgo, daysBetween } from './date'; |
| 3 | + |
| 4 | +describe('date utils', () => { |
| 5 | + describe('formatDate', () => { |
| 6 | + it('formats date correctly with default locale', () => { |
| 7 | + const date = new Date('2023-01-01T12:00:00Z'); |
| 8 | + // Note: This test might be sensitive to the running environment's time zone if not handled carefully. |
| 9 | + // However, Intl.DateTimeFormat uses local time by default. |
| 10 | + // To make it deterministic in tests, we can check if it returns a string format. |
| 11 | + // Better yet, for basic smoke test, checking the structure or specific parts. |
| 12 | + // Given the implementation uses Intl.DateTimeFormat, exact output depends on browser/node locale support. |
| 13 | + // We will assume "ja-JP" default and check for typical format or parts. |
| 14 | + |
| 15 | + const formatted = formatDate(date); |
| 16 | + expect(formatted).toMatch(/2023/); |
| 17 | + expect(formatted).toMatch(/01/); |
| 18 | + }); |
| 19 | + |
| 20 | + it('formats date string correctly', () => { |
| 21 | + const formatted = formatDate('2023-12-31'); |
| 22 | + expect(formatted).toMatch(/2023/); |
| 23 | + expect(formatted).toMatch(/12/); |
| 24 | + expect(formatted).toMatch(/31/); |
| 25 | + }); |
| 26 | + |
| 27 | + it('respects custom locale and options', () => { |
| 28 | + const date = new Date('2023-01-01T00:00:00'); |
| 29 | + const formatted = formatDate(date, 'en-US', { month: 'long', year: 'numeric' }); |
| 30 | + expect(formatted).toBe('January 2023'); |
| 31 | + }); |
| 32 | + }); |
| 33 | + |
| 34 | + describe('timeAgo', () => { |
| 35 | + it('returns "seconds ago" for recent times', () => { |
| 36 | + const now = new Date(); |
| 37 | + const past = new Date(now.getTime() - 1000 * 30); // 30 seconds ago |
| 38 | + expect(timeAgo(past)).toBe('30 seconds ago'); |
| 39 | + }); |
| 40 | + |
| 41 | + it('returns "minutes ago"', () => { |
| 42 | + const now = new Date(); |
| 43 | + const past = new Date(now.getTime() - 1000 * 60 * 5); // 5 minutes ago |
| 44 | + expect(timeAgo(past)).toBe('5 minutes ago'); |
| 45 | + }); |
| 46 | + |
| 47 | + it('returns "hours ago"', () => { |
| 48 | + const now = new Date(); |
| 49 | + const past = new Date(now.getTime() - 1000 * 60 * 60 * 2); // 2 hours ago |
| 50 | + expect(timeAgo(past)).toBe('2 hours ago'); |
| 51 | + }); |
| 52 | + |
| 53 | + it('returns "days ago"', () => { |
| 54 | + const now = new Date(); |
| 55 | + const past = new Date(now.getTime() - 1000 * 60 * 60 * 24 * 5); // 5 days ago |
| 56 | + expect(timeAgo(past)).toBe('5 days ago'); |
| 57 | + }); |
| 58 | + |
| 59 | + it('returns "months ago"', () => { |
| 60 | + const now = new Date(); |
| 61 | + const past = new Date(now.getTime() - 1000 * 60 * 60 * 24 * 60); // 60 days ~ 2 months |
| 62 | + expect(timeAgo(past)).toBe('2 months ago'); |
| 63 | + }); |
| 64 | + |
| 65 | + it('returns "years ago"', () => { |
| 66 | + const now = new Date(); |
| 67 | + const past = new Date(now.getTime() - 1000 * 60 * 60 * 24 * 400); // 400 days ~ 1 year |
| 68 | + expect(timeAgo(past)).toBe('1 years ago'); |
| 69 | + }); |
| 70 | + }); |
| 71 | + |
| 72 | + describe('daysBetween', () => { |
| 73 | + it('calculates days correctly', () => { |
| 74 | + const start = new Date('2023-01-01'); |
| 75 | + const end = new Date('2023-01-10'); |
| 76 | + expect(daysBetween(start, end)).toBe(9); |
| 77 | + }); |
| 78 | + |
| 79 | + it('returns 0 for same day', () => { |
| 80 | + const start = new Date('2023-01-01T10:00:00'); |
| 81 | + const end = new Date('2023-01-01T20:00:00'); |
| 82 | + expect(daysBetween(start, end)).toBe(0); |
| 83 | + }); |
| 84 | + |
| 85 | + it('works with string inputs', () => { |
| 86 | + expect(daysBetween('2023-01-01', '2023-01-02')).toBe(1); |
| 87 | + }); |
| 88 | + }); |
| 89 | +}); |
0 commit comments