diff --git a/src/cli.rs b/src/cli.rs index c3a299574..f25b24e9d 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -272,11 +272,7 @@ pub async fn cli() -> Result<(), Box> { if ctrlcbreak { std::process::exit(0); } else { - context - .host - .lock() - .unwrap() - .stdout("CTRL-C pressed (again to quit)"); + context.with_host(|host| host.stdout("CTRL-C pressed (again to quit)")); ctrlcbreak = true; continue; } @@ -285,18 +281,19 @@ pub async fn cli() -> Result<(), Box> { LineResult::Error(mut line, err) => { rl.add_history_entry(line.clone()); let diag = err.to_diagnostic(); - let host = context.host.lock().unwrap(); - let writer = host.err_termcolor(); - line.push_str(" "); - let files = crate::parser::Files::new(line); - let _ = std::panic::catch_unwind(move || { - let _ = language_reporting::emit( - &mut writer.lock(), - &files, - &diag, - &language_reporting::DefaultConfig, - ); - }); + context.with_host(|host| { + let writer = host.err_termcolor(); + line.push_str(" "); + let files = crate::parser::Files::new(line); + let _ = std::panic::catch_unwind(move || { + let _ = language_reporting::emit( + &mut writer.lock(), + &files, + &diag, + &language_reporting::DefaultConfig, + ); + }); + }) } LineResult::Break => { @@ -304,11 +301,9 @@ pub async fn cli() -> Result<(), Box> { } LineResult::FatalError(_, err) => { - context - .host - .lock() - .unwrap() - .stdout(&format!("A surprising fatal error occurred.\n{:?}", err)); + context.with_host(|host| { + host.stdout(&format!("A surprising fatal error occurred.\n{:?}", err)) + }); } } ctrlcbreak = false; diff --git a/src/commands/classified.rs b/src/commands/classified.rs index 926b08355..f74bab2f0 100644 --- a/src/commands/classified.rs +++ b/src/commands/classified.rs @@ -315,19 +315,23 @@ impl ExternalCommand { if arg_string.contains("$it") { let mut first = true; for i in &inputs { - if i.as_string().is_err() { - let mut span = name_span; - for arg in &self.args { - if arg.item.contains("$it") { - span = arg.span(); + let i = match i.as_string() { + Err(_err) => { + let mut span = name_span; + for arg in &self.args { + if arg.item.contains("$it") { + span = arg.span(); + } } + return Err(ShellError::labeled_error( + "External $it needs string data", + "given object instead of string data", + span, + )); } - return Err(ShellError::labeled_error( - "External $it needs string data", - "given object instead of string data", - span, - )); - } + Ok(val) => val, + }; + if !first { new_arg_string.push_str("&&"); new_arg_string.push_str(&self.name); @@ -341,7 +345,7 @@ impl ExternalCommand { } new_arg_string.push_str(" "); - new_arg_string.push_str(&arg.replace("$it", &i.as_string().unwrap())); + new_arg_string.push_str(&arg.replace("$it", &i)); } } } else { @@ -366,7 +370,7 @@ impl ExternalCommand { process = process.stdin(stdin); } - let mut popen = process.popen().unwrap(); + let mut popen = process.popen()?; match stream_next { StreamNext::Last => { diff --git a/src/context.rs b/src/context.rs index 0a69979d0..f2b0b8672 100644 --- a/src/context.rs +++ b/src/context.rs @@ -74,7 +74,7 @@ impl CommandRegistry { pub struct Context { registry: CommandRegistry, crate source_map: SourceMap, - crate host: Arc>, + host: Arc>, crate shell_manager: ShellManager, } @@ -93,6 +93,12 @@ impl Context { }) } + crate fn with_host(&mut self, block: impl FnOnce(&mut dyn Host)) { + let mut host = self.host.lock().unwrap(); + + block(&mut *host) + } + pub fn add_commands(&mut self, commands: Vec>) { for command in commands { self.registry.insert(command.name().to_string(), command); @@ -103,10 +109,6 @@ impl Context { self.source_map.insert(uuid, span_source); } - // pub fn clone_commands(&self) -> CommandRegistry { - // self.registry.clone() - // } - crate fn has_command(&self, name: &str) -> bool { self.registry.has(name) } diff --git a/src/lib.rs b/src/lib.rs index 74ad22a68..0a5ba9ccc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,7 +31,7 @@ pub use crate::env::host::BasicHost; pub use crate::object::base::OF64; pub use crate::parser::hir::SyntaxType; pub use crate::plugin::{serve_plugin, Plugin}; -pub use crate::utils::{AbsolutePath, RelativePath}; +pub use crate::utils::{AbsoluteFile, AbsolutePath, RelativePath}; pub use cli::cli; pub use errors::ShellError; pub use object::base::{Primitive, Value}; diff --git a/src/prelude.rs b/src/prelude.rs index 481d89757..38b61be38 100644 --- a/src/prelude.rs +++ b/src/prelude.rs @@ -16,10 +16,6 @@ macro_rules! trace_stream { (target: $target:tt, $desc:tt = $expr:expr) => {{ if log::log_enabled!(target: $target, log::Level::Trace) { use futures::stream::StreamExt; - // Blocking is generally quite bad, but this is for debugging - // let mut local = futures::executor::LocalPool::new(); - // let objects = local.run_until($expr.into_vec()); - // let objects: Vec<_> = futures::executor::block_on($expr.into_vec()); let objects = $expr.values.inspect(|o| { trace!(target: $target, "{} = {:#?}", $desc, o.debug()); diff --git a/src/utils.rs b/src/utils.rs index 6b4fc33f3..71d0b50fe 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,7 +1,52 @@ use crate::errors::ShellError; +use std::fmt; 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(self.inner.parent().unwrap()) + } +} + +impl From for PathBuf { + fn from(file: AbsoluteFile) -> Self { + file.inner + } +} + +impl fmt::Display for AbsoluteFile { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.inner.display()) + } +} + pub struct AbsolutePath { inner: PathBuf, } @@ -20,6 +65,12 @@ impl AbsolutePath { } } +impl fmt::Display for AbsolutePath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.inner.display()) + } +} + impl Div<&str> for &AbsolutePath { type Output = AbsolutePath; @@ -72,6 +123,12 @@ impl> Div for &RelativePath { } } +impl fmt::Display for RelativePath { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.inner.display()) + } +} + #[derive(Debug, Eq, Ord, PartialEq, PartialOrd)] pub struct Res { pub loc: PathBuf, diff --git a/tests/command_cd_tests.rs b/tests/command_cd_tests.rs index 670eb5f87..932484e59 100644 --- a/tests/command_cd_tests.rs +++ b/tests/command_cd_tests.rs @@ -4,8 +4,8 @@ use helpers::in_directory as cwd; #[test] fn cd_directory_not_found() { - nu_error!(output, cwd("tests/fixtures"), "cd dir_that_does_not_exist"); + let actual = nu_error!(cwd("tests/fixtures"), "cd dir_that_does_not_exist"); - assert!(output.contains("dir_that_does_not_exist")); - assert!(output.contains("directory not found")); + assert!(actual.contains("dir_that_does_not_exist")); + assert!(actual.contains("directory not found")); } diff --git a/tests/command_cp_tests.rs b/tests/command_cp_tests.rs index cf2037770..e41c24d1c 100644 --- a/tests/command_cp_tests.rs +++ b/tests/command_cp_tests.rs @@ -1,87 +1,78 @@ mod helpers; -use h::{in_directory as cwd, Playground, Stub::*}; -use helpers as h; - +use helpers::{in_directory as cwd, dir_exists_at, file_exists_at, files_exist_at, Playground, Stub::*}; +use nu::AbsoluteFile; use std::path::{Path, PathBuf}; #[test] fn copies_a_file() { - let sandbox = Playground::setup_for("cp_test_1").test_dir_name(); + Playground::setup("cp_test_1", |dirs, _| { + nu!( + cwd(dirs.root()), + "cp {} cp_test_1/sample.ini", + dirs.formats().join("sample.ini") + ); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let expected_file = format!("{}/{}", full_path, "sample.ini"); - - nu!( - _output, - cwd(&Playground::root()), - "cp ../formats/sample.ini cp_test_1/sample.ini" - ); - - assert!(h::file_exists_at(PathBuf::from(expected_file))); + assert!(file_exists_at(dirs.test().join("sample.ini"))); + }); } #[test] fn copies_the_file_inside_directory_if_path_to_copy_is_directory() { - let sandbox = Playground::setup_for("cp_test_2").test_dir_name(); + Playground::setup("cp_test_2", |dirs, _| { + let expected_file = AbsoluteFile::new(dirs.test().join("sample.ini")); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let expected_file = format!("{}/{}", full_path, "sample.ini"); + nu!( + cwd(dirs.formats()), + "cp ../formats/sample.ini {}", + expected_file.dir() + ); - nu!( - _output, - cwd(&Playground::root()), - "cp ../formats/sample.ini cp_test_2" - ); - - assert!(h::file_exists_at(PathBuf::from(expected_file))); + assert!(file_exists_at(dirs.test().join("sample.ini"))); + }) } #[test] fn error_if_attempting_to_copy_a_directory_to_another_directory() { - Playground::setup_for("cp_test_3"); + Playground::setup("cp_test_3", |dirs, _| { + let actual = nu_error!(dirs.formats(), "cp ../formats {}", dirs.test()); - nu_error!(output, cwd(&Playground::root()), "cp ../formats cp_test_3"); - - assert!(output.contains("../formats")); - assert!(output.contains("is a directory (not copied)")); + assert!(actual.contains("../formats")); + assert!(actual.contains("is a directory (not copied)")); + }); } #[test] fn copies_the_directory_inside_directory_if_path_to_copy_is_directory_and_with_recursive_flag() { - let sandbox = Playground::setup_for("cp_test_4") - .within("originals") - .with_files(vec![ - EmptyFile("yehuda.txt"), - EmptyFile("jonathan.txt"), - EmptyFile("andres.txt"), - ]) - .mkdir("expected") - .test_dir_name(); + Playground::setup("cp_test_4", |dirs, sandbox| { + sandbox + .within("originals") + .with_files(vec![ + EmptyFile("yehuda.txt"), + EmptyFile("jonathan.txt"), + EmptyFile("andres.txt"), + ]) + .mkdir("expected"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let expected_dir = format!("{}/{}", full_path, "expected/originals"); + let expected_dir = dirs.test().join("expected").join("originals"); - nu!( - _output, - cwd(&full_path), - "cp originals expected --recursive" - ); + nu!(cwd(dirs.test()), "cp originals expected --recursive"); - assert!(h::dir_exists_at(PathBuf::from(&expected_dir))); - assert!(h::files_exist_at( - vec![ - Path::new("yehuda.txt"), - Path::new("jonathan.txt"), - Path::new("andres.txt") - ], - PathBuf::from(&expected_dir) - )); + assert!(dir_exists_at(PathBuf::from(&expected_dir))); + assert!(files_exist_at( + vec![ + Path::new("yehuda.txt"), + Path::new("jonathan.txt"), + Path::new("andres.txt") + ], + PathBuf::from(&expected_dir) + )); + }) } #[test] fn deep_copies_with_recursive_flag() { - r#" + r#" Given these files and directories originals originals/manifest.txt @@ -99,96 +90,82 @@ fn deep_copies_with_recursive_flag() { originals/contributors/yehuda/defer-evaluation.txt "#; - let sandbox = Playground::setup_for("cp_test_5") - .within("originals") - .with_files(vec![EmptyFile("manifest.txt")]) - .within("originals/contributors") - .with_files(vec![ - EmptyFile("yehuda.txt"), - EmptyFile("jonathan.txt"), - EmptyFile("andres.txt"), - ]) - .within("originals/contributors/jonathan") - .with_files(vec![EmptyFile("errors.txt"), EmptyFile("multishells.txt")]) - .within("originals/contributors/andres") - .with_files(vec![EmptyFile("coverage.txt"), EmptyFile("commands.txt")]) - .within("originals/contributors/yehuda") - .with_files(vec![EmptyFile("defer-evaluation.txt")]) - .mkdir("expected") - .test_dir_name(); + Playground::setup("cp_test_5", |dirs, sandbox| { + sandbox + .within("originals") + .with_files(vec![EmptyFile("manifest.txt")]) + .within("originals/contributors") + .with_files(vec![ + EmptyFile("yehuda.txt"), + EmptyFile("jonathan.txt"), + EmptyFile("andres.txt"), + ]) + .within("originals/contributors/jonathan") + .with_files(vec![EmptyFile("errors.txt"), EmptyFile("multishells.txt")]) + .within("originals/contributors/andres") + .with_files(vec![EmptyFile("coverage.txt"), EmptyFile("commands.txt")]) + .within("originals/contributors/yehuda") + .with_files(vec![EmptyFile("defer-evaluation.txt")]) + .mkdir("expected"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let expected_dir = format!("{}/{}", full_path, "expected/originals"); + let expected_dir = dirs.test().join("expected").join("originals"); - let jonathans_expected_copied_dir = format!("{}/contributors/jonathan", expected_dir); - let andres_expected_copied_dir = format!("{}/contributors/andres", expected_dir); - let yehudas_expected_copied_dir = format!("{}/contributors/yehuda", expected_dir); + let jonathans_expected_copied_dir = expected_dir.join("contributors").join("jonathan"); + let andres_expected_copied_dir = expected_dir.join("contributors").join("andres"); + let yehudas_expected_copied_dir = expected_dir.join("contributors").join("yehuda"); - nu!( - _output, - cwd(&full_path), - "cp originals expected --recursive" - ); + nu!(cwd(dirs.test()), "cp originals expected --recursive"); - assert!(h::dir_exists_at(PathBuf::from(&expected_dir))); - assert!(h::files_exist_at( - vec![Path::new("errors.txt"), Path::new("multishells.txt")], - PathBuf::from(&jonathans_expected_copied_dir) - )); - assert!(h::files_exist_at( - vec![Path::new("coverage.txt"), Path::new("commands.txt")], - PathBuf::from(&andres_expected_copied_dir) - )); - assert!(h::files_exist_at( - vec![Path::new("defer-evaluation.txt")], - PathBuf::from(&yehudas_expected_copied_dir) - )); + assert!(dir_exists_at(PathBuf::from(&expected_dir))); + assert!(files_exist_at( + vec![Path::new("errors.txt"), Path::new("multishells.txt")], + PathBuf::from(&jonathans_expected_copied_dir) + )); + assert!(files_exist_at( + vec![Path::new("coverage.txt"), Path::new("commands.txt")], + PathBuf::from(&andres_expected_copied_dir) + )); + assert!(files_exist_at( + vec![Path::new("defer-evaluation.txt")], + PathBuf::from(&yehudas_expected_copied_dir) + )); + }) } #[test] fn copies_using_path_with_wildcard() { - let sandbox = Playground::setup_for("cp_test_6").test_dir_name(); - let expected_copies_path = format!("{}/{}", Playground::root(), sandbox); + Playground::setup("cp_test_6", |dirs, _| { + nu!(cwd(dirs.formats()), "cp ../formats/* {}", dirs.test()); - nu!( - _output, - cwd(&Playground::root()), - "cp ../formats/* cp_test_6" - ); - - assert!(h::files_exist_at( - vec![ - Path::new("caco3_plastics.csv"), - Path::new("cargo_sample.toml"), - Path::new("jonathan.xml"), - Path::new("sample.ini"), - Path::new("sgml_description.json"), - Path::new("utf16.ini"), - ], - PathBuf::from(&expected_copies_path) - )); + assert!(files_exist_at( + vec![ + Path::new("caco3_plastics.csv"), + Path::new("cargo_sample.toml"), + Path::new("jonathan.xml"), + Path::new("sample.ini"), + Path::new("sgml_description.json"), + Path::new("utf16.ini"), + ], + dirs.test() + )); + }) } #[test] fn copies_using_a_glob() { - let sandbox = Playground::setup_for("cp_test_7").test_dir_name(); - let expected_copies_path = format!("{}/{}", Playground::root(), sandbox); + Playground::setup("cp_test_7", |dirs, _| { + nu!(cwd(dirs.formats()), "cp * {}", dirs.test()); - nu!( - _output, - cwd("tests/fixtures/formats"), - "cp * ../nuplayground/cp_test_7" - ); - - assert!(h::files_exist_at( - vec![ - Path::new("caco3_plastics.csv"), - Path::new("cargo_sample.toml"), - Path::new("jonathan.xml"), - Path::new("sample.ini"), - Path::new("sgml_description.json"), - Path::new("utf16.ini"), - ], - PathBuf::from(&expected_copies_path) - )); + assert!(files_exist_at( + vec![ + Path::new("caco3_plastics.csv"), + Path::new("cargo_sample.toml"), + Path::new("jonathan.xml"), + Path::new("sample.ini"), + Path::new("sgml_description.json"), + Path::new("utf16.ini"), + ], + dirs.test() + )); + }); } diff --git a/tests/command_enter_test.rs b/tests/command_enter_test.rs index 077c1f66c..61a7441df 100644 --- a/tests/command_enter_test.rs +++ b/tests/command_enter_test.rs @@ -6,33 +6,30 @@ use std::path::{Path, PathBuf}; #[test] fn knows_the_filesystems_entered() { - let sandbox = Playground::setup_for("enter_filesystem_sessions_test") - .within("red_pill") - .with_files(vec![ - EmptyFile("andres.nu"), - EmptyFile("jonathan.nu"), - EmptyFile("yehuda.nu"), - ]) - .within("blue_pill") - .with_files(vec![ - EmptyFile("bash.nxt"), - EmptyFile("korn.nxt"), - EmptyFile("powedsh.nxt"), - ]) - .mkdir("expected") - .test_dir_name(); + Playground::setup("enter_test_1", |dirs, sandbox| { + sandbox + .within("red_pill") + .with_files(vec![ + EmptyFile("andres.nu"), + EmptyFile("jonathan.nu"), + EmptyFile("yehuda.nu"), + ]) + .within("blue_pill") + .with_files(vec![ + EmptyFile("bash.nxt"), + EmptyFile("korn.nxt"), + EmptyFile("powedsh.nxt"), + ]) + .mkdir("expected"); - let full_path = format!("{}/{}", Playground::root(), sandbox); + let red_pill_dir = dirs.test().join("red_pill"); + let blue_pill_dir = dirs.test().join("blue_pill"); + let expected = dirs.test().join("expected"); + let expected_recycled = expected.join("recycled"); - let red_pill_dir = format!("{}/{}", full_path, "red_pill"); - let blue_pill_dir = format!("{}/{}", full_path, "blue_pill"); - let expected = format!("{}/{}", full_path, "expected"); - let expected_recycled = format!("{}/{}", expected, "recycled"); - - nu!( - _output, - cwd(&full_path), - r#" + nu!( + cwd(dirs.test()), + r#" enter expected mkdir recycled enter ../red_pill @@ -52,25 +49,26 @@ fn knows_the_filesystems_entered() { rm blue_pill --recursive exit "# - ); + ); - assert!(!h::dir_exists_at(PathBuf::from(red_pill_dir))); - assert!(h::files_exist_at( - vec![ - Path::new("andres.nu"), - Path::new("jonathan.nu"), - Path::new("yehuda.nu"), - ], - PathBuf::from(&expected) - )); + assert!(!h::dir_exists_at(PathBuf::from(red_pill_dir))); + assert!(h::files_exist_at( + vec![ + Path::new("andres.nu"), + Path::new("jonathan.nu"), + Path::new("yehuda.nu"), + ], + PathBuf::from(&expected) + )); - assert!(!h::dir_exists_at(PathBuf::from(blue_pill_dir))); - assert!(h::files_exist_at( - vec![ - Path::new("bash.nxt"), - Path::new("korn.nxt"), - Path::new("powedsh.nxt"), - ], - PathBuf::from(&expected_recycled) - )); + assert!(!h::dir_exists_at(PathBuf::from(blue_pill_dir))); + assert!(h::files_exist_at( + vec![ + Path::new("bash.nxt"), + Path::new("korn.nxt"), + Path::new("powedsh.nxt"), + ], + PathBuf::from(&expected_recycled) + )); + }) } diff --git a/tests/command_ls_tests.rs b/tests/command_ls_tests.rs index 20f299764..0f1bc8b7d 100644 --- a/tests/command_ls_tests.rs +++ b/tests/command_ls_tests.rs @@ -5,65 +5,86 @@ use helpers as h; #[test] fn ls_lists_regular_files() { - let sandbox = Playground::setup_for("ls_lists_files_test") - .with_files(vec![ - EmptyFile("yehuda.10.txt"), - EmptyFile("jonathan.10.txt"), - EmptyFile("andres.10.txt"), - ]) - .test_dir_name(); + Playground::setup("ls_test_1", |dirs, sandbox| { + sandbox + .with_files(vec![ + EmptyFile("yehuda.10.txt"), + EmptyFile("jonathan.10.txt"), + EmptyFile("andres.10.txt"), + ]); - let full_path = format!("{}/{}", Playground::root(), sandbox); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + ls + | get name + | lines + | split-column "." + | get Column2 + | str --to-int + | sum + | echo $it + "# + )); - nu!( - output, - cwd(&full_path), - r#"ls | get name | lines | split-column "." | get Column2 | str --to-int | sum | echo $it"# - ); - - assert_eq!(output, "30"); + assert_eq!(actual, "30"); + }) } #[test] fn ls_lists_regular_files_using_asterisk_wildcard() { - let sandbox = Playground::setup_for("ls_asterisk_wildcard_test") - .with_files(vec![ - EmptyFile("los.1.txt"), - EmptyFile("tres.1.txt"), - EmptyFile("amigos.1.txt"), - EmptyFile("arepas.1.clu"), - ]) - .test_dir_name(); + Playground::setup("ls_test_2", |dirs, sandbox| { + sandbox + .with_files(vec![ + EmptyFile("los.1.txt"), + EmptyFile("tres.1.txt"), + EmptyFile("amigos.1.txt"), + EmptyFile("arepas.1.clu"), + ]); - let full_path = format!("{}/{}", Playground::root(), sandbox); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + ls *.txt + | get name + | lines + | split-column "." + | get Column2 + | str --to-int + | sum + | echo $it + "# + )); - nu!( - output, - cwd(&full_path), - r#"ls *.txt | get name | lines| split-column "." | get Column2 | str --to-int | sum | echo $it"# - ); - - assert_eq!(output, "3"); + assert_eq!(actual, "3"); + }) } #[test] fn ls_lists_regular_files_using_question_mark_wildcard() { - let sandbox = Playground::setup_for("ls_question_mark_wildcard_test") - .with_files(vec![ - EmptyFile("yehuda.10.txt"), - EmptyFile("jonathan.10.txt"), - EmptyFile("andres.10.txt"), - EmptyFile("chicken_not_to_be_picked_up.100.txt"), - ]) - .test_dir_name(); + Playground::setup("ls_test_3", |dirs, sandbox| { + sandbox + .with_files(vec![ + EmptyFile("yehuda.10.txt"), + EmptyFile("jonathan.10.txt"), + EmptyFile("andres.10.txt"), + EmptyFile("chicken_not_to_be_picked_up.100.txt"), + ]); - let full_path = format!("{}/{}", Playground::root(), sandbox); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + ls *.??.txt + | get name + | lines + | split-column "." + | get Column2 + | str --to-int + | sum + | echo $it + "# + )); - nu!( - output, - cwd(&full_path), - r#"ls *.??.txt | get name | lines| split-column "." | get Column2 | str --to-int | sum | echo $it"# - ); - - assert_eq!(output, "30"); + assert_eq!(actual, "30"); + }) } diff --git a/tests/command_mkdir_tests.rs b/tests/command_mkdir_tests.rs index fcc88ee9f..192349ae0 100644 --- a/tests/command_mkdir_tests.rs +++ b/tests/command_mkdir_tests.rs @@ -6,46 +6,35 @@ use std::path::{Path, PathBuf}; #[test] fn creates_directory() { - let sandbox = Playground::setup_for("mkdir_test_1").test_dir_name(); + Playground::setup("mkdir_test_1", |dirs, _| { + nu!(cwd(dirs.test()), "mkdir my_new_directory"); - let full_path = format!("{}/{}", Playground::root(), sandbox); + let expected = dirs.test().join("my_new_directory"); - nu!(_output, cwd(&full_path), "mkdir my_new_directory"); - - let mut expected = PathBuf::from(full_path); - expected.push("my_new_directory"); - - assert!(h::dir_exists_at(expected)); + assert!(h::dir_exists_at(expected)); + }) } #[test] fn accepts_and_creates_directories() { - let sandbox = Playground::setup_for("mkdir_test_2").test_dir_name(); + Playground::setup("mkdir_test_2", |dirs, _| { + nu!(cwd(dirs.test()), "mkdir dir_1 dir_2 dir_3"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - - nu!(_output, cwd(&full_path), "mkdir dir_1 dir_2 dir_3"); - - assert!(h::files_exist_at( - vec![Path::new("dir_1"), Path::new("dir_2"), Path::new("dir_3")], - PathBuf::from(&full_path) - )); + assert!(h::files_exist_at( + vec![Path::new("dir_1"), Path::new("dir_2"), Path::new("dir_3")], + dirs.test() + )); + }) } #[test] fn creates_intermediary_directories() { - let sandbox = Playground::setup_for("mkdir_test_3").test_dir_name(); + Playground::setup("mkdir_test_3", |dirs, _| { + nu!(cwd(dirs.test()), "mkdir some_folder/another/deeper_one"); - let full_path = format!("{}/{}", Playground::root(), sandbox); + let mut expected = PathBuf::from(dirs.test()); + expected.push("some_folder/another/deeper_one"); - nu!( - _output, - cwd(&full_path), - "mkdir some_folder/another/deeper_one" - ); - - let mut expected = PathBuf::from(full_path); - expected.push("some_folder/another/deeper_one"); - - assert!(h::dir_exists_at(expected)); + assert!(h::dir_exists_at(expected)); + }) } diff --git a/tests/command_mv_tests.rs b/tests/command_mv_tests.rs index dc4c1a25f..7fa70495e 100644 --- a/tests/command_mv_tests.rs +++ b/tests/command_mv_tests.rs @@ -3,185 +3,170 @@ mod helpers; use h::{in_directory as cwd, Playground, Stub::*}; use helpers as h; -use std::path::{Path, PathBuf}; - #[test] fn moves_a_file() { - let sandbox = Playground::setup_for("mv_test_1") - .with_files(vec![EmptyFile("andres.txt")]) - .mkdir("expected") - .test_dir_name(); + Playground::setup("mv_test_1", |dirs, sandbox| { + sandbox + .with_files(vec![EmptyFile("andres.txt")]) + .mkdir("expected"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let original = format!("{}/{}", full_path, "andres.txt"); - let expected = format!("{}/{}", full_path, "expected/yehuda.txt"); + let original = dirs.test().join("andres.txt"); + let expected = dirs.test().join("expected/yehuda.txt"); - nu!( - _output, - cwd(&full_path), - "mv andres.txt expected/yehuda.txt" - ); + nu!(cwd(dirs.test()), "mv andres.txt expected/yehuda.txt"); - assert!(!h::file_exists_at(PathBuf::from(original))); - assert!(h::file_exists_at(PathBuf::from(expected))); + assert!(!h::file_exists_at(original)); + assert!(h::file_exists_at(expected)); + }) } #[test] fn overwrites_if_moving_to_existing_file() { - let sandbox = Playground::setup_for("mv_test_2") - .with_files(vec![EmptyFile("andres.txt"), EmptyFile("jonathan.txt")]) - .test_dir_name(); + Playground::setup("mv_test_2", |dirs, sandbox| { + sandbox + .with_files(vec![ + EmptyFile("andres.txt"), + EmptyFile("jonathan.txt") + ]); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let original = format!("{}/{}", full_path, "andres.txt"); - let expected = format!("{}/{}", full_path, "jonathan.txt"); + let original = dirs.test().join("andres.txt"); + let expected = dirs.test().join("jonathan.txt"); - nu!(_output, cwd(&full_path), "mv andres.txt jonathan.txt"); + nu!(cwd(dirs.test()), "mv andres.txt jonathan.txt"); - assert!(!h::file_exists_at(PathBuf::from(original))); - assert!(h::file_exists_at(PathBuf::from(expected))); + assert!(!h::file_exists_at(original)); + assert!(h::file_exists_at(expected)); + }) } #[test] fn moves_a_directory() { - let sandbox = Playground::setup_for("mv_test_3") - .mkdir("empty_dir") - .test_dir_name(); + Playground::setup("mv_test_3", |dirs, sandbox| { + sandbox.mkdir("empty_dir"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let original_dir = format!("{}/{}", full_path, "empty_dir"); - let expected = format!("{}/{}", full_path, "renamed_dir"); + let original_dir = dirs.test().join("empty_dir"); + let expected = dirs.test().join("renamed_dir"); - nu!(_output, cwd(&full_path), "mv empty_dir renamed_dir"); + nu!(cwd(dirs.test()), "mv empty_dir renamed_dir"); - assert!(!h::dir_exists_at(PathBuf::from(original_dir))); - assert!(h::dir_exists_at(PathBuf::from(expected))); + assert!(!h::dir_exists_at(original_dir)); + assert!(h::dir_exists_at(expected)); + }) } #[test] fn moves_the_file_inside_directory_if_path_to_move_is_existing_directory() { - let sandbox = Playground::setup_for("mv_test_4") - .with_files(vec![EmptyFile("jonathan.txt")]) - .mkdir("expected") - .test_dir_name(); + Playground::setup("mv_test_4", |dirs, sandbox| { + sandbox + .with_files(vec![EmptyFile("jonathan.txt")]) + .mkdir("expected"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let original_dir = format!("{}/{}", full_path, "jonathan.txt"); - let expected = format!("{}/{}", full_path, "expected/jonathan.txt"); + let original_dir = dirs.test().join("jonathan.txt"); + let expected = dirs.test().join("expected/jonathan.txt"); - nu!(_output, cwd(&full_path), "mv jonathan.txt expected"); + nu!(dirs.test(), "mv jonathan.txt expected"); - assert!(!h::file_exists_at(PathBuf::from(original_dir))); - assert!(h::file_exists_at(PathBuf::from(expected))); + assert!(!h::file_exists_at(original_dir)); + assert!(h::file_exists_at(expected)); + }) } #[test] fn moves_the_directory_inside_directory_if_path_to_move_is_existing_directory() { - let sandbox = Playground::setup_for("mv_test_5") - .within("contributors") - .with_files(vec![EmptyFile("jonathan.txt")]) - .mkdir("expected") - .test_dir_name(); + Playground::setup("mv_test_5", |dirs, sandbox| { + sandbox + .within("contributors") + .with_files(vec![EmptyFile("jonathan.txt")]) + .mkdir("expected"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let original_dir = format!("{}/{}", full_path, "contributors"); - let expected = format!("{}/{}", full_path, "expected/contributors"); + let original_dir = dirs.test().join("contributors"); + let expected = dirs.test().join("expected/contributors"); - nu!(_output, cwd(&full_path), "mv contributors expected"); + nu!(dirs.test(), "mv contributors expected"); - assert!(!h::dir_exists_at(PathBuf::from(original_dir))); - assert!(h::file_exists_at(PathBuf::from(expected))); + assert!(!h::dir_exists_at(original_dir)); + assert!(h::file_exists_at(expected)); + }) } #[test] fn moves_the_directory_inside_directory_if_path_to_move_is_nonexistent_directory() { - let sandbox = Playground::setup_for("mv_test_6") - .within("contributors") - .with_files(vec![EmptyFile("jonathan.txt")]) - .mkdir("expected") - .test_dir_name(); + Playground::setup("mv_test_6", |dirs, sandbox| { + sandbox + .within("contributors") + .with_files(vec![EmptyFile("jonathan.txt")]) + .mkdir("expected"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let original_dir = format!("{}/{}", full_path, "contributors"); + let original_dir = dirs.test().join("contributors"); - nu!( - _output, - cwd(&full_path), - "mv contributors expected/this_dir_exists_now/los_tres_amigos" - ); + nu!( + cwd(dirs.test()), + "mv contributors expected/this_dir_exists_now/los_tres_amigos" + ); - let expected = format!( - "{}/{}", - full_path, "expected/this_dir_exists_now/los_tres_amigos" - ); + let expected = dirs + .test() + .join("expected/this_dir_exists_now/los_tres_amigos"); - assert!(!h::dir_exists_at(PathBuf::from(original_dir))); - assert!(h::file_exists_at(PathBuf::from(expected))); + assert!(!h::dir_exists_at(original_dir)); + assert!(h::file_exists_at(expected)); + }) } #[test] fn moves_using_path_with_wildcard() { - let sandbox = Playground::setup_for("mv_test_7") - .within("originals") - .with_files(vec![ - EmptyFile("andres.ini"), - EmptyFile("caco3_plastics.csv"), - EmptyFile("cargo_sample.toml"), - EmptyFile("jonathan.ini"), - EmptyFile("jonathan.xml"), - EmptyFile("sgml_description.json"), - EmptyFile("sample.ini"), - EmptyFile("utf16.ini"), - EmptyFile("yehuda.ini"), - ]) - .mkdir("work_dir") - .mkdir("expected") - .test_dir_name(); + Playground::setup("mv_test_7", |dirs, sandbox| { + sandbox + .within("originals") + .with_files(vec![ + EmptyFile("andres.ini"), + EmptyFile("caco3_plastics.csv"), + EmptyFile("cargo_sample.toml"), + EmptyFile("jonathan.ini"), + EmptyFile("jonathan.xml"), + EmptyFile("sgml_description.json"), + EmptyFile("sample.ini"), + EmptyFile("utf16.ini"), + EmptyFile("yehuda.ini") + ]) + .mkdir("work_dir") + .mkdir("expected"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let work_dir = format!("{}/{}", full_path, "work_dir"); - let expected_copies_path = format!("{}/{}", full_path, "expected"); + let work_dir = dirs.test().join("work_dir"); + let expected = dirs.test().join("expected"); - nu!(_output, cwd(&work_dir), "mv ../originals/*.ini ../expected"); + nu!(cwd(work_dir), "mv ../originals/*.ini ../expected"); - assert!(h::files_exist_at( - vec![ - Path::new("yehuda.ini"), - Path::new("jonathan.ini"), - Path::new("sample.ini"), - Path::new("andres.ini"), - ], - PathBuf::from(&expected_copies_path) - )); + assert!(h::files_exist_at( + vec!["yehuda.ini", "jonathan.ini", "sample.ini", "andres.ini",], + expected + )); + }) } #[test] fn moves_using_a_glob() { - let sandbox = Playground::setup_for("mv_test_8") - .within("meals") - .with_files(vec![ - EmptyFile("arepa.txt"), - EmptyFile("empanada.txt"), - EmptyFile("taquiza.txt"), - ]) - .mkdir("work_dir") - .mkdir("expected") - .test_dir_name(); + Playground::setup("mv_test_8", |dirs, sandbox| { + sandbox + .within("meals") + .with_files(vec![ + EmptyFile("arepa.txt"), + EmptyFile("empanada.txt"), + EmptyFile("taquiza.txt") + ]) + .mkdir("work_dir") + .mkdir("expected"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let meal_dir = format!("{}/{}", full_path, "meals"); - let work_dir = format!("{}/{}", full_path, "work_dir"); - let expected_copies_path = format!("{}/{}", full_path, "expected"); + let meal_dir = dirs.test().join("meals"); + let work_dir = dirs.test().join("work_dir"); + let expected = dirs.test().join("expected"); - nu!(_output, cwd(&work_dir), "mv ../meals/* ../expected"); + nu!(cwd(work_dir), "mv ../meals/* ../expected"); - assert!(h::dir_exists_at(PathBuf::from(meal_dir))); - assert!(h::files_exist_at( - vec![ - Path::new("arepa.txt"), - Path::new("empanada.txt"), - Path::new("taquiza.txt"), - ], - PathBuf::from(&expected_copies_path) - )); + assert!(h::dir_exists_at(meal_dir)); + assert!(h::files_exist_at( + vec!["arepa.txt", "empanada.txt", "taquiza.txt",], + expected + )); + }) } diff --git a/tests/command_open_tests.rs b/tests/command_open_tests.rs index d962d3e88..4824936c2 100644 --- a/tests/command_open_tests.rs +++ b/tests/command_open_tests.rs @@ -1,114 +1,126 @@ mod helpers; use helpers::{in_directory as cwd, Playground, Stub::*}; +use helpers as h; #[test] fn recognizes_csv() { - Playground::setup_for("open_recognizes_csv_test").with_files(vec![FileWithContentToBeTrimmed( - "nu.zion.csv", - r#" - author,lang,source - Jonathan Turner,Rust,New Zealand - Andres N. Robalino,Rust,Ecuador - Yehuda Katz,Rust,Estados Unidos - "#, - )]); + Playground::setup("open_test_1", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContentToBeTrimmed( + "nu.zion.csv", + r#" + author,lang,source + Jonathan Turner,Rust,New Zealand + Andres N. Robalino,Rust,Ecuador + Yehuda Katz,Rust,Estados Unidos + "# + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/open_recognizes_csv_test"), - r#"open nu.zion.csv | where author == "Andres N. Robalino" | get source | echo $it"# - ); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + open nu.zion.csv + | where author == "Andres N. Robalino" + | get source + | echo $it + "# + )); - assert_eq!(output, "Ecuador"); + assert_eq!(actual, "Ecuador"); + }) } #[test] fn open_can_parse_bson_1() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "open sample.bson | get root | nth 0 | get b | echo $it" ); - assert_eq!(output, "hello"); + assert_eq!(actual, "hello"); } #[test] fn open_can_parse_bson_2() { - nu!( - output, - cwd("tests/fixtures/formats"), - "open sample.bson | get root | nth 6 | get b | get '$binary_subtype' | echo $it " - ); + let actual = nu!( + cwd("tests/fixtures/formats"), h::pipeline( + r#" + open sample.bson + | get root + | nth 6 + | get b + | get '$binary_subtype' + | echo $it + "# + )); - assert_eq!(output, "function"); + assert_eq!(actual, "function"); } #[test] fn open_can_parse_toml() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "open cargo_sample.toml | get package.edition | echo $it" ); - assert_eq!(output, "2018"); + assert_eq!(actual, "2018"); } #[test] fn open_can_parse_json() { - nu!(output, - cwd("tests/fixtures/formats"), - "open sgml_description.json | get glossary.GlossDiv.GlossList.GlossEntry.GlossSee | echo $it" - ); + let actual = nu!( + cwd("tests/fixtures/formats"), h::pipeline( + r#" + open sgml_description.json + | get glossary.GlossDiv.GlossList.GlossEntry.GlossSee + | echo $it + "# + )); - assert_eq!(output, "markup") + assert_eq!(actual, "markup") } #[test] fn open_can_parse_xml() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "open jonathan.xml | get rss.channel.item.link | echo $it" ); assert_eq!( - output, + actual, "http://www.jonathanturner.org/2015/10/off-to-new-adventures.html" ) } #[test] fn open_can_parse_ini() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "open sample.ini | get SectionOne.integer | echo $it" ); - assert_eq!(output, "1234") + assert_eq!(actual, "1234") } #[test] fn open_can_parse_utf16_ini() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "open utf16.ini | get .ShellClassInfo | get IconIndex | echo $it" ); - assert_eq!(output, "-236") + assert_eq!(actual, "-236") } #[test] fn errors_if_file_not_found() { - nu_error!( - output, + let actual = nu_error!( cwd("tests/fixtures/formats"), "open i_dont_exist.txt | echo $it" ); - assert!(output.contains("File could not be opened")); + assert!(actual.contains("File could not be opened")); } diff --git a/tests/command_rm_tests.rs b/tests/command_rm_tests.rs index 126465a2d..2d5a90e8d 100644 --- a/tests/command_rm_tests.rs +++ b/tests/command_rm_tests.rs @@ -2,171 +2,145 @@ mod helpers; use h::{in_directory as cwd, Playground, Stub::*}; use helpers as h; -use std::path::{Path, PathBuf}; #[test] fn rm_removes_a_file() { - let sandbox = Playground::setup_for("rm_regular_file_test") - .with_files(vec![EmptyFile("i_will_be_deleted.txt")]) - .test_dir_name(); + Playground::setup("rm_test_1", |dirs, sandbox| { + sandbox + .with_files(vec![EmptyFile("i_will_be_deleted.txt") + ]); - nu!( - _output, - cwd(&Playground::root()), - "rm rm_regular_file_test/i_will_be_deleted.txt" - ); + nu!(cwd(dirs.root()), "rm rm_test_1/i_will_be_deleted.txt"); - let path = &format!( - "{}/{}/{}", - Playground::root(), - sandbox, - "i_will_be_deleted.txt" - ); + let path = dirs.test().join("i_will_be_deleted.txt"); - assert!(!h::file_exists_at(PathBuf::from(path))); + assert!(!h::file_exists_at(path)); + }) } #[test] fn rm_removes_files_with_wildcard() { - let sandbox = Playground::setup_for("rm_wildcard_test_1") - .within("src") - .with_files(vec![ - EmptyFile("cli.rs"), - EmptyFile("lib.rs"), - EmptyFile("prelude.rs"), - ]) - .within("src/parser") - .with_files(vec![EmptyFile("parse.rs"), EmptyFile("parser.rs")]) - .within("src/parser/parse") - .with_files(vec![EmptyFile("token_tree.rs")]) - .within("src/parser/hir") - .with_files(vec![ - EmptyFile("baseline_parse.rs"), - EmptyFile("baseline_parse_tokens.rs"), - ]) - .test_dir_name(); + Playground::setup("rm_test_2", |dirs, sandbox| { + sandbox + .within("src") + .with_files(vec![ + EmptyFile("cli.rs"), + EmptyFile("lib.rs"), + EmptyFile("prelude.rs") + ]) + .within("src/parser") + .with_files(vec![EmptyFile("parse.rs"), EmptyFile("parser.rs")]) + .within("src/parser/parse") + .with_files(vec![EmptyFile("token_tree.rs")]) + .within("src/parser/hir") + .with_files(vec![ + EmptyFile("baseline_parse.rs"), + EmptyFile("baseline_parse_tokens.rs") + ]); - let full_path = format!("{}/{}", Playground::root(), sandbox); + nu!(cwd(dirs.test()), r#"rm "src/*/*/*.rs""#); - nu!( - _output, - cwd("tests/fixtures/nuplayground/rm_wildcard_test_1"), - r#"rm "src/*/*/*.rs""# - ); + assert!(!h::files_exist_at( + vec![ + "src/parser/parse/token_tree.rs", + "src/parser/hir/baseline_parse.rs", + "src/parser/hir/baseline_parse_tokens.rs" + ], + dirs.test() + )); - assert!(!h::files_exist_at( - vec![ - Path::new("src/parser/parse/token_tree.rs"), - Path::new("src/parser/hir/baseline_parse.rs"), - Path::new("src/parser/hir/baseline_parse_tokens.rs") - ], - PathBuf::from(&full_path) - )); - - assert_eq!( - Playground::glob_vec(&format!("{}/src/*/*/*.rs", &full_path)), - Vec::::new() - ); + assert_eq!( + Playground::glob_vec(&format!("{}/src/*/*/*.rs", dirs.test().display())), + Vec::::new() + ); + }) } #[test] fn rm_removes_deeply_nested_directories_with_wildcard_and_recursive_flag() { - let sandbox = Playground::setup_for("rm_wildcard_test_2") - .within("src") - .with_files(vec![ - EmptyFile("cli.rs"), - EmptyFile("lib.rs"), - EmptyFile("prelude.rs"), - ]) - .within("src/parser") - .with_files(vec![EmptyFile("parse.rs"), EmptyFile("parser.rs")]) - .within("src/parser/parse") - .with_files(vec![EmptyFile("token_tree.rs")]) - .within("src/parser/hir") - .with_files(vec![ - EmptyFile("baseline_parse.rs"), - EmptyFile("baseline_parse_tokens.rs"), - ]) - .test_dir_name(); + Playground::setup("rm_test_3", |dirs, sandbox| { + sandbox + .within("src") + .with_files(vec![ + EmptyFile("cli.rs"), + EmptyFile("lib.rs"), + EmptyFile("prelude.rs") + ]) + .within("src/parser") + .with_files(vec![EmptyFile("parse.rs"), EmptyFile("parser.rs")]) + .within("src/parser/parse") + .with_files(vec![EmptyFile("token_tree.rs")]) + .within("src/parser/hir") + .with_files(vec![ + EmptyFile("baseline_parse.rs"), + EmptyFile("baseline_parse_tokens.rs") + ]); - let full_path = format!("{}/{}", Playground::root(), sandbox); + nu!(cwd(dirs.test()), "rm src/* --recursive"); - nu!( - _output, - cwd("tests/fixtures/nuplayground/rm_wildcard_test_2"), - "rm src/* --recursive" - ); - - assert!(!h::files_exist_at( - vec![Path::new("src/parser/parse"), Path::new("src/parser/hir"),], - PathBuf::from(&full_path) - )); + assert!(!h::files_exist_at( + vec!["src/parser/parse", "src/parser/hir"], + dirs.test() + )); + }) } #[test] fn rm_removes_directory_contents_without_recursive_flag_if_empty() { - let sandbox = Playground::setup_for("rm_directory_removal_recursively_test_1").test_dir_name(); + Playground::setup("rm_test_4", |dirs, _| { + nu!(cwd(dirs.root()), "rm rm_test_4"); - nu!( - _output, - cwd("tests/fixtures/nuplayground"), - "rm rm_directory_removal_recursively_test_1" - ); - - let expected = format!("{}/{}", Playground::root(), sandbox); - - assert!(!h::file_exists_at(PathBuf::from(expected))); + assert!(!h::file_exists_at(dirs.test())); + }) } #[test] fn rm_removes_directory_contents_with_recursive_flag() { - let sandbox = Playground::setup_for("rm_directory_removal_recursively_test_2") - .with_files(vec![ - EmptyFile("yehuda.txt"), - EmptyFile("jonathan.txt"), - EmptyFile("andres.txt"), - ]) - .test_dir_name(); + Playground::setup("rm_test_5", |dirs, sandbox| { + sandbox + .with_files(vec![ + EmptyFile("yehuda.txt"), + EmptyFile("jonathan.txt"), + EmptyFile("andres.txt") + ]); - nu!( - _output, - cwd("tests/fixtures/nuplayground"), - "rm rm_directory_removal_recursively_test_2 --recursive" - ); + nu!(cwd(dirs.root()), "rm rm_test_5 --recursive"); - let expected = format!("{}/{}", Playground::root(), sandbox); - - assert!(!h::file_exists_at(PathBuf::from(expected))); + assert!(!h::file_exists_at(dirs.test())); + }) } #[test] fn rm_errors_if_attempting_to_delete_a_directory_with_content_without_recursive_flag() { - let sandbox = Playground::setup_for("rm_prevent_directory_removal_without_flag_test") - .with_files(vec![EmptyFile("some_empty_file.txt")]) - .test_dir_name(); + Playground::setup("rm_test_6", |dirs, sandbox| { + sandbox + .with_files(vec![EmptyFile("some_empty_file.txt") + ]); - let full_path = format!("{}/{}", Playground::root(), sandbox); + let actual = nu_error!( + cwd(dirs.root()), + "rm rm_test_6" + ); - nu_error!( - output, - cwd(&Playground::root()), - "rm rm_prevent_directory_removal_without_flag_test" - ); - - assert!(h::file_exists_at(PathBuf::from(full_path))); - assert!(output.contains("is a directory")); + assert!(h::file_exists_at(dirs.test())); + assert!(actual.contains("is a directory")); + }) } #[test] fn rm_errors_if_attempting_to_delete_single_dot_as_argument() { - nu_error!(output, cwd(&Playground::root()), "rm ."); + Playground::setup("rm_test_7", |dirs, _| { + let actual = nu_error!(cwd(dirs.root()), "rm ."); - assert!(output.contains("may not be removed")); + assert!(actual.contains("may not be removed")); + }) } #[test] fn rm_errors_if_attempting_to_delete_two_dot_as_argument() { - nu_error!(output, cwd(&Playground::root()), "rm .."); + Playground::setup("rm_test_8", |dirs, _| { + let actual = nu_error!(cwd(dirs.root()), "rm .."); - assert!(output.contains("may not be removed")); + assert!(actual.contains("may not be removed")); + }) } diff --git a/tests/commands_test.rs b/tests/commands_test.rs index 1c8ddd25d..6384581c9 100644 --- a/tests/commands_test.rs +++ b/tests/commands_test.rs @@ -5,18 +5,18 @@ use helpers as h; #[test] fn lines() { - nu!(output, + let actual = nu!( cwd("tests/fixtures/formats"), r#"open cargo_sample.toml --raw | lines | skip-while $it != "[dependencies]" | skip 1 | first 1 | split-column "=" | get Column1 | trim | echo $it"# ); - assert_eq!(output, "rustyline"); + assert_eq!(actual, "rustyline"); } #[test] fn save_figures_out_intelligently_where_to_write_out_with_metadata() { - let sandbox = Playground::setup_for("save_smart_test") - .with_files(vec![FileWithContent( + Playground::setup("save_test_1", |dirs, sandbox| { + sandbox.with_files(vec![FileWithContent( "cargo_sample.toml", r#" [package] @@ -26,36 +26,33 @@ fn save_figures_out_intelligently_where_to_write_out_with_metadata() { description = "A shell for the GitHub era" license = "ISC" edition = "2018" - "#, - )]) - .test_dir_name(); + "#) + ]); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let subject_file = format!("{}/{}", full_path, "cargo_sample.toml"); + let subject_file = dirs.test().join("cargo_sample.toml"); - nu!( - _output, - cwd(&Playground::root()), - "open save_smart_test/cargo_sample.toml | inc package.version --minor | save" - ); + nu!( + cwd(dirs.root()), + "open save_test_1/cargo_sample.toml | inc package.version --minor | save" + ); - let actual = h::file_contents(&subject_file); - assert!(actual.contains("0.2.0")); + let actual = h::file_contents(&subject_file); + assert!(actual.contains("0.2.0")); + }) } #[test] fn save_can_write_out_csv() { - let sandbox = Playground::setup_for("save_writes_out_csv_test").test_dir_name(); + Playground::setup("save_test_2", |dirs, _| { + let expected_file = dirs.test().join("cargo_sample.csv"); - let full_path = format!("{}/{}", Playground::root(), sandbox); - let expected_file = format!("{}/{}", full_path, "cargo_sample.csv"); + nu!( + dirs.root(), + "open {}/cargo_sample.toml | inc package.version --minor | get package | save save_test_2/cargo_sample.csv", + dirs.formats() + ); - nu!( - _output, - cwd(&Playground::root()), - "open ../formats/cargo_sample.toml | inc package.version --minor | get package | save save_writes_out_csv_test/cargo_sample.csv" - ); - - let actual = h::file_contents(&expected_file); - assert!(actual.contains("[list list],A shell for the GitHub era,2018,ISC,nu,0.2.0")); + let actual = h::file_contents(expected_file); + assert!(actual.contains("[list list],A shell for the GitHub era,2018,ISC,nu,0.2.0")); + }) } diff --git a/tests/external_tests.rs b/tests/external_tests.rs index ba62c5e12..6e1d2eec7 100644 --- a/tests/external_tests.rs +++ b/tests/external_tests.rs @@ -4,7 +4,7 @@ use helpers::in_directory as cwd; #[test] fn external_command() { - nu!(output, cwd("tests/fixtures"), "echo 1"); + let actual = nu!(cwd("tests/fixtures"), "echo 1"); - assert!(output.contains("1")); + assert!(actual.contains("1")); } diff --git a/tests/filter_inc_tests.rs b/tests/filter_inc_tests.rs index 449380961..6ba98e554 100644 --- a/tests/filter_inc_tests.rs +++ b/tests/filter_inc_tests.rs @@ -5,131 +5,136 @@ use helpers as h; #[test] fn can_only_apply_one() { - nu_error!( - output, + let actual = nu_error!( cwd("tests/fixtures/formats"), "open cargo_sample.toml | first 1 | inc package.version --major --minor" ); - assert!(output.contains("Usage: inc field [--major|--minor|--patch]")); + assert!(actual.contains("Usage: inc field [--major|--minor|--patch]")); } #[test] fn by_one_with_field_passed() { - Playground::setup_for("plugin_inc_by_one_with_field_passed_test").with_files(vec![ - FileWithContent( - "sample.toml", - r#" - [package] - edition = "2018" - "#, - ), - ]); + Playground::setup("plugin_inc_test_1", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [package] + edition = "2018" + "# + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_inc_by_one_with_field_passed_test"), - "open sample.toml | inc package.edition | get package.edition | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), + "open sample.toml | inc package.edition | get package.edition | echo $it" + ); - assert_eq!(output, "2019"); + assert_eq!(actual, "2019"); + }) } #[test] fn by_one_with_no_field_passed() { - Playground::setup_for("plugin_inc_by_one_with_no_field_passed_test").with_files(vec![ - FileWithContent( - "sample.toml", - r#" - [package] - contributors = "2" - "#, - ), - ]); + Playground::setup("plugin_inc_test_2", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [package] + contributors = "2" + "# + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_inc_by_one_with_no_field_passed_test"), - "open sample.toml | get package.contributors | inc | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), + "open sample.toml | get package.contributors | inc | echo $it" + ); - assert_eq!(output, "3"); + assert_eq!(actual, "3"); + }) } #[test] fn semversion_major_inc() { - Playground::setup_for("plugin_inc_major_semversion_test").with_files(vec![FileWithContent( - "sample.toml", - r#" - [package] - version = "0.1.3" - "#, - )]); + Playground::setup("plugin_inc_test_3", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [package] + version = "0.1.3" + "# + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_inc_major_semversion_test"), - "open sample.toml | inc package.version --major | get package.version | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), + "open sample.toml | inc package.version --major | get package.version | echo $it" + ); - assert_eq!(output, "1.0.0"); + assert_eq!(actual, "1.0.0"); + }) } #[test] fn semversion_minor_inc() { - Playground::setup_for("plugin_inc_minor_semversion_test").with_files(vec![FileWithContent( - "sample.toml", - r#" - [package] - version = "0.1.3" - "#, - )]); + Playground::setup("plugin_inc_test_4", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [package] + version = "0.1.3" + "# + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_inc_minor_semversion_test"), - "open sample.toml | inc package.version --minor | get package.version | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), + "open sample.toml | inc package.version --minor | get package.version | echo $it" + ); - assert_eq!(output, "0.2.0"); + assert_eq!(actual, "0.2.0"); + }) } #[test] fn semversion_patch_inc() { - Playground::setup_for("plugin_inc_patch_semversion_test").with_files(vec![FileWithContent( - "sample.toml", - r#" - [package] - version = "0.1.3" - "#, - )]); + Playground::setup("plugin_inc_test_5", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [package] + version = "0.1.3" + "# + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_inc_patch_semversion_test"), - "open sample.toml | inc package.version --patch | get package.version | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), + "open sample.toml | inc package.version --patch | get package.version | echo $it" + ); - assert_eq!(output, "0.1.4"); + assert_eq!(actual, "0.1.4"); + }) } #[test] fn semversion_without_passing_field() { - Playground::setup_for("plugin_inc_semversion_without_passing_field_test").with_files(vec![ - FileWithContent( - "sample.toml", - r#" - [package] - version = "0.1.3" - "#, - ), - ]); + Playground::setup("plugin_inc_test_6", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [package] + version = "0.1.3" + "# + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_inc_semversion_without_passing_field_test"), - "open sample.toml | get package.version | inc --patch | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), + "open sample.toml | get package.version | inc --patch | echo $it" + ); - assert_eq!(output, "0.1.4"); + assert_eq!(actual, "0.1.4"); + }) } diff --git a/tests/filter_str_tests.rs b/tests/filter_str_tests.rs index 630c144c8..7774f9dcf 100644 --- a/tests/filter_str_tests.rs +++ b/tests/filter_str_tests.rs @@ -5,143 +5,170 @@ use helpers as h; #[test] fn can_only_apply_one() { - nu_error!( - output, + let actual = nu_error!( cwd("tests/fixtures/formats"), "open caco3_plastics.csv | first 1 | str origin --downcase --upcase" ); assert!( - output.contains("Usage: str field [--downcase|--upcase|--to-int|--replace|--find-replace]") + actual.contains("Usage: str field [--downcase|--upcase|--to-int|--replace|--find-replace]") ); } #[test] fn acts_without_passing_field() { - Playground::setup_for("plugin_str_acts_without_passing_field_test").with_files(vec![ - FileWithContent( + Playground::setup("plugin_str_test_1", |dirs, sandbox| { + sandbox.with_files(vec![FileWithContent( "sample.yml", r#" environment: global: PROJECT_NAME: nushell "#, - ), - ]); + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_str_acts_without_passing_field_test"), - "open sample.yml | get environment.global.PROJECT_NAME | str --upcase | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), + "open sample.yml | get environment.global.PROJECT_NAME | str --upcase | echo $it" + ); - assert_eq!(output, "NUSHELL"); + assert_eq!(actual, "NUSHELL"); + }) } #[test] fn downcases() { - Playground::setup_for("plugin_str_downcases_test").with_files(vec![FileWithContent( - "sample.toml", - r#" - [dependency] - name = "LIGHT" - "#, - )]); + Playground::setup("plugin_str_test_2", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [dependency] + name = "LIGHT" + "#, + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_str_downcases_test"), - "open sample.toml | str dependency.name --downcase | get dependency.name | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), + "open sample.toml | str dependency.name --downcase | get dependency.name | echo $it" + ); - assert_eq!(output, "light"); + assert_eq!(actual, "light"); + }) } #[test] fn upcases() { - Playground::setup_for("plugin_str_upcases_test").with_files(vec![FileWithContent( - "sample.toml", - r#" - [package] - name = "nushell" - "#, - )]); + Playground::setup("plugin_str_test_3", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [package] + name = "nushell" + "#, + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_str_upcases_test"), - "open sample.toml | str package.name --upcase | get package.name | echo $it" - ); - - assert_eq!(output, "NUSHELL"); + let actual = nu!( + cwd(dirs.test()), + "open sample.toml | str package.name --upcase | get package.name | echo $it" + ); + + assert_eq!(actual, "NUSHELL"); + }) } #[test] fn converts_to_int() { - nu!( - output, - cwd("tests/fixtures/formats"), - "open caco3_plastics.csv | first 1 | str tariff_item --to-int | where tariff_item == 2509000000 | get tariff_item | echo $it" - ); + let actual = nu!( + cwd("tests/fixtures/formats"), h::pipeline( + r#" + open caco3_plastics.csv + | first 1 + | str tariff_item --to-int + | where tariff_item == 2509000000 + | get tariff_item + | echo $it + "# + )); - assert_eq!(output, "2509000000"); + assert_eq!(actual, "2509000000"); } #[test] fn replaces() { - Playground::setup_for("plugin_str_replaces_test").with_files(vec![FileWithContent( - "sample.toml", - r#" - [package] - name = "nushell" - "#, - )]); + Playground::setup("plugin_str_test_4", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [package] + name = "nushell" + "#, + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_str_replaces_test"), - "open sample.toml | str package.name --replace wykittenshell | get package.name | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + open sample.toml + | str package.name --replace wykittenshell + | get package.name + | echo $it + "# + )); - assert_eq!(output, "wykittenshell"); + assert_eq!(actual, "wykittenshell"); + }) } #[test] fn find_and_replaces() { - Playground::setup_for("plugin_str_find_and_replaces_test").with_files(vec![FileWithContent( - "sample.toml", - r#" - [fortune.teller] - phone = "1-800-KATZ" - "#, - )]); + Playground::setup("plugin_str_test_5", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( + "sample.toml", + r#" + [fortune.teller] + phone = "1-800-KATZ" + "#, + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_str_find_and_replaces_test"), - r#"open sample.toml | str fortune.teller.phone --find-replace KATZ "5289" | get fortune.teller.phone | echo $it"# - ); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + open sample.toml + | str fortune.teller.phone --find-replace KATZ "5289" + | get fortune.teller.phone + | echo $it + "# + )); - assert_eq!(output, "1-800-5289"); + assert_eq!(actual, "1-800-5289"); + }) } #[test] fn find_and_replaces_without_passing_field() { - Playground::setup_for("plugin_str_find_and_replaces_without_passing_field_test").with_files( - vec![FileWithContent( + Playground::setup("plugin_str_test_6", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContent( "sample.toml", + r#" + [fortune.teller] + phone = "1-800-KATZ" + "#, + )]); + + let actual = nu!( + cwd(dirs.test()), h::pipeline( r#" - [fortune.teller] - phone = "1-800-KATZ" - "#, - )], - ); + open sample.toml + | get fortune.teller.phone + | str --find-replace KATZ "5289" + | echo $it + "# + )); - nu!( - output, - cwd("tests/fixtures/nuplayground/plugin_str_find_and_replaces_without_passing_field_test"), - r#"open sample.toml | get fortune.teller.phone | str --find-replace KATZ "5289" | echo $it"# - ); - - assert_eq!(output, "1-800-5289"); + assert_eq!(actual, "1-800-5289"); + }) } diff --git a/tests/filters_test.rs b/tests/filters_test.rs index f5b8ebb77..842b0a574 100644 --- a/tests/filters_test.rs +++ b/tests/filters_test.rs @@ -1,271 +1,360 @@ mod helpers; use helpers::{in_directory as cwd, Playground, Stub::*}; +use helpers as h; #[test] fn can_convert_table_to_csv_text_and_from_csv_text_back_into_table() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "open caco3_plastics.csv | to-csv | from-csv | first 1 | get origin | echo $it" ); - assert_eq!(output, "SPAIN"); + assert_eq!(actual, "SPAIN"); } #[test] fn converts_structured_table_to_csv_text() { - Playground::setup_for("filter_to_csv_test_1").with_files(vec![FileWithContentToBeTrimmed( - "sample.txt", - r#" - importer,shipper,tariff_item,name,origin - Plasticos Rival,Reverte,2509000000,Calcium carbonate,Spain - Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia - "#, - )]); + Playground::setup("filter_to_csv_test_1", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContentToBeTrimmed( + "csv_text_sample.txt", + r#" + importer,shipper,tariff_item,name,origin + Plasticos Rival,Reverte,2509000000,Calcium carbonate,Spain + Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia + "# + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/filter_to_csv_test_1"), - r#"open sample.txt | lines | split-column "," a b c d origin | last 1 | to-csv | lines | nth 1 | echo "$it""# - ); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + open csv_text_sample.txt + | lines + | split-column "," a b c d origin + | last 1 + | to-csv + | lines + | nth 1 + | echo "$it" + "# + )); - assert!(output.contains("Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia")); + assert!(actual.contains("Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia")); + }) } #[test] fn converts_structured_table_to_csv_text_skipping_headers_after_conversion() { - Playground::setup_for("filter_to_csv_test_2").with_files(vec![FileWithContentToBeTrimmed( - "sample.txt", - r#" - importer,shipper,tariff_item,name,origin - Plasticos Rival,Reverte,2509000000,Calcium carbonate,Spain - Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia - "#, - )]); + Playground::setup("filter_to_csv_test_2", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContentToBeTrimmed( + "csv_text_sample.txt", + r#" + importer,shipper,tariff_item,name,origin + Plasticos Rival,Reverte,2509000000,Calcium carbonate,Spain + Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia + "# + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/filter_to_csv_test_2"), - r#"open sample.txt | lines | split-column "," a b c d origin | last 1 | to-csv --headerless | echo "$it""# - ); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + open csv_text_sample.txt + | lines + | split-column "," a b c d origin + | last 1 + | to-csv --headerless + | echo "$it" + "# + )); - assert!(output.contains("Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia")); + assert!(actual.contains("Tigre Ecuador,OMYA Andina,3824909999,Calcium carbonate,Colombia")); + }) } #[test] fn converts_from_csv_text_to_structured_table() { - Playground::setup_for("filter_from_csv_test_1").with_files(vec![FileWithContentToBeTrimmed( - "los_tres_amigos.txt", - r#" - first_name,last_name,rusty_luck - Andrés,Robalino,1 - Jonathan,Turner,1 - Yehuda,Katz,1 - "#, - )]); + Playground::setup("filter_from_csv_test_1", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContentToBeTrimmed( + "los_tres_amigos.txt", + r#" + first_name,last_name,rusty_luck + Andrés,Robalino,1 + Jonathan,Turner,1 + Yehuda,Katz,1 + "#, + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/filter_from_csv_test_1"), - "open los_tres_amigos.txt | from-csv | get rusty_luck | str --to-int | sum | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + open los_tres_amigos.txt + | from-csv + | get rusty_luck + | str --to-int + | sum + | echo $it + "# + )); - assert_eq!(output, "3"); + assert_eq!(actual, "3"); + }) } #[test] fn converts_from_csv_text_skipping_headers_to_structured_table() { - Playground::setup_for("filter_from_csv_test_2").with_files(vec![FileWithContentToBeTrimmed( - "los_tres_amigos.txt", - r#" - first_name,last_name,rusty_luck - Andrés,Robalino,1 - Jonathan,Turner,1 - Yehuda,Katz,1 - "#, - )]); + Playground::setup("filter_from_csv_test_2", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContentToBeTrimmed( + "los_tres_amigos.txt", + r#" + first_name,last_name,rusty_luck + Andrés,Robalino,1 + Jonathan,Turner,1 + Yehuda,Katz,1 + "#, + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/filter_from_csv_test_2"), - "open los_tres_amigos.txt | from-csv --headerless | get Column3 | str --to-int | sum | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + open los_tres_amigos.txt + | from-csv --headerless + | get Column3 + | str --to-int + | sum + | echo $it + "# + )); - assert_eq!(output, "3"); + assert_eq!(actual, "3"); + }) } #[test] fn can_convert_table_to_json_text_and_from_json_text_back_into_table() { - nu!( - output, - cwd("tests/fixtures/formats"), - "open sgml_description.json | to-json | from-json | get glossary.GlossDiv.GlossList.GlossEntry.GlossSee | echo $it" - ); + let actual = nu!( + cwd("tests/fixtures/formats"), h::pipeline( + r#" + open sgml_description.json + | to-json + | from-json + | get glossary.GlossDiv.GlossList.GlossEntry.GlossSee + | echo $it + "# + )); - assert_eq!(output, "markup"); + assert_eq!(actual, "markup"); } #[test] fn converts_from_json_text_to_structured_table() { - Playground::setup_for("filter_from_json_test_1").with_files(vec![FileWithContentToBeTrimmed( - "katz.txt", - r#" - { - "katz": [ - {"name": "Yehuda", "rusty_luck": 1}, - {"name": "Jonathan", "rusty_luck": 1}, - {"name": "Andres", "rusty_luck": 1}, - {"name":"GorbyPuff", "rusty_luck": 1} - ] - } - "#, - )]); + Playground::setup("filter_from_json_test_1", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContentToBeTrimmed( + "katz.txt", + r#" + { + "katz": [ + {"name": "Yehuda", "rusty_luck": 1}, + {"name": "Jonathan", "rusty_luck": 1}, + {"name": "Andres", "rusty_luck": 1}, + {"name":"GorbyPuff", "rusty_luck": 1} + ] + } + "#, + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/filter_from_json_test_1"), - "open katz.txt | from-json | get katz | get rusty_luck | sum | echo $it" - ); + let actual = nu!( + cwd(dirs.test()), + "open katz.txt | from-json | get katz | get rusty_luck | sum | echo $it" + ); - assert_eq!(output, "4"); + assert_eq!(actual, "4"); + + }) } #[test] fn converts_from_json_text_recognizing_objects_independendtly_to_structured_table() { - Playground::setup_for("filter_from_json_test_2").with_files(vec![FileWithContentToBeTrimmed( - "katz.txt", - r#" - {"name": "Yehuda", "rusty_luck": 1} - {"name": "Jonathan", "rusty_luck": 1} - {"name": "Andres", "rusty_luck": 1} - {"name":"GorbyPuff", "rusty_luck": 3} - "#, - )]); + Playground::setup("filter_from_json_test_2", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContentToBeTrimmed( + "katz.txt", + r#" + {"name": "Yehuda", "rusty_luck": 1} + {"name": "Jonathan", "rusty_luck": 1} + {"name": "Andres", "rusty_luck": 1} + {"name":"GorbyPuff", "rusty_luck": 3} + "#, + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/filter_from_json_test_2"), - r#"open katz.txt | from-json --objects | where name == "GorbyPuff" | get rusty_luck | echo $it"# - ); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + open katz.txt + | from-json --objects + | where name == "GorbyPuff" + | get rusty_luck + | echo $it + "# + )); - assert_eq!(output, "3"); + assert_eq!(actual, "3"); + }) } #[test] fn converts_structured_table_to_json_text() { - Playground::setup_for("filter_to_json_test_1").with_files(vec![FileWithContentToBeTrimmed( - "sample.txt", - r#" - JonAndrehudaTZ,3 - GorbyPuff,100 - "#, - )]); + Playground::setup("filter_to_json_test", |dirs, sandbox| { + sandbox + .with_files(vec![FileWithContentToBeTrimmed( + "sample.txt", + r#" + JonAndrehudaTZ,3 + GorbyPuff,100 + "#, + )]); - nu!( - output, - cwd("tests/fixtures/nuplayground/filter_to_json_test_1"), - r#"open sample.txt | lines | split-column "," name luck | pick name | to-json | nth 0 | from-json | get name | echo $it"# - ); + let actual = nu!( + cwd(dirs.test()), h::pipeline( + r#" + open sample.txt + | lines + | split-column "," name luck + | pick name + | to-json + | nth 0 + | from-json + | get name + | echo $it + "# + )); - assert_eq!(output, "JonAndrehudaTZ"); + assert_eq!(actual, "JonAndrehudaTZ"); + }) } #[test] fn can_convert_json_text_to_bson_and_back_into_table() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "open sample.bson | to-bson | from-bson | get root | nth 1 | get b | echo $it" ); - assert_eq!(output, "whel"); + assert_eq!(actual, "whel"); } #[test] fn can_convert_table_to_toml_text_and_from_toml_text_back_into_table() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "open cargo_sample.toml | to-toml | from-toml | get package.name | echo $it" ); - assert_eq!(output, "nu"); + assert_eq!(actual, "nu"); } #[test] fn can_convert_table_to_yaml_text_and_from_yaml_text_back_into_table() { - nu!( - output, - cwd("tests/fixtures/formats"), - "open appveyor.yml | to-yaml | from-yaml | get environment.global.PROJECT_NAME | echo $it" - ); + let actual = nu!( + cwd("tests/fixtures/formats"), h::pipeline( + r#" + open appveyor.yml + | to-yaml + | from-yaml + | get environment.global.PROJECT_NAME + | echo $it + "# + )); - assert_eq!(output, "nushell"); + assert_eq!(actual, "nushell"); } #[test] fn can_sort_by_column() { - nu!( - output, - cwd("tests/fixtures/formats"), - r#"open cargo_sample.toml --raw | lines | skip 1 | first 4 | split-column "=" | sort-by Column1 | skip 1 | first 1 | get Column1 | trim | echo $it"# - ); + let actual = nu!( + cwd("tests/fixtures/formats"), h::pipeline( + r#" + open cargo_sample.toml --raw + | lines + | skip 1 + | first 4 + | split-column "=" + | sort-by Column1 + | skip 1 + | first 1 + | get Column1 + | trim + | echo $it + "# + )); - assert_eq!(output, "description"); + assert_eq!(actual, "description"); } #[test] fn can_split_by_column() { - nu!( - output, - cwd("tests/fixtures/formats"), - r#"open cargo_sample.toml --raw | lines | skip 1 | first 1 | split-column "=" | get Column1 | trim | echo $it"# - ); + let actual = nu!( + cwd("tests/fixtures/formats"), h::pipeline( + r#" + open cargo_sample.toml --raw + | lines + | skip 1 + | first 1 + | split-column "=" + | get Column1 + | trim + | echo $it + "# + )); - assert_eq!(output, "name"); + assert_eq!(actual, "name"); } #[test] fn can_sum() { - nu!( - output, - cwd("tests/fixtures/formats"), - "open sgml_description.json | get glossary.GlossDiv.GlossList.GlossEntry.Sections | sum | echo $it" - ); + let actual = nu!( + cwd("tests/fixtures/formats"), h::pipeline( + r#" + open sgml_description.json + | get glossary.GlossDiv.GlossList.GlossEntry.Sections + | sum + | echo $it + "# + )); - assert_eq!(output, "203") + assert_eq!(actual, "203") } #[test] fn can_filter_by_unit_size_comparison() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "ls | where size > 1kb | sort-by size | get name | skip 1 | trim | echo $it" ); - assert_eq!(output, "caco3_plastics.csv"); + assert_eq!(actual, "caco3_plastics.csv"); } #[test] fn can_get_last() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "ls | sort-by name | last 1 | get name | trim | echo $it" ); - assert_eq!(output, "utf16.ini"); + assert_eq!(actual, "utf16.ini"); } #[test] fn can_get_reverse_first() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "ls | sort-by name | reverse | first 1 | get name | trim | echo $it" ); - assert_eq!(output, "utf16.ini"); + assert_eq!(actual, "utf16.ini"); } diff --git a/tests/helpers/mod.rs b/tests/helpers/mod.rs index 5d062c1d2..e371b46ce 100644 --- a/tests/helpers/mod.rs +++ b/tests/helpers/mod.rs @@ -4,11 +4,63 @@ use glob::glob; pub use std::path::Path; pub use std::path::PathBuf; +use getset::Getters; use std::io::Read; +use tempfile::{tempdir, TempDir}; + +pub trait DisplayPath { + fn display_path(&self) -> String; +} + +impl DisplayPath for PathBuf { + fn display_path(&self) -> String { + self.display().to_string() + } +} + +impl DisplayPath for str { + fn display_path(&self) -> String { + self.to_string() + } +} + +impl DisplayPath for &str { + fn display_path(&self) -> String { + self.to_string() + } +} + +impl DisplayPath for String { + fn display_path(&self) -> String { + self.clone() + } +} + +impl DisplayPath for &String { + fn display_path(&self) -> String { + self.to_string() + } +} + +impl DisplayPath for nu::AbsolutePath { + fn display_path(&self) -> String { + self.to_string() + } +} #[macro_export] macro_rules! nu { - ($out:ident, $cwd:expr, $commands:expr) => { + ($cwd:expr, $path:expr, $($part:expr),*) => {{ + use $crate::helpers::DisplayPath; + + let path = format!($path, $( + $part.display_path() + ),*); + + nu!($cwd, &path) + }}; + + ($cwd:expr, $path:expr) => {{ pub use std::error::Error; pub use std::io::prelude::*; pub use std::process::{Command, Stdio}; @@ -18,7 +70,8 @@ macro_rules! nu { cd {} {} exit", - $cwd, $commands + $crate::helpers::in_directory($cwd), + $crate::helpers::DisplayPath::display_path(&$path) ); let mut process = match Command::new(helpers::executable_path()) @@ -39,15 +92,27 @@ macro_rules! nu { .wait_with_output() .expect("couldn't read from stdout"); - let $out = String::from_utf8_lossy(&output.stdout); - let $out = $out.replace("\r\n", ""); - let $out = $out.replace("\n", ""); - }; + let out = String::from_utf8_lossy(&output.stdout); + let out = out.replace("\r\n", ""); + let out = out.replace("\n", ""); + out + }}; } #[macro_export] macro_rules! nu_error { - ($out:ident, $cwd:expr, $commands:expr) => { + ($cwd:expr, $path:expr, $($part:expr),*) => {{ + use $crate::helpers::DisplayPath; + + let path = format!($path, $( + $part.display_path() + ),*); + + nu_error!($cwd, &path) + }}; + + + ($cwd:expr, $commands:expr) => {{ use std::io::prelude::*; use std::process::{Command, Stdio}; @@ -56,7 +121,7 @@ macro_rules! nu_error { cd {} {} exit", - $cwd, $commands + $crate::helpers::in_directory($cwd), $commands ); let mut process = Command::new(helpers::executable_path()) @@ -73,8 +138,11 @@ macro_rules! nu_error { let output = process .wait_with_output() .expect("couldn't read from stderr"); - let $out = String::from_utf8_lossy(&output.stderr); - }; + + let out = String::from_utf8_lossy(&output.stderr); + + out.into_owned() + }}; } pub enum Stub<'a> { @@ -84,26 +152,38 @@ pub enum Stub<'a> { } pub struct Playground { + root: TempDir, tests: String, cwd: PathBuf, } -impl Playground { - pub fn root() -> String { - String::from("tests/fixtures/nuplayground") - } +#[derive(Getters)] +#[get = "pub"] +pub struct Dirs { + pub root: PathBuf, + pub test: PathBuf, + pub fixtures: PathBuf, +} - pub fn test_dir_name(&self) -> String { - self.tests.clone() +impl Dirs { + pub fn formats(&self) -> PathBuf { + PathBuf::from(self.fixtures.join("formats")) + } +} + +impl Playground { + pub fn root(&self) -> &Path { + self.root.path() } pub fn back_to_playground(&mut self) -> &mut Self { - self.cwd = PathBuf::from([Playground::root(), self.tests.clone()].join("/")); + self.cwd = PathBuf::from(self.root()).join(self.tests.clone()); self } - pub fn setup_for(topic: &str) -> Playground { - let nuplay_dir = format!("{}/{}", Playground::root(), topic); + 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); if PathBuf::from(&nuplay_dir).exists() { std::fs::remove_dir_all(PathBuf::from(&nuplay_dir)).expect("can not remove directory"); @@ -111,10 +191,41 @@ impl Playground { std::fs::create_dir(PathBuf::from(&nuplay_dir)).expect("can not create directory"); - Playground { + let mut playground = Playground { + root: root, tests: topic.to_string(), - cwd: PathBuf::from([Playground::root(), topic.to_string()].join("/")), - } + cwd: nuplay_dir, + }; + + let project_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let playground_root = playground.root.path(); + + let fixtures = project_root.join(file!()); + let fixtures = fixtures + .parent() + .expect("Couldn't find the fixtures directory") + .parent() + .expect("Couldn't find the fixtures directory") + .join("fixtures"); + + let fixtures = dunce::canonicalize(fixtures.clone()).expect(&format!( + "Couldn't canonicalize fixtures path {}", + fixtures.display() + )); + + let test = + dunce::canonicalize(PathBuf::from(playground_root.join(topic))).expect(&format!( + "Couldn't canonicalize test path {}", + playground_root.join(topic).display() + )); + + let dirs = Dirs { + root: PathBuf::from(playground_root), + test, + fixtures, + }; + + block(dirs, &mut playground); } pub fn mkdir(&mut self, directory: &str) -> &mut Self { @@ -180,8 +291,8 @@ impl Playground { } } -pub fn file_contents(full_path: &str) -> String { - let mut file = std::fs::File::open(full_path).expect("can not open file"); +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) .expect("can not read file"); @@ -226,20 +337,20 @@ 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>, path: PathBuf) -> bool { +pub fn files_exist_at(files: Vec>, path: impl AsRef) -> bool { files.iter().all(|f| { - let mut loc = path.clone(); + let mut loc = PathBuf::from(path.as_ref()); loc.push(f); loc.exists() }) } -pub fn file_exists_at(path: PathBuf) -> bool { - path.exists() +pub fn file_exists_at(path: impl AsRef) -> bool { + path.as_ref().exists() } -pub fn dir_exists_at(path: PathBuf) -> bool { - path.exists() +pub fn dir_exists_at(path: impl AsRef) -> bool { + path.as_ref().exists() } pub fn delete_directory_at(full_path: &str) { @@ -254,6 +365,17 @@ pub fn executable_path() -> PathBuf { buf } -pub fn in_directory(str: &str) -> &str { - str +pub fn in_directory(str: impl AsRef) -> String { + str.as_ref().display().to_string() +} + + +pub fn pipeline(commands: &str) -> String { + commands.lines() + .skip(1) + .map(|line| line.trim()) + .collect::>() + .join(" ") + .trim_end() + .to_string() } diff --git a/tests/tests.rs b/tests/tests.rs index 2090e8e04..f66ac0904 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1,44 +1,58 @@ mod helpers; -use helpers::in_directory as cwd; -use helpers::normalize_string; +use helpers::{in_directory as cwd}; +use helpers as h; + +#[test] +fn pipeline_helper() { + let actual = h::pipeline( + r#" + open los_tres_amigos.txt + | from-csv + | get rusty_luck + | str --to-int + | sum + | echo "$it" + "#); + + assert_eq!(actual, r#"open los_tres_amigos.txt | from-csv | get rusty_luck | str --to-int | sum | echo "$it""#); +} #[test] fn external_num() { - nu!( - output, + let actual = nu!( cwd("tests/fixtures/formats"), "open sgml_description.json | get glossary.GlossDiv.GlossList.GlossEntry.Height | echo $it" ); - assert_eq!(output, "10"); + assert_eq!(actual, "10"); } #[test] fn external_has_correct_quotes() { - nu!(output, cwd("."), r#"echo "hello world""#); + let actual = nu!(cwd("."), r#"echo "hello world""#); - let output = normalize_string(&output); + let actual = h::normalize_string(&actual); - assert_eq!(output, r#""hello world""#); + assert_eq!(actual, r#""hello world""#); } #[test] fn add_plugin() { - nu!(output, + let actual = nu!( cwd("tests/fixtures/formats"), r#"open cargo_sample.toml | add dev-dependencies.newdep "1" | get dev-dependencies.newdep | echo $it"# ); - assert_eq!(output, "1"); + assert_eq!(actual, "1"); } #[test] fn edit_plugin() { - nu!(output, + let actual = nu!( cwd("tests/fixtures/formats"), r#"open cargo_sample.toml | edit dev-dependencies.pretty_assertions "7" | get dev-dependencies.pretty_assertions | echo $it"# ); - assert_eq!(output, "7"); + assert_eq!(actual, "7"); }