Files
headroom/openspec/templates/VitestUnitTest.test.ts

206 lines
5.0 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest';
/*
* Test Template for Vitest Unit Tests (Utilities, Stores, API Clients)
*
* Copy this file and replace:
* - {{module}} with the module name
* - {{capability}} with the capability name
*
* Mark pending tests with test.skip() during Red Phase
* Remove .skip and implement during Green Phase
*/
describe('{{module}}', () => {
beforeEach(() => {
// Reset state before each test
vi.clearAllMocks();
});
/*
* Test: Core functionality
*/
it.skip('{{functionality_description}}', () => {
// Arrange
const input = {
// Test input
};
const expected = {
// Expected output
};
// Act
const result = {{module}}.{{method}}(input);
// Assert
expect(result).toEqual(expected);
});
/*
* Test: Edge cases
*/
it.skip('handles {{edge_case}}', () => {
// Arrange
const edgeCaseInput = null;
// Act & Assert
expect(() => {{module}}.{{method}}(edgeCaseInput))
.toThrow('Invalid input');
});
/*
* Test: Async operations
*/
it.skip('{{async_description}}', async () => {
// Arrange
const mockResponse = { data: 'test' };
global.fetch = vi.fn().mockResolvedValue({
ok: true,
json: () => Promise.resolve(mockResponse)
});
// Act
const result = await {{module}}.{{async_method}}();
// Assert
expect(result).toEqual(mockResponse);
expect(fetch).toHaveBeenCalledWith('/api/{{endpoint}}');
});
/*
* Test: Error handling
*/
it.skip('handles API errors', async () => {
// Arrange
global.fetch = vi.fn().mockResolvedValue({
ok: false,
status: 500,
json: () => Promise.resolve({ message: 'Server error' })
});
// Act & Assert
await expect({{module}}.{{async_method}}())
.rejects.toThrow('Server error');
});
/*
* Test: Store behavior (if testing Svelte stores)
*/
it.skip('updates store value', () => {
// Arrange
const store = {{module}}.{{store_name}};
// Act
store.set({ value: 'new value' });
// Assert
let value;
store.subscribe(v => { value = v; })();
expect(value).toEqual({ value: 'new value' });
});
/*
* Test: Store derived values
*/
it.skip('computes derived value correctly', () => {
// Arrange
const store = {{module}}.{{store_name}};
store.set({ items: [1, 2, 3] });
// Act
let derivedValue;
{{module}}.{{derived_store}}.subscribe(v => { derivedValue = v; })();
// Assert
expect(derivedValue).toBe(6); // sum of items
});
/*
* Test: Validation logic
*/
it.skip('validates {{field}} correctly', () => {
// Valid cases
expect({{module}}.validate{{field}}('valid')).toBe(true);
expect({{module}}.validate{{field}}('another-valid')).toBe(true);
// Invalid cases
expect({{module}}.validate{{field}}('')).toBe(false);
expect({{module}}.validate{{field}}(null)).toBe(false);
expect({{module}}.validate{{field}}('invalid!')).toBe(false);
});
/*
* Test: Calculation accuracy
*/
it.skip('calculates {{calculation}} correctly', () => {
expect({{module}}.calculate(10, 20)).toBe(30);
expect({{module}}.calculate(0, 0)).toBe(0);
expect({{module}}.calculate(-5, 5)).toBe(0);
});
/*
* Test: Formatting functions
*/
it.skip('formats {{data_type}} correctly', () => {
expect({{module}}.format{{data_type}}(1000)).toBe('$1,000.00');
expect({{module}}.format{{data_type}}(0)).toBe('$0.00');
expect({{module}}.format{{data_type}}(-500)).toBe('-$500.00');
});
/*
* Test: Date/time utilities
*/
it.skip('parses date correctly', () => {
const result = {{module}}.parseDate('2024-01-15');
expect(result).toBeInstanceOf(Date);
expect(result.getFullYear()).toBe(2024);
expect(result.getMonth()).toBe(0); // January is 0
expect(result.getDate()).toBe(15);
});
it.skip('formats date as YYYY-MM', () => {
const date = new Date(2024, 0, 15); // January 15, 2024
expect({{module}}.formatMonth(date)).toBe('2024-01');
});
/*
* Test: Local storage operations
*/
it.skip('saves to localStorage', () => {
const data = { key: 'value' };
{{module}}.saveToStorage('test-key', data);
expect(localStorage.setItem).toHaveBeenCalledWith(
'test-key',
JSON.stringify(data)
);
});
it.skip('loads from localStorage', () => {
const data = { key: 'value' };
localStorage.getItem.mockReturnValue(JSON.stringify(data));
const result = {{module}}.loadFromStorage('test-key');
expect(result).toEqual(data);
});
});
/*
* Data providers for parameterized tests
*/
const testCases = [
{ input: 'case1', expected: 'result1' },
{ input: 'case2', expected: 'result2' },
{ input: 'case3', expected: 'result3' },
];
it.skip('processes multiple cases correctly', () => {
testCases.forEach(({ input, expected }) => {
expect({{module}}.process(input)).toBe(expected);
});
});