36 lines
1.9 KiB
Markdown
36 lines
1.9 KiB
Markdown
# Prevent Tests from Writing to Real User Data
|
|
|
|
## Context
|
|
|
|
Two tests in `src/app.rs` (`adaptive_auto_continue_arms_input_lock` and `adaptive_does_not_auto_continue_with_milestones`) call `App::new()` which connects to the real `JsonStore` at `~/.local/share/keydr/`. When they call `finish_drill()` → `save_data()`, fake drill results get persisted to the user's actual history file. All other app tests also use `App::new()` but happen to not call `finish_drill()`.
|
|
|
|
## Changes
|
|
|
|
### 1. Add `#[cfg(not(test))]` gate on `App::new()` (`src/app.rs:293`)
|
|
|
|
Mark `App::new()` with `#[cfg(not(test))]` so it cannot be called from test code at all. This is a compile-time guarantee — any future test that tries `App::new()` will fail to compile.
|
|
|
|
### 2. Add `App::new_test()` (`src/app.rs`, in `#[cfg(test)]` block)
|
|
|
|
Add a `pub fn new_test()` constructor inside a `#[cfg(test)] impl App` block that mirrors `App::new()` but sets `store: None`. This prevents any persistence to disk. All existing fields get their default/empty values (no loading from disk either).
|
|
|
|
Since most test fields just need defaults and a started drill, the test constructor can be minimal:
|
|
- `Config::default()`, `Theme::default()` (leaked), `Menu::new()`, `store: None`
|
|
- Default key stats, skill tree, profile, empty drill history
|
|
- `Dictionary::load()`, `TransitionTable`, `KeyboardModel` — same as production (needed for `start_drill()`)
|
|
- Call `start_drill()` at the end (same as `App::new()`)
|
|
|
|
### 3. Update all existing tests to use `App::new_test()`
|
|
|
|
Replace every `App::new()` call in the test module with `App::new_test()`. This covers all 7 tests in `#[cfg(test)] mod tests`.
|
|
|
|
## File to Modify
|
|
|
|
- `src/app.rs` — gate `new()`, add `new_test()`, update test calls
|
|
|
|
## Verification
|
|
|
|
1. `cargo test` — all tests pass
|
|
2. `cargo build` — production build still compiles (ungated `new()` available)
|
|
3. Temporarily add `App::new()` in a test → should fail to compile
|