| 1 | # `crates/tui/tests/` |
| 2 | |
| 3 | Integration tests for the TUI binary. Per `CONTRIBUTING.md`, each crate's |
| 4 | integration tests live in its own `tests/` directory; the repository-root |
| 5 | `tests/` directory is unused. |
| 6 | |
| 7 | ## Mock LLM client (`integration_mock_llm.rs`) |
| 8 | |
| 9 | `crates/tui/src/llm_client/mock.rs` provides a `MockLlmClient` that implements |
| 10 | the `LlmClient` trait by replaying queue-driven canned responses and capturing |
| 11 | every outgoing `MessageRequest`. Tests mock at the **trait boundary** — never |
| 12 | at the `reqwest` HTTP layer — because the trait is the durable abstraction the |
| 13 | runtime is meant to depend on. |
| 14 | |
| 15 | Coverage today exercises the trait surface end-to-end: |
| 16 | |
| 17 | - streaming turn loop |
| 18 | - reasoning-content replay across tool-call rounds (V4 §5.1.1, the bug that |
| 19 | broke v0.4.9-v0.5.1) |
| 20 | - tool-call round-trip with chunked input JSON |
| 21 | - multi-tool-call ordering inside a single turn |
| 22 | - compaction-style non-streaming `create_message` |
| 23 | - sub-agent style independent parent/child mocks |
| 24 | - capacity-gate observation of a captured request before stream drain |
| 25 | |
| 26 | Full-engine mock coverage remains blocked until `core::engine::Engine` is |
| 27 | refactored to take `Arc<dyn LlmClient>` instead of a concrete |
| 28 | `Option<DeepSeekClient>`. The obsolete ignored `engine_full_*` placeholders were |
| 29 | removed; add real end-to-end tests once that constructor seam exists. |
| 30 | |
| 31 | ## `--record` mode for `deepseek eval` |
| 32 | |
| 33 | The offline `deepseek eval` harness now accepts `--record <DIR>`. When set, |
| 34 | each tool step appends one JSON Lines record to `<DIR>/<scenario>.jsonl` |
| 35 | (default scenario: `offline-tool-loop.jsonl`). Each line is a self-contained |
| 36 | JSON object with the schema: |
| 37 | |
| 38 | ```json |
| 39 | { "request": { "step": "list_dir", "kind": "List" }, |
| 40 | "response_events": [ { "type": "ok", "output": "…" } ] } |
| 41 | ``` |
| 42 | |
| 43 | The mock LLM client (`crate::llm_client::mock`) replays these fixtures by |
| 44 | mapping each `response_events` array onto a canned `Vec<StreamEvent>`. Drop |
| 45 | generated fixtures into `crates/tui/tests/fixtures/` so they ride the repo and |
| 46 | feed the mock in CI. |
| 47 | |
| 48 | Quick example: |
| 49 | |
| 50 | ```bash |
| 51 | cargo run --bin codewhale -- eval --record crates/tui/tests/fixtures |
| 52 | cat crates/tui/tests/fixtures/offline-tool-loop.jsonl | jq . |
| 53 | ``` |
| 54 | |
| 55 | The scenario name is sanitized to `[A-Za-z0-9_-]` before forming the filename, |
| 56 | so unusual scenario strings stay portable across platforms. |
| 57 |