use revue::widget::data::tree::Tree;
use revue::widget::data::tree::TreeNode;
#[test]
fn test_tree_query_default_empty() {
let tree = Tree::new();
assert_eq!(tree.query(), "");
}
#[test]
fn test_tree_query_after_set() {
let mut tree = Tree::new().searchable(true);
tree.set_query("test");
assert_eq!(tree.query(), "test");
}
#[test]
fn test_tree_is_searchable_default() {
let tree = Tree::new();
assert!(!tree.is_searchable());
}
#[test]
fn test_tree_is_searchable_enabled() {
let tree = Tree::new().searchable(true);
assert!(tree.is_searchable());
}
#[test]
fn test_tree_is_searchable_disabled_explicit() {
let tree = Tree::new().searchable(false);
assert!(!tree.is_searchable());
}
#[test]
fn test_tree_match_count_default() {
let tree = Tree::new().searchable(true);
assert_eq!(tree.match_count(), 0);
}
#[test]
fn test_tree_match_count_after_query() {
let mut tree = Tree::new()
.nodes(vec![
TreeNode::new("file1.txt"),
TreeNode::new("file2.txt"),
TreeNode::new("other.txt"),
])
.searchable(true);
tree.set_query("file");
assert_eq!(tree.match_count(), 2);
}
#[test]
fn test_tree_match_count_no_matches() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("file.txt")])
.searchable(true);
tree.set_query("xyz");
assert_eq!(tree.match_count(), 0);
}
#[test]
fn test_tree_current_match_index_default() {
let tree = Tree::new().searchable(true);
assert_eq!(tree.current_match_index(), 0);
}
#[test]
fn test_tree_current_match_index_with_matches() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("file1.txt"), TreeNode::new("file2.txt")])
.searchable(true);
tree.set_query("file");
assert_eq!(tree.current_match_index(), 1);
tree.next_match();
assert_eq!(tree.current_match_index(), 2);
}
#[test]
fn test_tree_set_query_updates_matches() {
let mut tree = Tree::new()
.nodes(vec![
TreeNode::new("apple.txt"),
TreeNode::new("banana.txt"),
TreeNode::new("application.txt"),
])
.searchable(true);
tree.set_query("app");
assert_eq!(tree.match_count(), 2); assert_eq!(tree.query(), "app");
}
#[test]
fn test_tree_set_query_empty_clears_matches() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("test")])
.searchable(true);
tree.set_query("test");
assert!(tree.match_count() > 0);
tree.set_query("");
assert_eq!(tree.match_count(), 0);
}
#[test]
fn test_tree_set_query_selects_first_match() {
let mut tree = Tree::new()
.nodes(vec![
TreeNode::new("zebra"),
TreeNode::new("apple"),
TreeNode::new("banana"),
])
.searchable(true);
tree.set_query("a");
assert_eq!(tree.selected_index(), 0);
assert_eq!(tree.match_count(), 3); }
#[test]
fn test_tree_set_query_with_string() {
let mut tree = Tree::new().searchable(true);
tree.set_query(String::from("test"));
assert_eq!(tree.query(), "test");
}
#[test]
fn test_tree_set_query_with_str() {
let mut tree = Tree::new().searchable(true);
tree.set_query("test");
assert_eq!(tree.query(), "test");
}
#[test]
fn test_tree_clear_query() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("test")])
.searchable(true);
tree.set_query("test");
assert!(tree.match_count() > 0);
tree.clear_query();
assert_eq!(tree.query(), "");
assert_eq!(tree.match_count(), 0);
assert_eq!(tree.current_match_index(), 0);
}
#[test]
fn test_tree_clear_query_when_already_empty() {
let mut tree = Tree::new().searchable(true);
tree.clear_query();
assert_eq!(tree.query(), "");
assert_eq!(tree.match_count(), 0);
}
#[test]
fn test_tree_update_matches_empty_query() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("test")])
.searchable(true);
tree.update_matches();
assert_eq!(tree.match_count(), 0);
}
#[test]
fn test_tree_update_matches_with_query() {
let mut tree = Tree::new()
.nodes(vec![
TreeNode::new("file1.txt"),
TreeNode::new("file2.txt"),
TreeNode::new("other.txt"),
])
.searchable(true);
tree.set_query("file");
assert_eq!(tree.match_count(), 2);
}
#[test]
fn test_tree_update_matches_resets_current_match() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("file1"), TreeNode::new("file2")])
.searchable(true);
tree.set_query("file");
tree.next_match();
assert_eq!(tree.current_match_index(), 2);
tree.set_query("file1");
assert_eq!(tree.current_match_index(), 1); }
#[test]
fn test_tree_next_match_single() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("test")])
.searchable(true);
tree.set_query("test");
let before = tree.selected_index();
let result = tree.next_match();
assert!(result); assert_eq!(tree.selected_index(), before);
assert_eq!(tree.current_match_index(), 1);
}
#[test]
fn test_tree_next_match_multiple() {
let mut tree = Tree::new()
.nodes(vec![
TreeNode::new("file1.txt"),
TreeNode::new("file2.txt"),
TreeNode::new("file3.txt"),
])
.searchable(true);
tree.set_query("file");
assert_eq!(tree.selected_index(), 0);
tree.next_match();
assert_eq!(tree.selected_index(), 1);
tree.next_match();
assert_eq!(tree.selected_index(), 2);
}
#[test]
fn test_tree_next_match_wraps() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("file1"), TreeNode::new("file2")])
.searchable(true);
tree.set_query("file");
tree.next_match();
assert_eq!(tree.current_match_index(), 2);
tree.next_match();
assert_eq!(tree.current_match_index(), 1); }
#[test]
fn test_tree_next_match_returns_true() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("file1"), TreeNode::new("file2")])
.searchable(true);
tree.set_query("file");
assert!(tree.next_match());
}
#[test]
fn test_tree_next_match_no_matches_returns_false() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("test")])
.searchable(true);
let result = tree.next_match();
assert!(!result);
}
#[test]
fn test_tree_prev_match_single() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("test")])
.searchable(true);
tree.set_query("test");
let before = tree.selected_index();
let result = tree.prev_match();
assert!(result); assert_eq!(tree.selected_index(), before);
}
#[test]
fn test_tree_prev_match_multiple() {
let mut tree = Tree::new()
.nodes(vec![
TreeNode::new("file1"),
TreeNode::new("file2"),
TreeNode::new("file3"),
])
.searchable(true);
tree.set_query("file");
tree.next_match();
tree.next_match();
assert_eq!(tree.current_match_index(), 3);
tree.prev_match();
assert_eq!(tree.current_match_index(), 2);
tree.prev_match();
assert_eq!(tree.current_match_index(), 1);
}
#[test]
fn test_tree_prev_match_wraps() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("file1"), TreeNode::new("file2")])
.searchable(true);
tree.set_query("file");
assert_eq!(tree.current_match_index(), 1);
tree.prev_match();
assert_eq!(tree.current_match_index(), 2); }
#[test]
fn test_tree_prev_match_no_matches_returns_false() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("test")])
.searchable(true);
let result = tree.prev_match();
assert!(!result);
}
#[test]
fn test_tree_is_match_true() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("file1.txt"), TreeNode::new("file2.txt")])
.searchable(true);
tree.set_query("file");
assert!(tree.is_match(0));
assert!(tree.is_match(1));
}
#[test]
fn test_tree_is_match_false() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("file1.txt"), TreeNode::new("other.txt")])
.searchable(true);
tree.set_query("file");
assert!(tree.is_match(0));
assert!(!tree.is_match(1));
}
#[test]
fn test_tree_is_match_no_query() {
let tree = Tree::new()
.nodes(vec![TreeNode::new("test")])
.searchable(true);
assert!(!tree.is_match(0));
}
#[test]
fn test_tree_get_match_no_query() {
let tree = Tree::new()
.nodes(vec![TreeNode::new("Hello World")])
.searchable(true);
let result = tree.get_match("Hello World");
assert!(result.is_none());
}
#[test]
fn test_tree_get_match_with_query() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("Hello World")])
.searchable(true);
tree.set_query("hw");
let result = tree.get_match("Hello World");
assert!(result.is_some());
}
#[test]
fn test_tree_get_match_no_match() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("Hello World")])
.searchable(true);
tree.set_query("xyz");
let result = tree.get_match("Hello World");
assert!(result.is_none());
}
#[test]
fn test_tree_get_match_indices() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("Hello World")])
.searchable(true);
tree.set_query("hw");
let result = tree.get_match("Hello World").unwrap();
assert!(result.indices.contains(&0)); assert!(result.indices.contains(&6)); }
#[test]
fn test_tree_get_match_case_sensitive() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("Hello World")])
.searchable(true);
tree.set_query("hw");
assert!(tree.get_match("Hello World").is_some());
assert!(tree.get_match("HELLO WORLD").is_some());
}
#[test]
fn test_tree_search_collapsed_children() {
let mut tree = Tree::new()
.node(
TreeNode::new("src")
.child(TreeNode::new("main.rs"))
.child(TreeNode::new("lib.rs")),
)
.searchable(true);
tree.set_query("main");
assert_eq!(tree.match_count(), 0); }
#[test]
fn test_tree_search_expanded_children() {
let mut tree = Tree::new()
.node(
TreeNode::new("src")
.expanded(true)
.child(TreeNode::new("main.rs"))
.child(TreeNode::new("lib.rs")),
)
.searchable(true);
tree.set_query("main");
assert_eq!(tree.match_count(), 1); }
#[test]
fn test_tree_search_partially_expanded() {
let mut tree = Tree::new()
.node(
TreeNode::new("src")
.expanded(true)
.child(TreeNode::new("utils").child(TreeNode::new("helper.rs")))
.child(TreeNode::new("main.rs")),
)
.searchable(true);
tree.set_query("helper");
assert_eq!(tree.match_count(), 0);
tree.set_query("main");
assert_eq!(tree.match_count(), 1); }
#[test]
fn test_tree_search_deeply_nested() {
let mut tree = Tree::new()
.node(
TreeNode::new("a").expanded(true).child(
TreeNode::new("b").expanded(true).child(
TreeNode::new("c")
.expanded(true)
.child(TreeNode::new("target")),
),
),
)
.searchable(true);
tree.set_query("target");
assert_eq!(tree.match_count(), 1);
}
#[test]
fn test_tree_search_multiple_roots() {
let mut tree = Tree::new()
.nodes(vec![
TreeNode::new("file1.txt"),
TreeNode::new("file2.txt"),
TreeNode::new("other.txt"),
])
.searchable(true);
tree.set_query("file");
assert_eq!(tree.match_count(), 2);
}
#[test]
fn test_tree_search_multiple_roots_with_children() {
let mut tree = Tree::new()
.node(
TreeNode::new("folder1")
.expanded(true)
.child(TreeNode::new("file1.txt"))
.child(TreeNode::new("file2.txt")),
)
.node(
TreeNode::new("folder2")
.expanded(true)
.child(TreeNode::new("other.txt")),
)
.searchable(true);
tree.set_query("file");
assert_eq!(tree.match_count(), 2);
}
#[test]
fn test_tree_set_query_special_chars() {
let mut tree = Tree::new()
.nodes(vec![
TreeNode::new("file-name.txt"),
TreeNode::new("file_name.txt"),
TreeNode::new("file.name.txt"),
])
.searchable(true);
tree.set_query("file-name");
assert_eq!(tree.match_count(), 1);
tree.set_query("file_name");
assert_eq!(tree.match_count(), 1);
tree.set_query("file.name");
assert_eq!(tree.match_count(), 1);
}
#[test]
fn test_tree_set_query_unicode() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("📁 文件夹")])
.searchable(true);
tree.set_query("文");
assert_eq!(tree.match_count(), 1);
}
#[test]
fn test_tree_set_query_whitespace() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("my file.txt")])
.searchable(true);
tree.set_query("my file");
assert_eq!(tree.match_count(), 1);
}
#[test]
fn test_tree_current_match_increments() {
let mut tree = Tree::new()
.nodes(vec![
TreeNode::new("file1"),
TreeNode::new("file2"),
TreeNode::new("file3"),
])
.searchable(true);
tree.set_query("file");
assert_eq!(tree.current_match_index(), 1);
tree.next_match();
assert_eq!(tree.current_match_index(), 2);
tree.next_match();
assert_eq!(tree.current_match_index(), 3);
}
#[test]
fn test_tree_matches_cleared_on_new_query() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("file1"), TreeNode::new("file2")])
.searchable(true);
tree.set_query("file");
assert_eq!(tree.match_count(), 2);
tree.set_query("file1");
assert_eq!(tree.match_count(), 1);
}
#[test]
fn test_tree_search_with_highlight_color() {
let mut tree = Tree::new()
.nodes(vec![TreeNode::new("test")])
.searchable(true)
.highlight_fg(revue::style::Color::YELLOW);
tree.set_query("test");
}