Last updated: 2026-03-22
cargo test # Run all tests (284 unit + 2 doc)
cargo test -- --nocapture # Show println! output
cargo test test_window # Run tests matching pattern
cargo test -- --test-threads=1 # Sequential (needed if tests share theme state)
cargo clippy -- -D warnings # Lint check (pedantic enabled)
cargo fmt --check # Format check (dry-run)All tests are co-located with their implementation:
src/module.rs
// ... production code ...
#[cfg(test)]
mod tests {
use super::*;
// tests here
}
No separate tests/ directory. No integration test files. Everything is unit tests inside #[cfg(test)] mod tests.
| Module | Tests | Notes |
|---|---|---|
command.rs |
4 | CommandId, CommandSet bitfield |
view.rs |
16 | ViewId, Event, StateFlags, deferred queue |
container/mod.rs |
20 | Z-order, focus, three-phase dispatch, mouse capture |
frame.rs |
23 | Borders, title, close button, resize handle, hover, scrollbars |
window.rs |
20 | Drag/resize state machine, zoom, minimize |
desktop.rs |
17 | Background, tile, cascade, click-to-front |
overlay.rs |
14 | Overlay stack, dismiss logic, overflow flip |
application.rs |
12 | Dispatch chain, resize, deferred events |
dialog.rs |
12 | Modal, Escape/Enter/command handling |
horizontal_bar.rs |
26 | BarEntry, dropdown, keyboard, Alt+letter |
menu_bar.rs |
8 | MenuItem, Menu, backward-compat wrapper |
status_line.rs |
8 | StatusItem, KB_* constants |
menu_box.rs |
15 | Dropdown rendering, keyboard navigation |
scrollbar.rs |
20 | Thumb position, drag, active/inactive |
button.rs |
14 | Click, hotkey, focus |
static_text.rs |
6 | Rendering, centering |
msgbox.rs |
9 | Factory functions, button layout |
clip.rs |
6 | Intersection clipping |
theme.rs |
8 | Style validation, registry, cycling |
theme_json.rs |
12 | JSON roundtrip, color parsing, border presets |
| Total | ~284 |
- 2 runnable doc tests, 17 ignored (require terminal context:
ignore) - Ignored doc tests use
/// ```ignorebecause they need a live terminal
Most widget tests need the theme initialized. Use a helper function:
fn setup_theme() {
crate::theme::set(Theme::turbo_vision());
}Call setup_theme() at the start of each test that renders or checks theme-dependent behavior. Thread-local theme means tests can run in parallel without interference.
Window and container tests use helper functions for mouse events:
fn mouse_down(col: u16, row: u16) -> Event {
Event::mouse(MouseEvent {
kind: MouseEventKind::Down(MouseButton::Left),
column: col,
row,
modifiers: KeyModifiers::NONE,
})
}
fn mouse_drag(col: u16, row: u16) -> Event { ... }
fn mouse_up(col: u16, row: u16) -> Event { ... }Frame and widget tests render to a Buffer and check cell contents:
let bounds = Rect::new(0, 0, 20, 10);
let mut buf = Buffer::empty(bounds);
let frame = Frame::new(bounds, "Test", FrameType::Window);
frame.draw(&mut buf, bounds);
// Check specific cell
let cell = buf.cell(Position::new(0, 0)).unwrap();
assert_eq!(cell.symbol(), "╔");Test event handling by creating events, passing to handle_event, and checking if cleared:
let mut win = Window::new(bounds, "Test");
let mut event = mouse_down(close_col, title_row);
win.handle_event(&mut event);
assert!(event.is_cleared()); // Event was consumedVerify state transitions using bitfield checks:
win.set_state(win.state() | SF_FOCUSED);
assert_ne!(win.state() & SF_FOCUSED, 0);Pattern: test_{module}_{what}_{condition}
Examples:
test_window_new_defaults— defaults after constructiontest_window_resize_clamps_to_min_size— resize behaviortest_frame_hover_close_button— hover statetest_container_focus_cycle— focus managementtest_scrollbar_thumb_position_at_zero— specific state
When adding a new widget, ensure tests cover:
- Construction defaults —
test_{widget}_new_defaults - View trait basics —
id(),bounds(),set_bounds(),can_focus() - Rendering — Buffer-based: check expected characters appear
- Event handling — Mouse clicks, keyboard, commands
- State transitions — Focus, hover, disabled
- Edge cases — Zero-size bounds, empty content, boundary positions
- Theme interaction — Active vs inactive styling (if applicable)
No CI pipeline yet (private repo). Before committing:
cargo test && cargo clippy -- -D warnings && cargo fmt --checkAll three must pass. Zero warnings policy.