Files
timeline-svg/TESTING.md
tegwick 2090e372bd add: comprehensive TDD test infrastructure
- Add Vitest + jsdom testing framework
- Create unit tests for engine.js and generator.js
- Add integration tests for end-to-end workflows
- Include test utilities and setup helpers
- Document testing approach in TESTING.md
- Document all dependencies in DEPENDS.md
- Add Makefile with test targets and dev workflow

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-18 23:36:22 +01:00

245 lines
5.0 KiB
Markdown

# Timeline SVG - Test Infrastructure
This document describes the test-driven development (TDD) infrastructure for the Timeline SVG Generator project.
## Test Framework Setup
The project uses **Vitest** with **jsdom** for testing browser-based JavaScript code.
### Dependencies
```json
{
"@vitest/ui": "^2.1.0",
"@vitest/coverage-v8": "^2.1.0",
"jsdom": "^25.0.0",
"vitest": "^2.1.0"
}
```
### Installation
```bash
npm install
```
## Running Tests
```bash
# Run all tests once
npm test
# Run tests in watch mode (for TDD)
npm run test:watch
# Run with coverage report
npm run test:coverage
# Open test UI (browser-based test runner)
npm run test:ui
```
## Test Structure
### Unit Tests
- **`test/engine.test.js`** - Tests for timeline data processing
- CSV parsing and validation
- Date parsing (multiple formats)
- Project configuration loading
- DOM integration
- **`test/generator.test.js`** - Tests for SVG generation
- SVG template processing
- Month grid generation
- Lane and item positioning
- XML escaping
### Integration Tests
- **`test/integration.test.js`** - End-to-end workflow tests
- Complete timeline generation pipeline
- File upload simulation
- DOM event handling
- Export functionality
### Test Utilities
- **`test/setup.js`** - Global test setup and mocks
- **`test/testHelpers.js`** - Common test data and utilities
## TDD Workflow
### 1. Red Phase - Write Failing Test
```bash
# Start test watcher
npm run test:watch
# Create test for new feature
touch test/newFeature.test.js
```
Example test:
```javascript
describe('New Feature', () => {
it('should do something specific', () => {
const result = myNewFunction('input')
expect(result).toBe('expected output')
})
})
```
### 2. Green Phase - Make Test Pass
Implement minimal code to make the test pass:
```javascript
// In the appropriate source file
function myNewFunction(input) {
return 'expected output' // Minimal implementation
}
```
### 3. Refactor Phase - Improve Code
```bash
# Ensure tests still pass after refactoring
npm test
```
## Key Testing Patterns
### Mocking Browser APIs
```javascript
// In test/setup.js
global.fetch = vi.fn()
global.Papa = { parse: vi.fn() }
// In tests
mockFetch(sampleData)
```
### DOM Testing
```javascript
// Setup DOM elements
setupBasicDOM()
// Test DOM manipulation
await timelineEngine.loadProjectConfigObject(config)
expectElementToHaveText('#projectName', 'Test Project')
```
### Testing Vanilla JS Modules
Since the project uses global objects, tests load modules by evaluating the source:
```javascript
const fs = await import('fs/promises')
const engineCode = await fs.readFile('./engine.js', 'utf-8')
eval(engineCode)
const timelineEngine = global.window.timelineEngine
```
## Coverage Goals
- **Statements**: >90%
- **Branches**: >85%
- **Functions**: >90%
- **Lines**: >90%
View detailed coverage:
```bash
npm run test:coverage
open coverage/index.html
```
## Common Test Scenarios
### Testing Date Parsing
```javascript
it('should parse various date formats', () => {
expect(parseDate('2025-12-15')).toEqual(new Date(2025, 11, 15))
expect(parseDate('15.12.2025')).toEqual(new Date(2025, 11, 15))
expect(parseDate('invalid')).toBeNull()
})
```
### Testing SVG Generation
```javascript
it('should generate valid SVG with timeline items', () => {
const result = timelineGenerator.generate(items, config, template)
expect(result).toContain('<svg xmlns="http://www.w3.org/2000/svg">')
expect(result).toContain('Task Title')
})
```
### Testing Error Handling
```javascript
it('should handle missing configuration gracefully', () => {
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
timelineEngine.processCsv('data', null)
expect(consoleSpy).toHaveBeenCalledWith('No config or fieldMapping found.')
})
```
## Debugging Tests
### Using Test UI
```bash
npm run test:ui
```
Opens browser interface with:
- Test results visualization
- Coverage reports
- Test file exploration
- Real-time test watching
### Console Debugging
```javascript
it('should debug test data', () => {
console.log('Debug data:', testData)
// Test continues...
})
```
## Adding New Tests
1. **Create test file** in `test/` directory
2. **Import helpers** from `test/testHelpers.js`
3. **Follow naming convention**: `*.test.js`
4. **Group related tests** with `describe()` blocks
5. **Use descriptive test names** with `it('should ...')`
## CI Integration
Tests can be easily integrated into CI pipelines:
```yaml
# GitHub Actions example
- name: Run tests
run: npm test
- name: Upload coverage
run: npm run test:coverage
```
## Best Practices
1. **Test behavior, not implementation**
2. **Use descriptive test names**
3. **Keep tests focused and small**
4. **Mock external dependencies**
5. **Test both success and error cases**
6. **Maintain test data helpers**
7. **Run tests frequently during development**
This test infrastructure enables confident refactoring and feature development while maintaining code quality and preventing regressions.