nushell/src/tests.rs

159 lines
3.7 KiB
Rust
Raw Normal View History

mod test_bits;
2022-12-21 22:54:39 +00:00
mod test_cell_path;
mod test_commandline;
mod test_conditionals;
mod test_config_path;
mod test_converters;
mod test_custom_commands;
mod test_engine;
mod test_env;
mod test_hiding;
mod test_ide;
mod test_iteration;
mod test_known_external;
mod test_math;
mod test_modules;
mod test_parser;
mod test_ranges;
mod test_regex;
allow lists to have type annotations (#8529) this pr refines #8270 and closes #8109 # description examples: the original syntax is okay ```nu def okay [nums: list] {} # the type of list will be list<any> ``` empty annotations are allowed in any variation the last two may be caught by a future formatter, but do not affect `nu` code currently ```nu def okay [nums: list<>] {} # okay def okay [nums: list< >] {} # weird but also okay def okay [nums: list< >] {} # also weird but okay ``` types are allowed (See [notes](#notes) below) ```nu def okay [nums: list<int>] {} # `test [a b c]` will throw an error def okay [nums: list< int > {} # any amount of space within the angle brackets is okay def err [nums: list <int>] {} # this is not okay, `nums` and `<int>` will be parsed as # two separate params, ``` nested annotations are allowed in many variations ```nu def okay [items: list<list<int>>] {} def okay [items: list<list>] {} ``` any unterminated annotation is caught ```nu Error: nu::parser::unexpected_eof × Unexpected end of code. ╭─[source:1:1] 1 │ def err [nums: list<int] {} · ▲ · ╰── expected closing > ╰──── ``` unknown types are flagged ```nu Error: nu::parser::unknown_type × Unknown type. ╭─[source:1:1] 1 │ def err [nums: list<str>] {} · ─┬─ · ╰── unknown type ╰──── Error: nu::parser::unknown_type × Unknown type. ╭─[source:1:1] 1 │ def err [nums: list<int, string>] {} · ─────┬───── · ╰── unknown type ╰──── ``` # notes the error message for mismatched types in not as intuitive ```nu Error: nu::parser::parse_mismatch × Parse mismatch during operation. ╭─[source:1:1] 1 │ def err [nums: list<int>] {}; err [a b c] · ┬ · ╰── expected int ╰──── ``` it should be something like this ```nu Error: nu::parser::parse_mismatch × Parse mismatch during operation. ╭─[source:1:1] 1 │ def err [nums: list<int>] {}; err [a b c] · ──┬── · ╰── expected list<int> ╰──── ``` this is currently not implemented
2023-03-24 11:54:06 +00:00
mod test_signatures;
mod test_stdlib;
mod test_strings;
mod test_table_operations;
mod test_type_check;
2021-07-30 20:02:16 +00:00
use assert_cmd::prelude::*;
use pretty_assertions::assert_eq;
use std::collections::HashMap;
2021-07-30 20:02:16 +00:00
use std::io::Write;
use std::process::Command;
use tempfile::NamedTempFile;
2021-07-17 18:52:50 +00:00
pub type TestResult = Result<(), Box<dyn std::error::Error>>;
2021-07-30 20:02:16 +00:00
pub fn run_test_with_env(input: &str, expected: &str, env: &HashMap<&str, &str>) -> TestResult {
let mut file = NamedTempFile::new()?;
let name = file.path();
let mut cmd = Command::cargo_bin("nu")?;
cmd.arg(name).envs(env);
writeln!(file, "{input}")?;
run_cmd_and_assert(cmd, expected)
}
2021-07-30 20:02:16 +00:00
#[cfg(test)]
pub fn run_test(input: &str, expected: &str) -> TestResult {
2021-07-30 20:02:16 +00:00
let mut file = NamedTempFile::new()?;
let name = file.path();
let mut cmd = Command::cargo_bin("nu")?;
cmd.arg(name);
cmd.env(
"PWD",
std::env::current_dir().expect("Can't get current dir"),
);
2021-07-30 20:02:16 +00:00
writeln!(file, "{input}")?;
2021-07-30 20:02:16 +00:00
run_cmd_and_assert(cmd, expected)
}
#[cfg(test)]
fn run_cmd_and_assert(mut cmd: Command, expected: &str) -> TestResult {
2021-07-30 20:02:16 +00:00
let output = cmd.output()?;
2021-07-30 21:57:22 +00:00
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
println!("stdout: {stdout}");
println!("stderr: {stderr}");
2021-07-30 20:02:16 +00:00
2021-07-30 21:57:22 +00:00
assert!(output.status.success());
2021-07-30 20:02:16 +00:00
2021-07-30 21:57:22 +00:00
assert_eq!(stdout.trim(), expected);
2021-07-30 20:02:16 +00:00
Ok(())
}
#[cfg(test)]
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("nu")?;
cmd.arg(name);
writeln!(file, "{input}")?;
let output = cmd.output()?;
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
println!("stdout: {stdout}");
println!("stderr: {stderr}");
assert!(output.status.success());
assert!(stdout.contains(expected));
Ok(())
}
#[cfg(test)]
pub fn test_ide_contains(input: &str, ide_commands: &[&str], expected: &str) -> TestResult {
let mut file = NamedTempFile::new()?;
let name = file.path();
let mut cmd = Command::cargo_bin("nu")?;
for ide_command in ide_commands {
cmd.arg(ide_command);
}
cmd.arg(name);
writeln!(file, "{input}")?;
let output = cmd.output()?;
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
println!("stdout: {stdout}");
println!("stderr: {stderr}");
assert!(output.status.success());
assert!(stdout.contains(expected));
Ok(())
}
2021-07-30 20:02:16 +00:00
#[cfg(test)]
pub fn fail_test(input: &str, expected: &str) -> TestResult {
2021-07-30 20:02:16 +00:00
let mut file = NamedTempFile::new()?;
let name = file.path();
let mut cmd = Command::cargo_bin("nu")?;
2021-07-30 20:02:16 +00:00
cmd.arg(name);
cmd.env(
"PWD",
std::env::current_dir().expect("Can't get current dir"),
);
2021-07-30 20:02:16 +00:00
writeln!(file, "{input}")?;
2021-07-30 20:02:16 +00:00
let output = cmd.output()?;
let stderr = String::from_utf8_lossy(&output.stderr).to_string();
let stdout = String::from_utf8_lossy(&output.stdout).to_string();
println!("stdout: {stdout}");
println!("stderr: {stderr}");
2021-07-30 20:02:16 +00:00
assert!(!stderr.is_empty() && stderr.contains(expected));
2021-07-30 20:02:16 +00:00
Ok(())
}