use super::support::Trusted; use nu_test_support::fs::Stub::FileWithContent; use nu_test_support::playground::Playground; use nu_test_support::{nu, pipeline}; use pretty_assertions::assert_eq; use serial_test::serial; const SCRIPTS: &str = r#"startup = ["touch hello.txt"] on_exit = ["touch bye.txt"]"#; #[test] #[serial] fn picks_up_env_keys_when_entering_trusted_directory() { Playground::setup("autoenv_test_1", |dirs, sandbox| { sandbox.with_files(vec![FileWithContent( ".nu-env", &format!( "{}\n{}", SCRIPTS, r#"[env] testkey = "testvalue" [scriptvars] myscript = "echo myval" "# ), )]); let expected = "testvalue"; let actual = Trusted::in_path(&dirs, || nu!(cwd: dirs.test(), "echo $env.testkey")); assert_eq!(actual.out, expected); }) } #[test] #[serial] fn picks_up_and_lets_go_env_keys_when_entering_trusted_directory_with_implied_cd() { use nu_test_support::fs::Stub::FileWithContent; Playground::setup("autoenv_test", |dirs, sandbox| { sandbox.mkdir("foo"); sandbox.mkdir("foo/bar"); sandbox.with_files(vec![ FileWithContent( "foo/.nu-env", r#"[env] testkey = "testvalue" "#, ), FileWithContent( "foo/bar/.nu-env", r#" [env] bar = "true" "#, ), ]); let actual = nu!( cwd: dirs.test(), " do {autoenv trust -q foo ; = null } foo echo $env.testkey" ); assert_eq!(actual.out, "testvalue"); //Assert testkey is gone when leaving foo let actual = nu!( cwd: dirs.test(), " do {autoenv trust -q foo; = null } ; foo .. echo $env.testkey " ); assert!(actual.err.contains("Unknown")); //Assert testkey is present also when jumping over foo let actual = nu!( cwd: dirs.test(), " do {autoenv trust -q foo; = null } ; do {autoenv trust -q foo/bar; = null } ; foo/bar echo $env.testkey echo $env.bar " ); assert_eq!(actual.out, "testvaluetrue"); //Assert bar removed after leaving bar let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; foo/bar ../.. echo $env.bar" ); assert!(actual.err.contains("Unknown")); }); } #[test] #[serial] #[ignore] fn picks_up_script_vars_when_entering_trusted_directory() { Playground::setup("autoenv_test_2", |dirs, sandbox| { sandbox.with_files(vec![FileWithContent( ".nu-env", &format!( "{}\n{}", SCRIPTS, r#"[env] testkey = "testvalue" [scriptvars] myscript = "echo myval" "# ), )]); let expected = "myval"; let actual = Trusted::in_path(&dirs, || nu!(cwd: dirs.test(), "echo $env.myscript")); // scriptvars are not supported // and why is myval expected when myscript is "echo myval" assert_eq!(actual.out, expected); }) } #[test] #[serial] fn picks_up_env_keys_when_entering_trusted_directory_indirectly() { Playground::setup("autoenv_test_3", |dirs, sandbox| { sandbox.mkdir("crates"); sandbox.with_files(vec![FileWithContent( ".nu-env", r#"[env] nu-ver = "0.30.0" "#, )]); let expected = "0.30.0"; let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test().join("crates"), " cd ../../autoenv_test_3 echo $env.nu-ver ") }); assert_eq!(actual.out, expected); }) } #[test] #[serial] fn entering_a_trusted_directory_runs_entry_scripts() { Playground::setup("autoenv_test_4", |dirs, sandbox| { sandbox.with_files(vec![FileWithContent( ".nu-env", &format!( "{}\n{}", SCRIPTS, r#"[env] testkey = "testvalue" "# ), )]); let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test(), pipeline(r#" ls | where name == "hello.txt" | get name "#)) }); assert_eq!(actual.out, "hello.txt"); }) } #[test] #[serial] fn leaving_a_trusted_directory_runs_exit_scripts() { Playground::setup("autoenv_test_5", |dirs, sandbox| { sandbox.with_files(vec![FileWithContent( ".nu-env", &format!( "{}\n{}", SCRIPTS, r#"[env] testkey = "testvalue" [scriptvars] myscript = "echo myval" "# ), )]); let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test(), r#" cd .. ls autoenv_test_5 | get name | path basename | where $it == "bye.txt" "#) }); assert_eq!(actual.out, "bye.txt"); }) } #[test] #[serial] fn entry_scripts_are_called_when_revisiting_a_trusted_directory() { Playground::setup("autoenv_test_6", |dirs, sandbox| { sandbox.with_files(vec![FileWithContent( ".nu-env", &format!( "{}\n{}", SCRIPTS, r#"[env] testkey = "testvalue" [scriptvars] myscript = "echo myval" "# ), )]); let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test(), r#" do { rm hello.txt | ignore } ; # Silence file deletion message from output cd .. cd autoenv_test_6 ls | where name == "hello.txt" | get name "#) }); assert_eq!(actual.out, "hello.txt"); }) } #[test] #[serial] fn given_a_trusted_directory_with_entry_scripts_when_entering_a_subdirectory_entry_scripts_are_not_called( ) { Playground::setup("autoenv_test_7", |dirs, sandbox| { sandbox.mkdir("time_to_cook_arepas"); sandbox.with_files(vec![FileWithContent( ".nu-env", &format!( "{}\n{}", SCRIPTS, r#"[env] testkey = "testvalue" [scriptvars] myscript = "echo myval" "# ), )]); let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test(), r#" cd time_to_cook_arepas ls | where name == "hello.txt" | length "#) }); assert_eq!(actual.out, "0"); }) } #[test] #[serial] fn given_a_trusted_directory_with_exit_scripts_when_entering_a_subdirectory_exit_scripts_are_not_called( ) { Playground::setup("autoenv_test_8", |dirs, sandbox| { sandbox.mkdir("time_to_cook_arepas"); sandbox.with_files(vec![FileWithContent( ".nu-env", &format!( "{}\n{}", SCRIPTS, r#"[env] testkey = "testvalue" [scriptvars] myscript = "echo myval" "# ), )]); let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test(), r#" cd time_to_cook_arepas ls | where name == "bye.txt" | length "#) }); assert_eq!(actual.out, "0"); }) } #[test] #[serial] fn given_a_hierarchy_of_trusted_directories_when_entering_in_any_nested_ones_should_carry_over_variables_set_from_the_root( ) { Playground::setup("autoenv_test_9", |dirs, sandbox| { sandbox.mkdir("nu_plugin_rb"); sandbox.with_files(vec![ FileWithContent( ".nu-env", r#"[env] organization = "nushell""#, ), FileWithContent( "nu_plugin_rb/.nu-env", r#"[env] language = "Ruby""#, ), ]); let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test().parent().unwrap(), " do { autoenv trust -q autoenv_test_9/nu_plugin_rb ; = null } # Silence autoenv trust -q message from output cd autoenv_test_9/nu_plugin_rb echo $env.organization ") }); assert_eq!(actual.out, "nushell"); }) } #[test] #[serial] fn given_a_hierarchy_of_trusted_directories_nested_ones_should_overwrite_variables_from_parent_directories( ) { Playground::setup("autoenv_test_10", |dirs, sandbox| { sandbox.mkdir("nu_plugin_rb"); sandbox.with_files(vec![ FileWithContent( ".nu-env", r#"[env] organization = "nushell""#, ), FileWithContent( "nu_plugin_rb/.nu-env", r#"[env] organization = "Andrab""#, ), ]); let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test().parent().unwrap(), " do { autoenv trust -q autoenv_test_10/nu_plugin_rb ; = null } # Silence autoenv trust -q message from output cd autoenv_test_10/nu_plugin_rb echo $env.organization ") }); assert_eq!(actual.out, "Andrab"); }) } #[test] #[serial] #[cfg(not(windows))] //TODO figure out why this test doesn't work on windows fn local_config_should_not_be_added_when_running_scripts() { Playground::setup("autoenv_test_10", |dirs, sandbox| { sandbox.mkdir("foo"); sandbox.with_files(vec![ FileWithContent( ".nu-env", r#"[env] organization = "nu""#, ), FileWithContent( "foo/.nu-env", r#"[env] organization = "foo""#, ), FileWithContent( "script.nu", "cd foo echo $env.organization", ), ]); let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test(), " do { autoenv trust -q foo } # Silence autoenv trust message from output nu script.nu ") }); assert_eq!(actual.out, "nu"); }) } #[test] #[serial] fn given_a_hierarchy_of_trusted_directories_going_back_restores_overwritten_variables() { Playground::setup("autoenv_test_11", |dirs, sandbox| { sandbox.mkdir("nu_plugin_rb"); sandbox.with_files(vec![ FileWithContent( ".nu-env", r#"[env] organization = "nushell""#, ), FileWithContent( "nu_plugin_rb/.nu-env", r#"[env] organization = "Andrab""#, ), ]); let actual = Trusted::in_path(&dirs, || { nu!(cwd: dirs.test().parent().unwrap(), " do { autoenv trust -q autoenv_test_11/nu_plugin_rb } # Silence autoenv trust message from output cd autoenv_test_11 cd nu_plugin_rb do { rm ../.nu-env | ignore } # By deleting the root nu-env we have guarantees that the variable gets restored (not by autoenv when re-entering) cd .. echo $env.organization ") }); assert_eq!(actual.out, "nushell"); }) } #[test] #[serial] fn local_config_env_var_present_and_removed_correctly() { use nu_test_support::fs::Stub::FileWithContent; Playground::setup("autoenv_test", |dirs, sandbox| { sandbox.mkdir("foo"); sandbox.mkdir("foo/bar"); sandbox.with_files(vec![FileWithContent( "foo/.nu-env", r#"[env] testkey = "testvalue" "#, )]); //Assert testkey is not present before entering directory let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; echo $env.testkey" ); assert!(actual.err.contains("Unknown")); //Assert testkey is present in foo let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; cd foo echo $env.testkey" ); assert_eq!(actual.out, "testvalue"); //Assert testkey is present also in subdirectories let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; cd foo cd bar echo $env.testkey" ); assert_eq!(actual.out, "testvalue"); //Assert testkey is present also when jumping over foo let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; cd foo/bar echo $env.testkey" ); assert_eq!(actual.out, "testvalue"); //Assert testkey removed after leaving foo let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; cd foo cd .. echo $env.testkey" ); assert!(actual.err.contains("Unknown")); }); } #[test] #[serial] fn local_config_env_var_gets_overwritten() { use nu_test_support::fs::Stub::FileWithContent; Playground::setup("autoenv_test", |dirs, sandbox| { sandbox.mkdir("foo"); sandbox.mkdir("foo/bar"); sandbox.with_files(vec![ FileWithContent( "foo/.nu-env", r#"[env] overwrite_me = "foo" "#, ), FileWithContent( "foo/bar/.nu-env", r#"[env] overwrite_me = "bar" "#, ), ]); //Assert overwrite_me is not present before entering directory let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; echo $env.overwrite_me" ); assert!(actual.err.contains("Unknown")); //Assert overwrite_me is foo in foo let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; cd foo echo $env.overwrite_me" ); assert_eq!(actual.out, "foo"); //Assert overwrite_me is bar in bar let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo autoenv trust -q foo/bar cd foo cd bar echo $env.overwrite_me" ); assert_eq!(actual.out, "bar"); //Assert overwrite_me is present also when jumping over foo let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; autoenv trust -q foo/bar; cd foo/bar echo $env.overwrite_me " ); assert_eq!(actual.out, "bar"); //Assert overwrite_me removed after leaving bar let actual = nu!( cwd: dirs.test(), "autoenv trust -q foo; autoenv trust -q foo/bar; cd foo cd bar cd .. echo $env.overwrite_me" ); assert_eq!(actual.out, "foo"); }); } #[test] #[serial] fn autoenv_test_entry_scripts() { use nu_test_support::fs::Stub::FileWithContent; Playground::setup("autoenv_test", |dirs, sandbox| { sandbox.mkdir("foo/bar"); // Windows uses a different command to create an empty file so we need to have different content on windows. let nu_env = if cfg!(target_os = "windows") { r#"startup = ["echo nul > hello.txt"]"# } else { r#"startup = ["touch hello.txt"]"# }; sandbox.with_files(vec![FileWithContent("foo/.nu-env", nu_env)]); // Make sure entryscript is run when entering directory let actual = nu!( cwd: dirs.test(), r#"autoenv trust -q foo cd foo ls | where name == "hello.txt" | get name"# ); assert!(actual.out.contains("hello.txt")); // Make sure entry scripts are also run when jumping over directory let actual = nu!( cwd: dirs.test(), r#"autoenv trust -q foo cd foo/bar ls .. | where name == "../hello.txt" | get name"# ); assert!(actual.out.contains("hello.txt")); // Entryscripts should not run after changing to a subdirectory. let actual = nu!( cwd: dirs.test(), r#"autoenv trust -q foo cd foo rm hello.txt cd bar ls .. | where name == "../hello.txt" | length"# ); assert!(actual.out.contains('0')); }); } #[test] #[serial] fn autoenv_test_exit_scripts() { use nu_test_support::fs::Stub::FileWithContent; Playground::setup("autoenv_test", |dirs, sandbox| { sandbox.mkdir("foo/bar"); // Windows uses a different command to create an empty file so we need to have different content on windows. let nu_env = r#"on_exit = ["touch bye.txt"]"#; sandbox.with_files(vec![FileWithContent("foo/.nu-env", nu_env)]); // Make sure exitscript is run let actual = nu!( cwd: dirs.test(), r#"autoenv trust -q foo cd foo cd .. ls foo | where name =~ "bye.txt" | length rm foo/bye.txt | ignore; cd . "# ); assert_eq!(actual.out, "1"); // Entering a subdir should not trigger exitscripts let actual = nu!( cwd: dirs.test(), r#"autoenv trust -q foo cd foo cd bar ls .. | where name =~ "bye.txt" | length"# ); assert_eq!(actual.out, "0"); // Also run exitscripts when jumping over directory let actual = nu!( cwd: dirs.test(), r#"autoenv trust -q foo cd foo/bar cd ../.. ls foo | where name =~ "bye.txt" | length rm foo/bye.txt | ignore; cd ."# ); assert_eq!(actual.out, "1"); }); } #[test] #[serial] #[cfg(unix)] fn prepends_path_from_local_config() { //If this test fails for you, make sure that your environment from which you start nu //contains some env vars Playground::setup("autoenv_test_1", |dirs, sandbox| { sandbox.with_files(vec![FileWithContent( ".nu-env", r#" path = ["/hi", "/nushell"] "#, )]); let expected = "[\"/hi\",\"/nushell\","; let actual = Trusted::in_path(&dirs, || nu!(cwd: dirs.test(), "echo $nu.path | to json")); // assert_eq!("", actual.out); assert!(actual.out.starts_with(expected)); assert!(actual.out.len() > expected.len()); }) }