mod common;
use dioxus_swdir_tree_core::{DirectoryTree, DisplayFilter, SelectionMode};
use common::fixture;
#[test]
fn s6_1_insertion_order_and_no_duplicates() {
let fx = fixture();
let mut tree = DirectoryTree::new(&fx.root);
tree.expand_blocking(&fx.root).expect("root scan");
let alpha = fx.path("alpha");
let beta = fx.path("beta");
let zeta = fx.path("zeta.txt");
tree.on_selected(&alpha, true, SelectionMode::Toggle);
tree.on_selected(&beta, true, SelectionMode::Toggle);
tree.on_selected(&zeta, false, SelectionMode::Toggle);
assert_eq!(
tree.selected_paths(),
[alpha.clone(), beta.clone(), zeta.clone()]
);
tree.on_selected(&alpha, true, SelectionMode::Toggle); tree.on_selected(&alpha, true, SelectionMode::Toggle); assert_eq!(
tree.selected_paths(),
[beta.clone(), zeta.clone(), alpha.clone()]
);
}
#[test]
fn s6_2_toggle_add_and_remove() {
let fx = fixture();
let mut tree = DirectoryTree::new(&fx.root);
tree.expand_blocking(&fx.root).expect("root scan");
let alpha = fx.path("alpha");
assert!(!tree.is_selected(&alpha));
tree.on_selected(&alpha, true, SelectionMode::Toggle);
assert!(tree.is_selected(&alpha));
assert!(tree.find(&alpha).unwrap().is_selected);
tree.on_selected(&alpha, true, SelectionMode::Toggle);
assert!(!tree.is_selected(&alpha));
assert!(!tree.find(&alpha).unwrap().is_selected);
}
#[test]
fn s6_3_extend_range_anchor_does_not_move() {
let fx = fixture();
let mut tree = DirectoryTree::new(&fx.root);
tree.expand_blocking(&fx.root).expect("root scan");
let root = fx.root.clone();
let alpha = fx.path("alpha");
let beta = fx.path("beta");
let zeta = fx.path("zeta.txt");
tree.on_selected(&alpha, true, SelectionMode::Replace);
assert_eq!(tree.selected_paths(), std::slice::from_ref(&alpha));
tree.on_selected(&beta, true, SelectionMode::ExtendRange);
assert_eq!(tree.selected_paths(), [alpha.clone(), beta.clone()]);
tree.on_selected(&zeta, false, SelectionMode::ExtendRange);
assert_eq!(
tree.selected_paths(),
[alpha.clone(), beta.clone(), zeta.clone()]
);
tree.on_selected(&root, true, SelectionMode::ExtendRange);
assert_eq!(tree.selected_paths(), [root.clone(), alpha.clone()]);
tree.on_selected(&beta, true, SelectionMode::ExtendRange);
assert_eq!(tree.selected_paths(), [alpha.clone(), beta.clone()]);
}
#[test]
fn s6_3_extend_range_without_anchor_is_replace() {
let fx = fixture();
let mut tree = DirectoryTree::new(&fx.root);
tree.expand_blocking(&fx.root).expect("root scan");
let beta = fx.path("beta");
tree.on_selected(&beta, true, SelectionMode::ExtendRange);
assert_eq!(tree.selected_paths(), std::slice::from_ref(&beta));
}
#[test]
fn s6_4_selection_survives_filter_change() {
let fx = fixture();
let mut tree = DirectoryTree::new(&fx.root).with_filter(DisplayFilter::AllIncludingHidden);
tree.expand_blocking(&fx.root).expect("root scan");
let hidden_dir = fx.path(".hidden_dir");
tree.on_selected(&hidden_dir, true, SelectionMode::Replace);
assert!(tree.is_selected(&hidden_dir));
assert!(tree.find(&hidden_dir).unwrap().is_selected);
tree.set_filter(DisplayFilter::FilesAndFolders);
assert!(tree.find(&hidden_dir).is_none(), "node hidden by filter");
assert!(
tree.is_selected(&hidden_dir),
"authoritative path survives filter change"
);
tree.set_filter(DisplayFilter::AllIncludingHidden);
let node = tree.find(&hidden_dir).expect("node visible again");
assert!(
node.is_selected,
"flag re-synced when node becomes visible again"
);
}
#[test]
fn s6_5_selection_survives_on_loaded_merge() {
let fx = fixture();
let mut tree = DirectoryTree::new(&fx.root);
tree.expand_blocking(&fx.root).expect("initial root scan");
let alpha = fx.path("alpha");
let beta = fx.path("beta");
let inner = fx.path("alpha/inner");
tree.on_selected(&alpha, true, SelectionMode::Toggle);
tree.on_selected(&beta, true, SelectionMode::Toggle);
tree.on_selected(&inner, true, SelectionMode::Toggle);
assert_eq!(
tree.selected_paths(),
[alpha.clone(), beta.clone(), inner.clone()]
);
assert!(tree.find(&inner).is_none(), "inner not yet loaded");
let request = tree
.on_toggled(&alpha)
.expect("alpha is unloaded; scan required");
let payload = crate::common::fixture_scan_run(&tree, &request);
let outcome = tree.on_loaded(payload);
assert!(outcome.accepted);
assert_eq!(
tree.selected_paths(),
[alpha.clone(), beta.clone(), inner.clone()]
);
assert!(tree.find(&alpha).unwrap().is_selected);
assert!(tree.find(&beta).unwrap().is_selected);
let inner_node = tree.find(&inner).expect("inner now visible");
assert!(inner_node.is_selected);
}
#[test]
fn extend_range_respects_visible_rows_skipping_collapsed_children() {
let fx = fixture();
let mut tree = DirectoryTree::new(&fx.root);
tree.expand_blocking(&fx.root).expect("root scan");
tree.expand_blocking(&fx.path("alpha")).expect("alpha scan");
let root = fx.root.clone();
let beta = fx.path("beta");
tree.on_toggled(&fx.path("alpha"));
tree.on_selected(&root, true, SelectionMode::Replace);
tree.on_selected(&beta, true, SelectionMode::ExtendRange);
assert_eq!(
tree.selected_paths(),
[root.clone(), fx.path("alpha"), beta.clone()]
);
assert!(!tree.is_selected(&fx.path("alpha/inner")));
assert!(!tree.is_selected(&fx.path("alpha/notes.txt")));
}