test: add 163 tests for tui and ui-core crates#388
Conversation
… and session_state
|
Caution Review failedPull request was closed or merged during review WalkthroughThis pull request introduces comprehensive test infrastructure and test utilities across the Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~35 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
.mcp.json (1)
3-4: Avoid committing machine-specific MCP endpoint configurationLine 4 hardcodes a localhost port, which is likely environment-specific and brittle for other contributors. Consider using a local-only config (gitignored) or environment-variable substitution, and keep a checked-in example file for discoverability.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.mcp.json around lines 3 - 4, The checked-in .mcp.json contains a hardcoded machine-specific URL at the forge_extension.url key; replace this with a non-committed, environment-driven configuration: remove the literal "http://localhost:39263/mcp" from .mcp.json and instead reference an environment placeholder or leave the value empty in the committed file (e.g. a placeholder like {MCP_URL}), add a gitignored local override (e.g. .mcp.local.json) that developers can populate with their localhost URL, and add a checked-in example file (e.g. .mcp.example.json) showing how to set forge_extension.url and documenting the use of an env var (MCP_URL) so runtime code reads process.env.MCP_URL or a config loader that merges .mcp.local.json.crates/tui/src/ui/mod.rs (1)
137-162: Consider extracting common setup logic to reduce duplication.
render_to_stringandrender_to_string_with_configsshare nearly identical setup and teardown code. Extracting the common parts into a shared builder or helper would reduce maintenance burden.♻️ Suggested refactor
+ fn make_test_app(configs: Vec<LaunchConfiguration>, config_names: Vec<String>) -> (tempfile::TempDir, App) { + let dir = tempfile::tempdir().expect("tempdir"); + let state_path = dir.path().join("state.json"); + let state_manager = state::StateManager::new(&state_path).expect("StateManager"); + let (wakeup_tx, _) = crossbeam_channel::unbounded(); + + let mut app = crate::app::App::new( + configs, + config_names, + 0, + std::path::PathBuf::from("/tmp/test"), + std::path::PathBuf::from("/tmp/test"), + state_manager, + wakeup_tx, + vec![], + ); + app.file_browser_loaded = true; + (dir, app) + } + fn render_to_string(width: u16, height: u16, f: impl FnOnce(&mut App)) -> String { - let dir = tempfile::tempdir().expect("tempdir"); - let state_path = dir.path().join("state.json"); - let state_manager = state::StateManager::new(&state_path).expect("StateManager"); - let (wakeup_tx, _) = crossbeam_channel::unbounded(); - - let mut app = crate::app::App::new( - vec![], - vec![], - 0, - std::path::PathBuf::from("/tmp/test"), - std::path::PathBuf::from("/tmp/test"), - state_manager, - wakeup_tx, - vec![], - ); - app.file_browser_loaded = true; - + let (_dir, mut app) = make_test_app(vec![], vec![]); f(&mut app); - let backend = TestBackend::new(width, height); let mut terminal = Terminal::new(backend).unwrap(); terminal.draw(|frame| render(&mut app, frame)).unwrap(); terminal.backend().to_string() }Also applies to: 165-208
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@crates/tui/src/ui/mod.rs` around lines 137 - 162, The two helpers render_to_string and render_to_string_with_configs duplicate tempdir/state setup, wakeup channel creation, App construction (crate::app::App::new and app.file_browser_loaded = true), and TestBackend/Terminal drawing; extract that common setup into a single helper (e.g., build_test_app or TestAppBuilder) that takes width/height and any optional config args and returns the ready-to-use App and a function or TestBackend/Terminal pair for rendering; update render_to_string and render_to_string_with_configs to call this helper and only apply their specific changes (invoke the passed closure f, any extra config handling, and the terminal.draw/render call), keeping references to state::StateManager, TestBackend, Terminal, and wakeup_tx so callers still operate on the same objects.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/ui-core/src/file_cache.rs`:
- Around line 72-75: The test get_or_load_returns_none_for_missing_file
currently uses a hard-coded Path::new("/nonexistent/file.py"); change it to
create a temporary directory (e.g., with tempfile::tempdir()), construct a path
inside that tempdir that you do not create (e.g.,
temp_dir.path().join("nonexistent.py")), and pass that path to
FileCache::get_or_load so the missing-file assertion is portable across
platforms and environments.
---
Nitpick comments:
In @.mcp.json:
- Around line 3-4: The checked-in .mcp.json contains a hardcoded
machine-specific URL at the forge_extension.url key; replace this with a
non-committed, environment-driven configuration: remove the literal
"http://localhost:39263/mcp" from .mcp.json and instead reference an environment
placeholder or leave the value empty in the committed file (e.g. a placeholder
like {MCP_URL}), add a gitignored local override (e.g. .mcp.local.json) that
developers can populate with their localhost URL, and add a checked-in example
file (e.g. .mcp.example.json) showing how to set forge_extension.url and
documenting the use of an env var (MCP_URL) so runtime code reads
process.env.MCP_URL or a config loader that merges .mcp.local.json.
In `@crates/tui/src/ui/mod.rs`:
- Around line 137-162: The two helpers render_to_string and
render_to_string_with_configs duplicate tempdir/state setup, wakeup channel
creation, App construction (crate::app::App::new and app.file_browser_loaded =
true), and TestBackend/Terminal drawing; extract that common setup into a single
helper (e.g., build_test_app or TestAppBuilder) that takes width/height and any
optional config args and returns the ready-to-use App and a function or
TestBackend/Terminal pair for rendering; update render_to_string and
render_to_string_with_configs to call this helper and only apply their specific
changes (invoke the passed closure f, any extra config handling, and the
terminal.draw/render call), keeping references to state::StateManager,
TestBackend, Terminal, and wakeup_tx so callers still operate on the same
objects.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 9c487afa-88b0-42db-ab6d-05d5b1ecd15d
⛔ Files ignored due to path filters (11)
Cargo.lockis excluded by!**/*.lockcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__breakpoints_in_running_mode.snapis excluded by!**/*.snapcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__help_overlay.snapis excluded by!**/*.snapcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__no_session_empty.snapis excluded by!**/*.snapcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__no_session_with_configs.snapis excluded by!**/*.snapcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__no_session_with_file.snapis excluded by!**/*.snapcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__output_tab_with_lines.snapis excluded by!**/*.snapcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__repl_tab.snapis excluded by!**/*.snapcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__running_mode.snapis excluded by!**/*.snapcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__status_bar_with_error.snapis excluded by!**/*.snapcrates/tui/src/ui/snapshots/tui__ui__snapshot_tests__terminated_mode.snapis excluded by!**/*.snap
📒 Files selected for processing (14)
.config/wt.toml.new.mcp.jsoncrates/tui/Cargo.tomlcrates/tui/src/app.rscrates/tui/src/input.rscrates/tui/src/session.rscrates/tui/src/syntax.rscrates/tui/src/ui/mod.rscrates/ui-core/Cargo.tomlcrates/ui-core/src/async_bridge.rscrates/ui-core/src/code_view.rscrates/ui-core/src/file_cache.rscrates/ui-core/src/file_picker.rscrates/ui-core/src/session_state.rs
| fn get_or_load_returns_none_for_missing_file() { | ||
| let mut cache = FileCache::default(); | ||
| let result = cache.get_or_load(Path::new("/nonexistent/file.py")); | ||
| assert_eq!(result, None); |
There was a problem hiding this comment.
Use a tempdir-based missing path to keep this test portable.
Line 74 hard-codes /nonexistent/file.py; using a guaranteed-missing path inside a temp directory is more robust across environments.
💡 Suggested tweak
#[test]
fn get_or_load_returns_none_for_missing_file() {
let mut cache = FileCache::default();
- let result = cache.get_or_load(Path::new("/nonexistent/file.py"));
+ let dir = tempfile::tempdir().unwrap();
+ let missing = dir.path().join("missing.py");
+ let result = cache.get_or_load(&missing);
assert_eq!(result, None);
}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@crates/ui-core/src/file_cache.rs` around lines 72 - 75, The test
get_or_load_returns_none_for_missing_file currently uses a hard-coded
Path::new("/nonexistent/file.py"); change it to create a temporary directory
(e.g., with tempfile::tempdir()), construct a path inside that tempdir that you
do not create (e.g., temp_dir.path().join("nonexistent.py")), and pass that path
to FileCache::get_or_load so the missing-file assertion is portable across
platforms and environments.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@crates/debugger/tests/debugger.rs`:
- Line 151: The test sets breakpoint_line to a non-executable line (10, the "def
foo()" declaration) which won't hit in attach mode; change the breakpoint_line
constant in the test (breakpoint_line) from 10 to 11 so the breakpoint targets
the first executable statement inside foo (the print("Foo") line) to ensure the
debugger receives Paused instead of Ended.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 0a7eb41f-939d-443f-b1c7-2de69af68807
📒 Files selected for processing (2)
attach.pycrates/debugger/tests/debugger.rs
Phase 2 & 3 of the TUI testing plan: - Add test infrastructure: with_test_app(closure) helper that manages TempDir lifetime, with_test_app_configs for config cycling tests, write_temp_file for disk-backed test fixtures - Add 22 app state tests: Focus cycling, open_file (load/reset/nonexistent), file content caching, breakpoint toggle/add/remove, REPL history navigation, start session error, evaluate popup, word under cursor - Add 36 input handling tests: global keys (q, Ctrl+C, ?, Esc), focus cycling (Tab/BackTab/Shift+Tab), bottom tabs (Alt+1/2/3), Ctrl+P/F, config cycling with wrap, code view navigation (j/k/g/G/Ctrl+D/U), breakpoint toggle (b), visual selection (v), search mode, file picker mode, breakpoint input mode, breakpoint panel, REPL focus, output focus, evaluate popup, inline eval clear, F5 no-session
Phase 4: Tests for SyntaxHighlighter covering: - highlight_lines: no syntax (unstyled), Python (styled spans), range slicing, empty content, range clamping beyond content - Checkpoint caching: set_file clears checkpoints, re-highlighting reuses cached checkpoints - build_lines: gutter line numbers, cursor line background, breakpoint marker, execution line marker with background, visual selection background, inline evaluation annotations (green for values, red for errors), search match highlighting with span splitting, start_line offset for gutter numbering
Phase 5: Snapshot tests using ratatui TestBackend + insta. Snapshots cover all major UI states: - no_session_empty: File browser with no files, no file open - no_session_with_configs: Config selector (h/l cycling) visible - no_session_with_file: Code view with Python file loaded - running_mode: Running state with call stack/breakpoints sidebar - terminated_mode: Terminated state with restart controls - help_overlay: Help popup over the normal UI - status_bar_with_error: Error message displayed in status bar - output_tab_with_lines: Output panel with stdout/stderr/console - repl_tab: REPL tab with history and input - breakpoints_in_running_mode: Breakpoints panel with entries Test infrastructure: - render_to_string() and render_to_string_with_configs() helpers create deterministic App instances with file_browser_loaded=true to prevent reading real git files - Uses write_temp_file() from app::test_helpers for file content - All snapshots are deterministic across machines
Phase 7 & 8: Integration tests for drain_debugger_events and breakpoint persistence. Infrastructure: - Add AsyncBridge::dummy() test constructor to ui-core (behind testing feature flag) for creating mock bridges without a real debugger connection - Add Session::new_for_test() constructor for creating test sessions - Add mock_session() and make_program_state() test helpers - Add 'testing' feature to ui-core crate Event draining tests (11): - Paused event: sets mode, updates breakpoints, clears caches, jumps cursor to execution line - Running event: sets mode, clears inline evaluations - Ended event: sets Terminated mode - Initialised event: sets Running mode - Output events: appends to output_lines - Thread started/exited: adds/removes from threads list - Error event: sets status_error - ScopeChange event: clears variable cache, jumps cursor - No session: drain is a no-op - Multiple events: processes all in sequence Breakpoint persistence tests (2): - persist_and_restore_breakpoints: round-trip through StateManager - collect_all_breakpoints_merges_ui_and_persisted: verifies merge of UI breakpoints with previously persisted ones
…n test_remote_attach
The test_remote_attach test was failing in CI with 'Connection refused'
(os error 111) because it used a fixed 1-second sleep to wait for the
Python debugpy process to start listening. On slower CI runners, this
was insufficient.
Fix:
- Add a readiness marker ('DAP server listening') to attach.py that is
printed to stderr immediately after debugpy.listen() succeeds
- Replace the naive sleep in the test with a stderr reader thread that
waits for this marker, matching the pattern used by the server crate's
wait_for_ready() function
- Update breakpoint line number (9 -> 10) to account for the added
import line in attach.py
Two fixes for CI failures:
1. Update breakpoint_line from 10 to 11 in test_remote_attach to match
the actual line of print("Foo") in attach.py after ruff-format
added blank lines between top-level definitions.
2. Bump tempfile minimum version from "3" to "3.23.0" in ui-core and
tui dev-dependencies to match the debugger crate's requirement,
fixing the minimal-versions CI job which was failing because
tempfile 3.0.2 conflicts with tempfile 3.23.0.
f84a5e0 to
b09a7e2
Compare
## 🤖 New release * `dap-gui-async-transport`: 0.1.0 * `dap-gui-types`: 0.1.0 * `dap-gui-launch-configuration`: 0.1.0 * `dap-gui-server`: 0.1.0 * `dap-gui-debugger`: 0.1.0 * `dap-gui-fuzzy`: 0.1.0 * `dap-gui-state`: 0.1.0 * `dap-gui-ui-core`: 0.1.0 * `dap-gui-egui`: 0.1.0 * `dap-gui-pcaplog`: 0.1.0 * `dap-tui`: 0.1.0 <details><summary><i><b>Changelog</b></i></summary><p> ## `dap-gui-async-transport` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-async-transport-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Move bytes to workspace dependency to fix minimal-versions CI - Rename transport2 crate to async-transport </blockquote> ## `dap-gui-types` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-types-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Add documentation to dap-types crate from DAP specification - Replace hand-written DAP types in transport with auto-generated dap-types - fmt - Add dap-types crate </blockquote> ## `dap-gui-launch-configuration` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-launch-configuration-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Merge file browser into main app's no-session view - Add GUI launch controls: start, stop, and restart debug sessions - Remove transport crate, sync debugger, and repl crate - Fix cargo fmt formatting across 7 files - Robustness improvements for startup procedure - Add more tests - Add 30-second timeout for DAP request responses ([#355](#355)) - Create crates/ subdir </blockquote> ## `dap-gui-server` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-server-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Remove transport crate, sync debugger, and repl crate - Fix cargo fmt formatting across 7 files - Robustness improvements for startup procedure - Add 30-second timeout for DAP request responses ([#355](#355)) - Use mise and fix test issues - Create crates/ subdir </blockquote> ## `dap-gui-debugger` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-debugger-v0.1.0) - 2026-04-05 ### Added - add Event::Error variant to surface background task failures ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) - start DAP sequence numbers at 1 instead of 0 - replace panic with error propagation in stopped event handler ### Other - add version fields to path dependencies for release-plz compatibility - add 163 tests for tui and ui-core crates ([#388](#388)) - scaffold TUI crate with ratatui (Phase 1) - surface Output and Thread events from DAP - add missing unit tests for error paths and scope changes - move command-name mapping into RequestBody and simplify argument serialisation - extract send_and_expect_success helper to eliminate boilerplate - gate testing module behind cfg to exclude from release builds - Deduplicate DAP session initialization with SessionArgs/StartMode enums - Add file:line breakpoint input for remote attach workflows ([#386](#386)) - Rename transport2 crate to async-transport - Remove transport crate, sync debugger, and repl crate - Replace hand-written DAP types in transport with auto-generated dap-types - Move tokio to workspace dependency to fix minimal-versions CI - Add 5 GUI improvements: breakpoints, variable tree, syntax highlighting, async migration, error handling - Fix cargo fmt formatting across 7 files - Robustness improvements for startup procedure - Add more tests - Fix minimal versions - Error handling for bad responses - Shortly hold lock - Try to get implementation working - Integrate launch configuration and staged debugger initialization - Fix clippy lints - Complete debugger transport integration phases ([#383](#383)) - Clean out old POC crates - Add testing infrastructure for async debugger (Phase 5) ([#382](#382)) - Implement transport2 integration phases 1 and 2 ([#381](#381)) - Add integration plan for debugger + transport2 ([#380](#380)) - Fix try_poll_message to handle partial reads across timeouts ([#378](#378)) - Add infrastructure for non-blocking request handling ([#375](#375)) - Add refactoring plan for message receiving architecture ([#374](#374)) - Switch debugger to use TransportConnection instead of Client ([#372](#372)) - Migrate to latest iced version ([#373](#373)) - Refactor debugger background thread to use command pattern ([#371](#371)) - Add Command infrastructure for background thread communication ([#370](#370)) - Add non-blocking event processing foundation ([#367](#367)) - Fix stack frame handling panics in Stopped event ([#362](#362)) - Fix home directory panic in path normalization ([#364](#364)) - Fix runaway background thread termination ([#361](#361)) - Fix race condition in test_remote_attach event handling ([#365](#365)) - Fix poisoned mutex panic in with_internals ([#363](#363)) - Fix panic in Drop implementation ([#360](#360)) - Add 30-second timeout for DAP request responses ([#355](#355)) - Ensure launch program exists - Use mise and fix test issues - Create crates/ subdir </blockquote> ## `dap-gui-fuzzy` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-fuzzy-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Extract fuzzy crate and add file picker to egui GUI </blockquote> ## `dap-gui-state` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-state-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - add version fields to path dependencies for release-plz compatibility - no-session polish and robustness (Phase 5) - Add Lilex font for code view with Cmd+/- font size shortcuts - fmt - Persist breakpoints to disk when modified via gutter clicks - Add more tests - Create crates/ subdir </blockquote> ## `dap-gui-ui-core` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-ui-core-v0.1.0) - 2026-04-05 ### Added - make config_path optional, defaulting to .vscode/launch.json - add user-facing documentation to CLI argument parser ([#390](#390)) ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - add version fields to path dependencies for release-plz compatibility - add 163 tests for tui and ui-core crates ([#388](#388)) - extract shared ui-core crate from gui and tui ([#387](#387)) </blockquote> ## `dap-gui-egui` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-egui-v0.1.0) - 2026-04-05 ### Added - add Event::Error variant to surface background task failures ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - add version fields to path dependencies for release-plz compatibility - extract shared ui-core crate from gui and tui ([#387](#387)) - surface Output and Thread events from DAP - Deduplicate DAP session initialization with SessionArgs/StartMode enums - Add always-visible text search to no-session code viewer - Merge file browser into main app's no-session view - Add Cmd+F / Ctrl+F text search in code view - Add GUI launch controls: start, stop, and restart debug sessions - Add Lilex font for code view with Cmd+/- font size shortcuts - Add file-picker startup mode when no breakpoints provided - Add file:line breakpoint input for remote attach workflows ([#386](#386)) - Rename transport2 crate to async-transport - Remove transport crate, sync debugger, and repl crate - Persist breakpoints to disk when modified via gutter clicks - fmt - Move tokio to workspace dependency to fix minimal-versions CI - Fix breakpoint rendering - Canonicalize all paths early to fix breakpoint gutter display - Make code window fill full width of the code panel - Fix breakpoint toggle: persist UI breakpoints across frames and match by path+line - Fix code panel scroll stability: use viewport height and only scroll when needed - Fix debug server lifetime: keep server handle alive for app duration - Move CentralPanel into renderer and add status messages for empty states - Add 5 GUI improvements: breakpoints, variable tree, syntax highlighting, async migration, error handling - Fix cargo fmt formatting across 7 files - Extract fuzzy crate and add file picker to egui GUI - Robustness improvements for startup procedure - Fix variable parsing - Update controls - Migrate to latest iced version ([#373](#373)) - Bump versions - Formatting - Create crates/ subdir </blockquote> ## `dap-gui-pcaplog` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-pcaplog-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - add version fields to path dependencies for release-plz compatibility - Move bytes to workspace dependency to fix minimal-versions CI - Rename transport2 crate to async-transport - Remove transport crate, sync debugger, and repl crate - Use mise and fix test issues - Create crates/ subdir </blockquote> ## `dap-tui` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-tui-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - rename main crate to dap-tui again - add version fields to path dependencies for release-plz compatibility - set up release pipeline with release-plz and GitHub Actions ([#389](#389)) - add zen mode to maximize code view - add 163 tests for tui and ui-core crates ([#388](#388)) - extract shared ui-core crate from gui and tui ([#387](#387)) - add inline evaluation annotations in code view (Phase C) - add visual line selection in code view (Phase B) - add Ctrl+E evaluate expression popup (Phase A) - remove modal REPL input, type directly when focused - no-session polish and robustness (Phase 5) - interactive breakpoints, REPL, and variable tree (Phase 4) - connect to debugger and hit breakpoints (Phase 3) - file browsing with syntax highlighting (Phase 2) - scaffold TUI crate with ratatui (Phase 1) - Clean out old POC crates - Create crates/ subdir </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
## 🤖 New release * `dap-gui-async-transport`: 0.1.0 * `dap-gui-config`: 0.1.0 * `dap-gui-types`: 0.1.0 * `dap-gui-launch-configuration`: 0.1.0 * `dap-gui-server`: 0.1.0 * `dap-gui-debugger`: 0.1.0 * `dap-gui-fuzzy`: 0.1.0 * `dap-gui-state`: 0.1.0 * `dap-gui-ui-core`: 0.1.0 * `dap-gui-egui`: 0.1.0 * `dap-gui-pcaplog`: 0.1.0 * `dap-tui`: 0.1.0 <details><summary><i><b>Changelog</b></i></summary><p> ## `dap-gui-async-transport` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-async-transport-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Move bytes to workspace dependency to fix minimal-versions CI - Rename transport2 crate to async-transport </blockquote> ## `dap-gui-config` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-config-v0.1.0) - 2026-04-06 ### Added - add configurable keybindings with TOML config file ([#393](#393)) </blockquote> ## `dap-gui-types` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-types-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Add documentation to dap-types crate from DAP specification - Replace hand-written DAP types in transport with auto-generated dap-types - fmt - Add dap-types crate </blockquote> ## `dap-gui-launch-configuration` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-launch-configuration-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Merge file browser into main app's no-session view - Add GUI launch controls: start, stop, and restart debug sessions - Remove transport crate, sync debugger, and repl crate - Fix cargo fmt formatting across 7 files - Robustness improvements for startup procedure - Add more tests - Add 30-second timeout for DAP request responses ([#355](#355)) - Create crates/ subdir </blockquote> ## `dap-gui-server` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-server-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Remove transport crate, sync debugger, and repl crate - Fix cargo fmt formatting across 7 files - Robustness improvements for startup procedure - Add 30-second timeout for DAP request responses ([#355](#355)) - Use mise and fix test issues - Create crates/ subdir </blockquote> ## `dap-gui-debugger` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-debugger-v0.1.0) - 2026-04-05 ### Added - add Event::Error variant to surface background task failures ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) - start DAP sequence numbers at 1 instead of 0 - replace panic with error propagation in stopped event handler ### Other - add version fields to path dependencies for release-plz compatibility - add 163 tests for tui and ui-core crates ([#388](#388)) - scaffold TUI crate with ratatui (Phase 1) - surface Output and Thread events from DAP - add missing unit tests for error paths and scope changes - move command-name mapping into RequestBody and simplify argument serialisation - extract send_and_expect_success helper to eliminate boilerplate - gate testing module behind cfg to exclude from release builds - Deduplicate DAP session initialization with SessionArgs/StartMode enums - Add file:line breakpoint input for remote attach workflows ([#386](#386)) - Rename transport2 crate to async-transport - Remove transport crate, sync debugger, and repl crate - Replace hand-written DAP types in transport with auto-generated dap-types - Move tokio to workspace dependency to fix minimal-versions CI - Add 5 GUI improvements: breakpoints, variable tree, syntax highlighting, async migration, error handling - Fix cargo fmt formatting across 7 files - Robustness improvements for startup procedure - Add more tests - Fix minimal versions - Error handling for bad responses - Shortly hold lock - Try to get implementation working - Integrate launch configuration and staged debugger initialization - Fix clippy lints - Complete debugger transport integration phases ([#383](#383)) - Clean out old POC crates - Add testing infrastructure for async debugger (Phase 5) ([#382](#382)) - Implement transport2 integration phases 1 and 2 ([#381](#381)) - Add integration plan for debugger + transport2 ([#380](#380)) - Fix try_poll_message to handle partial reads across timeouts ([#378](#378)) - Add infrastructure for non-blocking request handling ([#375](#375)) - Add refactoring plan for message receiving architecture ([#374](#374)) - Switch debugger to use TransportConnection instead of Client ([#372](#372)) - Migrate to latest iced version ([#373](#373)) - Refactor debugger background thread to use command pattern ([#371](#371)) - Add Command infrastructure for background thread communication ([#370](#370)) - Add non-blocking event processing foundation ([#367](#367)) - Fix stack frame handling panics in Stopped event ([#362](#362)) - Fix home directory panic in path normalization ([#364](#364)) - Fix runaway background thread termination ([#361](#361)) - Fix race condition in test_remote_attach event handling ([#365](#365)) - Fix poisoned mutex panic in with_internals ([#363](#363)) - Fix panic in Drop implementation ([#360](#360)) - Add 30-second timeout for DAP request responses ([#355](#355)) - Ensure launch program exists - Use mise and fix test issues - Create crates/ subdir </blockquote> ## `dap-gui-fuzzy` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-fuzzy-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - Extract fuzzy crate and add file picker to egui GUI </blockquote> ## `dap-gui-state` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-state-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - add version fields to path dependencies for release-plz compatibility - no-session polish and robustness (Phase 5) - Add Lilex font for code view with Cmd+/- font size shortcuts - fmt - Persist breakpoints to disk when modified via gutter clicks - Add more tests - Create crates/ subdir </blockquote> ## `dap-gui-ui-core` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-ui-core-v0.1.0) - 2026-04-05 ### Added - make config_path optional, defaulting to .vscode/launch.json - add user-facing documentation to CLI argument parser ([#390](#390)) ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - add version fields to path dependencies for release-plz compatibility - add 163 tests for tui and ui-core crates ([#388](#388)) - extract shared ui-core crate from gui and tui ([#387](#387)) </blockquote> ## `dap-gui-egui` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-egui-v0.1.0) - 2026-04-05 ### Added - add Event::Error variant to surface background task failures ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - add version fields to path dependencies for release-plz compatibility - extract shared ui-core crate from gui and tui ([#387](#387)) - surface Output and Thread events from DAP - Deduplicate DAP session initialization with SessionArgs/StartMode enums - Add always-visible text search to no-session code viewer - Merge file browser into main app's no-session view - Add Cmd+F / Ctrl+F text search in code view - Add GUI launch controls: start, stop, and restart debug sessions - Add Lilex font for code view with Cmd+/- font size shortcuts - Add file-picker startup mode when no breakpoints provided - Add file:line breakpoint input for remote attach workflows ([#386](#386)) - Rename transport2 crate to async-transport - Remove transport crate, sync debugger, and repl crate - Persist breakpoints to disk when modified via gutter clicks - fmt - Move tokio to workspace dependency to fix minimal-versions CI - Fix breakpoint rendering - Canonicalize all paths early to fix breakpoint gutter display - Make code window fill full width of the code panel - Fix breakpoint toggle: persist UI breakpoints across frames and match by path+line - Fix code panel scroll stability: use viewport height and only scroll when needed - Fix debug server lifetime: keep server handle alive for app duration - Move CentralPanel into renderer and add status messages for empty states - Add 5 GUI improvements: breakpoints, variable tree, syntax highlighting, async migration, error handling - Fix cargo fmt formatting across 7 files - Extract fuzzy crate and add file picker to egui GUI - Robustness improvements for startup procedure - Fix variable parsing - Update controls - Migrate to latest iced version ([#373](#373)) - Bump versions - Formatting - Create crates/ subdir </blockquote> ## `dap-gui-pcaplog` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-gui-pcaplog-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - add version fields to path dependencies for release-plz compatibility - Move bytes to workspace dependency to fix minimal-versions CI - Rename transport2 crate to async-transport - Remove transport crate, sync debugger, and repl crate - Use mise and fix test issues - Create crates/ subdir </blockquote> ## `dap-tui` <blockquote> ## [0.1.0](https://github.com/simonrw/dap-gui/releases/tag/dap-tui-v0.1.0) - 2026-04-05 ### Fixed - rename workspace crates with dap-gui- prefix for cargo package compatibility ([#391](#391)) ### Other - rename main crate to dap-tui again - add version fields to path dependencies for release-plz compatibility - set up release pipeline with release-plz and GitHub Actions ([#389](#389)) - add zen mode to maximize code view - add 163 tests for tui and ui-core crates ([#388](#388)) - extract shared ui-core crate from gui and tui ([#387](#387)) - add inline evaluation annotations in code view (Phase C) - add visual line selection in code view (Phase B) - add Ctrl+E evaluate expression popup (Phase A) - remove modal REPL input, type directly when focused - no-session polish and robustness (Phase 5) - interactive breakpoints, REPL, and variable tree (Phase 4) - connect to debugger and hit breakpoints (Phase 3) - file browsing with syntax highlighting (Phase 2) - scaffold TUI crate with ratatui (Phase 1) - Clean out old POC crates - Create crates/ subdir </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
Add comprehensive test coverage for the
tuiandui-corecrates, going from zero tests to 163 tests covering state logic, input handling, syntax highlighting, UI rendering snapshots, event draining, and breakpoint persistence.Context
The TUI crate had no tests at all, making it risky to refactor or extend. The crate has a clean layered architecture (state, input, rendering, session) that lends itself well to unit testing. This PR implements the full testing plan across all layers.
Changes
Test infrastructure
with_test_app(closure)/with_test_app_configs()helpers that manageTempDirlifetime automaticallymock_session()andmake_program_state()helpers for creating test sessions with dummyAsyncBridgeAsyncBridge::dummy()test constructor inui-core(behindtestingfeature flag) for mock bridges without a real debuggerSession::new_for_test()constructor for bypassing the real DAP connectionrender_to_string()helper using ratatuiTestBackendfor deterministic UI snapshotsTest coverage by layer
ui-core::code_viewui-core::file_cacheui-core::session_stateui-core::file_pickertui::apptui::inputtui::syntaxtui::ui::snapshot_teststui::app(event draining)tui::app(persistence)UI snapshot tests
Uses
instawith ratatui'sTestBackendfor visual regression testing. Snapshots cover: no-session (empty, with configs, with file), running, terminated, help overlay, error status bar, output tab, REPL tab, and breakpoints panel. All snapshots are deterministic (file browser is pre-loaded to prevent reading real git files).Testing
Summary by CodeRabbit
Release Notes
Tests
Chores