Files

109 lines
5.0 KiB
Rust

//! Sidebar persistence and command regressions.
use notescraft_ui_egui::state::UiState;
#[test]
fn sidebar_defaults_to_explorer_and_persists_search() {
let default: serde_json::Value = serde_json::from_str(&UiState::default().to_json()).unwrap_or_default();
assert_eq!(default.get("sidebar_tab").and_then(serde_json::Value::as_str), Some("Explorer"));
let saved = UiState::from_json(r#"{"sidebar_tab":"Search"}"#);
let json: serde_json::Value = serde_json::from_str(&saved.to_json()).unwrap_or_default();
assert_eq!(json.get("sidebar_tab").and_then(serde_json::Value::as_str), Some("Search"));
}
#[test]
fn search_debounces_and_navigates_ranked_results() {
let root = std::env::temp_dir().join(format!("notescraft-sidebar-search-{}", std::process::id()));
assert!(std::fs::create_dir_all(&root).is_ok());
assert!(std::fs::write(root.join("Alpha.md"), "# Alpha\nalpha #work/project\n").is_ok());
assert!(std::fs::write(root.join("Other.md"), "alpha body\n").is_ok());
let session = notescraft_engine::Session::open_read_only(&root);
assert!(session.is_ok());
let Ok(session) = session else { return };
let mut search = notescraft_ui_egui::search_panel::SearchState::default();
search.set_query("alpha".into(), 1.0);
search.refresh(&session, 1.1);
assert_eq!(search.hits.len(), 0);
search.refresh(&session, 1.121);
assert_eq!(search.hits.len(), 2);
assert_eq!(search.hits.first().map(|hit| hit.path.as_str()), Some("Alpha.md"));
search.move_selection(1);
assert_eq!(search.selected, 1);
search.move_selection(1);
assert_eq!(search.selected, 0);
search.set_query("\"unfinished".into(), 2.0);
search.refresh(&session, 2.2);
assert!(search.error.is_some());
let _ = std::fs::remove_dir_all(root);
}
#[test]
fn tag_filter_uses_full_nested_tag() {
assert_eq!(notescraft_ui_egui::tags_panel::search_query("work/project"), "tag:#work/project");
}
#[test]
fn buffers_are_dirty_first_and_save_all_clears_them() {
let root = std::env::temp_dir().join(format!("notescraft-sidebar-buffers-{}", std::process::id()));
assert!(std::fs::create_dir_all(&root).is_ok());
assert!(std::fs::write(root.join("clean.md"), "clean\n").is_ok());
assert!(std::fs::write(root.join("dirty.md"), "dirty\n").is_ok());
let session = notescraft_engine::Session::open(&root);
assert!(session.is_ok());
let theme = notescraft_themes::builtin("catppuccin-mocha");
let (Ok(mut session), Some(theme)) = (session, theme) else { return };
session.use_settings_dir(root.join(".notescraft/test-config"));
let mut app = notescraft_ui_egui::app::NotesApp::new(session, theme);
app.open_note("clean.md");
app.open_note("dirty.md");
assert!(app.session.buffer_mut("dirty.md").and_then(|buffer| buffer.edit(0..0, "new ")).is_ok());
let rows = notescraft_ui_egui::buffers_panel::rows(&app.session, &app.tabs);
assert_eq!(rows.first().map(|row| (row.path.as_str(), row.dirty)), Some(("dirty.md", true)));
assert!(app.save_buffers());
assert!(!app.has_dirty_buffers());
drop(app);
let _ = std::fs::remove_dir_all(root);
}
#[test]
fn unified_diff_classifies_counts_and_caps_lines() {
use notescraft_git::{Diff, DiffLine, Hunk, LineKind};
use notescraft_ui_egui::diff_view::{MAX_VISIBLE_LINES, counts, visible_lines};
let lines: Vec<_> = (0..MAX_VISIBLE_LINES + 10)
.map(|index| DiffLine { kind: if index % 2 == 0 { LineKind::Add } else { LineKind::Del }, old_no: None, new_no: None, text: "é content".into() })
.collect();
let diff = Diff { hunks: vec![Hunk { header: "@@ -1 +1 @@".into(), lines }], ..Default::default() };
assert_eq!(counts(&diff), (1005, 1005));
assert_eq!(visible_lines(&diff).count(), MAX_VISIBLE_LINES);
}
#[test]
fn source_commit_requires_staged_changes_and_valid_message() {
use notescraft_git::{Change, ChangeKind, Status};
use notescraft_ui_egui::source_panel::can_commit;
let mut status = Status::default();
assert!(!can_commit(&status, "message", false, false));
status.changes.push(Change { path: "note.md".into(), orig_path: None, index: ChangeKind::Added, worktree: ChangeKind::Modified });
assert!(can_commit(&status, "message", false, false));
for text in ["", " \n ", "bad\0message"] {
assert!(!can_commit(&status, text, false, false));
}
assert!(!can_commit(&status, &"x".repeat(4097), false, false));
assert!(!can_commit(&status, "message", true, false));
assert!(!can_commit(&status, "message", false, true));
}
#[test]
fn snapshot_timer_resets_on_activity_and_attempts() {
let mut timer = notescraft_ui_egui::source_panel::SnapshotTimer::default();
assert!(!timer.take_due(0.0, 1, true, true));
assert!(!timer.take_due(59.0, 1, true, true));
timer.activity(59.0);
assert!(!timer.take_due(118.0, 1, true, true));
assert!(timer.take_due(119.0, 1, true, true));
assert!(!timer.take_due(120.0, 1, true, true));
assert!(!timer.take_due(300.0, 0, true, true));
assert!(!timer.take_due(300.0, 1, false, true));
assert!(!timer.take_due(300.0, 1, true, false));
}