109 lines
5.0 KiB
Rust
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));
|
|
}
|