Enable users to see all their saved events on the home screen, sorted by date with upcoming events first. Key capabilities: - EventCard with title, relative time display, and organizer/attendee role badge - Sortable EventList with past-event visual distinction (faded style) - Empty state when no events are stored - Swipe-to-delete gesture with confirmation dialog - Floating action button for quick event creation - Rename router param :token → :eventToken across all views - useRelativeTime composable (Intl.RelativeTimeFormat) - useEventStorage: add validation, removeEvent(), reactive versioning - Full E2E and unit test coverage for all new components Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
import { describe, it, expect } from 'vitest'
|
|
import { formatRelativeTime } from '../useRelativeTime'
|
|
|
|
describe('formatRelativeTime', () => {
|
|
const now = new Date('2026-06-15T12:00:00Z')
|
|
|
|
it('formats seconds ago', () => {
|
|
const result = formatRelativeTime('2026-06-15T11:59:30Z', now)
|
|
expect(result).toMatch(/30 seconds ago/)
|
|
})
|
|
|
|
it('formats minutes ago', () => {
|
|
const result = formatRelativeTime('2026-06-15T11:55:00Z', now)
|
|
expect(result).toMatch(/5 minutes ago/)
|
|
})
|
|
|
|
it('formats hours ago', () => {
|
|
const result = formatRelativeTime('2026-06-15T09:00:00Z', now)
|
|
expect(result).toMatch(/3 hours ago/)
|
|
})
|
|
|
|
it('formats days ago', () => {
|
|
const result = formatRelativeTime('2026-06-13T12:00:00Z', now)
|
|
expect(result).toMatch(/2 days ago/)
|
|
})
|
|
|
|
it('formats weeks ago', () => {
|
|
const result = formatRelativeTime('2026-06-01T12:00:00Z', now)
|
|
expect(result).toMatch(/2 weeks ago/)
|
|
})
|
|
|
|
it('formats months ago', () => {
|
|
const result = formatRelativeTime('2026-03-15T12:00:00Z', now)
|
|
expect(result).toMatch(/3 months ago/)
|
|
})
|
|
|
|
it('formats years ago', () => {
|
|
const result = formatRelativeTime('2024-06-15T12:00:00Z', now)
|
|
expect(result).toMatch(/2 years ago/)
|
|
})
|
|
|
|
it('formats future seconds', () => {
|
|
const result = formatRelativeTime('2026-06-15T12:00:30Z', now)
|
|
expect(result).toMatch(/in 30 seconds/)
|
|
})
|
|
|
|
it('formats future days', () => {
|
|
const result = formatRelativeTime('2026-06-18T12:00:00Z', now)
|
|
expect(result).toMatch(/in 3 days/)
|
|
})
|
|
|
|
it('formats future months', () => {
|
|
const result = formatRelativeTime('2026-09-15T12:00:00Z', now)
|
|
expect(result).toMatch(/in 3 months/)
|
|
})
|
|
|
|
it('formats "now" for zero difference', () => {
|
|
const result = formatRelativeTime('2026-06-15T12:00:00Z', now)
|
|
// Intl.RelativeTimeFormat with numeric: 'auto' returns "now" for 0 seconds
|
|
expect(result).toMatch(/now/)
|
|
})
|
|
|
|
it('formats yesterday', () => {
|
|
const result = formatRelativeTime('2026-06-14T12:00:00Z', now)
|
|
expect(result).toMatch(/yesterday|1 day ago/)
|
|
})
|
|
|
|
it('formats tomorrow', () => {
|
|
const result = formatRelativeTime('2026-06-16T12:00:00Z', now)
|
|
expect(result).toMatch(/tomorrow|in 1 day/)
|
|
})
|
|
})
|