kxio/tests/fs.rs

1057 lines
31 KiB
Rust
Raw Permalink Normal View History

2024-11-01 08:54:55 +00:00
use assert2::let_assert;
use kxio::fs;
type TestResult = Result<(), fs::Error>;
mod path {
use fs::{PathHandle, PathMarker};
2024-11-01 08:54:55 +00:00
use super::*;
#[test]
fn temp_as_real() {
let fs = fs::temp().expect("temp fs");
let read = fs.as_real();
assert_eq!(read.base(), fs.base());
}
#[test]
fn display() {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let path_handle = fs.path(&path);
assert_eq!(path_handle.to_string(), format!("{}", path.display()));
}
2024-11-08 17:03:25 +00:00
mod is_link {
use super::*;
#[test]
fn create_soft_link() -> TestResult {
let fs = fs::temp().expect("temp fs");
let file_path = fs.base().join("foo");
let file = fs.file(&file_path);
file.write("content").expect("write");
let link_path = fs.base().join("bar");
let link = fs.path(&link_path);
file.soft_link(&link).expect("soft_link");
let exists = link.exists().expect("exists");
assert!(exists);
let is_link = link.is_link().expect("is_link");
assert!(is_link);
Ok(())
}
#[test]
fn dir_is_not_a_link() {
let fs = fs::temp().expect("temp fs");
let dir_path = fs.base().join("foo");
let dir = fs.dir(&dir_path);
dir.create().expect("create");
let is_link = dir.is_link().expect("is link");
assert!(!is_link);
}
#[test]
fn file_is_not_a_link() {
let fs = fs::temp().expect("temp fs");
let file_path = fs.base().join("foo");
let file = fs.file(&file_path);
file.write("content").expect("write");
let is_link = file.is_link().expect("is link");
assert!(!is_link);
}
}
mod set_permissions {
use super::*;
#[test]
fn should_set_permissions() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let file = fs.file(&path);
file.write("bar").expect("write");
let md = file.metadata().expect("metadata");
assert!(md.is_file());
let mut perms = md.permissions();
perms.set_readonly(true);
let path = fs.path(&path);
path.set_permissions(perms).expect("set_permissions");
let md = file.metadata().expect("metadata");
assert!(md.is_file());
assert!(md.permissions().readonly());
Ok(())
}
}
2024-11-03 20:29:08 +00:00
mod read_link {
use super::*;
#[test]
fn should_read_link() -> TestResult {
let fs = fs::temp().expect("temp fs");
let file_path = fs.base().join("foo");
let file = fs.file(&file_path);
file.write("bar").expect("write");
let link_path = fs.base().join("bar");
let link = fs.path(&link_path);
file.soft_link(&link).expect("soft_link");
let read_link = link.read_link().expect("read_link");
assert_eq!(read_link.as_pathbuf(), file_path);
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.path(&path).read_link()
);
Ok(())
}
}
2024-11-03 17:49:34 +00:00
mod metadata {
use super::*;
#[test]
fn should_return_metadata() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let file = fs.file(&path);
file.write("bar").expect("write");
let md = file.metadata().expect("metadata");
assert!(md.is_file());
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.file(&path).metadata()
);
Ok(())
}
}
mod path_of {
use super::*;
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
2024-11-01 08:54:55 +00:00
let_assert!(
Err(fs::Error::PathTraversal { base, path: _path }) = fs.path_of("..".into())
);
assert_eq!(base, fs.base());
2024-11-01 08:54:55 +00:00
Ok(())
}
#[test]
fn matches_joins() -> TestResult {
let fs = fs::temp().expect("temp fs");
let joined = fs.base().join("foo").join("bar");
let path_of = fs
.path_of("foo/bar".into())
.expect("parse foo/bar into path");
assert_eq!(joined, path_of);
Ok(())
}
2024-11-01 08:54:55 +00:00
}
mod as_dir {
use super::*;
2024-11-01 08:54:55 +00:00
#[test]
fn path_is_dir_as_dir_some() -> TestResult {
let fs = fs::temp().expect("temp fs");
2024-11-01 08:54:55 +00:00
let path = fs.base().join("foo");
let dir = fs.dir(&path);
dir.create().expect("create");
2024-11-01 08:54:55 +00:00
let_assert!(Ok(Some(as_dir)) = fs.path(&path).as_dir());
assert_eq!(dir.as_pathbuf(), as_dir.as_pathbuf());
Ok(())
}
#[test]
fn path_is_file_as_dir_none() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let file = fs.file(&path);
file.write("contents").expect("create");
let_assert!(Ok(Some(as_file)) = fs.path(&path).as_file());
assert_eq!(file.as_pathbuf(), as_file.as_pathbuf());
assert_eq!(as_file.reader().expect("reader").to_string(), "contents");
Ok(())
}
2024-11-01 08:54:55 +00:00
}
mod as_file {
use super::*;
#[test]
fn path_is_dir_as_file_none() -> TestResult {
let fs = fs::temp().expect("temp fs");
2024-11-01 08:54:55 +00:00
let path = fs.base().join("foo");
let dir = fs.dir(&path);
dir.create().expect("create");
let_assert!(Ok(None) = fs.path(&path).as_file());
Ok(())
}
#[test]
fn path_is_file_as_file_some() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let file = fs.file(&path);
file.write("contents").expect("create");
let_assert!(Ok(None) = fs.path(&path).as_dir());
Ok(())
}
}
mod is_dir {
use super::*;
#[test]
fn should_be_true_when_is_a_dir() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
fs.dir(&path).create().expect("create");
let is_dir = fs.path(&path).is_dir().expect("is_dir");
assert!(is_dir);
Ok(())
}
#[test]
fn should_be_false_when_is_a_file() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
fs.file(&path).write("bar").expect("write");
let is_dir = fs.path(&path).is_dir().expect("is_dir");
assert!(!is_dir);
Ok(())
}
#[test]
#[ignore]
fn should_be_false_when_is_a_link() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
// let_assert!(Ok(_) = fs.file_write(&path, "bar"));
let is_dir = fs.path(&path).is_dir().expect("is_dir");
assert!(!is_dir);
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.dir(&path).is_dir()
);
Ok(())
}
}
mod exists {
use super::*;
#[test]
fn should_be_true_when_it_exists() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
fs.file(&path).write("bar").expect("write");
let exists = fs.path(&path).exists().expect("exists");
assert!(exists);
Ok(())
}
#[test]
fn should_be_false_when_it_does_not_exist() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let exists = fs.path(&path).exists().expect("exists");
assert!(!exists);
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.path(&path).exists()
);
Ok(())
}
}
mod is_file {
use super::*;
#[test]
fn should_be_true_when_is_a_file() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
fs.file(&path).write("bar").expect("write");
let is_file = fs.path(&path).is_file().expect("is_file");
assert!(is_file);
Ok(())
}
#[test]
fn should_be_false_when_is_a_dir() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
fs.dir(&path).create().expect("create");
let is_file = fs.path(&path).is_file().expect("is_file");
assert!(!is_file);
Ok(())
}
#[test]
#[ignore]
fn should_be_false_when_is_a_link() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
// let_assert!(Ok(_) = fs.file_write(&path, "bar"));
let is_file = fs.path(&path).is_file().expect("is_file");
assert!(!is_file);
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.file(&path).is_file()
);
Ok(())
}
}
mod rename {
use super::*;
#[test]
fn should_rename_a_file() -> TestResult {
let fs = fs::temp().expect("temp fs");
let src_path = fs.base().join("foo");
let src = fs.file(&src_path);
src.write("bar").expect("write");
let src_contents = src.reader().expect("reader").to_string();
let dst_path = fs.base().join("bar");
let dst = fs.file(&dst_path);
src.rename(&dst).expect("rename");
let dst_contents = dst.reader().expect("reader").to_string();
assert_eq!(src_contents, dst_contents);
let src_exists = src.exists().expect("exists");
assert!(!src_exists);
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let src_path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.file(&src_path).rename(&fs.file(&src_path))
);
Ok(())
}
}
2024-11-08 17:03:25 +00:00
mod from_pathbuf {
use std::path::PathBuf;
use super::*;
#[test]
fn should_convert_from_pathbuf() {
let fs = fs::temp().expect("temp fs");
let src_pathbuf = fs.base().join("foo");
let dst_pathbuf: PathBuf = fs.path(&src_pathbuf).into();
assert_eq!(src_pathbuf, dst_pathbuf);
}
}
#[test]
fn from_file() {
let fs = fs::temp().expect("temp fs");
let file_path = fs.base().join("foo");
let file = fs.file(&file_path);
let path: PathHandle<PathMarker> = file.into();
assert_eq!(path.as_pathbuf(), file_path);
}
#[test]
fn from_dir() {
let fs = fs::temp().expect("temp fs");
let dir_path = fs.base().join("foo");
let dir = fs.dir(&dir_path);
let path: PathHandle<PathMarker> = dir.into();
assert_eq!(path.as_pathbuf(), dir_path);
}
}
2024-11-01 08:54:55 +00:00
mod file {
use super::*;
#[test]
fn display() {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let file_handle = fs.file(&path);
assert_eq!(file_handle.to_string(), format!("{}", path.display()));
}
#[test]
fn create_hard_link() -> TestResult {
let fs = fs::temp().expect("temp fs");
let file_path = fs.base().join("foo");
let file = fs.file(&file_path);
file.write("content").expect("write");
let link_path = fs.base().join("bar");
let link = fs.file(&link_path);
file.hard_link(&link).expect("hard_link");
let exists = link.exists().expect("exists");
assert!(exists);
Ok(())
}
2024-11-01 08:54:55 +00:00
#[test]
/// Write to a file, read it, verify it exists, is a file and has the expected contents
fn write_read_file_exists() -> TestResult {
let fs = fs::temp().expect("temp fs");
let pathbuf = fs.base().join("foo");
let file = fs.file(&pathbuf);
2024-11-01 08:54:55 +00:00
file.write("content").expect("write");
let c = file.reader().expect("reader").to_string();
assert_eq!(c, "content");
let path = fs.path(&pathbuf);
2024-11-01 08:54:55 +00:00
let exists = path.exists().expect("exists");
assert!(exists);
let is_file = path.is_file().expect("is_file");
assert!(is_file);
Ok(())
}
2024-11-01 20:50:20 +00:00
2024-11-08 17:03:25 +00:00
#[test]
fn use_file_as_file() {
let fs = fs::temp().expect("temp fs");
let file_path = fs.base().join("foo");
let file = fs.file(&file_path);
file.write("contents").expect("write");
file.remove().expect("remove");
}
#[test]
fn use_dir_as_file() {
let fs = fs::temp().expect("temp fs");
let dir_path = fs.base().join("foo");
let dir = fs.dir(&dir_path);
dir.create().expect("create");
let file = fs.file(&dir_path);
let_assert!(Err(fs::Error::NotAFile { path }) = file.remove());
assert_eq!(path, dir_path);
}
#[test]
fn use_link_as_file() {
let fs = fs::temp().expect("temp fs");
let file_path = fs.base().join("foo");
let file = fs.file(&file_path);
file.write("contents").expect("write");
let link_path = fs.base().join("bar");
let link = fs.path(&link_path);
file.soft_link(&link).expect("soft_link");
let path = fs.file(&link_path);
let contents = path.reader().expect("reader").to_string();
assert_eq!(contents, "contents");
path.remove().expect("remove");
}
mod from_path {
use fs::{Error, FileHandle};
use super::*;
#[test]
fn path_is_dir() {
let fs = fs::temp().expect("temp fs");
let pathbuf = fs.base().join("foo");
let dir = fs.dir(&pathbuf);
dir.create().expect("create dir");
let path = fs.path(&pathbuf);
let_assert!(Err(Error::NotAFile { path: err_path }) = FileHandle::try_from(path));
assert_eq!(err_path, pathbuf);
}
#[test]
fn path_is_file() {
let fs = fs::temp().expect("temp fs");
let pathbuf = fs.base().join("foo");
let file = fs.file(&pathbuf);
file.write("contents").expect("write file");
let path = fs.path(&pathbuf);
let_assert!(Ok(file_result) = FileHandle::try_from(path));
assert_eq!(file_result.as_pathbuf(), pathbuf);
}
#[test]
fn path_is_error() {
let fs = fs::temp().expect("temp fs");
let pathbuf = fs.base().join("foo");
// does not exist
let path = fs.path(&pathbuf);
let_assert!(Err(Error::NotAFile { path: err_path }) = FileHandle::try_from(path));
assert_eq!(err_path, pathbuf);
}
}
mod remove {
use super::*;
#[test]
fn should_remove_a_file() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let file = fs.file(&path);
file.write("bar").expect("write");
file.remove().expect("remove");
let exists = file.exists().expect("exists");
assert!(!exists);
2024-11-01 08:54:55 +00:00
Ok(())
}
2024-11-01 08:54:55 +00:00
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.file(&path).remove()
);
2024-11-01 08:54:55 +00:00
Ok(())
}
2024-11-01 08:54:55 +00:00
}
mod copy {
use super::*;
#[test]
fn should_copy_a_file() -> TestResult {
let fs = fs::temp().expect("temp fs");
let src_path = fs.base().join("foo");
let src = fs.file(&src_path);
src.write("bar").expect("write");
let dst_path = fs.base().join("bar");
let dst = fs.file(&dst_path);
src.copy(&dst).expect("copy");
let src_contents = src.reader().expect("reader").to_string();
let dst_contents = dst.reader().expect("reader").to_string();
assert_eq!(src_contents, dst_contents);
2024-11-01 08:54:55 +00:00
Ok(())
}
2024-11-01 08:54:55 +00:00
}
mod symlink_metadata {
use super::*;
#[test]
fn should_return_metadata_for_a_file() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let file = fs.file(&path);
file.write("bar").expect("write");
let md = file.symlink_metadata().expect("metadata");
assert!(md.is_file());
Ok(())
}
#[test]
fn should_return_metadata_for_a_dir() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let dir = fs.dir(&path);
dir.create().expect("create");
let md = dir.symlink_metadata().expect("metadata");
assert!(md.is_dir());
Ok(())
}
#[test]
fn should_return_metadata_for_a_symlink() -> TestResult {
let fs = fs::temp().expect("temp fs");
let file_path = fs.base().join("foo");
let file = fs.file(&file_path);
file.write("bar").expect("write");
let link_path = fs.base().join("bar");
let link = fs.path(&link_path);
file.soft_link(&link).expect("soft_link");
let md = link.symlink_metadata().expect("metadata");
assert!(md.is_symlink());
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.file(&path).symlink_metadata()
);
Ok(())
}
}
mod reader {
use super::*;
mod to_string {
use super::*;
2024-11-08 17:03:25 +00:00
use std::time::SystemTime;
#[test]
2024-11-08 17:03:25 +00:00
fn read_file_to_string() {
let fs = fs::temp().expect("temp fs");
2024-11-01 08:54:55 +00:00
let path = fs.base().join("foo");
let file = fs.file(&path);
2024-11-08 17:03:25 +00:00
let line3 = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("duration")
.as_millis()
.to_string();
let contents = format!("line 1\nline 2\n{line3}");
file.write(&contents).expect("write");
2024-11-01 08:54:55 +00:00
let reader = file.reader().expect("reader");
let string = reader.as_str().expect("as_str");
2024-11-08 17:03:25 +00:00
assert_eq!(string, contents);
}
#[test]
fn read_file_lines() {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let file = fs.file(&path);
let line3 = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
.expect("duration")
.as_millis()
.to_string();
let contents = format!("line 1\nline 2\n{line3}");
file.write(&contents).expect("write");
2024-11-01 08:54:55 +00:00
2024-11-08 17:03:25 +00:00
let reader = file.reader().expect("reader");
let lines = reader.lines().expect("lines").collect::<Vec<_>>();
2024-11-01 08:54:55 +00:00
2024-11-08 17:03:25 +00:00
assert_eq!(lines, vec!["line 1", "line 2", &line3]);
}
}
mod lines {
use super::*;
#[test]
fn read_file_lines() -> TestResult {
let fs = fs::temp().expect("temp fs");
2024-11-01 08:54:55 +00:00
let path = fs.base().join("foo");
let file = fs.file(&path);
file.write("line 1\nline 2").expect("write");
2024-11-01 08:54:55 +00:00
let reader = file.reader().expect("reader");
let lines = reader.lines().expect("lines").collect::<Vec<_>>();
2024-11-01 08:54:55 +00:00
assert_eq!(lines, vec!["line 1", "line 2"]);
2024-11-01 08:54:55 +00:00
Ok(())
}
}
mod bytes {
use super::*;
#[test]
fn should_return_bytes() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let file = fs.file(&path);
file.write("bar").expect("write");
let reader = file.reader().expect("reader");
let bytes = reader.bytes();
assert_eq!(bytes.len(), 3);
assert_eq!(bytes[0], b'b');
assert_eq!(bytes[1], b'a');
assert_eq!(bytes[2], b'r');
Ok(())
}
}
2024-11-01 08:54:55 +00:00
}
}
mod dir {
2024-11-03 11:54:07 +00:00
use super::*;
2024-11-03 14:06:22 +00:00
mod from_path {
use fs::{DirHandle, Error};
use super::*;
#[test]
fn display() {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let dir_handle = fs.dir(&path);
assert_eq!(dir_handle.to_string(), format!("{}/", path.display()));
}
#[test]
fn path_is_dir() {
let fs = fs::temp().expect("temp fs");
let pathbuf = fs.base().join("foo");
let dir = fs.dir(&pathbuf);
dir.create().expect("create dir");
let path = fs.path(&pathbuf);
let_assert!(Ok(dir_result) = DirHandle::try_from(path));
assert_eq!(dir_result.as_pathbuf(), pathbuf);
}
#[test]
fn path_is_file() {
let fs = fs::temp().expect("temp fs");
let pathbuf = fs.base().join("foo");
let file = fs.file(&pathbuf);
file.write("contents").expect("write file");
let path = fs.path(&pathbuf);
let_assert!(Err(Error::NotADirectory { path: err_path }) = DirHandle::try_from(path));
assert_eq!(err_path, pathbuf);
}
#[test]
fn path_is_error() {
let fs = fs::temp().expect("temp fs");
let pathbuf = fs.base().join("foo");
// does not exist
let path = fs.path(&pathbuf);
let_assert!(Err(Error::NotADirectory { path: err_path }) = DirHandle::try_from(path));
assert_eq!(err_path, pathbuf);
}
}
mod create {
use super::*;
#[test]
fn should_create_a_dir() -> TestResult {
let fs = fs::temp().expect("temp fs");
let pathbuf = fs.base().join("subdir");
2024-11-03 14:06:22 +00:00
fs.dir(&pathbuf).create().expect("create");
2024-11-03 14:06:22 +00:00
let exists = fs.path(&pathbuf).exists().expect("exitss");
assert!(exists);
2024-11-03 14:06:22 +00:00
let is_dir = fs.path(&pathbuf).is_dir().expect("is dir");
assert!(is_dir);
2024-11-01 08:54:55 +00:00
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.dir(&path).create()
);
2024-11-01 08:54:55 +00:00
Ok(())
}
2024-11-01 08:54:55 +00:00
}
mod create_all {
use super::*;
2024-11-01 08:54:55 +00:00
#[test]
fn should_create_a_dir() -> TestResult {
let fs = fs::temp().expect("temp fs");
let pathbuf = fs.base().join("subdir").join("child");
2024-11-01 08:54:55 +00:00
fs.dir(&pathbuf).create_all().expect("create_all");
2024-11-01 08:54:55 +00:00
let path = fs.path(&pathbuf);
let exists = path.exists().expect("exists");
assert!(exists, "path exists");
2024-11-01 08:54:55 +00:00
let is_dir = path.is_dir().expect("is_dir");
assert!(is_dir, "path is a directory");
2024-11-01 08:54:55 +00:00
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.dir(&path).create_all()
);
2024-11-01 08:54:55 +00:00
Ok(())
}
2024-11-01 08:54:55 +00:00
}
mod read {
use crate::fs::DirItem;
2024-11-01 08:54:55 +00:00
use super::*;
2024-11-01 08:54:55 +00:00
#[test]
fn should_return_dir_items() -> TestResult {
let fs = fs::temp().expect("temp fs");
let file1 = fs.base().join("file-1");
let dir = fs.base().join("dir");
let file2 = dir.join("file-2");
fs.file(&file1).write("file-1").expect("write: file-1");
fs.dir(&dir).create().expect("create dir");
fs.file(&file2).write("file-2").expect("write: file-2");
let items = fs
.dir(fs.base())
.read()
.expect("dir.read")
.filter_map(|i| i.ok())
.collect::<Vec<_>>();
assert_eq!(items.len(), 2);
assert!(items.contains(&DirItem::File(file1)));
assert!(items.contains(&DirItem::Dir(dir)));
2024-11-01 08:54:55 +00:00
Ok(())
}
#[test]
fn should_fail_on_not_a_dir() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("file");
fs.file(&path).write("contents").expect("write");
2024-11-01 08:54:55 +00:00
let_assert!(Err(fs::Error::NotADirectory { path: _path }) = fs.dir(&path).read());
2024-11-01 08:54:55 +00:00
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.dir(&path).read()
);
2024-11-03 14:18:32 +00:00
Ok(())
}
2024-11-03 14:18:32 +00:00
}
mod remove {
use super::*;
#[test]
fn should_remove_a_dir() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
fs.dir(&path).create().expect("create");
fs.dir(&path).remove().expect("remove");
let exists = fs.path(&path).exists().expect("exists");
assert!(!exists);
2024-11-03 14:18:32 +00:00
Ok(())
}
2024-11-03 11:28:00 +00:00
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.dir(&path).remove()
);
2024-11-03 14:12:40 +00:00
Ok(())
}
2024-11-03 14:12:40 +00:00
}
mod remove_all {
2024-11-03 11:36:20 +00:00
use super::*;
#[test]
fn should_remove_a_dir() -> TestResult {
2024-11-03 11:36:20 +00:00
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("foo");
let dir = fs.dir(&path);
dir.create().expect("create dir");
let sub_path = path.join("sub");
let sub = fs.dir(&sub_path);
sub.create().expect("create sub");
let file = sub_path.join("file");
fs.file(&file).write("contents").expect("write");
dir.remove_all().expect("remove");
let exists = dir.exists().expect("exists");
assert!(!exists);
Ok(())
}
#[test]
fn should_fail_on_path_traversal() -> TestResult {
let fs = fs::temp().expect("temp fs");
let path = fs.base().join("..").join("foo");
let_assert!(
Err(fs::Error::PathTraversal {
base: _base,
path: _path
}) = fs.dir(&path).remove_all()
);
2024-11-03 11:36:20 +00:00
Ok(())
}
}
}
mod canonicalize {
use std::path::Path;
use super::*;
#[test]
fn should_resolve_symlinks() -> TestResult {
let fs = fs::temp().expect("temp fs");
let file_path = fs.base().join("foo");
let file = fs.file(&file_path);
file.write("bar").expect("write");
let link_path = fs.base().join("link");
let link = fs.path(&link_path);
file.soft_link(&link).expect("create");
let canonical = link.canonicalize().expect("canonicalize");
let canonical = if canonical.starts_with("/private") {
// INFO: macos puts all temp files under /private
Path::new("/").join(canonical.strip_prefix("/private").unwrap())
} else {
canonical
};
assert_eq!(canonical, file_path);
Ok(())
}
}