This document explains the unit test suite for Astrologer Studio.
bun run test:run # Run all tests once
bun run test # Watch mode (re-runs on file changes)
bun run test:ui # Visual interface in browserThe testing suite is built with modern, standard tools for the React ecosystem:
| Tool | Purpose |
|---|---|
| Vitest | Fast Unit Test Runner (Vite-native, Jest-compatible) |
| React Testing Library | Component rendering and interaction testing |
| @testing-library/jest-dom | Custom DOM element matchers (e.g., toBeInTheDocument) |
| jsdom | Browser environment simulation for Node.js |
Unit tests are automated checks that verify your code works correctly. When you run bun run test:run, the test suite executes 92 tests that check various functions and components.
Tests verify two main things:
- Backend Utilities: Date parsing, validation logic, data sanitization.
- Frontend Components: Rendering, user interactions (clicks), error handling.
We verify both backend logic and frontend components. Here is a complete breakdown of coverage:
1. Date & Time Handling (src/lib/utils/date.test.ts) - 31 Tests
- Parsing: Converts birth strings (YYYY-MM-DD + HH:MM) to UTC Date objects.
- Validation: Rejects invalid formats, future dates, and non-existent times (e.g., 25:00).
- Formatting:
- Display: Localizes dates (EU
DD/MM/YYYY, USMM/DD/YYYY, ISO). - Forms: Prepares dates for HTML
<input type="date">. - Time: 12h (AM/PM) vs 24h format handling.
- Display: Localizes dates (EU
- Edge Cases: Midnight handling, mixed ISO strings, timezone offsets.
2. Data Validation Schemas (src/lib/validation/validation.test.ts) - 18 Tests
- Saved Charts: Validates creation/update payloads (name limits, chart types).
- Subjects: Ensures birth data integrity and note length limits.
- Security: Verifies that invalid types or massive payloads are rejected by Zod before DB access.
- Helpers: Tests
validateBodywrapper and error formatting utilities.
3. Object Manipulation (src/lib/utils/object.test.ts) - 7 Tests
- Security: Tests
omitKeysto ensuring passwords/sensitive data are stripped from responses. - Immutability: Verifies original objects are never mutated during sanitization.
1. Button Component (src/components/ui/button.test.tsx) - 18 Tests
- Visual Variants: Default, Destructive, Outline, Secondary, Ghost, Link.
- Sizes: Default, Sm, Lg, Icon (square).
- Interactions: Click handlers firing, disabled state blocking clicks.
- Polymorphism: Tests
asChildprop (rendering as<a>tag while keeping button styles). - A11y: Forwards generic attributes (type, aria-label, etc.).
2. Error Boundaries (src/components/ErrorBoundary.test.tsx) - 10 Tests
- Recovery: Catches render errors and displays fallback UI instead of white screen.
- Customization: Supports custom fallback components via props.
- Safety: Isolates errors so one broken widget doesn't crash the whole page.
- Logging: Verifies errors are logged to console (or monitoring service).
3. Theme Provider (src/test/ThemeProvider.test.tsx) - 5 Tests
- Context: Verifies
next-themesintegration writes attributes correctly. - Rendering: Ensures children (nested or single) render without visual regression.
4. CSS Utilities (src/test/utils.test.ts) - 3 Tests
- Class Merging: Tests
cn()for merging conditional Tailwind classes and resolving conflicts (e.g.,p-4vsp-2).
| File | Purpose |
|---|---|
vitest.config.ts |
Main configuration: jsdom environment, path aliases (@/), coverage settings |
src/test/setup.ts |
Runs before tests: loads jest-dom matchers, mocks matchMedia and ResizeObserver |
Tests use the same @/ alias as the rest of the project:
import { cn } from '@/lib/utils/cn' // Points to src/lib/utils/cn ✓ src/test/lib/utils/date.test.ts (31)
Test Files 7 passed (7)
FAIL src/test/lib/utils/date.test.ts > parseBirthDateTime > should parse valid date
AssertionError: expected '2025-01-15' to equal '2025-01-16'
❯ src/test/lib/utils/date.test.ts:35:18
This tells you:
- File:
date.test.ts - Test:
parseBirthDateTime > should parse valid date - Problem: Expected
'2025-01-16'but got'2025-01-15' - Line: 35
Mirror the source file structure:
- Source:
src/lib/utils/myHelper.ts - Test:
src/test/lib/utils/myHelper.test.ts
import { describe, it, expect } from 'vitest'
import { myFunction } from '@/lib/utils/myHelper'
describe('myFunction', () => {
it('should do something specific', () => {
const result = myFunction('input')
expect(result).toBe('expected')
})
})bun run test:runComponents need to be rendered before you can test them:
import { render, screen, fireEvent } from '@testing-library/react'
import { vi } from 'vitest'
import { Button } from '@/components/ui/button'
describe('Button', () => {
it('should render text', () => {
render(<Button>Click me</Button>)
expect(screen.getByText('Click me')).toBeInTheDocument()
})
it('should handle clicks', () => {
const onClick = vi.fn()
render(<Button onClick={onClick}>Click</Button>)
fireEvent.click(screen.getByRole('button'))
expect(onClick).toHaveBeenCalledTimes(1)
})
})it('should reject empty name', () => {
const result = schema.safeParse({ name: '' })
expect(result.success).toBe(false)
})it('should throw for invalid input', () => {
expect(() => myFunction('bad')).toThrow('Error message')
})it('should render destructive variant', () => {
render(<Button variant="destructive">Delete</Button>)
expect(screen.getByRole('button').className).toContain('bg-destructive')
})| Command | What It Does |
|---|---|
bun run test |
Starts tests in watch mode. Tests re-run automatically when you save a file. Good for active development. Press q to quit. |
bun run test:run |
Runs all tests once and exits. Shows pass/fail summary. Use this to verify everything works before committing. |
bun run test:ui |
Opens a visual web interface in your browser. You can click on tests, see results, and re-run specific tests. Best for learning and debugging. |
bun run test:coverage |
Runs tests and generates a coverage report showing which lines of code are tested. Creates an HTML report in coverage/ folder. |
bun vitest run path/to/file.test.ts |
Runs tests from a specific file only. Useful when working on one area. |
bun vitest --watch path/to/file.test.ts |
Watches a specific file for changes and re-runs its tests. |
When running bun run test (watch mode), these keys are available:
| Key | Action |
|---|---|
a |
Run all tests |
f |
Run only failed tests |
p |
Filter by file pattern (type to search) |
t |
Filter by test name pattern |
q |
Quit watch mode |
h |
Show help with all shortcuts |
Enter |
Re-run tests |
Last updated: 2026-01-15