Function bodies 251 total
save function · rust · L30-L39 (10 LOC)src/config.rs
pub fn save(&self) -> Result<()> {
let path = Self::config_path();
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let content = serde_json::to_string_pretty(self)?;
std::fs::write(&path, content)?;
Ok(())
}resolved_export_path function · rust · L40-L51 (12 LOC)src/config.rs
pub fn resolved_export_path(&self) -> PathBuf {
if let Some(stripped) = self.export_path.strip_prefix("~/") {
dirs::home_dir()
.expect("home dir")
.join(stripped)
} else if self.export_path == "~" {
dirs::home_dir().expect("home dir")
} else {
PathBuf::from(&self.export_path)
}
}config_path function · rust · L52-L60 (9 LOC)src/config.rs
fn config_path() -> PathBuf {
if let Ok(dir) = std::env::var("AGENT_CONFIG_DIR") {
return PathBuf::from(dir).join("config.json");
}
dirs::config_dir()
.expect("config dir")
.join("agent-session-manager/config.json")
}test_save_and_load_roundtrip function · rust · L75-L91 (17 LOC)src/config.rs
fn test_save_and_load_roundtrip() {
let tmp = TempDir::new().unwrap();
let config_path = tmp.path().join("config.json");
let config = AppConfig {
export_path: "/custom/export/path".to_string(),
};
// Save manually to tmp path
let content = serde_json::to_string_pretty(&config).unwrap();
std::fs::write(&config_path, content).unwrap();
// Load from same path
let loaded: AppConfig =
serde_json::from_str(&std::fs::read_to_string(&config_path).unwrap()).unwrap();
assert_eq!(loaded.export_path, "/custom/export/path");
}test_load_missing_file_returns_default function · rust · L94-L100 (7 LOC)src/config.rs
fn test_load_missing_file_returns_default() {
// AppConfig::load() uses the real config path, but we can test
// that if we call with a non-existent path we'd get the default.
// We test the logic indirectly: a fresh default has the expected path.
let config = AppConfig::default();
assert_eq!(config.export_path, "~/claude-exports");
}test_resolved_export_path_expands_tilde function · rust · L103-L111 (9 LOC)src/config.rs
fn test_resolved_export_path_expands_tilde() {
let config = AppConfig {
export_path: "~/my-exports".to_string(),
};
let resolved = config.resolved_export_path();
let home = dirs::home_dir().unwrap();
assert_eq!(resolved, home.join("my-exports"));
assert!(!resolved.to_string_lossy().contains('~'));
}test_resolved_export_path_absolute function · rust · L114-L120 (7 LOC)src/config.rs
fn test_resolved_export_path_absolute() {
let config = AppConfig {
export_path: "/absolute/path".to_string(),
};
let resolved = config.resolved_export_path();
assert_eq!(resolved, PathBuf::from("/absolute/path"));
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
test_config_path_uses_env_var function · rust · L123-L129 (7 LOC)src/config.rs
fn test_config_path_uses_env_var() {
let tmp = TempDir::new().unwrap();
std::env::set_var("AGENT_CONFIG_DIR", tmp.path());
let path = AppConfig::config_path();
assert_eq!(path, tmp.path().join("config.json"));
std::env::remove_var("AGENT_CONFIG_DIR");
}test_resolved_export_path_tilde_only function · rust · L132-L139 (8 LOC)src/config.rs
fn test_resolved_export_path_tilde_only() {
let config = AppConfig {
export_path: "~".to_string(),
};
let resolved = config.resolved_export_path();
let home = dirs::home_dir().unwrap();
assert_eq!(resolved, home);
}test_load_invalid_json_returns_default function · rust · L142-L149 (8 LOC)src/config.rs
fn test_load_invalid_json_returns_default() {
// Test that serde_json::from_str with invalid JSON falls back to default
// (matches the unwrap_or_default() path in AppConfig::load)
let result: Result<AppConfig, _> = serde_json::from_str("not valid json");
assert!(result.is_err());
let config = result.unwrap_or_default();
assert_eq!(config.export_path, "~/claude-exports");
}test_load_unreadable_file_returns_default function · rust · L152-L159 (8 LOC)src/config.rs
fn test_load_unreadable_file_returns_default() {
// Test that read_to_string failure falls back to default
// (matches the Err(_) => return Self::default() path in AppConfig::load)
let result = std::fs::read_to_string("/nonexistent-path-xyz/config.json");
assert!(result.is_err());
let config = AppConfig::default();
assert_eq!(config.export_path, "~/claude-exports");
}test_save_and_load_via_filesystem function · rust · L162-L178 (17 LOC)src/config.rs
fn test_save_and_load_via_filesystem() {
// Test save + load roundtrip without env vars
let tmp = TempDir::new().unwrap();
let config_path = tmp.path().join("deep").join("nested").join("config.json");
let config = AppConfig {
export_path: "/test/path".to_string(),
};
// Manually replicate save logic
std::fs::create_dir_all(config_path.parent().unwrap()).unwrap();
let content = serde_json::to_string_pretty(&config).unwrap();
std::fs::write(&config_path, content).unwrap();
// Verify
assert!(config_path.exists());
let loaded: AppConfig =
serde_json::from_str(&std::fs::read_to_string(&config_path).unwrap()).unwrap();
assert_eq!(loaded.export_path, "/test/path");
}main function · rust · L17-L56 (40 LOC)src/main.rs
fn main() -> Result<(), Box<dyn Error>> {
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, crossterm::event::EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.clear()?;
// Load sessions with progress bar
let store = store::SessionStore::new();
let sessions = store
.load_sessions_with_progress(|loaded, total| {
let _ = terminal.draw(|f| {
ui::draw_loading(f, loaded, total);
});
})
.unwrap_or_default();
let trash = store.load_trash().unwrap_or_default();
let app = App::new(sessions, trash);
let res = run_app(&mut terminal, app);
disable_raw_mode()?;
execute!(terminal.backend_mut(), LeaveAlternateScreen, crossterm::event::DisableMouseCapture)?;
terminal.show_cursor()?;
match res {
Ok(Some((command, path))) => {
let session_id = claunch_claude_resume function · rust · L60-L83 (24 LOC)src/main.rs
fn launch_claude_resume(session_id: &str, path: Option<String>) {
#[cfg(target_family = "unix")]
let (prog, args) = {
let cmd = match path {
Some(ref p) => format!("clear && cd {} && claude --resume {}", shell_escape(p), session_id),
None => format!("clear && claude --resume {}", session_id),
};
("sh", vec!["-c".to_string(), cmd])
};
#[cfg(target_os = "windows")]
let (prog, args) = {
let cmd = match path {
Some(ref p) => format!("cls && cd /d {} && claude --resume {}", cmd_quote(p), session_id),
None => format!("cls && claude --resume {}", session_id),
};
("cmd", vec!["/c".to_string(), cmd])
};
match std::process::Command::new(prog).args(&args).spawn() {
Ok(mut child) => { let _ = child.wait(); }
Err(e) => { eprintln!("Failed to launch claude: {}", e); std::process::exit(1); }
}
}run_app function · rust · L94-L133 (40 LOC)src/main.rs
fn run_app<B: Backend>(
terminal: &mut Terminal<B>,
mut app: App,
) -> io::Result<Option<(String, Option<String>)>> {
loop {
terminal.draw(|f| ui::draw(f, &mut app))?;
app.clear_expired_status();
// Check if we should resume a session
if let Some(command) = app.get_resume_command() {
let path = app.get_resume_session_path();
return Ok(Some((command, path)));
}
// Wait for at least one event (with timeout for status message expiry)
if crossterm::event::poll(std::time::Duration::from_millis(250))? {
// Drain all pending events before next draw to avoid rendering artifacts
loop {
match event::read()? {
Event::Key(key) if key.kind == event::KeyEventKind::Press => {
if let Some(result) = handle_key_event(&mut app, key) {
return result;
}
}
Powered by Repobility — scan your code at https://repobility.com
handle_key_event function · rust · L137-L321 (185 LOC)src/main.rs
fn handle_key_event(
app: &mut App,
key: event::KeyEvent,
) -> Option<io::Result<Option<(String, Option<String>)>>> {
if app.show_settings {
match key.code {
KeyCode::Enter => app.save_settings(),
KeyCode::Esc => app.cancel_settings(),
KeyCode::Char(c) => app.settings_add_char(c),
KeyCode::Backspace => app.settings_pop_char(),
_ => {}
}
return None;
}
if app.show_help {
match key.code {
KeyCode::Char('h') | KeyCode::Esc => app.toggle_help(),
KeyCode::Up => app.help_scroll_up(1),
KeyCode::Down => app.help_scroll_down(1),
KeyCode::PageUp => app.help_scroll_up(10),
KeyCode::PageDown => app.help_scroll_down(10),
_ => {}
}
return None;
}
match key.code {
KeyCode::Char('q') | KeyCode::Esc => {
if app.is_confirmation_pending() {
app.cancel_confirmatiohandle_mouse_event function · rust · L324-L379 (56 LOC)src/main.rs
fn handle_mouse_event(app: &mut App, mouse: event::MouseEvent) -> bool {
match mouse.kind {
MouseEventKind::ScrollUp => {
if app.show_help {
app.help_scroll_up(3);
} else if !app.show_settings {
// Scroll folgt Mausposition statt Fokus-Panel
let list_width = app.terminal_size.0 * 30 / 100;
if mouse.column < list_width {
app.select_prev();
} else {
app.preview_scroll_up(3);
}
}
}
MouseEventKind::ScrollDown => {
if app.show_help {
app.help_scroll_down(3);
} else if !app.show_settings {
let list_width = app.terminal_size.0 * 30 / 100;
if mouse.column < list_width {
app.select_next();
} else {
app.preview_scroll_down(3);
}
}
}
dispatch_click_action function · rust · L382-L458 (77 LOC)src/main.rs
fn dispatch_click_action(app: &mut App, action: crate::app::ClickAction) -> bool {
use crate::app::ClickAction;
match action {
// Tab-Wechsel funktioniert immer
ClickAction::SwitchTab(tab) => app.switch_to_tab(tab),
// Modal-Aktionen: Settings Save/Cancel, Confirm Yes/No
ClickAction::SaveSettings => app.save_settings(),
ClickAction::CancelSettings => app.cancel_settings(),
ClickAction::ConfirmYes => {
// Gleiche Logik wie 'y'-Taste
use crate::app::ConfirmAction;
if let Some(action) = &app.confirm_action {
match action {
ConfirmAction::DeleteToTrash(_) => {
if let Some(session) = app.get_selected_session() {
let session_clone = session.clone();
match commands::delete_session(&session_clone) {
Ok(_) => {
app.move_selmake_session function · rust · L475-L490 (16 LOC)src/main.rs
fn make_session(id: &str, project: &str) -> Session {
Session {
id: id.to_string(),
project_path: format!("/home/g/{}", project),
project_name: project.to_string(),
created_at: String::new(),
updated_at: String::new(),
size: 0,
total_entries: 1,
messages: vec![Message {
role: "user".to_string(),
content: "msg".to_string(),
}],
}
}press function · rust · L491-L499 (9 LOC)src/main.rs
fn press(code: KeyCode) -> KeyEvent {
KeyEvent {
code,
modifiers: KeyModifiers::NONE,
kind: KeyEventKind::Press,
state: KeyEventState::NONE,
}
}test_cmd_quote_with_quotes function · rust · L512-L517 (6 LOC)src/main.rs
fn test_cmd_quote_with_quotes() {
assert_eq!(
cmd_quote("path with \"quotes\""),
"\"path with \"\"quotes\"\"\""
);
}test_handle_s_toggles_sort function · rust · L548-L553 (6 LOC)src/main.rs
fn test_handle_s_toggles_sort() {
let mut app = App::with_sessions(vec![]);
let initial = app.sort_field;
handle_key_event(&mut app, press(KeyCode::Char('s')));
assert_ne!(app.sort_field, initial);
}test_handle_1_switches_to_sessions function · rust · L577-L582 (6 LOC)src/main.rs
fn test_handle_1_switches_to_sessions() {
let mut app = App::with_sessions(vec![]);
app.current_tab = crate::app::Tab::Trash;
handle_key_event(&mut app, press(KeyCode::Char('1')));
assert_eq!(app.current_tab, crate::app::Tab::Sessions);
}Want this analysis on your repo? https://repobility.com/scan/
mouse function · rust · L590-L598 (9 LOC)src/main.rs
fn mouse(kind: MouseEventKind, col: u16, row: u16) -> event::MouseEvent {
event::MouseEvent {
kind,
column: col,
row,
modifiers: event::KeyModifiers::NONE,
}
}test_mouse_scroll_down_selects_next function · rust · L601-L610 (10 LOC)src/main.rs
fn test_mouse_scroll_down_selects_next() {
let mut app = App::with_sessions(vec![
make_session("s1", "p1"),
make_session("s2", "p2"),
]);
app.terminal_size = (160, 40);
// col=10 liegt im Listen-Bereich (< 160*30/100=48) → scrollt Liste
handle_mouse_event(&mut app, mouse(MouseEventKind::ScrollDown, 10, 10));
assert_eq!(app.selected_session_idx, 1);
}test_mouse_scroll_up_selects_prev function · rust · L613-L622 (10 LOC)src/main.rs
fn test_mouse_scroll_up_selects_prev() {
let mut app = App::with_sessions(vec![
make_session("s1", "p1"),
make_session("s2", "p2"),
]);
app.terminal_size = (160, 40);
app.selected_session_idx = 1;
handle_mouse_event(&mut app, mouse(MouseEventKind::ScrollUp, 10, 10));
assert_eq!(app.selected_session_idx, 0);
}test_mouse_click_selects_session_row function · rust · L625-L636 (12 LOC)src/main.rs
fn test_mouse_click_selects_session_row() {
let mut app = App::with_sessions(vec![
make_session("s1", "p1"),
make_session("s2", "p2"),
make_session("s3", "p3"),
]);
app.terminal_size = (160, 40);
render_frame(&mut app, 160, 40);
// row=6 → list_data_row=1 → sessions[offset+1]
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 10, 6));
assert_eq!(app.selected_session_idx, 1);
}test_mouse_click_tab_bar_switches_to_trash function · rust · L639-L646 (8 LOC)src/main.rs
fn test_mouse_click_tab_bar_switches_to_trash() {
let mut app = App::with_sessions(vec![]);
// Sessions-Tab: " ● 1 Sessions (0) " = 20 Zeichen → cols 0-20
// Trash-Tab: " ○ 2 Trash (0) " = 18 Zeichen → cols 21-38
render_frame(&mut app, 160, 40);
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 25, 1));
assert_eq!(app.current_tab, crate::app::Tab::Trash);
}test_mouse_click_tab_bar_help_opens_help function · rust · L649-L656 (8 LOC)src/main.rs
fn test_mouse_click_tab_bar_help_opens_help() {
let mut app = App::with_sessions(vec![]);
// Help-Hint: "│ h help " = 11 Zeichen → cols 39-49
render_frame(&mut app, 160, 40);
assert!(!app.show_help);
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 42, 1));
assert!(app.show_help);
}test_mouse_click_tab_bar_switches_to_sessions function · rust · L659-L666 (8 LOC)src/main.rs
fn test_mouse_click_tab_bar_switches_to_sessions() {
let mut app = App::with_sessions(vec![]);
app.current_tab = crate::app::Tab::Trash;
// col=10 liegt im Sessions-Tab (cols 0-20)
render_frame(&mut app, 160, 40);
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 10, 1));
assert_eq!(app.current_tab, crate::app::Tab::Sessions);
}test_mouse_click_command_bar_opens_settings function · rust · L669-L677 (9 LOC)src/main.rs
fn test_mouse_click_command_bar_opens_settings() {
let mut app = App::with_sessions(vec![]);
render_frame(&mut app, 160, 40);
// "g settings" startet bei x=82 (nav=16 + sep=5 + Enter+resume=14 + d+delete=10
// + e+export=10 + 0+clean=9 + f+search=10 + s+sort=8 = 82), Breite=12
// cmd_y = 40-3 = 37 → row=38 liegt in height:3
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 85, 38));
assert!(app.show_settings);
}Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
test_mouse_scroll_in_preview_scrolls_content function · rust · L680-L687 (8 LOC)src/main.rs
fn test_mouse_scroll_in_preview_scrolls_content() {
let mut app = App::with_sessions(vec![]);
app.terminal_size = (160, 40);
app.preview_scroll = 10;
// col=100 liegt im Preview-Bereich (>= 160*30/100=48) → scrollt Preview
handle_mouse_event(&mut app, mouse(MouseEventKind::ScrollUp, 100, 10));
assert!(app.preview_scroll < 10);
}test_click_outside_closes_help function · rust · L692-L701 (10 LOC)src/main.rs
fn test_click_outside_closes_help() {
let mut app = App::with_sessions(vec![]);
app.terminal_size = (160, 40);
app.toggle_help();
assert!(app.show_help);
render_frame(&mut app, 160, 40);
// Klick auf (0, 0) — keine Regionen registriert bei show_help → click-outside
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 0, 0));
assert!(!app.show_help);
}test_click_outside_closes_settings function · rust · L704-L713 (10 LOC)src/main.rs
fn test_click_outside_closes_settings() {
let mut app = App::with_sessions(vec![]);
app.terminal_size = (160, 40);
app.open_settings();
assert!(app.show_settings);
render_frame(&mut app, 160, 40);
// Klick auf (0, 0) — außerhalb des Settings-Modals
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 0, 0));
assert!(!app.show_settings);
}test_click_outside_closes_search function · rust · L716-L725 (10 LOC)src/main.rs
fn test_click_outside_closes_search() {
let mut app = App::with_sessions(vec![]);
app.terminal_size = (160, 40);
app.toggle_search();
assert!(app.show_search);
render_frame(&mut app, 160, 40);
// Klick auf (0, 0) — keine Regionen bei show_search → click-outside
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 0, 0));
assert!(!app.show_search);
}test_click_outside_cancels_confirmation function · rust · L728-L737 (10 LOC)src/main.rs
fn test_click_outside_cancels_confirmation() {
let mut app = App::with_sessions(vec![make_session("s1", "p1")]);
app.terminal_size = (160, 40);
app.request_delete_confirmation();
assert!(app.is_confirmation_pending());
render_frame(&mut app, 160, 40);
// Klick auf (0, 0) — außerhalb der [y]/[n] Buttons
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 0, 0));
assert!(!app.is_confirmation_pending());
}test_mouse_scroll_in_help_modal function · rust · L740-L751 (12 LOC)src/main.rs
fn test_mouse_scroll_in_help_modal() {
let mut app = App::with_sessions(vec![]);
app.terminal_size = (160, 40);
app.toggle_help();
app.help_scroll = 5;
// Scroll down → help_scroll steigt
handle_mouse_event(&mut app, mouse(MouseEventKind::ScrollDown, 80, 20));
assert_eq!(app.help_scroll, 8); // 5 + 3
// Scroll up → help_scroll sinkt
handle_mouse_event(&mut app, mouse(MouseEventKind::ScrollUp, 80, 20));
assert_eq!(app.help_scroll, 5); // 8 - 3
}test_scroll_follows_mouse_position_not_focus function · rust · L754-L766 (13 LOC)src/main.rs
fn test_scroll_follows_mouse_position_not_focus() {
let mut app = App::with_sessions(vec![
make_session("s1", "p1"),
make_session("s2", "p2"),
]);
app.terminal_size = (160, 40);
// Fokus auf Preview, aber Maus über Liste (col=10 < 48)
app.focus = crate::app::FocusPanel::Preview;
handle_mouse_event(&mut app, mouse(MouseEventKind::ScrollDown, 10, 10));
// Liste wurde gescrollt, nicht Preview
assert_eq!(app.selected_session_idx, 1);
assert_eq!(app.preview_scroll, 0);
}test_settings_save_click function · rust · L769-L781 (13 LOC)src/main.rs
fn test_settings_save_click() {
let mut app = App::with_sessions(vec![]);
app.terminal_size = (160, 40);
app.open_settings();
app.settings_input = "/new/path".to_string();
render_frame(&mut app, 160, 40);
// Settings-Modal: popup_width = 160*0.6 = 96, popup_x = 32, inner_x = 33
// btn_y = (40-7)/2 + 1 + 4 = 16 + 1 + 4 = 21
// Save-Button: x=33, width=16, y=21
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 40, 21));
assert!(!app.show_settings);
assert_eq!(app.config.export_path, "/new/path");
}Provenance: Repobility (https://repobility.com) — every score reproducible from /scan/
test_settings_cancel_click function · rust · L784-L795 (12 LOC)src/main.rs
fn test_settings_cancel_click() {
let mut app = App::with_sessions(vec![]);
app.terminal_size = (160, 40);
app.open_settings();
let original = app.config.export_path.clone();
app.settings_input = "/changed".to_string();
render_frame(&mut app, 160, 40);
// Cancel-Button: x=33+16=49, width=12, y=21
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 52, 21));
assert!(!app.show_settings);
assert_eq!(app.config.export_path, original);
}test_confirm_yes_click function · rust · L798-L812 (15 LOC)src/main.rs
fn test_confirm_yes_click() {
let mut app = App::with_sessions(vec![]);
app.trash = vec![make_session("t1", "p1")];
app.current_tab = crate::app::Tab::Trash;
app.terminal_size = (160, 40);
app.confirm_action = Some(crate::app::ConfirmAction::DeletePermanently("t1".to_string()));
app.set_status("PERMANENTLY delete 'p1'? Press 'd' or 'y' to confirm, 'n' or Esc to cancel".to_string());
render_frame(&mut app, 160, 40);
// [y] Button: nach Question-Text + 2 Zeichen Abstand
// "PERMANENTLY delete 'p1'?" = 24 Zeichen + 2 = 26 → x=26
let action = app.get_click_action(28, 38);
assert_eq!(action, Some(crate::app::ClickAction::ConfirmYes));
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), 28, 38));
assert!(app.trash.is_empty());
}test_confirm_no_click function · rust · L815-L832 (18 LOC)src/main.rs
fn test_confirm_no_click() {
let mut app = App::with_sessions(vec![make_session("s1", "p1")]);
app.terminal_size = (160, 40);
app.request_delete_confirmation();
assert!(app.is_confirmation_pending());
render_frame(&mut app, 160, 40);
// [n] Button: nach [y] Button + 2 Zeichen
// Für diesen Test: prüfen dass ConfirmNo Region existiert
let has_confirm_no = app.click_regions.iter().any(|(_, a)| *a == crate::app::ClickAction::ConfirmNo);
assert!(has_confirm_no);
// Klick auf die [n] Region
let (rx, ry) = {
let (rect, _) = app.click_regions.iter().find(|(_, a)| *a == crate::app::ClickAction::ConfirmNo).unwrap();
(rect.x + 1, rect.y)
};
handle_mouse_event(&mut app, mouse(MouseEventKind::Down(MouseButton::Left), rx, ry));
assert!(!app.is_confirmation_pending());
}test_no_normal_regions_during_modals function · rust · L835-L864 (30 LOC)src/main.rs
fn test_no_normal_regions_during_modals() {
let mut app = App::with_sessions(vec![]);
// Help-Modal: keine Regionen registriert
app.toggle_help();
render_frame(&mut app, 160, 40);
assert!(app.click_regions.is_empty());
// Search-Modal: keine Regionen
app.toggle_help();
app.toggle_search();
render_frame(&mut app, 160, 40);
assert!(app.click_regions.is_empty());
// Settings-Modal: nur Save/Cancel Regionen
app.show_search = false;
app.open_settings();
render_frame(&mut app, 160, 40);
assert_eq!(app.click_regions.len(), 2);
assert!(app.click_regions.iter().any(|(_, a)| *a == crate::app::ClickAction::SaveSettings));
assert!(app.click_regions.iter().any(|(_, a)| *a == crate::app::ClickAction::CancelSettings));
// Confirmation: nur [y]/[n] Regionen
app.cancel_settings();
app.sessions = vec![make_session("s1", "p1")];
apptest_scroll_blocked_during_settings function · rust · L867-L877 (11 LOC)src/main.rs
fn test_scroll_blocked_during_settings() {
let mut app = App::with_sessions(vec![
make_session("s1", "p1"),
make_session("s2", "p2"),
]);
app.terminal_size = (160, 40);
app.open_settings();
handle_mouse_event(&mut app, mouse(MouseEventKind::ScrollDown, 10, 10));
// Scroll wird blockiert — Liste unverändert
assert_eq!(app.selected_session_idx, 0);
}test_handle_arrows_in_list function · rust · L880-L887 (8 LOC)src/main.rs
fn test_handle_arrows_in_list() {
let mut app =
App::with_sessions(vec![make_session("s1", "p1"), make_session("s2", "p2")]);
handle_key_event(&mut app, press(KeyCode::Down));
assert_eq!(app.selected_session_idx, 1);
handle_key_event(&mut app, press(KeyCode::Up));
assert_eq!(app.selected_session_idx, 0);
}test_handle_arrows_in_preview function · rust · L890-L897 (8 LOC)src/main.rs
fn test_handle_arrows_in_preview() {
let mut app = App::with_sessions(vec![make_session("s1", "p1")]);
app.focus = FocusPanel::Preview;
handle_key_event(&mut app, press(KeyCode::Down));
assert_eq!(app.preview_scroll, 1);
handle_key_event(&mut app, press(KeyCode::Up));
assert_eq!(app.preview_scroll, 0);
}test_handle_esc_cancels_confirmation function · rust · L900-L905 (6 LOC)src/main.rs
fn test_handle_esc_cancels_confirmation() {
let mut app = App::with_sessions(vec![make_session("s1", "p1")]);
app.request_delete_confirmation();
handle_key_event(&mut app, press(KeyCode::Esc));
assert!(!app.is_confirmation_pending());
}Powered by Repobility — scan your code at https://repobility.com
test_handle_search_mode_chars function · rust · L908-L916 (9 LOC)src/main.rs
fn test_handle_search_mode_chars() {
let mut app = App::with_sessions(vec![]);
app.show_search = true;
handle_key_event(&mut app, press(KeyCode::Char('a')));
handle_key_event(&mut app, press(KeyCode::Char('b')));
assert_eq!(app.search_query, "ab");
handle_key_event(&mut app, press(KeyCode::Backspace));
assert_eq!(app.search_query, "a");
}test_handle_settings_mode function · rust · L919-L927 (9 LOC)src/main.rs
fn test_handle_settings_mode() {
let mut app = App::with_sessions(vec![]);
app.open_settings();
let initial_len = app.settings_input.len();
handle_key_event(&mut app, press(KeyCode::Char('x')));
assert_eq!(app.settings_input.len(), initial_len + 1);
handle_key_event(&mut app, press(KeyCode::Esc));
assert!(!app.show_settings);
}test_handle_help_mode_scroll function · rust · L930-L937 (8 LOC)src/main.rs
fn test_handle_help_mode_scroll() {
let mut app = App::with_sessions(vec![]);
app.toggle_help();
handle_key_event(&mut app, press(KeyCode::Down));
assert_eq!(app.help_scroll, 1);
handle_key_event(&mut app, press(KeyCode::PageDown));
assert_eq!(app.help_scroll, 11);
}