Skip to content

Commit

Permalink
add os agnostic tests
Browse files Browse the repository at this point in the history
  • Loading branch information
woojiq committed Dec 22, 2023
1 parent ce81d5d commit ed4bec3
Showing 1 changed file with 95 additions and 52 deletions.
147 changes: 95 additions & 52 deletions helix-core/tests/path.rs
Original file line number Diff line number Diff line change
@@ -1,71 +1,114 @@
use std::{
env::set_current_dir,
error::Error,
path::{Component, Path, PathBuf},
};

#[cfg(unix)]
use std::os::unix;

use std::path::PathBuf;
use std::{error::Error, path::Path};
#[cfg(windows)]
use std::os::windows;

use helix_core::path::get_normalized_path;
use tempfile::{NamedTempFile, TempDir};
use tempfile::Builder;

fn file_name_from_path<T: AsRef<Path>>(path: T) -> String {
path.as_ref()
.file_name()
.unwrap()
.to_string_lossy()
.into_owned()
}

fn assert_path_from_str(case: &str, expected: &str) {
assert_eq!(
get_normalized_path(&PathBuf::from(case)),
PathBuf::from(expected)
);
}

#[cfg(unix)]
#[test]
fn test_unix_path_normalize() -> Result<(), Box<dyn Error>> {
// root/
// ├── link_up -> dir1/orig_file
fn test_normalize_path() -> Result<(), Box<dyn Error>> {
// tmp/root/
// ├── link -> dir1/orig_file
// ├── dir1/
// │ └── orig_file
// └── dir2/
// └── dir_link -> ../dir1/
let root = TempDir::new()?;
let dir1 = TempDir::new_in(&root)?;
let orig_file = NamedTempFile::new_in(&dir1)?;
let dir2 = TempDir::new_in(&root)?;
// Get temp path name for linking
let dir_link = NamedTempFile::new_in(&dir2)?.path().to_owned();
let link_up = NamedTempFile::new_in(&root)?.path().to_owned();

unix::fs::symlink(&dir1, &dir_link)?;
unix::fs::symlink(&orig_file, &link_up)?;
let tmp_prefix = std::env::temp_dir();
set_current_dir(&tmp_prefix)?;

let mut test_case = format!(
"{}/.././{}/{}/../{}/{}",
dir1.path().to_string_lossy(),
file_name_from_path(&dir2),
file_name_from_path(&dir_link),
file_name_from_path(&dir1),
file_name_from_path(&orig_file),
);
// normalized: path-to-root/root/dir2/dir_link/../dir1/orig_file
let mut normalized = format!(
"{}/../{}/{}",
dir_link.to_string_lossy(),
file_name_from_path(&dir1),
file_name_from_path(&orig_file)
);
// Create a tree structure as shown above
let root = Builder::new().prefix("root-").tempdir()?;
let dir1 = Builder::new().prefix("dir1-").tempdir_in(&root)?;
let orig_file = Builder::new().prefix("orig_file-").tempfile_in(&dir1)?;
let dir2 = Builder::new().prefix("dir2-").tempdir_in(&root)?;

assert_path_from_str(&test_case, &normalized);
// Create path and delete existing file
let dir_link = Builder::new()
.prefix("dir_link-")
.tempfile_in(&dir2)?
.path()
.to_owned();
let link = Builder::new()
.prefix("link-")
.tempfile_in(&root)?
.path()
.to_owned();

test_case.push_str("/fake/.././fake/yes.txt");
normalized.push_str("/fake/yes.txt");
#[cfg(unix)]
{
unix::fs::symlink(&dir1, &dir_link)?;
unix::fs::symlink(&orig_file, &link)?;
}
#[cfg(windows)]
{
windows::fs::symlink_dir(&dir1, &dir_link)?;
windows::fs::symlink_file(&orig_file, &link)?;
}

assert_path_from_str(&test_case, &normalized);
// root/link
let path = link.strip_prefix(&tmp_prefix)?;
assert_eq!(
get_normalized_path(path),
path,
"input {:?} and symlink last component shouldn't be resolved",
path
);

// root/dir2/dir_link/orig_file/../..
let path = dir_link
.strip_prefix(&tmp_prefix)
.unwrap()
.join(orig_file.path().file_name().unwrap())
.join(Component::ParentDir)
.join(Component::ParentDir);
let expected = dir_link
.strip_prefix(&tmp_prefix)
.unwrap()
.join(Component::ParentDir);
assert_eq!(
get_normalized_path(&path),
expected,
"input {:?} and \"..\" should not erase the simlink that goes ahead",
&path
);

assert_eq!(get_normalized_path(&link_up), link_up);
// root/link/.././../dir2/../
let path = link
.strip_prefix(&tmp_prefix)
.unwrap()
.join(Component::ParentDir)
.join(Component::CurDir)
.join(Component::ParentDir)
.join(dir2.path().file_name().unwrap())
.join(Component::ParentDir);
let expected = link
.strip_prefix(&tmp_prefix)
.unwrap()
.join(Component::ParentDir)
.join(Component::ParentDir);
assert_eq!(get_normalized_path(&path), expected, "input {:?}", &path);

// root/../..
let path = root
.path()
.strip_prefix(&tmp_prefix)
.unwrap()
.join(Component::ParentDir)
.join(Component::ParentDir);
assert_eq!(
get_normalized_path(&path),
PathBuf::from(AsRef::<Path>::as_ref(&Component::ParentDir)),
"input {:?} and \"..\" should not be lost if there are no components ahead",
&path
);

Ok(())
}

0 comments on commit ed4bec3

Please sign in to comment.