mirror of
https://github.com/nushell/nushell.git
synced 2025-08-18 00:29:46 +02:00
Add initial nu-test-support port (#913)
* Add initial nu-test-support port * finish changing binary name * Oops, these aren't Windows-safe tests
This commit is contained in:
@@ -39,7 +39,7 @@ pub(crate) fn read_config_file(engine_state: &mut EngineState, stack: &mut Stack
|
||||
|
||||
if config_path.exists() {
|
||||
// FIXME: remove this message when we're ready
|
||||
println!("Loading config from: {:?}", config_path);
|
||||
//println!("Loading config from: {:?}", config_path);
|
||||
let config_filename = config_path.to_string_lossy().to_owned();
|
||||
|
||||
if let Ok(contents) = std::fs::read_to_string(&config_path) {
|
||||
|
48
src/main.rs
48
src/main.rs
@@ -10,6 +10,8 @@ mod utils;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
mod test_bins;
|
||||
|
||||
use miette::Result;
|
||||
use nu_command::{create_default_context, BufferedReader};
|
||||
use nu_engine::get_full_help;
|
||||
@@ -21,7 +23,7 @@ use nu_protocol::{
|
||||
Spanned, SyntaxShape, Value, CONFIG_VARIABLE_ID,
|
||||
};
|
||||
use std::{
|
||||
io::BufReader,
|
||||
io::{BufReader, Write},
|
||||
path::Path,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
@@ -92,6 +94,7 @@ fn main() -> Result<()> {
|
||||
// Cool, it's a flag
|
||||
if arg == "-c"
|
||||
|| arg == "--commands"
|
||||
|| arg == "--testbin"
|
||||
|| arg == "--develop"
|
||||
|| arg == "--debug"
|
||||
|| arg == "--loglevel"
|
||||
@@ -115,6 +118,21 @@ fn main() -> Result<()> {
|
||||
|
||||
match nushell_config {
|
||||
Ok(nushell_config) => {
|
||||
if let Some(testbin) = &nushell_config.testbin {
|
||||
// Call out to the correct testbin
|
||||
match testbin.item.as_str() {
|
||||
"echo_env" => test_bins::echo_env(),
|
||||
"cococo" => test_bins::cococo(),
|
||||
"meow" => test_bins::meow(),
|
||||
"iecho" => test_bins::iecho(),
|
||||
"fail" => test_bins::fail(),
|
||||
"nonu" => test_bins::nonu(),
|
||||
"chop" => test_bins::chop(),
|
||||
"repeater" => test_bins::repeater(),
|
||||
_ => std::process::exit(1),
|
||||
}
|
||||
std::process::exit(0)
|
||||
}
|
||||
let input = if let Some(redirect_stdin) = &nushell_config.redirect_stdin {
|
||||
let stdin = std::io::stdin();
|
||||
let buf_reader = BufReader::new(stdin);
|
||||
@@ -193,6 +211,7 @@ fn parse_commandline_args(
|
||||
let login_shell = call.get_named_arg("login");
|
||||
let interactive_shell = call.get_named_arg("interactive");
|
||||
let commands: Option<Expression> = call.get_flag_expr("commands");
|
||||
let testbin: Option<Expression> = call.get_flag_expr("testbin");
|
||||
|
||||
let commands = if let Some(expression) = commands {
|
||||
let contents = engine_state.get_span_contents(&expression.span);
|
||||
@@ -205,12 +224,29 @@ fn parse_commandline_args(
|
||||
None
|
||||
};
|
||||
|
||||
let testbin = if let Some(expression) = testbin {
|
||||
let contents = engine_state.get_span_contents(&expression.span);
|
||||
|
||||
Some(Spanned {
|
||||
item: String::from_utf8_lossy(contents).to_string(),
|
||||
span: expression.span,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let help = call.has_flag("help");
|
||||
|
||||
if help {
|
||||
let full_help =
|
||||
get_full_help(&Nu.signature(), &Nu.examples(), engine_state, &mut stack);
|
||||
print!("{}", full_help);
|
||||
|
||||
let _ = std::panic::catch_unwind(move || {
|
||||
let stdout = std::io::stdout();
|
||||
let mut stdout = stdout.lock();
|
||||
let _ = stdout.write_all(full_help.as_bytes());
|
||||
});
|
||||
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
@@ -219,6 +255,7 @@ fn parse_commandline_args(
|
||||
login_shell,
|
||||
interactive_shell,
|
||||
commands,
|
||||
testbin,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -235,6 +272,7 @@ struct NushellConfig {
|
||||
login_shell: Option<Spanned<String>>,
|
||||
interactive_shell: Option<Spanned<String>>,
|
||||
commands: Option<Spanned<String>>,
|
||||
testbin: Option<Spanned<String>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -251,6 +289,12 @@ impl Command for Nu {
|
||||
.switch("stdin", "redirect the stdin", None)
|
||||
.switch("login", "start as a login shell", Some('l'))
|
||||
.switch("interactive", "start as an interactive shell", Some('i'))
|
||||
.named(
|
||||
"testbin",
|
||||
SyntaxShape::String,
|
||||
"run internal test binary",
|
||||
None,
|
||||
)
|
||||
.named(
|
||||
"commands",
|
||||
SyntaxShape::String,
|
||||
|
123
src/test_bins.rs
Normal file
123
src/test_bins.rs
Normal file
@@ -0,0 +1,123 @@
|
||||
use std::io::{self, BufRead, Write};
|
||||
|
||||
/// Echo's value of env keys from args
|
||||
/// Example: nu --testbin env_echo FOO BAR
|
||||
/// If it it's not present echo's nothing
|
||||
pub fn echo_env() {
|
||||
let args = args();
|
||||
for arg in args {
|
||||
if let Ok(v) = std::env::var(arg) {
|
||||
println!("{}", v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cococo() {
|
||||
let args: Vec<String> = args();
|
||||
|
||||
if args.len() > 1 {
|
||||
// Write back out all the arguments passed
|
||||
// if given at least 1 instead of chickens
|
||||
// speaking co co co.
|
||||
println!("{}", &args[1..].join(" "));
|
||||
} else {
|
||||
println!("cococo");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn meow() {
|
||||
let args: Vec<String> = args();
|
||||
|
||||
for arg in args.iter().skip(1) {
|
||||
let contents = std::fs::read_to_string(arg).expect("Expected a filepath");
|
||||
println!("{}", contents);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nonu() {
|
||||
args().iter().skip(1).for_each(|arg| print!("{}", arg));
|
||||
}
|
||||
|
||||
pub fn repeater() {
|
||||
let mut stdout = io::stdout();
|
||||
let args = args();
|
||||
let mut args = args.iter().skip(1);
|
||||
let letter = args.next().expect("needs a character to iterate");
|
||||
let count = args.next().expect("need the number of times to iterate");
|
||||
|
||||
let count: u64 = count.parse().expect("can't convert count to number");
|
||||
|
||||
for _ in 0..count {
|
||||
let _ = write!(stdout, "{}", letter);
|
||||
}
|
||||
let _ = stdout.flush();
|
||||
}
|
||||
|
||||
pub fn iecho() {
|
||||
// println! panics if stdout gets closed, whereas writeln gives us an error
|
||||
let mut stdout = io::stdout();
|
||||
let _ = args()
|
||||
.iter()
|
||||
.skip(1)
|
||||
.cycle()
|
||||
.try_for_each(|v| writeln!(stdout, "{}", v));
|
||||
}
|
||||
|
||||
pub fn fail() {
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
pub fn chop() {
|
||||
if did_chop_arguments() {
|
||||
// we are done and don't care about standard input.
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
// if no arguments given, chop from standard input and exit.
|
||||
let stdin = io::stdin();
|
||||
let mut stdout = io::stdout();
|
||||
|
||||
for given in stdin.lock().lines().flatten() {
|
||||
let chopped = if given.is_empty() {
|
||||
&given
|
||||
} else {
|
||||
let to = given.len() - 1;
|
||||
&given[..to]
|
||||
};
|
||||
|
||||
if let Err(_e) = writeln!(stdout, "{}", chopped) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
fn did_chop_arguments() -> bool {
|
||||
let args: Vec<String> = args();
|
||||
|
||||
if args.len() > 1 {
|
||||
let mut arguments = args.iter();
|
||||
arguments.next();
|
||||
|
||||
for arg in arguments {
|
||||
let chopped = if arg.is_empty() {
|
||||
&arg
|
||||
} else {
|
||||
let to = arg.len() - 1;
|
||||
&arg[..to]
|
||||
};
|
||||
|
||||
println!("{}", chopped);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn args() -> Vec<String> {
|
||||
// skip (--testbin bin_name args)
|
||||
std::env::args().skip(2).collect()
|
||||
}
|
@@ -26,7 +26,7 @@ pub fn run_test(input: &str, expected: &str) -> TestResult {
|
||||
let mut file = NamedTempFile::new()?;
|
||||
let name = file.path();
|
||||
|
||||
let mut cmd = Command::cargo_bin("engine-q")?;
|
||||
let mut cmd = Command::cargo_bin("nu")?;
|
||||
cmd.arg(name);
|
||||
|
||||
writeln!(file, "{}", input)?;
|
||||
@@ -51,7 +51,7 @@ pub fn run_test_contains(input: &str, expected: &str) -> TestResult {
|
||||
let mut file = NamedTempFile::new()?;
|
||||
let name = file.path();
|
||||
|
||||
let mut cmd = Command::cargo_bin("engine-q")?;
|
||||
let mut cmd = Command::cargo_bin("nu")?;
|
||||
cmd.arg(name);
|
||||
|
||||
writeln!(file, "{}", input)?;
|
||||
@@ -76,7 +76,7 @@ pub fn fail_test(input: &str, expected: &str) -> TestResult {
|
||||
let mut file = NamedTempFile::new()?;
|
||||
let name = file.path();
|
||||
|
||||
let mut cmd = Command::cargo_bin("engine-q")?;
|
||||
let mut cmd = Command::cargo_bin("nu")?;
|
||||
cmd.arg(name);
|
||||
cmd.env(
|
||||
"PWD",
|
||||
|
Reference in New Issue
Block a user