Unit test for tab::Message::Location
* Implement a working unit test for `tab::Message::Location` * Add more helper test functions and improve existing logic
This commit is contained in:
parent
5d51190169
commit
b0e8299ff4
2 changed files with 138 additions and 4 deletions
57
src/app.rs
57
src/app.rs
|
|
@ -1187,6 +1187,17 @@ pub(crate) mod test_utils {
|
|||
}
|
||||
}
|
||||
|
||||
/// Read directory entries from `path` and sort.
|
||||
pub fn read_dir_sorted(path: &Path) -> io::Result<Vec<PathBuf>> {
|
||||
let mut entries: Vec<_> = path
|
||||
.read_dir()?
|
||||
.map(|maybe_entry| maybe_entry.map(|entry| entry.path()))
|
||||
.collect::<io::Result<_>>()?;
|
||||
entries.sort_by(|a, b| sort_files(a, b));
|
||||
|
||||
Ok(entries)
|
||||
}
|
||||
|
||||
/// Equality for [Path] and [Item].
|
||||
pub fn eq_path_item(path: &Path, item: &Item) -> bool {
|
||||
let name = path
|
||||
|
|
@ -1214,4 +1225,50 @@ pub(crate) mod test_utils {
|
|||
&& path == item.path
|
||||
&& is_hidden == item.hidden
|
||||
}
|
||||
|
||||
/// Asserts `tab`'s location changed to `path`
|
||||
pub fn assert_eq_tab_path(tab: &Tab, path: &Path) {
|
||||
// Paths should be the same
|
||||
let Location::Path(ref tab_path) = tab.location else {
|
||||
panic!("Expected tab's location to be a path");
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
path,
|
||||
tab_path,
|
||||
"Tab's path is {} instead of being updated to {}",
|
||||
tab_path.display(),
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
|
||||
/// Assert that tab's items are equal to a path's entries.
|
||||
pub fn assert_eq_tab_path_contents(tab: &Tab, path: &Path) {
|
||||
let Location::Path(ref tab_path) = tab.location else {
|
||||
panic!("Expected tab's location to be a path");
|
||||
};
|
||||
|
||||
// Tab items are sorted so paths from read_dir must be too
|
||||
let entries = read_dir_sorted(path).expect("should be able to read paths from temp dir");
|
||||
|
||||
// Check lengths.
|
||||
// `items_opt` is optional and the directory at `path` may have zero entries
|
||||
// Therefore, this doesn't panic if `items_opt` is None
|
||||
let items_len = tab
|
||||
.items_opt
|
||||
.as_ref()
|
||||
.map(|items| items.len())
|
||||
.unwrap_or_default();
|
||||
assert_eq!(entries.len(), items_len);
|
||||
|
||||
assert!(
|
||||
entries
|
||||
.into_iter()
|
||||
.zip(tab.items_opt.clone().unwrap_or_default())
|
||||
.all(|(a, b)| eq_path_item(&a, &b)),
|
||||
"Path ({}) and Tab path ({}) don't have equal contents",
|
||||
path.display(),
|
||||
tab_path.display()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
85
src/tab.rs
85
src/tab.rs
|
|
@ -1038,13 +1038,14 @@ impl Tab {
|
|||
mod tests {
|
||||
use std::io;
|
||||
|
||||
use cosmic::iced_runtime::keyboard::Modifiers;
|
||||
use log::debug;
|
||||
use test_log::test;
|
||||
|
||||
use super::scan_path;
|
||||
use super::{scan_path, Item, Location, Message, Tab};
|
||||
use crate::app::test_utils::{
|
||||
empty_fs, eq_path_item, simple_fs, sort_files, NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN,
|
||||
NUM_NESTED,
|
||||
assert_eq_tab_path, assert_eq_tab_path_contents, empty_fs, eq_path_item, simple_fs,
|
||||
sort_files, NAME_LEN, NUM_DIRS, NUM_FILES, NUM_HIDDEN, NUM_NESTED,
|
||||
};
|
||||
|
||||
#[test]
|
||||
|
|
@ -1099,8 +1100,84 @@ mod tests {
|
|||
let actual = scan_path(&path.to_owned());
|
||||
|
||||
assert_eq!(0, path.read_dir()?.count());
|
||||
assert_eq!(0, actual.len());
|
||||
assert!(actual.is_empty());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_location_changes_location() -> io::Result<()> {
|
||||
let fs = simple_fs(NUM_FILES, NUM_NESTED, NUM_DIRS, NUM_NESTED, NAME_LEN)?;
|
||||
let path = fs.path();
|
||||
|
||||
// Next directory in temp directory
|
||||
let next_dir = path
|
||||
.read_dir()?
|
||||
.filter_map(|entry| {
|
||||
entry.ok().and_then(|entry| {
|
||||
let path = entry.path();
|
||||
if path.is_dir() {
|
||||
Some(path)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.next()
|
||||
.expect("temp directory should have at least one directory");
|
||||
|
||||
let mut tab = Tab::new(Location::Path(path.to_owned()));
|
||||
debug!(
|
||||
"Emitting Message::Location(Location::Path(\"{}\"))",
|
||||
next_dir.display()
|
||||
);
|
||||
tab.update(
|
||||
Message::Location(Location::Path(next_dir.clone())),
|
||||
Modifiers::empty(),
|
||||
);
|
||||
|
||||
// Validate that the tab's path updated
|
||||
// NOTE: `items_opt` is set to None with Message::Location so this ONLY checks for equal paths
|
||||
// If item contents are NOT None then this needs to be reevaluated for correctness
|
||||
assert_eq_tab_path(&tab, &next_dir);
|
||||
assert!(
|
||||
tab.items_opt.is_none(),
|
||||
"Tab's `items` is not None which means this test needs to be updated"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_click_single_selects_item() -> io::Result<()> {
|
||||
let fs = simple_fs(NUM_FILES, NUM_NESTED, NUM_DIRS, NUM_NESTED, NAME_LEN)?;
|
||||
let path = fs.path();
|
||||
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_click_double_opens_folder() -> io::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_click_ctrl_selects_multiple() -> io::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_gonext_moves_forward_in_history() -> io::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_goprev_moves_backward_in_history() -> io::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tab_empty_history_does_nothing_on_prev_next() -> io::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue