From 182b0ab4fb159dd07f198769929f27dc8197fb1b Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Tue, 28 Nov 2023 20:42:35 +0800 Subject: [PATCH] add echo_env_mixed testbin to reduce windows only tests (#11172) # Description We have seen some test cases which requires to output message to both stdout and stderr, especially in redirection scenario. This pr is going to introduce a new echo_env_mixed testbin, so we can have less tests which only runs on windows. # User-Facing Changes NaN # Tests + Formatting NaN # After Submitting NaN --- .../nu-command/tests/commands/redirection.rs | 231 ++++++------------ src/main.rs | 1 + src/test_bins.rs | 47 +++- 3 files changed, 110 insertions(+), 169 deletions(-) diff --git a/crates/nu-command/tests/commands/redirection.rs b/crates/nu-command/tests/commands/redirection.rs index cae01dbbd9..e55cb557a9 100644 --- a/crates/nu-command/tests/commands/redirection.rs +++ b/crates/nu-command/tests/commands/redirection.rs @@ -2,85 +2,43 @@ use nu_test_support::fs::{file_contents, Stub::FileWithContent}; use nu_test_support::nu; use nu_test_support::playground::Playground; -#[cfg(not(windows))] #[test] fn redirect_err() { Playground::setup("redirect_err_test", |dirs, _sandbox| { let output = nu!( cwd: dirs.test(), - "cat asdfasdfasdf.txt err> a.txt; cat a.txt" + r#"$env.BAZ = "asdfasdfasdf.txt"; nu --testbin echo_env_stderr BAZ err> a.txt; open a.txt"# ); - assert!(output.out.contains("asdfasdfasdf.txt")); // check append mode let output = nu!( - cwd: dirs.test(), - "cat asdfasdfasdf.txt err>> a.txt; cat a.txt" + cwd: dirs.test(), + r#"$env.BAZ = "asdfasdfasdf.txt"; nu --testbin echo_env_stderr BAZ err>> a.txt; open a.txt"# ); let v: Vec<_> = output.out.match_indices("asdfasdfasdf.txt").collect(); assert_eq!(v.len(), 2); }) } -#[cfg(windows)] -#[test] -fn redirect_err() { - Playground::setup("redirect_err_test", |dirs, _sandbox| { - let output = nu!( - cwd: dirs.test(), - "vol missingdrive err> a; (open a | str stats).bytes >= 16" - ); - - assert!(output.out.contains("true")); - - let output = nu!( - cwd: dirs.test(), - "vol missingdrive err>> a; (open a | str stats).bytes >= 32" - ); - assert!(output.out.contains("true")); - }) -} - -#[cfg(not(windows))] #[test] fn redirect_outerr() { Playground::setup("redirect_outerr_test", |dirs, _sandbox| { - nu!( + let output = nu!( cwd: dirs.test(), - "cat asdfasdfasdf.txt out+err> a" + r#"$env.BAZ = "asdfasdfasdf.txt"; nu --testbin echo_env_stderr BAZ out+err> a.txt; open a.txt"# ); - let output = nu!(cwd: dirs.test(), "cat a"); - assert!(output.out.contains("asdfasdfasdf.txt")); - let output = nu!(cwd: dirs.test(), "cat asdfasdfasdf.txt o+e>> a; cat a"); + let output = nu!( + cwd: dirs.test(), + r#"$env.BAZ = "asdfasdfasdf.txt"; nu --testbin echo_env_stderr BAZ o+e>> a.txt; open a.txt"# + ); let v: Vec<_> = output.out.match_indices("asdfasdfasdf.txt").collect(); assert_eq!(v.len(), 2); }) } -#[cfg(windows)] -#[test] -fn redirect_outerr() { - Playground::setup("redirect_outerr_test", |dirs, _sandbox| { - nu!( - cwd: dirs.test(), - "vol missingdrive out+err> a" - ); - let output = nu!(cwd: dirs.test(), "(open a | str stats).bytes >= 16"); - - assert!(output.out.contains("true")); - - nu!( - cwd: dirs.test(), - "vol missingdrive out+err>> a" - ); - let output = nu!(cwd: dirs.test(), "(open a | str stats).bytes >= 32"); - assert!(output.out.contains("true")); - }) -} - #[test] fn redirect_out() { Playground::setup("redirect_out_test", |dirs, _sandbox| { @@ -123,29 +81,13 @@ foobar"#); fn separate_redirection() { Playground::setup( "external with both stdout and stderr messages, to different file", - |dirs, sandbox| { - let script_body = r#" - echo message - echo message 1>&2 - "#; + |dirs, _| { let expect_body = "message"; + nu!( + cwd: dirs.test(), + r#"$env.BAZ = "message"; nu --testbin echo_env_mixed out-err BAZ BAZ o> out.txt e> err.txt"#, + ); - #[cfg(not(windows))] - { - sandbox.with_files(vec![FileWithContent("test.sh", script_body)]); - nu!( - cwd: dirs.test(), - "bash test.sh out> out.txt err> err.txt" - ); - } - #[cfg(windows)] - { - sandbox.with_files(vec![FileWithContent("test.bat", script_body)]); - nu!( - cwd: dirs.test(), - "cmd /D /c test.bat out> out.txt err> err.txt" - ); - } // check for stdout redirection file. let expected_out_file = dirs.test().join("out.txt"); let actual = file_contents(expected_out_file); @@ -155,25 +97,22 @@ fn separate_redirection() { let expected_err_file = dirs.test().join("err.txt"); let actual = file_contents(expected_err_file); assert!(actual.contains(expect_body)); - #[cfg(not(windows))] - { - sandbox.with_files(vec![FileWithContent("test.sh", script_body)]); - nu!( - cwd: dirs.test(), - "bash test.sh out>> out.txt err>> err.txt" - ); - // check for stdout redirection file. - let expected_out_file = dirs.test().join("out.txt"); - let actual = file_contents(expected_out_file); - let v: Vec<_> = actual.match_indices("message").collect(); - assert_eq!(v.len(), 2); - // check for stderr redirection file. - let expected_err_file = dirs.test().join("err.txt"); - let actual = file_contents(expected_err_file); - let v: Vec<_> = actual.match_indices("message").collect(); - assert_eq!(v.len(), 2); - } + nu!( + cwd: dirs.test(), + r#"$env.BAZ = "message"; nu --testbin echo_env_mixed out-err BAZ BAZ o>> out.txt e>> err.txt"#, + ); + // check for stdout redirection file. + let expected_out_file = dirs.test().join("out.txt"); + let actual = file_contents(expected_out_file); + let v: Vec<_> = actual.match_indices("message").collect(); + assert_eq!(v.len(), 2); + + // check for stderr redirection file. + let expected_err_file = dirs.test().join("err.txt"); + let actual = file_contents(expected_err_file); + let v: Vec<_> = actual.match_indices("message").collect(); + assert_eq!(v.len(), 2); }, ) } @@ -247,35 +186,30 @@ fn redirection_keep_exit_codes() { ) } -#[cfg(not(windows))] #[test] fn redirection_with_pipeline_works() { - use nu_test_support::fs::{file_contents, Stub::FileWithContent}; + use nu_test_support::fs::Stub::FileWithContent; use nu_test_support::playground::Playground; Playground::setup( "external with stdout message with pipeline should write data", |dirs, sandbox| { let script_body = r"echo message"; let expect_body = "message"; + sandbox.with_files(vec![FileWithContent("test.sh", script_body)]); - nu!( + let actual = nu!( cwd: dirs.test(), - "bash test.sh out> out.txt | describe" + r#"$env.BAZ = "message"; nu --testbin echo_env BAZ out> out.txt | describe; open out.txt"#, ); - // check for stdout redirection file. - let expected_out_file = dirs.test().join("out.txt"); - let actual = file_contents(expected_out_file); - assert!(actual.contains(expect_body)); + assert!(actual.out.contains(expect_body)); // check append mode works - nu!( + let actual = nu!( cwd: dirs.test(), - "bash test.sh o>> out.txt | describe" + r#"$env.BAZ = "message"; nu --testbin echo_env BAZ out>> out.txt | describe; open out.txt"#, ); - let expected_out_file = dirs.test().join("out.txt"); - let actual = file_contents(expected_out_file); - let v: Vec<_> = actual.match_indices("message").collect(); + let v: Vec<_> = actual.out.match_indices("message").collect(); assert_eq!(v.len(), 2); }, ) @@ -322,29 +256,15 @@ fn redirect_support_variable() { fn separate_redirection_support_variable() { Playground::setup( "external with both stdout and stderr messages, to different file", - |dirs, sandbox| { - let script_body = r#" - echo message - echo message 1>&2 - "#; + |dirs, _| { let expect_body = "message"; - - #[cfg(not(windows))] - { - sandbox.with_files(vec![FileWithContent("test.sh", script_body)]); - nu!( - cwd: dirs.test(), - r#"let o_f = "out2.txt"; let e_f = "err2.txt"; bash test.sh out> $o_f err> $e_f"# - ); - } - #[cfg(windows)] - { - sandbox.with_files(vec![FileWithContent("test.bat", script_body)]); - nu!( - cwd: dirs.test(), - r#"let o_f = "out2.txt"; let e_f = "err2.txt"; cmd /D /c test.bat out> $o_f err> $e_f"# - ); - } + nu!( + cwd: dirs.test(), + r#" + let o_f = "out2.txt" + let e_f = "err2.txt" + $env.BAZ = "message"; nu --testbin echo_env_mixed out-err BAZ BAZ o> $o_f e> $e_f"#, + ); // check for stdout redirection file. let expected_out_file = dirs.test().join("out2.txt"); let actual = file_contents(expected_out_file); @@ -355,25 +275,24 @@ fn separate_redirection_support_variable() { let actual = file_contents(expected_err_file); assert!(actual.contains(expect_body)); - #[cfg(not(windows))] - { - sandbox.with_files(vec![FileWithContent("test.sh", script_body)]); - nu!( - cwd: dirs.test(), - r#"let o_f = "out2.txt"; let e_f = "err2.txt"; bash test.sh out>> $o_f err>> $e_f"# - ); - // check for stdout redirection file. - let expected_out_file = dirs.test().join("out2.txt"); - let actual = file_contents(expected_out_file); - let v: Vec<_> = actual.match_indices("message").collect(); - assert_eq!(v.len(), 2); + nu!( + cwd: dirs.test(), + r#" + let o_f = "out2.txt" + let e_f = "err2.txt" + $env.BAZ = "message"; nu --testbin echo_env_mixed out-err BAZ BAZ out>> $o_f err>> $e_f"#, + ); + // check for stdout redirection file. + let expected_out_file = dirs.test().join("out2.txt"); + let actual = file_contents(expected_out_file); + let v: Vec<_> = actual.match_indices("message").collect(); + assert_eq!(v.len(), 2); - // check for stderr redirection file. - let expected_err_file = dirs.test().join("err2.txt"); - let actual = file_contents(expected_err_file); - let v: Vec<_> = actual.match_indices("message").collect(); - assert_eq!(v.len(), 2); - } + // check for stderr redirection file. + let expected_err_file = dirs.test().join("err2.txt"); + let actual = file_contents(expected_err_file); + let v: Vec<_> = actual.match_indices("message").collect(); + assert_eq!(v.len(), 2); }, ) } @@ -401,43 +320,29 @@ fn redirection_should_have_a_target() { } #[test] -#[cfg(not(windows))] fn redirection_with_pipe() { - use nu_test_support::fs::Stub::FileWithContent; use nu_test_support::playground::Playground; Playground::setup( "external with many stdout and stderr messages", - |dirs, sandbox| { - let script_body = r#" - x=$(printf '=%.0s' {1..40}) - echo -n $x - echo -n $x 1>&2 - "#; - let mut expect_body = String::new(); - for _ in 0..40 { - expect_body.push('='); - } - - sandbox.with_files(vec![FileWithContent("test.sh", script_body)]); - + |dirs, _| { // check for stdout let actual = nu!( cwd: dirs.test(), - "bash test.sh err> tmp_file | str length", + r#"$env.BAZ = "message"; nu --testbin echo_env_mixed out-err BAZ BAZ err> tmp_file | str length"#, ); - assert_eq!(actual.out, "40"); + assert_eq!(actual.out, "8"); // check for stderr redirection file. let expected_out_file = dirs.test().join("tmp_file"); let actual_len = file_contents(expected_out_file).len(); - assert_eq!(actual_len, 40); + assert_eq!(actual_len, 8); // check it inside a function let actual = nu!( cwd: dirs.test(), - "bash test.sh err> tmp_file; print aa" + r#"$env.BAZ = "message"; nu --testbin echo_env_mixed out-err BAZ BAZ err> tmp_file; print aa"#, ); - assert!(actual.out.contains(&format!("{}aa", expect_body))); + assert!(actual.out.contains("messageaa")); }, ) } diff --git a/src/main.rs b/src/main.rs index c60018a33a..a07f3142e7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -228,6 +228,7 @@ fn main() -> Result<()> { match testbin.item.as_str() { "echo_env" => test_bins::echo_env(true), "echo_env_stderr" => test_bins::echo_env(false), + "echo_env_mixed" => test_bins::echo_env_mixed(), "cococo" => test_bins::cococo(), "meow" => test_bins::meow(), "meowb" => test_bins::meowb(), diff --git a/src/test_bins.rs b/src/test_bins.rs index 2e5a4a5e22..32d7e6d408 100644 --- a/src/test_bins.rs +++ b/src/test_bins.rs @@ -12,16 +12,51 @@ use std::io::{self, BufRead, Read, Write}; pub fn echo_env(to_stdout: bool) { let args = args(); for arg in args { - if let Ok(v) = std::env::var(arg) { - if to_stdout { - println!("{v}"); - } else { - eprintln!("{v}"); - } + echo_one_env(&arg, to_stdout) + } +} + +fn echo_one_env(arg: &str, to_stdout: bool) { + if let Ok(v) = std::env::var(arg) { + if to_stdout { + println!("{v}"); + } else { + eprintln!("{v}"); } } } +/// Mix echo of env keys from input +/// Example: +/// * nu --testbin echo_env_mixed out-err FOO BAR +/// * nu --testbin echo_env_mixed err-out FOO BAR +/// If it's not present, panic instead +pub fn echo_env_mixed() { + let args = args(); + let args = &args[1..]; + + if args.len() != 3 { + panic!( + r#"Usage examples: +* nu --testbin echo_env_mixed out-err FOO BAR +* nu --testbin echo_env_mixed err-out FOO BAR"# + ) + } + match args[0].as_str() { + "out-err" => { + let (out_arg, err_arg) = (&args[1], &args[2]); + echo_one_env(out_arg, true); + echo_one_env(err_arg, false); + } + "err-out" => { + let (err_arg, out_arg) = (&args[1], &args[2]); + echo_one_env(err_arg, false); + echo_one_env(out_arg, true); + } + _ => panic!("The mixed type must be `out_err`, `err_out`"), + } +} + /// Cross platform echo using println!() /// Example: nu --testbin echo a b c /// a b c