diff --git a/crates/nu-cli/tests/completions/mod.rs b/crates/nu-cli/tests/completions/mod.rs index a7f88dc3b0..590979251e 100644 --- a/crates/nu-cli/tests/completions/mod.rs +++ b/crates/nu-cli/tests/completions/mod.rs @@ -721,7 +721,7 @@ fn file_completion_quoted() { "`te#st.txt`".to_string(), "`te'st.txt`".to_string(), "`te(st).txt`".to_string(), - format!("`{}`", folder("test dir".into())), + format!("`{}`", folder("test dir")), ]; match_suggestions(expected_paths, suggestions); diff --git a/crates/nu-cli/tests/completions/support/completions_helpers.rs b/crates/nu-cli/tests/completions/support/completions_helpers.rs index 027ac9d997..623d6fbc5a 100644 --- a/crates/nu-cli/tests/completions/support/completions_helpers.rs +++ b/crates/nu-cli/tests/completions/support/completions_helpers.rs @@ -1,5 +1,6 @@ use nu_engine::eval_block; use nu_parser::parse; +use nu_path::{AbsolutePathBuf, PathBuf}; use nu_protocol::{ debugger::WithoutDebug, engine::{EngineState, Stack, StateWorkingSet}, @@ -7,14 +8,14 @@ use nu_protocol::{ }; use nu_test_support::fs; use reedline::Suggestion; -use std::path::{PathBuf, MAIN_SEPARATOR}; +use std::path::MAIN_SEPARATOR; fn create_default_context() -> EngineState { nu_command::add_shell_command_context(nu_cmd_lang::create_default_context()) } // creates a new engine with the current path into the completions fixtures folder -pub fn new_engine() -> (PathBuf, String, EngineState, Stack) { +pub fn new_engine() -> (AbsolutePathBuf, String, EngineState, Stack) { // Target folder inside assets let dir = fs::fixtures().join("completions"); let dir_str = dir @@ -69,7 +70,7 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) { } // creates a new engine with the current path into the completions fixtures folder -pub fn new_dotnu_engine() -> (PathBuf, String, EngineState, Stack) { +pub fn new_dotnu_engine() -> (AbsolutePathBuf, String, EngineState, Stack) { // Target folder inside assets let dir = fs::fixtures().join("dotnu_completions"); let dir_str = dir @@ -114,7 +115,7 @@ pub fn new_dotnu_engine() -> (PathBuf, String, EngineState, Stack) { (dir, dir_str, engine_state, stack) } -pub fn new_quote_engine() -> (PathBuf, String, EngineState, Stack) { +pub fn new_quote_engine() -> (AbsolutePathBuf, String, EngineState, Stack) { // Target folder inside assets let dir = fs::fixtures().join("quoted_completions"); let dir_str = dir @@ -149,7 +150,7 @@ pub fn new_quote_engine() -> (PathBuf, String, EngineState, Stack) { (dir, dir_str, engine_state, stack) } -pub fn new_partial_engine() -> (PathBuf, String, EngineState, Stack) { +pub fn new_partial_engine() -> (AbsolutePathBuf, String, EngineState, Stack) { // Target folder inside assets let dir = fs::fixtures().join("partial_completions"); let dir_str = dir @@ -205,16 +206,15 @@ pub fn match_suggestions(expected: Vec, suggestions: Vec) { } // append the separator to the converted path -pub fn folder(path: PathBuf) -> String { +pub fn folder(path: impl Into) -> String { let mut converted_path = file(path); converted_path.push(MAIN_SEPARATOR); - converted_path } // convert a given path to string -pub fn file(path: PathBuf) -> String { - path.into_os_string().into_string().unwrap_or_default() +pub fn file(path: impl Into) -> String { + path.into().into_os_string().into_string().unwrap() } // merge_input executes the given input into the engine @@ -223,7 +223,7 @@ pub fn merge_input( input: &[u8], engine_state: &mut EngineState, stack: &mut Stack, - dir: PathBuf, + dir: AbsolutePathBuf, ) -> Result<(), ShellError> { let (block, delta) = { let mut working_set = StateWorkingSet::new(engine_state); diff --git a/crates/nu-command/src/system/run_external.rs b/crates/nu-command/src/system/run_external.rs index a7ca822011..5e8527b45e 100644 --- a/crates/nu-command/src/system/run_external.rs +++ b/crates/nu-command/src/system/run_external.rs @@ -580,7 +580,7 @@ mod test { Playground::setup("test_expand_glob", |dirs, play| { play.with_files(&[Stub::EmptyFile("a.txt"), Stub::EmptyFile("b.txt")]); - let cwd = dirs.test(); + let cwd = dirs.test().as_std_path(); let actual = expand_glob("*.txt", cwd, Span::unknown(), &Signals::empty()).unwrap(); let expected = &["a.txt", "b.txt"]; diff --git a/crates/nu-command/tests/commands/database/into_sqlite.rs b/crates/nu-command/tests/commands/database/into_sqlite.rs index 595c88dc38..faa45040b3 100644 --- a/crates/nu-command/tests/commands/database/into_sqlite.rs +++ b/crates/nu-command/tests/commands/database/into_sqlite.rs @@ -465,7 +465,7 @@ fn make_sqlite_db(dirs: &Dirs, nu_table: &str) -> PathBuf { ); assert!(nucmd.status.success()); - testdb_path + testdb_path.into() } fn insert_test_rows(dirs: &Dirs, nu_table: &str, sql_query: Option<&str>, expected: Vec) { diff --git a/crates/nu-command/tests/commands/rm.rs b/crates/nu-command/tests/commands/rm.rs index b3a273ea86..e6cbf88cda 100644 --- a/crates/nu-command/tests/commands/rm.rs +++ b/crates/nu-command/tests/commands/rm.rs @@ -1,3 +1,4 @@ +use nu_path::AbsolutePath; use nu_test_support::fs::{files_exist_at, Stub::EmptyFile}; use nu_test_support::nu; use nu_test_support::playground::Playground; @@ -405,10 +406,10 @@ fn removes_file_after_cd() { } struct Cleanup<'a> { - dir_to_clean: &'a Path, + dir_to_clean: &'a AbsolutePath, } -fn set_dir_read_only(directory: &Path, read_only: bool) { +fn set_dir_read_only(directory: &AbsolutePath, read_only: bool) { let mut permissions = fs::metadata(directory).unwrap().permissions(); permissions.set_readonly(read_only); fs::set_permissions(directory, permissions).expect("failed to set directory permissions"); diff --git a/crates/nu-command/tests/commands/source_env.rs b/crates/nu-command/tests/commands/source_env.rs index 9dd0320a45..f9cc3fbc1c 100644 --- a/crates/nu-command/tests/commands/source_env.rs +++ b/crates/nu-command/tests/commands/source_env.rs @@ -1,4 +1,3 @@ -use nu_test_support::fs::AbsolutePath; use nu_test_support::fs::Stub::{FileWithContent, FileWithContentToBeTrimmed}; use nu_test_support::nu; use nu_test_support::pipeline; @@ -8,17 +7,18 @@ use nu_test_support::playground::Playground; #[test] fn sources_also_files_under_custom_lib_dirs_path() { Playground::setup("source_test_1", |dirs, nu| { - let file = AbsolutePath::new(dirs.test().join("config.toml")); - let library_path = AbsolutePath::new(dirs.test().join("lib")); + let file = dirs.test().join("config.toml"); + let library_path = dirs.test().join("lib"); - nu.with_config(&file); + nu.with_config(file); nu.with_files(&[FileWithContent( "config.toml", &format!( r#" - lib_dirs = ["{library_path}"] + lib_dirs = ["{}"] skip_welcome_message = true - "# + "#, + library_path.as_os_str().to_str().unwrap(), ), )]); diff --git a/crates/nu-command/tests/commands/ucp.rs b/crates/nu-command/tests/commands/ucp.rs index 728cf1dcb2..2c2b30f252 100644 --- a/crates/nu-command/tests/commands/ucp.rs +++ b/crates/nu-command/tests/commands/ucp.rs @@ -1,6 +1,6 @@ use nu_test_support::fs::file_contents; use nu_test_support::fs::{ - files_exist_at, AbsoluteFile, + files_exist_at, Stub::{EmptyFile, FileWithContent, FileWithPermission}, }; use nu_test_support::nu; @@ -55,7 +55,7 @@ fn copies_the_file_inside_directory_if_path_to_copy_is_directory() { fn copies_the_file_inside_directory_if_path_to_copy_is_directory_impl(progress: bool) { Playground::setup("ucp_test_2", |dirs, _| { - let expected_file = AbsoluteFile::new(dirs.test().join("sample.ini")); + let expected_file = dirs.test().join("sample.ini"); let progress_flag = if progress { "-p" } else { "" }; // Get the hash of the file content to check integrity after copy. @@ -64,13 +64,13 @@ fn copies_the_file_inside_directory_if_path_to_copy_is_directory_impl(progress: cwd: dirs.formats(), "cp {} ../formats/sample.ini {}", progress_flag, - expected_file.dir() + expected_file.parent().unwrap().as_os_str().to_str().unwrap(), ); assert!(dirs.test().join("sample.ini").exists()); // Check the integrity of the file. - let after_cp_hash = get_file_hash(expected_file); + let after_cp_hash = get_file_hash(expected_file.display()); assert_eq!(first_hash, after_cp_hash); }) } diff --git a/crates/nu-command/tests/commands/use_.rs b/crates/nu-command/tests/commands/use_.rs index 63b1f8391a..2895e1635f 100644 --- a/crates/nu-command/tests/commands/use_.rs +++ b/crates/nu-command/tests/commands/use_.rs @@ -1,4 +1,3 @@ -use nu_test_support::fs::AbsolutePath; use nu_test_support::fs::Stub::{FileWithContent, FileWithContentToBeTrimmed}; use nu_test_support::nu; use nu_test_support::pipeline; @@ -7,10 +6,10 @@ use nu_test_support::playground::Playground; #[test] fn use_module_file_within_block() { Playground::setup("use_test_1", |dirs, nu| { - let file = AbsolutePath::new(dirs.test().join("spam.nu")); + let file = dirs.test().join("spam.nu"); nu.with_files(&[FileWithContent( - &file.to_string(), + file.as_os_str().to_str().unwrap(), r#" export def foo [] { echo "hello world" @@ -37,10 +36,10 @@ fn use_module_file_within_block() { #[test] fn use_keeps_doc_comments() { Playground::setup("use_doc_comments", |dirs, nu| { - let file = AbsolutePath::new(dirs.test().join("spam.nu")); + let file = dirs.test().join("spam.nu"); nu.with_files(&[FileWithContent( - &file.to_string(), + file.as_os_str().to_str().unwrap(), r#" # this is my foo command export def foo [ diff --git a/crates/nu-test-support/src/fs.rs b/crates/nu-test-support/src/fs.rs index 00321e6590..eb90e16ab2 100644 --- a/crates/nu-test-support/src/fs.rs +++ b/crates/nu-test-support/src/fs.rs @@ -1,137 +1,5 @@ -use std::fmt::Display; +use nu_path::{AbsolutePath, AbsolutePathBuf, Path}; use std::io::Read; -use std::ops::Div; -use std::path::{Path, PathBuf}; - -pub struct AbsoluteFile { - inner: PathBuf, -} - -impl AbsoluteFile { - pub fn new(path: impl AsRef) -> AbsoluteFile { - let path = path.as_ref(); - - if !path.is_absolute() { - panic!( - "AbsoluteFile::new must take an absolute path :: {}", - path.display() - ) - } else if path.is_dir() { - // At the moment, this is not an invariant, but rather a way to catch bugs - // in tests. - panic!( - "AbsoluteFile::new must not take a directory :: {}", - path.display() - ) - } else { - AbsoluteFile { - inner: path.to_path_buf(), - } - } - } - - pub fn dir(&self) -> AbsolutePath { - AbsolutePath::new(if let Some(parent) = self.inner.parent() { - parent - } else { - unreachable!("Internal error: could not get parent in dir") - }) - } -} - -impl From for PathBuf { - fn from(file: AbsoluteFile) -> Self { - file.inner - } -} - -pub struct AbsolutePath { - pub inner: PathBuf, -} - -impl AbsolutePath { - pub fn new(path: impl AsRef) -> AbsolutePath { - let path = path.as_ref(); - - if path.is_absolute() { - AbsolutePath { - inner: path.to_path_buf(), - } - } else { - panic!("AbsolutePath::new must take an absolute path") - } - } -} - -impl Div<&str> for &AbsolutePath { - type Output = AbsolutePath; - - fn div(self, rhs: &str) -> Self::Output { - let parts = rhs.split('/'); - let mut result = self.inner.clone(); - - for part in parts { - result = result.join(part); - } - - AbsolutePath::new(result) - } -} - -impl AsRef for AbsolutePath { - fn as_ref(&self) -> &Path { - self.inner.as_path() - } -} - -pub struct RelativePath { - inner: PathBuf, -} - -impl RelativePath { - pub fn new(path: impl Into) -> RelativePath { - let path = path.into(); - - if path.is_relative() { - RelativePath { inner: path } - } else { - panic!("RelativePath::new must take a relative path") - } - } -} - -impl> Div for &RelativePath { - type Output = RelativePath; - - fn div(self, rhs: T) -> Self::Output { - let parts = rhs.as_ref().split('/'); - let mut result = self.inner.clone(); - - for part in parts { - result = result.join(part); - } - - RelativePath::new(result) - } -} - -impl Display for AbsoluteFile { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.inner.display()) - } -} - -impl Display for AbsolutePath { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.inner.display()) - } -} - -impl Display for RelativePath { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.inner.display()) - } -} pub enum Stub<'a> { FileWithContent(&'a str, &'a str), @@ -140,7 +8,7 @@ pub enum Stub<'a> { FileWithPermission(&'a str, bool), } -pub fn file_contents(full_path: impl AsRef) -> String { +pub fn file_contents(full_path: impl AsRef) -> String { let mut file = std::fs::File::open(full_path.as_ref()).expect("can not open file"); let mut contents = String::new(); file.read_to_string(&mut contents) @@ -148,7 +16,7 @@ pub fn file_contents(full_path: impl AsRef) -> String { contents } -pub fn file_contents_binary(full_path: impl AsRef) -> Vec { +pub fn file_contents_binary(full_path: impl AsRef) -> Vec { let mut file = std::fs::File::open(full_path.as_ref()).expect("can not open file"); let mut contents = Vec::new(); file.read_to_end(&mut contents).expect("can not read file"); @@ -167,56 +35,32 @@ pub fn line_ending() -> String { } } -pub fn delete_file_at(full_path: impl AsRef) { - let full_path = full_path.as_ref(); - - if full_path.exists() { - std::fs::remove_file(full_path).expect("can not delete file"); - } +pub fn files_exist_at(files: Vec>, path: impl AsRef) -> bool { + let path = path.as_ref(); + files.iter().all(|f| path.join(f.as_ref()).exists()) } -pub fn create_file_at(full_path: impl AsRef) -> Result<(), std::io::Error> { - let full_path = full_path.as_ref(); - - if full_path.parent().is_some() { - panic!("path exists"); - } - - std::fs::write(full_path, b"fake data") -} - -pub fn copy_file_to(source: &str, destination: &str) { - std::fs::copy(source, destination).expect("can not copy file"); -} - -pub fn files_exist_at(files: Vec>, path: impl AsRef) -> bool { - files.iter().all(|f| { - let mut loc = PathBuf::from(path.as_ref()); - loc.push(f); - loc.exists() - }) -} - -pub fn delete_directory_at(full_path: &str) { - std::fs::remove_dir_all(PathBuf::from(full_path)).expect("can not remove directory"); -} - -pub fn executable_path() -> PathBuf { +pub fn executable_path() -> AbsolutePathBuf { let mut path = binaries(); path.push("nu"); path } -pub fn installed_nu_path() -> PathBuf { +pub fn installed_nu_path() -> AbsolutePathBuf { let path = std::env::var_os(crate::NATIVE_PATH_ENV_VAR); - which::which_in("nu", path, ".").unwrap_or_else(|_| executable_path()) + if let Ok(path) = which::which_in("nu", path, ".") { + AbsolutePathBuf::try_from(path).expect("installed nushell path is absolute") + } else { + executable_path() + } } -pub fn root() -> PathBuf { +pub fn root() -> AbsolutePathBuf { let manifest_dir = if let Ok(manifest_dir) = std::env::var("CARGO_MANIFEST_DIR") { - PathBuf::from(manifest_dir) + AbsolutePathBuf::try_from(manifest_dir).expect("CARGO_MANIFEST_DIR is not an absolute path") } else { - PathBuf::from(env!("CARGO_MANIFEST_DIR")) + AbsolutePathBuf::try_from(env!("CARGO_MANIFEST_DIR")) + .expect("CARGO_MANIFEST_DIR is not an absolute path") }; let test_path = manifest_dir.join("Cargo.lock"); @@ -228,11 +72,11 @@ pub fn root() -> PathBuf { .expect("Couldn't find the debug binaries directory") .parent() .expect("Couldn't find the debug binaries directory") - .to_path_buf() + .into() } } -pub fn binaries() -> PathBuf { +pub fn binaries() -> AbsolutePathBuf { let build_target = std::env::var("CARGO_BUILD_TARGET").unwrap_or_default(); let profile = if let Ok(env_profile) = std::env::var("NUSHELL_CARGO_PROFILE") { @@ -244,27 +88,28 @@ pub fn binaries() -> PathBuf { }; std::env::var("CARGO_TARGET_DIR") - .map(PathBuf::from) - .unwrap_or_else(|_| root().join("target")) + .ok() + .and_then(|p| AbsolutePathBuf::try_from(p).ok()) + .unwrap_or_else(|| root().join("target")) .join(build_target) .join(profile) } -pub fn fixtures() -> PathBuf { - root().join("tests").join("fixtures") +pub fn fixtures() -> AbsolutePathBuf { + let mut path = root(); + path.push("tests"); + path.push("fixtures"); + path } -pub fn assets() -> PathBuf { - root().join("tests/assets") -} +// FIXME: re-enable nu_json tests +// pub fn assets() -> AbsolutePathBuf { +// let mut path = root(); +// path.push("tests"); +// path.push("assets"); +// path +// } -pub fn in_directory(str: impl AsRef) -> String { - let path = str.as_ref(); - let path = if path.is_relative() { - root().join(path) - } else { - path.to_path_buf() - }; - - path.display().to_string() +pub fn in_directory(path: impl AsRef) -> AbsolutePathBuf { + root().join(path) } diff --git a/crates/nu-test-support/src/macros.rs b/crates/nu-test-support/src/macros.rs index 958a2453f5..6fd3a8c307 100644 --- a/crates/nu-test-support/src/macros.rs +++ b/crates/nu-test-support/src/macros.rs @@ -234,16 +234,16 @@ macro_rules! nu_with_plugins { } use crate::{Outcome, NATIVE_PATH_ENV_VAR}; -use std::ffi::OsStr; +use nu_path::{AbsolutePath, AbsolutePathBuf, Path}; use std::{ - path::Path, + ffi::OsStr, process::{Command, Stdio}, }; use tempfile::tempdir; #[derive(Default)] pub struct NuOpts { - pub cwd: Option, + pub cwd: Option, pub locale: Option, pub envs: Option>, pub collapse_output: Option, @@ -251,19 +251,12 @@ pub struct NuOpts { } pub fn nu_run_test(opts: NuOpts, commands: impl AsRef, with_std: bool) -> Outcome { - let test_bins = crate::fs::binaries(); - - let cwd = std::env::current_dir().expect("Could not get current working directory."); - let test_bins = nu_path::canonicalize_with(&test_bins, cwd).unwrap_or_else(|e| { - panic!( - "Couldn't canonicalize dummy binaries path {}: {:?}", - test_bins.display(), - e - ) - }); + let test_bins = crate::fs::binaries() + .canonicalize() + .expect("Could not canonicalize dummy binaries path"); let mut paths = crate::shell_os_paths(); - paths.insert(0, test_bins); + paths.insert(0, test_bins.into()); let commands = commands.as_ref().lines().collect::>().join("; "); @@ -272,7 +265,7 @@ pub fn nu_run_test(opts: NuOpts, commands: impl AsRef, with_std: bool) -> O Err(_) => panic!("Couldn't join paths for PATH var."), }; - let target_cwd = opts.cwd.unwrap_or(".".to_string()); + let target_cwd = opts.cwd.unwrap_or_else(crate::fs::root); let locale = opts.locale.unwrap_or("en_US.UTF-8".to_string()); let executable_path = crate::fs::executable_path(); @@ -450,7 +443,7 @@ fn collapse_output(out: &str) -> String { out.replace('\n', "") } -fn setup_command(executable_path: &Path, target_cwd: &str) -> Command { +fn setup_command(executable_path: &AbsolutePath, target_cwd: &AbsolutePath) -> Command { let mut command = Command::new(executable_path); command diff --git a/crates/nu-test-support/src/playground.rs b/crates/nu-test-support/src/playground.rs index 375f192983..4d33dcebe5 100644 --- a/crates/nu-test-support/src/playground.rs +++ b/crates/nu-test-support/src/playground.rs @@ -6,5 +6,5 @@ mod play; mod tests; pub use director::Director; -pub use nu_process::{Executable, NuProcess, NuResult, Outcome}; +pub use nu_process::{Executable, NuProcess, Outcome}; pub use play::{Dirs, EnvironmentVariable, Playground}; diff --git a/crates/nu-test-support/src/playground/director.rs b/crates/nu-test-support/src/playground/director.rs index 3d04155c25..a361342495 100644 --- a/crates/nu-test-support/src/playground/director.rs +++ b/crates/nu-test-support/src/playground/director.rs @@ -83,7 +83,7 @@ impl Director { } impl Executable for Director { - fn execute(&mut self) -> NuResult { + fn execute(&mut self) -> Result { use std::process::Stdio; match self.executable() { diff --git a/crates/nu-test-support/src/playground/nu_process.rs b/crates/nu-test-support/src/playground/nu_process.rs index 0031a173e8..2eeac703c6 100644 --- a/crates/nu-test-support/src/playground/nu_process.rs +++ b/crates/nu-test-support/src/playground/nu_process.rs @@ -1,12 +1,13 @@ use super::EnvironmentVariable; use crate::fs::{binaries as test_bins_path, executable_path}; -use std::ffi::{OsStr, OsString}; -use std::fmt; -use std::path::Path; -use std::process::{Command, ExitStatus}; +use std::{ + ffi::{OsStr, OsString}, + fmt, + process::{Command, ExitStatus}, +}; pub trait Executable { - fn execute(&mut self) -> NuResult; + fn execute(&mut self) -> Result; } #[derive(Clone, Debug)] @@ -24,8 +25,6 @@ impl Outcome { } } -pub type NuResult = Result; - #[derive(Debug)] pub struct NuError { pub desc: String, @@ -69,14 +68,10 @@ impl NuProcess { self } - pub fn get_cwd(&self) -> Option<&Path> { - self.cwd.as_ref().map(Path::new) - } - pub fn construct(&self) -> Command { let mut command = Command::new(executable_path()); - if let Some(cwd) = self.get_cwd() { + if let Some(cwd) = &self.cwd { command.current_dir(cwd); } diff --git a/crates/nu-test-support/src/playground/play.rs b/crates/nu-test-support/src/playground/play.rs index 902997200e..12295c2690 100644 --- a/crates/nu-test-support/src/playground/play.rs +++ b/crates/nu-test-support/src/playground/play.rs @@ -1,8 +1,9 @@ use super::Director; -use crate::fs; -use crate::fs::Stub; +use crate::fs::{self, Stub}; use nu_glob::glob; -use std::path::{Path, PathBuf}; +#[cfg(not(target_arch = "wasm32"))] +use nu_path::Path; +use nu_path::{AbsolutePath, AbsolutePathBuf}; use std::str; use tempfile::{tempdir, TempDir}; @@ -22,46 +23,46 @@ impl EnvironmentVariable { } pub struct Playground<'a> { - root: TempDir, + _root: TempDir, tests: String, - cwd: PathBuf, - config: Option, + cwd: AbsolutePathBuf, + config: Option, environment_vars: Vec, dirs: &'a Dirs, } -#[derive(Default, Clone)] +#[derive(Clone)] pub struct Dirs { - pub root: PathBuf, - pub test: PathBuf, - pub fixtures: PathBuf, + pub root: AbsolutePathBuf, + pub test: AbsolutePathBuf, + pub fixtures: AbsolutePathBuf, } impl Dirs { - pub fn formats(&self) -> PathBuf { + pub fn formats(&self) -> AbsolutePathBuf { self.fixtures.join("formats") } - pub fn root(&self) -> &Path { - self.root.as_path() + pub fn root(&self) -> &AbsolutePath { + &self.root } - pub fn test(&self) -> &Path { - self.test.as_path() + pub fn test(&self) -> &AbsolutePath { + &self.test } } impl<'a> Playground<'a> { - pub fn root(&self) -> &Path { - self.root.path() + pub fn root(&self) -> &AbsolutePath { + &self.dirs.root } - pub fn cwd(&self) -> &Path { + pub fn cwd(&self) -> &AbsolutePath { &self.cwd } pub fn back_to_playground(&mut self) -> &mut Self { - self.cwd = PathBuf::from(self.root()).join(self.tests.clone()); + self.cwd = self.root().join(&self.tests); self } @@ -70,68 +71,46 @@ impl<'a> Playground<'a> { } pub fn setup(topic: &str, block: impl FnOnce(Dirs, &mut Playground)) { - let root = tempdir().expect("Couldn't create a tempdir"); - let nuplay_dir = root.path().join(topic); + let temp = tempdir().expect("Could not create a tempdir"); - if PathBuf::from(&nuplay_dir).exists() { - std::fs::remove_dir_all(PathBuf::from(&nuplay_dir)).expect("can not remove directory"); + let root = AbsolutePathBuf::try_from(temp.path()) + .expect("Tempdir is not an absolute path") + .canonicalize() + .expect("Could not canonicalize tempdir"); + + let test = root.join(topic); + if test.exists() { + std::fs::remove_dir_all(&test).expect("Could not remove directory"); } + std::fs::create_dir(&test).expect("Could not create directory"); + let test = test + .canonicalize() + .expect("Could not canonicalize test path"); - std::fs::create_dir(PathBuf::from(&nuplay_dir)).expect("can not create directory"); - - let fixtures = fs::fixtures(); - let cwd = std::env::current_dir().expect("Could not get current working directory."); - let fixtures = nu_path::canonicalize_with(fixtures.clone(), cwd).unwrap_or_else(|e| { - panic!( - "Couldn't canonicalize fixtures path {}: {:?}", - fixtures.display(), - e - ) - }); - - let mut playground = Playground { - root, - tests: topic.to_string(), - cwd: nuplay_dir, - config: None, - environment_vars: Vec::default(), - dirs: &Dirs::default(), - }; - - let playground_root = playground.root.path(); - - let cwd = std::env::current_dir().expect("Could not get current working directory."); - let test = - nu_path::canonicalize_with(playground_root.join(topic), cwd).unwrap_or_else(|e| { - panic!( - "Couldn't canonicalize test path {}: {:?}", - playground_root.join(topic).display(), - e - ) - }); - - let cwd = std::env::current_dir().expect("Could not get current working directory."); - let root = nu_path::canonicalize_with(playground_root, cwd).unwrap_or_else(|e| { - panic!( - "Couldn't canonicalize tests root path {}: {:?}", - playground_root.display(), - e - ) - }); + let fixtures = fs::fixtures() + .canonicalize() + .expect("Could not canonicalize fixtures path"); let dirs = Dirs { - root, - test, - fixtures, + root: root.into(), + test: test.as_path().into(), + fixtures: fixtures.into(), }; - playground.dirs = &dirs; + let mut playground = Playground { + _root: temp, + tests: topic.to_string(), + cwd: test.into(), + config: None, + environment_vars: Vec::default(), + dirs: &dirs, + }; block(dirs.clone(), &mut playground); } - pub fn with_config(&mut self, source_file: impl AsRef) -> &mut Self { - self.config = Some(source_file.as_ref().to_path_buf()); + pub fn with_config(&mut self, source_file: AbsolutePathBuf) -> &mut Self { + self.config = Some(source_file); self } @@ -205,7 +184,6 @@ impl<'a> Playground<'a> { files .iter() .map(|f| { - let mut path = PathBuf::from(&self.cwd); let mut permission_set = false; let mut write_able = true; let (file_name, contents) = match *f { @@ -227,7 +205,7 @@ impl<'a> Playground<'a> { } }; - path.push(file_name); + let path = self.cwd.join(file_name); std::fs::write(&path, contents.as_bytes()).expect("can not create file"); if permission_set { @@ -252,7 +230,7 @@ impl<'a> Playground<'a> { self } - pub fn glob_vec(pattern: &str) -> Vec { + pub fn glob_vec(pattern: &str) -> Vec { let glob = glob(pattern); glob.expect("invalid pattern") diff --git a/crates/nu-test-support/src/playground/tests.rs b/crates/nu-test-support/src/playground/tests.rs index cc4daa597b..7c2be0237e 100644 --- a/crates/nu-test-support/src/playground/tests.rs +++ b/crates/nu-test-support/src/playground/tests.rs @@ -1,11 +1,4 @@ use crate::playground::Playground; -use std::path::{Path, PathBuf}; - -fn path(p: &Path) -> PathBuf { - let cwd = std::env::current_dir().expect("Could not get current working directory."); - nu_path::canonicalize_with(p, cwd) - .unwrap_or_else(|e| panic!("Couldn't canonicalize path {}: {:?}", p.display(), e)) -} #[test] fn current_working_directory_in_sandbox_directory_created() { @@ -13,7 +6,7 @@ fn current_working_directory_in_sandbox_directory_created() { let original_cwd = dirs.test(); nu.within("some_directory_within"); - assert_eq!(path(nu.cwd()), original_cwd.join("some_directory_within")); + assert_eq!(nu.cwd(), original_cwd.join("some_directory_within")); }) } @@ -25,6 +18,6 @@ fn current_working_directory_back_to_root_from_anywhere() { nu.within("some_directory_within"); nu.back_to_playground(); - assert_eq!(path(nu.cwd()), *original_cwd); + assert_eq!(nu.cwd(), original_cwd); }) } diff --git a/tests/plugins/nu_plugin_nu_example.rs b/tests/plugins/nu_plugin_nu_example.rs index f178c64316..afeb487b60 100644 --- a/tests/plugins/nu_plugin_nu_example.rs +++ b/tests/plugins/nu_plugin_nu_example.rs @@ -4,7 +4,7 @@ use assert_cmd::Command; fn call() { // Add the `nu` binaries to the path env let path_env = std::env::join_paths( - std::iter::once(nu_test_support::fs::binaries()).chain( + std::iter::once(nu_test_support::fs::binaries().into()).chain( std::env::var_os(nu_test_support::NATIVE_PATH_ENV_VAR) .as_deref() .map(std::env::split_paths) diff --git a/tests/plugins/registry_file.rs b/tests/plugins/registry_file.rs index c0f0fa0724..2cb1473b6f 100644 --- a/tests/plugins/registry_file.rs +++ b/tests/plugins/registry_file.rs @@ -162,7 +162,7 @@ fn plugin_rm_then_restart_nu() { contents.upsert_plugin(PluginRegistryItem { name: "foo".into(), // this doesn't exist, but it should be ok - filename: dirs.test().join("nu_plugin_foo"), + filename: dirs.test().join("nu_plugin_foo").into(), shell: None, data: valid_plugin_item_data(), }); @@ -238,7 +238,7 @@ fn plugin_rm_from_custom_path() { contents.upsert_plugin(PluginRegistryItem { name: "foo".into(), // this doesn't exist, but it should be ok - filename: dirs.test().join("nu_plugin_foo"), + filename: dirs.test().join("nu_plugin_foo").into(), shell: None, data: valid_plugin_item_data(), }); @@ -286,7 +286,7 @@ fn plugin_rm_using_filename() { contents.upsert_plugin(PluginRegistryItem { name: "foo".into(), // this doesn't exist, but it should be ok - filename: dirs.test().join("nu_plugin_foo"), + filename: dirs.test().join("nu_plugin_foo").into(), shell: None, data: valid_plugin_item_data(), }); @@ -344,7 +344,7 @@ fn warning_on_invalid_plugin_item() { contents.upsert_plugin(PluginRegistryItem { name: "badtest".into(), // this doesn't exist, but it should be ok - filename: dirs.test().join("nu_plugin_badtest"), + filename: dirs.test().join("nu_plugin_badtest").into(), shell: None, data: PluginRegistryItemData::Invalid, });