mirror of
https://github.com/nushell/nushell
synced 2024-11-10 15:14:14 +00:00
Restore nu_with_plugins
test macro (#6065)
* Updated nu_with_plugins to handle new nushell - Now it requires the plugin format and name to be passed in, because we can't really guess the format - It calls `register` with format and plugin path - It creates a temporary folder and in it an empty temporary plugin.nu so that the tests don't conflict with each other or with local copy of plugin.nu - Instead of passing the commands via stdin it passes them via the new --commands command line argument * Rename path to command for clarity * Enable core_inc tests Remove deprecated inc feature and replace with new plugin feature * Update core_inc tests for new nu_with_plugins syntax * Rework core_inc::can_only_apply_one The new inc plugin doesn't error if passed more than one but instead chooses the highest increment * Gate all plugin tests behind feature = "plugin" instead of one by one * Remove format!-like behavior from nu_with_plugins nu_with_plugins had format!-like behavior where it would allow calls such as this: ```rs nu_with_plugins!( cwd: "dir/", "open {} | get {}", "Cargo.toml", "package.version" ) ``` And although nifty it seems to have never been used before and the same can be achieved with a format! like so: ```rs nu_with_plugins!( cwd: "dir/", format!("open {} | get {}", "Cargo.toml", "package.version") ) ``` So I am removing it to keep the complexity of the macro in check * Add multi-plugin support to nu_with_plugins Useful for testing interactions between plugins * Alternative 1: run `cargo build` inside of tests * Handle Windows by canonicalizing paths and add .exe One VM install later and lots of learning about how command line arguments work and here we are
This commit is contained in:
parent
0646f1118c
commit
c66b97126f
5 changed files with 111 additions and 47 deletions
|
@ -51,3 +51,47 @@
|
|||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
use std::{
|
||||
io::Read,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
pub fn ensure_binary_present(package: &str) {
|
||||
let cargo_path = env!("CARGO");
|
||||
let mut arguments = vec!["build", "--package", package, "--quiet"];
|
||||
|
||||
let profile = std::env::var("NUSHELL_CARGO_TARGET");
|
||||
if let Ok(profile) = &profile {
|
||||
arguments.push("--profile");
|
||||
arguments.push(profile);
|
||||
}
|
||||
|
||||
let mut command = Command::new(cargo_path)
|
||||
.args(arguments)
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.expect("Failed to spawn cargo build command");
|
||||
|
||||
let stderr = command.stderr.take();
|
||||
|
||||
let success = command
|
||||
.wait()
|
||||
.expect("failed to wait cargo build command")
|
||||
.success();
|
||||
|
||||
if let Some(mut stderr) = stderr {
|
||||
let mut buffer = String::new();
|
||||
stderr
|
||||
.read_to_string(&mut buffer)
|
||||
.expect("failed to read cargo build stderr");
|
||||
if !buffer.is_empty() {
|
||||
println!("=== cargo build stderr\n{}", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if !success {
|
||||
panic!("cargo build failed");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,37 +102,38 @@ macro_rules! nu {
|
|||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! with_exe {
|
||||
($name:literal) => {{
|
||||
#[cfg(windows)]
|
||||
{
|
||||
concat!($name, ".exe")
|
||||
}
|
||||
#[cfg(not(windows))]
|
||||
{
|
||||
$name
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! nu_with_plugins {
|
||||
(cwd: $cwd:expr, $path:expr, $($part:expr),*) => {{
|
||||
use $crate::fs::DisplayPath;
|
||||
|
||||
let path = format!($path, $(
|
||||
$part.display_path()
|
||||
),*);
|
||||
|
||||
nu_with_plugins!($cwd, &path)
|
||||
(cwd: $cwd:expr, plugins: [$(($format:expr, $plugin_name:expr)),+$(,)?], $command:expr) => {{
|
||||
nu_with_plugins!($cwd, [$(($format, $plugin_name)),+], $command)
|
||||
}};
|
||||
(cwd: $cwd:expr, plugin: ($format:expr, $plugin_name:expr), $command:expr) => {{
|
||||
nu_with_plugins!($cwd, [($format, $plugin_name)], $command)
|
||||
}};
|
||||
|
||||
(cwd: $cwd:expr, $path:expr) => {{
|
||||
nu_with_plugins!($cwd, $path)
|
||||
}};
|
||||
|
||||
($cwd:expr, $path:expr) => {{
|
||||
($cwd:expr, [$(($format:expr, $plugin_name:expr)),+$(,)?], $command:expr) => {{
|
||||
pub use std::error::Error;
|
||||
pub use std::io::prelude::*;
|
||||
pub use std::process::{Command, Stdio};
|
||||
pub use $crate::NATIVE_PATH_ENV_VAR;
|
||||
|
||||
let commands = &*format!(
|
||||
"
|
||||
{}
|
||||
exit",
|
||||
$crate::fs::DisplayPath::display_path(&$path)
|
||||
);
|
||||
pub use tempfile::tempdir;
|
||||
pub use $crate::{NATIVE_PATH_ENV_VAR, with_exe};
|
||||
|
||||
let test_bins = $crate::fs::binaries();
|
||||
let test_bins = nu_path::canonicalize(&test_bins).unwrap_or_else(|e| {
|
||||
let test_bins = nu_path::canonicalize_with(&test_bins, ".").unwrap_or_else(|e| {
|
||||
panic!(
|
||||
"Couldn't canonicalize dummy binaries path {}: {:?}",
|
||||
test_bins.display(),
|
||||
|
@ -140,21 +141,33 @@ macro_rules! nu_with_plugins {
|
|||
)
|
||||
});
|
||||
|
||||
let mut paths = $crate::shell_os_paths();
|
||||
paths.insert(0, test_bins);
|
||||
let temp = tempdir().expect("couldn't create a temporary directory");
|
||||
let temp_plugin_file = temp.path().join("plugin.nu");
|
||||
std::fs::File::create(&temp_plugin_file).expect("couldn't create temporary plugin file");
|
||||
|
||||
let paths_joined = match std::env::join_paths(paths) {
|
||||
Ok(all) => all,
|
||||
Err(_) => panic!("Couldn't join paths for PATH var."),
|
||||
};
|
||||
$($crate::commands::ensure_binary_present($plugin_name);)+
|
||||
|
||||
let registrations = format!(
|
||||
concat!($(concat!("register -e ", $format, " {};")),+),
|
||||
$(
|
||||
nu_path::canonicalize_with(with_exe!($plugin_name), &test_bins)
|
||||
.unwrap_or_else(|e| {
|
||||
panic!("failed to canonicalize plugin {} path", $plugin_name)
|
||||
})
|
||||
.display()
|
||||
),+
|
||||
);
|
||||
let commands = format!("{registrations}{}", $command);
|
||||
|
||||
let target_cwd = $crate::fs::in_directory(&$cwd);
|
||||
|
||||
let mut process = match Command::new($crate::fs::executable_path())
|
||||
.env("PWD", &target_cwd) // setting PWD is enough to set cwd
|
||||
.env(NATIVE_PATH_ENV_VAR, paths_joined)
|
||||
.current_dir(&target_cwd)
|
||||
.env("PWD", &target_cwd) // setting PWD is enough to set cwd
|
||||
.arg("--commands")
|
||||
.arg(commands)
|
||||
.arg("--plugin-config")
|
||||
.arg(temp_plugin_file)
|
||||
.stdout(Stdio::piped())
|
||||
.stdin(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
{
|
||||
|
@ -162,13 +175,6 @@ macro_rules! nu_with_plugins {
|
|||
Err(why) => panic!("Can't run test {}", why.to_string()),
|
||||
};
|
||||
|
||||
let stdin = process.stdin.as_mut().expect("couldn't open stdin");
|
||||
stdin
|
||||
.write_all(commands.as_bytes())
|
||||
.expect("couldn't write to stdin");
|
||||
|
||||
stdin.flush()?
|
||||
|
||||
let output = process
|
||||
.wait_with_output()
|
||||
.expect("couldn't read from stdout/stderr");
|
||||
|
@ -176,9 +182,9 @@ macro_rules! nu_with_plugins {
|
|||
let out = $crate::macros::read_std(&output.stdout);
|
||||
let err = String::from_utf8_lossy(&output.stderr);
|
||||
|
||||
println!("=== stderr\n{}", err);
|
||||
println!("=== stderr\n{}", err);
|
||||
|
||||
$crate::Outcome::new(out,err.into_owned())
|
||||
$crate::Outcome::new(out, err.into_owned())
|
||||
}};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ mod nu_repl;
|
|||
mod overlays;
|
||||
mod parsing;
|
||||
mod path;
|
||||
#[cfg(feature = "plugin")]
|
||||
mod plugins;
|
||||
mod scope;
|
||||
mod shell;
|
||||
|
|
|
@ -3,15 +3,23 @@ use nu_test_support::nu_with_plugins;
|
|||
use nu_test_support::playground::Playground;
|
||||
|
||||
#[test]
|
||||
fn can_only_apply_one() {
|
||||
fn chooses_highest_increment_if_given_more_than_one() {
|
||||
let actual = nu_with_plugins!(
|
||||
cwd: "tests/fixtures/formats",
|
||||
"open cargo_sample.toml | first 1 | inc package.version --major --minor"
|
||||
plugin: ("json", "nu_plugin_inc"),
|
||||
"open cargo_sample.toml | first 1 | inc package.version --major --minor | get package.version"
|
||||
);
|
||||
|
||||
assert!(actual
|
||||
.err
|
||||
.contains("Usage: inc field [--major|--minor|--patch]"));
|
||||
assert_eq!(actual.out, "1.0.0");
|
||||
|
||||
let actual = nu_with_plugins!(
|
||||
cwd: "tests/fixtures/formats",
|
||||
plugin: ("json", "nu_plugin_inc"),
|
||||
// Regardless of order of arguments
|
||||
"open cargo_sample.toml | first 1 | inc package.version --minor --major | get package.version"
|
||||
);
|
||||
|
||||
assert_eq!(actual.out, "1.0.0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -27,6 +35,7 @@ fn by_one_with_field_passed() {
|
|||
|
||||
let actual = nu_with_plugins!(
|
||||
cwd: dirs.test(),
|
||||
plugin: ("json", "nu_plugin_inc"),
|
||||
"open sample.toml | inc package.edition | get package.edition"
|
||||
);
|
||||
|
||||
|
@ -47,6 +56,7 @@ fn by_one_with_no_field_passed() {
|
|||
|
||||
let actual = nu_with_plugins!(
|
||||
cwd: dirs.test(),
|
||||
plugin: ("json", "nu_plugin_inc"),
|
||||
"open sample.toml | get package.contributors | inc"
|
||||
);
|
||||
|
||||
|
@ -67,6 +77,7 @@ fn semversion_major_inc() {
|
|||
|
||||
let actual = nu_with_plugins!(
|
||||
cwd: dirs.test(),
|
||||
plugin: ("json", "nu_plugin_inc"),
|
||||
"open sample.toml | inc package.version -M | get package.version"
|
||||
);
|
||||
|
||||
|
@ -87,6 +98,7 @@ fn semversion_minor_inc() {
|
|||
|
||||
let actual = nu_with_plugins!(
|
||||
cwd: dirs.test(),
|
||||
plugin: ("json", "nu_plugin_inc"),
|
||||
"open sample.toml | inc package.version --minor | get package.version"
|
||||
);
|
||||
|
||||
|
@ -107,6 +119,7 @@ fn semversion_patch_inc() {
|
|||
|
||||
let actual = nu_with_plugins!(
|
||||
cwd: dirs.test(),
|
||||
plugin: ("json", "nu_plugin_inc"),
|
||||
"open sample.toml | inc package.version --patch | get package.version"
|
||||
);
|
||||
|
||||
|
@ -127,6 +140,7 @@ fn semversion_without_passing_field() {
|
|||
|
||||
let actual = nu_with_plugins!(
|
||||
cwd: dirs.test(),
|
||||
plugin: ("json", "nu_plugin_inc"),
|
||||
"open sample.toml | get package.version | inc --patch"
|
||||
);
|
||||
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
#[cfg(features = "inc")]
|
||||
mod core_inc;
|
||||
|
|
Loading…
Reference in a new issue