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

5.0 KiB

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

{
  "@vitest/ui": "^2.1.0",
  "@vitest/coverage-v8": "^2.1.0",
  "jsdom": "^25.0.0",
  "vitest": "^2.1.0"
}

Installation

npm install

Running Tests

# 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

# Start test watcher
npm run test:watch

# Create test for new feature
touch test/newFeature.test.js

Example test:

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:

// In the appropriate source file
function myNewFunction(input) {
  return 'expected output'  // Minimal implementation
}

3. Refactor Phase - Improve Code

# Ensure tests still pass after refactoring
npm test

Key Testing Patterns

Mocking Browser APIs

// In test/setup.js
global.fetch = vi.fn()
global.Papa = { parse: vi.fn() }

// In tests
mockFetch(sampleData)

DOM Testing

// 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:

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:

npm run test:coverage
open coverage/index.html

Common Test Scenarios

Testing Date Parsing

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

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

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

npm run test:ui

Opens browser interface with:

  • Test results visualization
  • Coverage reports
  • Test file exploration
  • Real-time test watching

Console Debugging

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:

# 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.