use crate::app::{App, AppConfig};
use std::{
fs,
time::{SystemTime, UNIX_EPOCH},
};
#[test]
fn file_picker_lists_dirs_then_markdown_files_only() {
let unique = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let root = std::env::temp_dir().join(format!("leaf-picker-test-{unique}"));
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(root.join("notes")).unwrap();
fs::write(root.join("README.md"), "# Demo\n").unwrap();
fs::write(root.join("draft.markdown"), "# Draft\n").unwrap();
fs::write(root.join("ignore.txt"), "nope\n").unwrap();
let mut app = App::new_with_source(
Vec::new(),
Vec::new(),
AppConfig {
filename: "picker".to_string(),
source: String::new(),
debug_input: false,
watch: false,
filepath: None,
last_file_state: None,
},
);
assert!(app.open_file_picker(root.clone()));
let labels: Vec<_> = app
.file_picker_entries()
.iter()
.map(|entry| entry.label())
.collect();
assert!(labels.contains(&"notes/"));
assert!(labels.contains(&"README.md"));
assert!(labels.contains(&"draft.markdown"));
assert!(!labels.contains(&"ignore.txt"));
let notes_idx = labels.iter().position(|label| *label == "notes/").unwrap();
let readme_idx = labels
.iter()
.position(|label| *label == "README.md")
.unwrap();
assert!(notes_idx < readme_idx);
let _ = fs::remove_dir_all(root);
}
#[test]
fn fuzzy_file_picker_lists_markdown_files_from_subdirectories() {
let unique = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let root = std::env::temp_dir().join(format!("leaf-fuzzy-picker-test-{unique}"));
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(root.join("docs/nested")).unwrap();
fs::write(root.join("README.md"), "# Demo\n").unwrap();
fs::write(root.join("docs/guide.md"), "# Guide\n").unwrap();
fs::write(root.join("docs/nested/deep.markdown"), "# Deep\n").unwrap();
fs::write(root.join("ignore.txt"), "nope\n").unwrap();
let mut app = App::new_with_source(
Vec::new(),
Vec::new(),
AppConfig {
filename: "picker".to_string(),
source: String::new(),
debug_input: false,
watch: false,
filepath: None,
last_file_state: None,
},
);
assert!(app.open_fuzzy_file_picker(root.clone()));
assert!(app.is_fuzzy_file_picker());
let labels: Vec<_> = app
.file_picker_filtered_indices()
.iter()
.map(|idx| app.file_picker_entries()[*idx].label())
.collect();
assert!(labels.contains(&"README.md"));
assert!(labels.contains(&"docs/guide.md"));
assert!(labels.contains(&"docs/nested/deep.markdown"));
assert!(!labels.contains(&"ignore.txt"));
let _ = fs::remove_dir_all(root);
}
#[test]
fn queued_fuzzy_picker_transitions_from_pending_to_loading_to_open() {
let unique = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let root = std::env::temp_dir().join(format!("leaf-fuzzy-picker-queued-{unique}"));
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(root.join("docs")).unwrap();
fs::write(root.join("README.md"), "# Demo\n").unwrap();
fs::write(root.join("docs/guide.md"), "# Guide\n").unwrap();
let mut app = App::new_with_source(
Vec::new(),
Vec::new(),
AppConfig {
filename: "picker".to_string(),
source: String::new(),
debug_input: false,
watch: false,
filepath: None,
last_file_state: None,
},
);
app.queue_fuzzy_file_picker(root.clone());
assert!(app.has_pending_picker());
assert_eq!(
app.pending_picker_mode(),
Some(crate::app::FilePickerMode::Fuzzy)
);
assert_eq!(app.pending_picker_dir(), Some(root.as_path()));
assert!(!app.is_picker_loading());
assert!(app.start_pending_picker_loading());
assert!(app.is_picker_loading());
app.age_picker_loading_by(std::time::Duration::from_secs(1));
let mut opened = false;
for _ in 0..50 {
if app.poll_picker_loading() {
opened = app.is_file_picker_open();
break;
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
assert!(opened);
assert!(app.is_file_picker_open());
assert!(app.is_fuzzy_file_picker());
assert!(!app.has_pending_picker());
assert!(!app.is_picker_loading());
let labels: Vec<_> = app
.file_picker_filtered_indices()
.iter()
.map(|idx| app.file_picker_entries()[*idx].label())
.collect();
assert!(labels.contains(&"README.md"));
assert!(labels.contains(&"docs/guide.md"));
let _ = fs::remove_dir_all(root);
}
#[test]
fn fuzzy_file_picker_uses_depth_first_order_with_hidden_first() {
let unique = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_nanos();
let root = std::env::temp_dir().join(format!("leaf-fuzzy-picker-order-{unique}"));
let _ = fs::remove_dir_all(&root);
fs::create_dir_all(root.join(".private")).unwrap();
fs::create_dir_all(root.join("docs")).unwrap();
fs::write(root.join(".draft.md"), "# Hidden\n").unwrap();
fs::write(root.join(".private/alpha.md"), "# Private\n").unwrap();
fs::write(root.join("README.md"), "# Demo\n").unwrap();
fs::write(root.join("docs/guide.md"), "# Guide\n").unwrap();
let mut app = App::new_with_source(
Vec::new(),
Vec::new(),
AppConfig {
filename: "picker".to_string(),
source: String::new(),
debug_input: false,
watch: false,
filepath: None,
last_file_state: None,
},
);
assert!(app.open_fuzzy_file_picker(root.clone()));
let labels: Vec<_> = app
.file_picker_filtered_indices()
.iter()
.map(|idx| app.file_picker_entries()[*idx].label())
.collect();
assert_eq!(
labels,
vec![
".draft.md",
"README.md",
".private/alpha.md",
"docs/guide.md",
]
);
let _ = fs::remove_dir_all(root);
}