Change the error style during tests to plain (#13061)

# Description

This fixes issues with trying to run the tests with a terminal that is
small enough to cause errors to wrap around, or in cases where the test
environment might produce strings that are reasonably expected to wrap
around anyway. "Fancy" errors are too fancy for tests to work
predictably 😉

cc @abusch

# User-Facing Changes

- Added `--error-style` option for use with `--commands` (like
`--table-mode`)

# Tests + Formatting

Surprisingly, all of the tests pass, including in small windows! I only
had to make one change to a test for `error make` which was looking for
the box drawing characters miette uses to determine whether the span
label was showing up - but the plain error style output is even better
and easier to match on, so this test is actually more specific now.
This commit is contained in:
Devyn Cairns 2024-06-18 21:37:24 -07:00 committed by GitHub
parent 103f59be52
commit 12991cd36f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 62 additions and 14 deletions

View File

@ -47,8 +47,7 @@ fn setup_stack_and_engine_from_command(command: &str) -> (Stack, EngineState) {
&mut engine, &mut engine,
&mut stack, &mut stack,
PipelineData::empty(), PipelineData::empty(),
None, Default::default(),
false,
) )
.unwrap(); .unwrap();
@ -90,8 +89,7 @@ fn bench_command(
&mut engine, &mut engine,
&mut stack, &mut stack,
PipelineData::empty(), PipelineData::empty(),
None, Default::default(),
false,
) )
.unwrap(), .unwrap(),
); );

View File

@ -8,15 +8,45 @@ use nu_protocol::{
}; };
use std::sync::Arc; use std::sync::Arc;
#[derive(Default)]
pub struct EvaluateCommandsOpts {
pub table_mode: Option<Value>,
pub error_style: Option<Value>,
pub no_newline: bool,
}
/// Run a command (or commands) given to us by the user /// Run a command (or commands) given to us by the user
pub fn evaluate_commands( pub fn evaluate_commands(
commands: &Spanned<String>, commands: &Spanned<String>,
engine_state: &mut EngineState, engine_state: &mut EngineState,
stack: &mut Stack, stack: &mut Stack,
input: PipelineData, input: PipelineData,
table_mode: Option<Value>, opts: EvaluateCommandsOpts,
no_newline: bool,
) -> Result<(), ShellError> { ) -> Result<(), ShellError> {
let EvaluateCommandsOpts {
table_mode,
error_style,
no_newline,
} = opts;
// Handle the configured error style early
if let Some(e_style) = error_style {
match e_style.coerce_str()?.parse() {
Ok(e_style) => {
Arc::make_mut(&mut engine_state.config).error_style = e_style;
}
Err(err) => {
return Err(ShellError::GenericError {
error: "Invalid value for `--error-style`".into(),
msg: err.into(),
span: Some(e_style.span()),
help: None,
inner: vec![],
});
}
}
}
// Translate environment variables from Strings to Values // Translate environment variables from Strings to Values
convert_env_values(engine_state, stack)?; convert_env_values(engine_state, stack)?;

View File

@ -17,7 +17,7 @@ mod validation;
pub use commands::add_cli_context; pub use commands::add_cli_context;
pub use completions::{FileCompletion, NuCompleter, SemanticSuggestion, SuggestionKind}; pub use completions::{FileCompletion, NuCompleter, SemanticSuggestion, SuggestionKind};
pub use config_files::eval_config_contents; pub use config_files::eval_config_contents;
pub use eval_cmds::evaluate_commands; pub use eval_cmds::{evaluate_commands, EvaluateCommandsOpts};
pub use eval_file::evaluate_file; pub use eval_file::evaluate_file;
pub use menus::NuHelpCompleter; pub use menus::NuHelpCompleter;
pub use nu_cmd_base::util::get_init_cwd; pub use nu_cmd_base::util::get_init_cwd;

View File

@ -4,8 +4,9 @@ use nu_test_support::nu;
fn error_label_works() { fn error_label_works() {
let actual = nu!("error make {msg:foo label:{text:unseen}}"); let actual = nu!("error make {msg:foo label:{text:unseen}}");
assert!(actual.err.contains("unseen")); assert!(actual
assert!(actual.err.contains("╰──")); .err
.contains("label at line 1, columns 1 to 10: unseen"));
} }
#[test] #[test]

View File

@ -283,6 +283,8 @@ pub fn nu_run_test(opts: NuOpts, commands: impl AsRef<str>, with_std: bool) -> O
if !with_std { if !with_std {
command.arg("--no-std-lib"); command.arg("--no-std-lib");
} }
// Use plain errors to help make error text matching more consistent
command.args(["--error-style", "plain"]);
command command
.arg(format!("-c {}", escape_quote_string(&commands))) .arg(format!("-c {}", escape_quote_string(&commands)))
.stdout(Stdio::piped()) .stdout(Stdio::piped())
@ -369,6 +371,8 @@ where
.envs(envs) .envs(envs)
.arg("--commands") .arg("--commands")
.arg(command) .arg(command)
// Use plain errors to help make error text matching more consistent
.args(["--error-style", "plain"])
.arg("--config") .arg("--config")
.arg(temp_config_file) .arg(temp_config_file)
.arg("--env-config") .arg("--env-config")

View File

@ -29,8 +29,10 @@ pub(crate) fn gather_commandline_args() -> (Vec<String>, String, Vec<String>) {
} }
let flag_value = match arg.as_ref() { let flag_value = match arg.as_ref() {
"--commands" | "-c" | "--table-mode" | "-m" | "-e" | "--execute" | "--config" "--commands" | "-c" | "--table-mode" | "-m" | "--error-style" | "-e" | "--execute"
| "--env-config" | "-I" | "ide-ast" => args.next().map(|a| escape_quote_string(&a)), | "--config" | "--env-config" | "-I" | "ide-ast" => {
args.next().map(|a| escape_quote_string(&a))
}
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
"--plugin-config" => args.next().map(|a| escape_quote_string(&a)), "--plugin-config" => args.next().map(|a| escape_quote_string(&a)),
"--log-level" | "--log-target" | "--log-include" | "--log-exclude" | "--testbin" "--log-level" | "--log-target" | "--log-include" | "--log-exclude" | "--testbin"
@ -102,6 +104,8 @@ pub(crate) fn parse_commandline_args(
let execute = call.get_flag_expr("execute"); let execute = call.get_flag_expr("execute");
let table_mode: Option<Value> = let table_mode: Option<Value> =
call.get_flag(engine_state, &mut stack, "table-mode")?; call.get_flag(engine_state, &mut stack, "table-mode")?;
let error_style: Option<Value> =
call.get_flag(engine_state, &mut stack, "error-style")?;
let no_newline = call.get_named_arg("no-newline"); let no_newline = call.get_named_arg("no-newline");
// ide flags // ide flags
@ -245,6 +249,7 @@ pub(crate) fn parse_commandline_args(
ide_check, ide_check,
ide_ast, ide_ast,
table_mode, table_mode,
error_style,
no_newline, no_newline,
}); });
} }
@ -278,6 +283,7 @@ pub(crate) struct NushellCliArgs {
pub(crate) log_exclude: Option<Vec<Spanned<String>>>, pub(crate) log_exclude: Option<Vec<Spanned<String>>>,
pub(crate) execute: Option<Spanned<String>>, pub(crate) execute: Option<Spanned<String>>,
pub(crate) table_mode: Option<Value>, pub(crate) table_mode: Option<Value>,
pub(crate) error_style: Option<Value>,
pub(crate) no_newline: Option<Spanned<String>>, pub(crate) no_newline: Option<Spanned<String>>,
pub(crate) include_path: Option<Spanned<String>>, pub(crate) include_path: Option<Spanned<String>>,
pub(crate) lsp: bool, pub(crate) lsp: bool,
@ -325,6 +331,12 @@ impl Command for Nu {
"the table mode to use. rounded is default.", "the table mode to use. rounded is default.",
Some('m'), Some('m'),
) )
.named(
"error-style",
SyntaxShape::String,
"the error style to use (fancy or plain). default: fancy",
None,
)
.switch("no-newline", "print the result for --commands(-c) without a newline", None) .switch("no-newline", "print the result for --commands(-c) without a newline", None)
.switch( .switch(
"no-config-file", "no-config-file",

View File

@ -7,7 +7,7 @@ use crate::{
use log::trace; use log::trace;
#[cfg(feature = "plugin")] #[cfg(feature = "plugin")]
use nu_cli::read_plugin_file; use nu_cli::read_plugin_file;
use nu_cli::{evaluate_commands, evaluate_file, evaluate_repl}; use nu_cli::{evaluate_commands, evaluate_file, evaluate_repl, EvaluateCommandsOpts};
use nu_protocol::{ use nu_protocol::{
engine::{EngineState, Stack}, engine::{EngineState, Stack},
report_error_new, PipelineData, Spanned, report_error_new, PipelineData, Spanned,
@ -114,8 +114,11 @@ pub(crate) fn run_commands(
engine_state, engine_state,
&mut stack, &mut stack,
input, input,
parsed_nu_cli_args.table_mode, EvaluateCommandsOpts {
parsed_nu_cli_args.no_newline.is_some(), table_mode: parsed_nu_cli_args.table_mode,
error_style: parsed_nu_cli_args.error_style,
no_newline: parsed_nu_cli_args.no_newline.is_some(),
},
) { ) {
report_error_new(engine_state, &err); report_error_new(engine_state, &err);
std::process::exit(1); std::process::exit(1);