#![allow(non_upper_case_globals)]
#![allow(clippy::bool_comparison)]
use std::path::{Path, PathBuf};
use std::fs::create_dir_all as create_dirs;
use std::fs::remove_dir_all as remove_dirs;
use std::sync::{Mutex, LazyLock};
use minstd::MINSTD;
const TEST_FNAME: &str = "normalizefs.txt";
static shared_rng: LazyLock<Mutex<MINSTD>> = LazyLock::new(||
{
let g = minstd::MINSTD::seed(minstd::clamp_seed(stdrandom::fast_i32()));
Mutex::new(g)
});
fn create_file(file: impl AsRef<Path>) {
use std::fs::OpenOptions;
OpenOptions::new()
.read(false)
.write(true)
.create(true)
.truncate(true)
.open(file).expect("file created");
}
fn exists(file: impl AsRef<Path>) -> bool {
use std::fs::OpenOptions;
OpenOptions::new()
.read(true)
.write(false)
.create(false)
.open(file).is_ok()
}
fn exists_in(dir: impl AsRef<Path>) -> bool {
exists( dir.as_ref().join( TEST_FNAME ) )
}
fn prepare_dirs(levels: isize, inlevel: isize) -> (PathBuf,PathBuf) {
let tmp = std::env::temp_dir();
let mut g = shared_rng.lock().expect("aquired valid rng mutex");
let root = tmp.join(format!("walkup{}", g.next()));
let mut current = { let mut c = PathBuf::new(); c.clone_from(&root); c };
create_dirs(&root).expect("root created");
for level in 0..=levels {
if level > 0 {
current = current.join(format!("dir{}", g.next()));
}
if level == inlevel {
create_dirs(¤t).expect("subdir created");
create_file(current.join(TEST_FNAME));
}
}
create_dirs(¤t).expect("lowest lvl subdir created");
(root, current)
}
#[test]
fn prepare_dirs_validation_lvl0_empty() {
let (top, low) = prepare_dirs(0, -1);
assert_eq! ( top, low );
assert! ( exists_in(&top) == false );
let _ = remove_dirs(top);
}
#[test]
fn prepare_dirs_validation_lvl0_with_file() {
let (top, low) = prepare_dirs(0, 0);
assert_eq! ( top, low );
assert! ( exists_in(&top) );
let _ = remove_dirs(top);
}
#[test]
fn prepare_dirs_validation_lvl1_empty() {
let (top, low) = prepare_dirs(1, -1);
let _ = remove_dirs(&top);
assert! ( top != low );
}
#[test]
fn prepare_dirs_validation_lvl1_with_file_low() {
let (top, low) = prepare_dirs(1, 1);
assert! ( top != low );
assert! ( exists_in(&top) == false );
assert! ( exists_in(&low) == true );
let _ = remove_dirs(top);
}
#[test]
fn prepare_dirs_validation_lvl1_with_file_high() {
let (top, low) = prepare_dirs(1, 0);
assert! ( top != low );
assert! ( exists_in(&top) == true );
assert! ( exists_in(&low) == false );
let _ = remove_dirs(top);
}
use super::canonicalize;
#[test]
fn make_absolute_curdir() {
let (top, low) = prepare_dirs(0, -1);
let _guard = shared_rng.lock().expect("Using rng as CD lock");
let saved = std::env::current_dir().unwrap();
std::env::set_current_dir(&low).unwrap();
let rc = canonicalize( "." );
std::env::set_current_dir(&saved).expect("Failed to change curdir back");
drop(_guard);
let _ = remove_dirs(top);
assert! ( rc.is_ok(), "make_absolute failed to read current_dir");
let rc = rc.unwrap();
assert_eq! ( low, rc );
assert! ( rc.is_absolute() );
}
#[test]
fn make_absolute_updir() {
let (top, low) = prepare_dirs(1, -1);
let _guard = shared_rng.lock().expect("Using rng as CD lock");
let saved = std::env::current_dir().unwrap();
std::env::set_current_dir(&low).unwrap();
let rc = canonicalize( ".." );
std::env::set_current_dir(&saved).expect("Failed to change curdir back");
drop(_guard);
let _ = remove_dirs(&top);
assert! ( rc.is_ok(), "make_absolute failed to read current_dir");
let rc = rc.unwrap();
assert! ( rc.is_absolute() );
}