use crate::{PathBoundary, StrictPathError};
#[test]
fn test_strict_path_accessors_and_manipulation() {
let temp = tempfile::tempdir().unwrap();
let restriction: PathBoundary = PathBoundary::try_new(temp.path()).unwrap();
let dir = restriction.strict_join("dir").unwrap();
dir.create_dir_all().unwrap();
let file = restriction.strict_join("dir/file.txt").unwrap();
file.write("hello").unwrap();
let display_str = file.strictpath_display().to_string();
assert!(!display_str.is_empty());
assert_eq!(
file.strictpath_file_name().unwrap().to_string_lossy(),
"file.txt"
);
assert_eq!(
file.strictpath_file_stem().unwrap().to_string_lossy(),
"file"
);
assert_eq!(
file.strictpath_extension().unwrap().to_string_lossy(),
"txt"
);
assert!(file.strictpath_starts_with(restriction.interop_path()));
assert!(file.strictpath_ends_with("file.txt"));
let parent = file.strictpath_parent().unwrap().unwrap();
assert!(parent.strictpath_ends_with("dir"));
let joined = file.strict_join("sibling.log").unwrap();
assert!(joined.strictpath_ends_with("file.txt/sibling.log"));
let renamed = file.strictpath_with_file_name("renamed.bin").unwrap();
assert!(renamed.strictpath_ends_with("dir/renamed.bin"));
let changed_ext = file.strictpath_with_extension("bak").unwrap();
assert!(changed_ext.strictpath_ends_with("dir/file.bak"));
let root: crate::path::strict_path::StrictPath<()> =
crate::path::strict_path::StrictPath::with_boundary(temp.path()).unwrap();
let err = root.strictpath_with_extension("x").unwrap_err();
match err {
StrictPathError::PathEscapesBoundary { .. } => {}
other => panic!("Unexpected error: {other:?}"),
}
assert!(file.exists());
assert!(file.is_file());
assert!(!dir.is_file());
assert!(dir.is_dir());
let md = file.metadata().unwrap();
assert!(md.len() > 0);
assert_eq!(file.read_to_string().unwrap(), "hello");
let bytes = file.read().unwrap();
assert_eq!(bytes, b"hello");
let tmp_sub = restriction.strict_join("dir/tmp").unwrap();
tmp_sub.create_dir_all().unwrap();
let tmp_file = restriction.strict_join("dir/tmp/note.txt").unwrap();
tmp_file.write("bye").unwrap();
assert!(tmp_file.exists());
tmp_file.remove_file().unwrap();
assert!(!tmp_file.exists());
tmp_sub.remove_dir().unwrap();
assert!(!tmp_sub.exists());
let deep_dir = restriction.strict_join("deep/a/b").unwrap();
deep_dir.create_dir_all().unwrap();
let deep_root = restriction.strict_join("deep").unwrap();
deep_root.remove_dir_all().unwrap();
assert!(!deep_root.exists());
}
#[cfg(feature = "virtual-path")]
#[test]
fn test_virtual_path_components_and_checks() {
let temp = tempfile::tempdir().unwrap();
let restriction: PathBoundary = PathBoundary::try_new(temp.path()).unwrap();
let jp = restriction.strict_join("a/b.txt").unwrap();
let vp = jp.clone().virtualize();
assert_eq!(vp.virtualpath_display().to_string(), "/a/b.txt");
assert_eq!(
vp.virtualpath_file_name().unwrap().to_string_lossy(),
"b.txt"
);
assert_eq!(vp.virtualpath_file_stem().unwrap().to_string_lossy(), "b");
assert_eq!(vp.virtualpath_extension().unwrap().to_string_lossy(), "txt");
assert!(vp.virtualpath_starts_with("a"));
assert!(vp.virtualpath_ends_with("b.txt"));
let vparent = vp.virtualpath_parent().unwrap().unwrap();
assert_eq!(vparent.virtualpath_display().to_string(), "/a");
let vsib = vp.virtual_join("c.log").unwrap();
assert_eq!(vsib.virtualpath_display().to_string(), "/a/b.txt/c.log");
assert_eq!(
vp.as_unvirtual().strictpath_display().to_string(),
jp.strictpath_display().to_string()
);
assert_eq!(
vp.as_unvirtual().strictpath_display().to_string(),
jp.strictpath_display().to_string()
);
let vfile = restriction
.strict_join("delegated/x.txt")
.unwrap()
.virtualize();
let vdir = restriction.strict_join("delegated").unwrap().virtualize();
vdir.create_dir_all().unwrap();
vfile.write(b"vdata").unwrap();
assert!(vfile.exists());
assert!(vfile.is_file());
assert!(vdir.is_dir());
assert_eq!(vfile.read().unwrap(), b"vdata");
assert_eq!(vfile.read_to_string().unwrap(), "vdata");
vfile.remove_file().unwrap();
assert!(!vfile.exists());
}