Rewrite all folder-level CLAUDE.md files; update root
net10.0 throughout; corrected EntryKey field name; documented *.Services split. Two new files (DeepDrftWeb.Services, DeepDrftContent.Services). FileDatabase README inaccuracies fixed (ImageVault, project target).
This commit is contained in:
+190
-142
@@ -1,103 +1,125 @@
|
||||
# CLAUDE.md - DeepDrftTests
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with the DeepDrftTests project.
|
||||
Guidance for working in the DeepDrftTests project (the test suite).
|
||||
|
||||
## Project Overview
|
||||
See the root `CLAUDE.md` for full architecture overview. This file covers what is specific to this project.
|
||||
|
||||
DeepDrftTests is a **comprehensive test suite** using **NUnit framework** that validates the FileDatabase system and related components. The tests follow SOLID principles and provide extensive coverage of the custom FileDatabase functionality.
|
||||
## One-line purpose
|
||||
|
||||
## Architecture
|
||||
NUnit test project. Covers the FileDatabase subsystem end-to-end (the only piece of the codebase with non-trivial test coverage). References `DeepDrftContent.Services`.
|
||||
|
||||
### Technology Stack
|
||||
- **NUnit 4.2.2**: Testing framework with modern async support
|
||||
- **NUnit3TestAdapter**: Visual Studio test adapter
|
||||
- **.NET 9.0**: Latest framework features
|
||||
- **Coverlet**: Code coverage collection
|
||||
## Layout
|
||||
|
||||
### Project Structure
|
||||
```
|
||||
DeepDrftTests/
|
||||
├── FileDatabaseTests.cs # Main FileDatabase integration tests
|
||||
├── MediaVaultTests.cs # MediaVault component tests
|
||||
├── MediaVaultFactoryTests.cs # Factory pattern tests
|
||||
├── IndexSystemTests.cs # Index management tests
|
||||
├── SimpleMediaTypeRegistryTests.cs # Media type registry tests
|
||||
├── UtilityTests.cs # Utility class tests
|
||||
├── ModelTests.cs # Model validation tests
|
||||
├── TestData.cs # Shared test data and helpers
|
||||
├── environment/ # Test configuration files
|
||||
│ └── filedatabase.json # FileDatabase test settings
|
||||
└── DeepDrftTests.csproj # Project configuration
|
||||
├── FileDatabaseTests.cs # Main FileDatabase integration tests
|
||||
├── MediaVaultTests.cs # MediaVault component tests
|
||||
├── MediaVaultFactoryTests.cs # Factory pattern tests
|
||||
├── IndexSystemTests.cs # Index management tests
|
||||
├── SimpleMediaTypeRegistryTests.cs # Media type registry tests
|
||||
├── UtilityTests.cs # Utility class tests (StructuralMap, FileUtils, etc.)
|
||||
├── ModelTests.cs # Model validation tests
|
||||
├── TestData.cs # Shared test fixtures and helpers
|
||||
├── environment/
|
||||
│ └── filedatabase.json # Test-config FileDatabase settings
|
||||
└── DeepDrftTests.csproj
|
||||
```
|
||||
|
||||
## Test Organization
|
||||
## Test isolation strategy
|
||||
|
||||
### SOLID Principles Implementation
|
||||
Tests follow SOLID design principles:
|
||||
Each test creates a unique directory under `Path.GetTempPath() + "DeepDrftTests/{Guid}"` in `[SetUp]` and best-effort deletes it in `[TearDown]`.
|
||||
|
||||
- **Single Responsibility**: Each test class focuses on one component
|
||||
- **Open/Closed**: Base test classes allow extension without modification
|
||||
- **Liskov Substitution**: All vault implementations tested consistently
|
||||
- **Interface Segregation**: Tests through abstractions where possible
|
||||
- **Dependency Inversion**: Tests depend on abstractions, not concretions
|
||||
|
||||
### DRY Pattern with Base Classes
|
||||
```csharp
|
||||
// Base class eliminates test setup duplication
|
||||
public abstract class MediaVaultTestBase
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
protected string TestDirectory { get; private set; }
|
||||
|
||||
[SetUp] public virtual void SetUp() { /* Common setup */ }
|
||||
[TearDown] public virtual void TearDown() { /* Common cleanup */ }
|
||||
_testDatabasePath = Path.Combine(
|
||||
Path.GetTempPath(),
|
||||
"DeepDrftTests",
|
||||
Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(_testDatabasePath);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
try { Directory.Delete(_testDatabasePath, recursive: true); }
|
||||
catch { /* Best-effort cleanup — ignore failures */ }
|
||||
}
|
||||
```
|
||||
|
||||
## Key Test Classes
|
||||
**New tests touching the filesystem must follow this pattern.** Do not write into the real `Database/Vaults` path. Do not use `[SetUp]` in base classes without allowing derived classes to override — some tests need custom setup.
|
||||
|
||||
## Core test classes
|
||||
|
||||
### FileDatabaseTests
|
||||
**Core integration tests** for the main FileDatabase functionality:
|
||||
- Database creation and initialization
|
||||
- Vault management (create, retrieve, check existence)
|
||||
- Resource operations (register, load, type safety)
|
||||
- Multi-vault scenarios and error handling
|
||||
|
||||
### MediaVaultTests
|
||||
**Component tests** for individual MediaVault implementations:
|
||||
- Entry storage and retrieval
|
||||
- Media type handling (Audio, Image, Media)
|
||||
- File path sanitization
|
||||
- Index maintenance
|
||||
Integration tests for the main FileDatabase functionality:
|
||||
- Database creation and initialization at a specified path.
|
||||
- Vault management (create, retrieve, check existence).
|
||||
- Resource operations (register, load, type safety, edge cases).
|
||||
- Multi-vault scenarios.
|
||||
- Error handling (e.g., load from non-existent vault returns null).
|
||||
|
||||
These are the load-bearing tests. When FileDatabase semantics change, **these tests anchor the intent**. Update them in the same commit as the code change.
|
||||
|
||||
### MediaVaultTests
|
||||
|
||||
Component tests for individual vault implementations:
|
||||
- Entry storage and retrieval.
|
||||
- Media type handling (Audio, Image).
|
||||
- File path sanitization (regex: `[^a-zA-Z0-9]` → `-`).
|
||||
- Index maintenance (entries added/removed from vault index).
|
||||
|
||||
### IndexSystemTests
|
||||
**Index management** validation:
|
||||
- DirectoryIndex creation and persistence
|
||||
- VaultIndex type management
|
||||
- JSON serialization/deserialization
|
||||
- Index factory service operations
|
||||
|
||||
Index management validation:
|
||||
- DirectoryIndex creation and persistence (JSON round-trip).
|
||||
- VaultIndex type management (MediaVaultType recorded and rehydrated).
|
||||
- IndexFactoryService operations.
|
||||
|
||||
### MediaVaultFactoryTests
|
||||
**Factory pattern** validation:
|
||||
- Vault creation for different MediaVaultTypes
|
||||
- Path handling and directory creation
|
||||
- Type-specific vault instantiation
|
||||
|
||||
## Test Data Management
|
||||
Factory pattern validation:
|
||||
- Vault creation for different `MediaVaultType` values.
|
||||
- Path handling and directory creation.
|
||||
- Type-specific vault instantiation.
|
||||
|
||||
### TestData Class
|
||||
Centralized test data and helper methods:
|
||||
### SimpleMediaTypeRegistryTests
|
||||
|
||||
Media type registry tests:
|
||||
- Extension → MIME type mapping.
|
||||
- Supported formats (wav, mp3, jpg, png, gif, etc.).
|
||||
|
||||
### UtilityTests
|
||||
|
||||
Utility class tests:
|
||||
- `StructuralMap<TKey, TValue>` (JSON-based equality).
|
||||
- `StructuralSet<T>` (set semantics with structural equality).
|
||||
- `FileUtils` (async file I/O, chunked reading/writing).
|
||||
|
||||
### ModelTests
|
||||
|
||||
Model validation:
|
||||
- Binary models can be created and serialized.
|
||||
- DTOs round-trip correctly (serialize → deserialize).
|
||||
- Metadata hierarchy is correct.
|
||||
|
||||
## TestData (shared fixtures)
|
||||
|
||||
Centralised test data and helper methods:
|
||||
|
||||
```csharp
|
||||
public static class TestData
|
||||
{
|
||||
// Real PNG bytes for authentic image testing
|
||||
public static readonly byte[] TestPngBytes = [...];
|
||||
|
||||
// Factory methods for test objects
|
||||
public static ImageBinary CreateTestImageBinary(double aspectRatio = 1.0)
|
||||
public static AudioBinary CreateTestAudioBinary(double duration = 120.0, int bitrate = 320)
|
||||
|
||||
// Consistent test keys
|
||||
// Real PNG byte buffer (16x16) — reused for mock audio testing
|
||||
public static readonly byte[] TestPngBytes = [/* 144 bytes */];
|
||||
|
||||
// Factory methods
|
||||
public static ImageBinary CreateTestImageBinary(double aspectRatio = 1.0);
|
||||
public static AudioBinary CreateTestAudioBinary(double duration = 120.0, int bitrate = 320);
|
||||
|
||||
// Named constants
|
||||
public static class TestKeys
|
||||
{
|
||||
public const string TestImageEntry = "test";
|
||||
@@ -107,111 +129,137 @@ public static class TestData
|
||||
}
|
||||
```
|
||||
|
||||
## Development Commands
|
||||
**Important**: `TestData.CreateTestAudioBinary` deliberately reuses PNG bytes as a mock audio buffer. The FileDatabase does not parse audio content — it stores any bytes with the metadata. Real WAV parsing is exercised by the CLI and content host, not the FileDatabase tests.
|
||||
|
||||
## Run commands
|
||||
|
||||
### Running All Tests
|
||||
```bash
|
||||
# Run entire test suite
|
||||
# Run all tests
|
||||
dotnet test DeepDrftTests/
|
||||
|
||||
# Run with detailed output
|
||||
dotnet test DeepDrftTests/ --verbosity normal
|
||||
|
||||
# Run with code coverage
|
||||
# Run specific test class
|
||||
dotnet test DeepDrftTests/ --filter "ClassName=FileDatabaseTests"
|
||||
|
||||
# Run specific test method
|
||||
dotnet test DeepDrftTests/ --filter "Name=FileDatabase_CanBeCreatedAtSpecifiedLocation"
|
||||
|
||||
# Run with code coverage (if tooling is installed)
|
||||
dotnet test DeepDrftTests/ --collect:"XPlat Code Coverage"
|
||||
```
|
||||
|
||||
### Running Specific Tests
|
||||
```bash
|
||||
# Run FileDatabase tests only
|
||||
dotnet test DeepDrftTests/ --filter "FileDatabaseTests"
|
||||
## Testing patterns
|
||||
|
||||
# Run specific test method
|
||||
dotnet test DeepDrftTests/ --filter "FileDatabase_CanBeCreatedAtSpecifiedLocation"
|
||||
### Async test methods
|
||||
|
||||
# Run tests by category
|
||||
dotnet test DeepDrftTests/ --filter "Category=Integration"
|
||||
```
|
||||
|
||||
### Build and Clean
|
||||
```bash
|
||||
# Build test project
|
||||
dotnet build DeepDrftTests/
|
||||
|
||||
# Clean test outputs
|
||||
dotnet clean DeepDrftTests/
|
||||
```
|
||||
|
||||
## Test Isolation Strategy
|
||||
|
||||
### Temporary Directory Management
|
||||
Each test uses isolated temporary directories:
|
||||
```csharp
|
||||
_testDatabasePath = Path.Combine(Path.GetTempPath(), "DeepDrftTests", Guid.NewGuid().ToString());
|
||||
```
|
||||
|
||||
### Setup and Cleanup Pattern
|
||||
```csharp
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
// Create unique test directory
|
||||
Directory.CreateDirectory(_testDatabasePath);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void TearDown()
|
||||
{
|
||||
// Clean up test directory (with error tolerance)
|
||||
try { Directory.Delete(_testDatabasePath, true); }
|
||||
catch { /* Ignore cleanup errors */ }
|
||||
}
|
||||
```
|
||||
|
||||
## Testing Patterns
|
||||
|
||||
### Async Test Methods
|
||||
All database operations tested with async/await:
|
||||
|
||||
```csharp
|
||||
[Test]
|
||||
public async Task FileDatabase_CanRegisterAndRetrieveAudio()
|
||||
{
|
||||
var fileDatabase = await FileDatabase.FromAsync(_testDatabasePath);
|
||||
// ... async operations
|
||||
var audio = new AudioBinary(/* params */);
|
||||
var registered = await fileDatabase.RegisterResourceAsync("tracks", "test-entry", audio);
|
||||
Assert.That(registered, Is.True);
|
||||
var loaded = await fileDatabase.LoadResourceAsync<AudioBinary>("tracks", "test-entry");
|
||||
Assert.That(loaded, Is.Not.Null);
|
||||
}
|
||||
```
|
||||
|
||||
### Type-Safe Media Testing
|
||||
### Type-safe media testing
|
||||
|
||||
Generic type parameters ensure type safety:
|
||||
|
||||
```csharp
|
||||
var audio = await fileDatabase.LoadResourceAsync<AudioBinary>("tracks", trackId);
|
||||
Assert.That(audio, Is.Not.Null);
|
||||
Assert.That(audio.Duration, Is.EqualTo(120.0));
|
||||
Assert.That(audio.Bitrate, Is.EqualTo(320));
|
||||
```
|
||||
|
||||
### Error Scenario Coverage
|
||||
Tests validate error handling patterns:
|
||||
- Non-existent vaults return null
|
||||
- Invalid entry IDs return null
|
||||
- File system errors are handled gracefully
|
||||
### Error scenario coverage
|
||||
|
||||
## Important Testing Principles
|
||||
Tests validate the error-swallowing contract:
|
||||
|
||||
### Authentic Test Data
|
||||
Uses real PNG bytes instead of mock data for realistic testing scenarios.
|
||||
```csharp
|
||||
// Load from non-existent vault returns null
|
||||
var result = await fileDatabase.LoadResourceAsync<AudioBinary>("non-existent", "entry");
|
||||
Assert.That(result, Is.Null);
|
||||
|
||||
// Register to non-existent vault returns false (after creating it? depends on semantics — check code)
|
||||
```
|
||||
|
||||
## Important testing principles
|
||||
|
||||
### The tests are the load-bearing documentation
|
||||
|
||||
When FileDatabase semantics change, especially:
|
||||
- The swallow-and-return-null contract
|
||||
- Entry-key sanitisation regex
|
||||
- Vault-type round-trip on index
|
||||
- Index-watcher reload
|
||||
|
||||
...the tests are where intent is anchored. Update them in the same commit as the code change.
|
||||
|
||||
### Authentic test data
|
||||
|
||||
Uses real PNG bytes instead of mock data for realistic testing scenarios. The FileDatabase doesn't care about actual audio/image content — it stores opaque buffers. But using real bytes makes the tests less misleading.
|
||||
|
||||
### Comprehensive coverage
|
||||
|
||||
### Comprehensive Coverage
|
||||
Tests cover:
|
||||
- Happy path scenarios
|
||||
- Edge cases and error conditions
|
||||
- Type safety and generics
|
||||
- Async operation patterns
|
||||
- File system interactions
|
||||
- Happy path scenarios (create, register, load, list).
|
||||
- Edge cases (empty vault, non-existent entry, sanitisation edge cases).
|
||||
- Type safety and generics.
|
||||
- Async operation patterns.
|
||||
- File system interactions (directory creation, file I/O, index JSON round-trip).
|
||||
|
||||
### Performance
|
||||
|
||||
### Performance Considerations
|
||||
Tests are designed for speed:
|
||||
- Minimal test data sizes
|
||||
- Parallel test execution support
|
||||
- Efficient cleanup strategies
|
||||
- Minimal test data sizes.
|
||||
- Parallel test execution support (via temp directory isolation).
|
||||
- Efficient cleanup.
|
||||
|
||||
When working with this test project, maintain the established patterns for test isolation, async operations, and comprehensive coverage of the FileDatabase system.
|
||||
## What is NOT tested
|
||||
|
||||
Be honest about coverage gaps:
|
||||
|
||||
- `TrackService` (Web or Content).
|
||||
- `TrackController` (Web or Content).
|
||||
- `TrackClient` / `TrackMediaClient` (HTTP clients).
|
||||
- The audio player services (streaming, seek, interop).
|
||||
- Dark-mode round-trip (cookie → settings → persistent state).
|
||||
- `WavOffsetService` (byte offset → new WAV stream).
|
||||
- `AudioProcessor` (WAV parsing, metadata extraction).
|
||||
|
||||
Any planned work in those areas should consider whether tests need to land alongside. **Testing the FileDatabase thoroughly does not mean testing everything** — it means testing the part that is most likely to break.
|
||||
|
||||
## Development commands
|
||||
|
||||
```bash
|
||||
# Build
|
||||
dotnet build DeepDrftTests/
|
||||
|
||||
# Run all tests
|
||||
dotnet test DeepDrftTests/
|
||||
|
||||
# Run with live output
|
||||
dotnet test DeepDrftTests/ -v normal
|
||||
|
||||
# Run a single test class
|
||||
dotnet test DeepDrftTests/ --filter "ClassName=FileDatabaseTests"
|
||||
|
||||
# Clean test artifacts
|
||||
dotnet clean DeepDrftTests/
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
- `environment/filedatabase.json`: Test-config FileDatabase settings (copied to output at build).
|
||||
- `TestData.cs`: Centralised fixtures and helpers. Use these rather than duplicating test data.
|
||||
|
||||
When working with this project, treat the tests as the load-bearing specification of FileDatabase behaviour. When in doubt, read the tests first — they are clearer than the code.
|
||||
|
||||
Reference in New Issue
Block a user