strategy change to TDD
This commit is contained in:
174
openspec/templates/VitestComponentTest.test.ts
Normal file
174
openspec/templates/VitestComponentTest.test.ts
Normal file
@@ -0,0 +1,174 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/svelte';
|
||||
import {{component}} from './{{component}}.svelte';
|
||||
|
||||
/*
|
||||
* Test Template for Vitest Component Tests
|
||||
*
|
||||
* Copy this file and replace:
|
||||
* - {{component}} with the Svelte component name
|
||||
* - {{capability}} with the capability name
|
||||
*
|
||||
* Mark pending tests with test.skip() during Red Phase
|
||||
* Remove .skip and implement during Green Phase
|
||||
*/
|
||||
|
||||
describe('{{component}}', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
// Reset mocks and state
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
/*
|
||||
* Test: Component renders correctly
|
||||
*/
|
||||
it.skip('renders with default props', () => {
|
||||
const { container } = render({{component}});
|
||||
|
||||
expect(container.querySelector('[data-testid="{{component}}"]')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
/*
|
||||
* Test: Component displays data correctly
|
||||
*/
|
||||
it.skip('displays {{data_type}} data', () => {
|
||||
const mockData = {
|
||||
id: '123',
|
||||
name: 'Test Name',
|
||||
value: 100
|
||||
};
|
||||
|
||||
render({{component}}, { props: { data: mockData } });
|
||||
|
||||
expect(screen.getByText('Test Name')).toBeInTheDocument();
|
||||
expect(screen.getByText('100')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
/*
|
||||
* Test: User interaction
|
||||
*/
|
||||
it.skip('handles {{action}} click', async () => {
|
||||
const mockHandler = vi.fn();
|
||||
|
||||
render({{component}}, {
|
||||
props: {
|
||||
on{{action}}: mockHandler
|
||||
}
|
||||
});
|
||||
|
||||
const button = screen.getByTestId('{{action}}-button');
|
||||
await fireEvent.click(button);
|
||||
|
||||
expect(mockHandler).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
/*
|
||||
* Test: Form submission
|
||||
*/
|
||||
it.skip('submits form with correct data', async () => {
|
||||
const mockSubmit = vi.fn();
|
||||
|
||||
render({{component}}, {
|
||||
props: {
|
||||
onSubmit: mockSubmit
|
||||
}
|
||||
});
|
||||
|
||||
// Fill form
|
||||
await fireEvent.input(screen.getByLabelText('Name'), {
|
||||
target: { value: 'Test Name' }
|
||||
});
|
||||
|
||||
await fireEvent.input(screen.getByLabelText('Email'), {
|
||||
target: { value: 'test@example.com' }
|
||||
});
|
||||
|
||||
// Submit
|
||||
await fireEvent.click(screen.getByText('Submit'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSubmit).toHaveBeenCalledWith({
|
||||
name: 'Test Name',
|
||||
email: 'test@example.com'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* Test: Validation errors
|
||||
*/
|
||||
it.skip('displays validation errors', async () => {
|
||||
render({{component}});
|
||||
|
||||
// Submit empty form
|
||||
await fireEvent.click(screen.getByText('Submit'));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Name is required')).toBeInTheDocument();
|
||||
expect(screen.getByText('Email is required')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
* Test: Loading state
|
||||
*/
|
||||
it.skip('shows loading state', () => {
|
||||
render({{component}}, {
|
||||
props: {
|
||||
loading: true
|
||||
}
|
||||
});
|
||||
|
||||
expect(screen.getByTestId('loading-spinner')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
/*
|
||||
* Test: Empty state
|
||||
*/
|
||||
it.skip('displays empty state when no data', () => {
|
||||
render({{component}}, {
|
||||
props: {
|
||||
data: []
|
||||
}
|
||||
});
|
||||
|
||||
expect(screen.getByText('No data available')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
/*
|
||||
* Test: Error state
|
||||
*/
|
||||
it.skip('displays error message', () => {
|
||||
render({{component}}, {
|
||||
props: {
|
||||
error: 'Failed to load data'
|
||||
}
|
||||
});
|
||||
|
||||
expect(screen.getByText('Failed to load data')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
/*
|
||||
* Test: Accessibility
|
||||
*/
|
||||
it.skip('has accessible attributes', () => {
|
||||
render({{component}});
|
||||
|
||||
const element = screen.getByRole('button');
|
||||
expect(element).toHaveAttribute('aria-label');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
function createMock{{model}}(overrides = {}) {
|
||||
return {
|
||||
id: '123',
|
||||
name: 'Test {{model}}',
|
||||
createdAt: new Date().toISOString(),
|
||||
...overrides
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user