Testing Strategy
Relevant source files
The following files were used as context for generating this wiki page:
- vitest.config.ts
- src/app/script/bb/base/tests/base.test.ts
- src/app/script/bb/base/tests/canvas.test.ts
- src/app/script/app/services/tests/service-container.test.ts
- src/app/script/klecks/filters/tests/noise.test.ts
- src/app/script/klecks/image-operations/tests/flood-fill-async.test.ts
- src/app/script/klecks/brushes/tests/brush.interface.test.ts
- src/app/script/klecks/storage/tests/project-store.test.ts
The testing strategy for Rocreate is centered around a robust unit testing framework and a modular architectural approach that emphasizes testability. The project utilizes Vitest as its primary testing runner and assertion library, focusing on validating core utilities, graphics processing logic, and service-oriented architecture. Manual testing via a development server remains a primary verification method for complex UI interactions, but automated coverage is extensive for logic-heavy modules.
Sources: vitest.config.ts, CLAUDE.md:65
Test Infrastructure and Tooling
The project is configured for modern TypeScript testing using Bun and Vitest. The configuration supports both standard logic testing and DOM-dependent testing through specialized environments.
Core Testing Tools
| Tool | Purpose |
|---|---|
| Vitest | Main test runner and assertion framework. |
| JSDOM | Simulated browser environment for DOM and Canvas API testing. |
| vi (Vitest Mock) | Used extensively for mocking Canvas contexts, Workers, and Services. |
| Bun | Runtime for executing test scripts and builds. |
Sources: vitest.config.ts:1-10, package.json:110, CLAUDE.md:12
Testing Environment Workflow
The following diagram illustrates how tests are executed and how external dependencies (like Canvas or Web Workers) are handled during the testing phase.
The diagram shows the separation between pure logic validation and browser-specific simulations using JSDOM and manual mocks.
Sources: vitest.config.ts, src/app/script/klecks/image-operations/tests/flood-fill-async.test.ts:7-10
Testing Categories
1. Base Utility and Math Testing
Rocreate relies on a "Bitbof Base" (bb) library for fundamental operations. Testing in this area focuses on pure functions, geometric calculations, and DOM manipulation helpers.
- Logic Coverage: Functions like
gcd,reduce,fitInto, andcenterWithinare tested for mathematical accuracy and edge cases. - DOM Helpers: Utilities like
insertAfter,css, andsetAttributesare validated within the JSDOM environment. - Safety Guards: Custom error throwers like
throwIfNullandthrowIfUndefinedensure runtime safety.
Sources: src/app/script/bb/base/tests/base.test.ts:20-150
2. Graphics and Canvas Testing
Since the application is graphics-intensive, testing includes specialized canvas utilities and image operation logic.
- Canvas Context Mocks: Tests for filters (e.g.,
filterNoise) and canvas operations mock theCanvasRenderingContext2Dto verify that specific drawing methods likesave,restore, anddrawImageare called with correct parameters. - Image Operations: Logic such as
floodFillBitsis tested for algorithmic correctness, including tolerance matching, contiguous vs. non-contiguous fill, and boundary calculations. - Asynchronous Fallbacks: The testing strategy includes verifying that multi-threaded operations (Web Workers) gracefully fall back to synchronous execution when the environment does not support Workers.
Sources: src/app/script/klecks/filters/tests/noise.test.ts:40-70, src/app/script/klecks/image-operations/tests/flood-fill.test.ts:30-100, src/app/script/klecks/image-operations/tests/flood-fill-async.test.ts:60-80
3. Service and Architecture Testing
The project uses a Service Container to manage dependencies. Tests ensure that the application state is managed through distinct, decoupled services.
- Mock Implementation: Services like
IBrushService,ILayerService, andIHistoryServiceare mocked to test theServiceContainerwithout requiring a full application boot. - Interface Validation: Explicit tests verify that objects implement required interfaces (e.g.,
hasBrushSpacing,hasBrushPressure) using type guards.
This sequence shows the standard pattern for testing service interactions within the Rocreate architecture.
Sources: src/app/script/app/services/tests/service-container.test.ts:10-100, src/app/script/klecks/brushes/tests/brush.interface.test.ts:15-50
4. Persistence and Storage Testing
Testing for ProjectStore and KL_INDEXED_DB ensures that user data is saved and recovered reliably.
- Concurrency: Verification that image data (layers and thumbnails) is written in parallel using
Promise.allto optimize performance. - Integrity: Tests ensure that new image data is stored before old data is removed to prevent data loss during overwrites.
- Error Recovery: Simulations of database failures to ensure the application correctly marks storage as unavailable and handles the error gracefully.
Sources: src/app/script/klecks/storage/tests/project-store.test.ts:100-150, src/app/script/klecks/storage/tests/project-store.test.ts:250-270
Technical Patterns in Tests
Common Mocking Patterns
Tests frequently use vi.mock to isolate the unit under test from complex UI or global browser dependencies.
// Example of mocking UI components to test a filter
vi.mock('../../ui/components/kl-slider', () => ({ KlSlider: vi.fn() }));
vi.mock('../../../fx-canvas/shared-fx', () => ({
getSharedFx: vi.fn().mockReturnValue({
noise: vi.fn().mockReturnThis(),
update: vi.fn().mockReturnThis(),
})
}));
Sources: src/app/script/klecks/filters/tests/noise.test.ts:4-15
Interface Guarding
Rocreate uses runtime type guards to verify brush capabilities, which are rigorously tested to ensure the brush engine behaves predictably.
| Interface Guard | Properties Verified |
|---|---|
hasBrushSpacing | setSpacing, getSpacing |
hasBrushPressure | sizePressure, opacityPressure |
hasBrushLockAlpha | setLockAlpha, getLockAlpha |
hasBrushStrokeContext | setStrokeContext |
Sources: src/app/script/klecks/brushes/tests/brush.interface.test.ts:220-240
Conclusion
The testing strategy for Rocreate combines strict logic validation for utilities and services with simulated browser environments for graphics. By leveraging Vitest's mocking capabilities and JSDOM, the project maintains high confidence in its rendering kernels, storage reliability, and mathematical foundations while allowing for manual verification of the complex, touch-friendly user interface.