strategy change to TDD
This commit is contained in:
205
openspec/templates/VitestUnitTest.test.ts
Normal file
205
openspec/templates/VitestUnitTest.test.ts
Normal file
@@ -0,0 +1,205 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user