diff --git a/packages/hurl/src/json/result.rs b/packages/hurl/src/json/result.rs index 1c8b2db6f6f..7c0cb1c41e7 100644 --- a/packages/hurl/src/json/result.rs +++ b/packages/hurl/src/json/result.rs @@ -17,7 +17,7 @@ */ use chrono::SecondsFormat; use hurl_core::ast::SourceInfo; -use hurl_core::error::error_string; +use hurl_core::error::{error_string, OutputFormat}; use serde::{Deserialize, Serialize}; use std::fs::File; use std::io; @@ -459,7 +459,7 @@ impl AssertJson { content, &err, Some(entry_src_info), - false, + OutputFormat::Json, ) }); AssertJson { diff --git a/packages/hurl/src/parallel/runner.rs b/packages/hurl/src/parallel/runner.rs index d0e5c0215f8..4e4b2968506 100644 --- a/packages/hurl/src/parallel/runner.rs +++ b/packages/hurl/src/parallel/runner.rs @@ -15,7 +15,7 @@ * limitations under the License. * */ -use hurl_core::error::error_string; +use hurl_core::error::{error_string, OutputFormat}; use hurl_core::typing::Repeat; use std::sync::mpsc::{Receiver, Sender}; use std::sync::{mpsc, Arc, Mutex}; @@ -315,7 +315,7 @@ impl ParallelRunner { content, &e, None, - color, + OutputFormat::Terminal(color), ))); } } diff --git a/packages/hurl/src/report/html/nav.rs b/packages/hurl/src/report/html/nav.rs index 37ae58f8289..0877e0cbe11 100644 --- a/packages/hurl/src/report/html/nav.rs +++ b/packages/hurl/src/report/html/nav.rs @@ -17,7 +17,7 @@ */ use crate::report::html::Testcase; use crate::runner::RunnerError; -use hurl_core::error::error_string; +use hurl_core::error::{error_string, OutputFormat}; #[derive(Copy, Clone, Eq, PartialEq)] pub enum Tab { @@ -83,7 +83,13 @@ fn error_to_html( ) -> String { let line = error.source_info.start.line; let column = error.source_info.start.column; - let message = error_string(filename, content, error, Some(error.source_info), false); + let message = error_string( + filename, + content, + error, + Some(error.source_info), + OutputFormat::Terminal(false), + ); let message = html_escape(&message); // We override the first part of the error string to add an anchor to // the error context. diff --git a/packages/hurl/src/report/junit/testcase.rs b/packages/hurl/src/report/junit/testcase.rs index 7b7109983b3..b8b16097e39 100644 --- a/packages/hurl/src/report/junit/testcase.rs +++ b/packages/hurl/src/report/junit/testcase.rs @@ -17,7 +17,7 @@ */ use crate::report::junit::xml::Element; use crate::runner::{HurlResult, Input}; -use hurl_core::error::error_string; +use hurl_core::error::{error_string, OutputFormat}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct Testcase { @@ -38,7 +38,13 @@ impl Testcase { let mut errors = vec![]; for (error, entry_src_info) in hurl_result.errors() { - let message = error_string(&name, content, error, Some(entry_src_info), false); + let message = error_string( + &name, + content, + error, + Some(entry_src_info), + OutputFormat::Json, + ); if error.assert { failures.push(message); } else { diff --git a/packages/hurl/src/run.rs b/packages/hurl/src/run.rs index e15db0fb0b1..ff8afa4cf3b 100644 --- a/packages/hurl/src/run.rs +++ b/packages/hurl/src/run.rs @@ -27,7 +27,7 @@ use hurl::parallel::runner::ParallelRunner; use hurl::runner::{HurlResult, Input, Output}; use hurl::util::term::{Stdout, WriteMode}; use hurl::{output, parallel, runner}; -use hurl_core::error::error_string; +use hurl_core::error::{error_string, OutputFormat}; use hurl_core::typing::Repeat; /// Runs Hurl `files` sequentially, given a current directory and command-line options (see @@ -128,7 +128,7 @@ fn print_output( content, &e, None, - options.color, + OutputFormat::Terminal(options.color), ))); } } diff --git a/packages/hurl/src/runner/error.rs b/packages/hurl/src/runner/error.rs index 99750616aec..86902bab988 100644 --- a/packages/hurl/src/runner/error.rs +++ b/packages/hurl/src/runner/error.rs @@ -318,7 +318,7 @@ mod tests { use crate::http::HttpError; use crate::runner::{RunnerError, RunnerErrorKind}; use hurl_core::ast::{Pos, SourceInfo}; - use hurl_core::error::{error_string, split_lines, DisplaySourceError}; + use hurl_core::error::{error_string, split_lines, DisplaySourceError, OutputFormat}; use hurl_core::text::Format; #[test] @@ -339,7 +339,13 @@ mod tests { "\n 1 | GET http://unknown\n | ^^^^^^^^^^^^^^ (6) Could not resolve host: unknown\n |" ); assert_eq!( - error_string(filename, content, &error, Some(entry_source_info), false), + error_string( + filename, + content, + &error, + Some(entry_source_info), + OutputFormat::Terminal(false) + ), r#"HTTP connection --> test.hurl:1:5 | @@ -375,7 +381,13 @@ HTTP/1.0 200 ); assert_eq!( - error_string(filename, content, &error, Some(entry_source_info), false), + error_string( + filename, + content, + &error, + Some(entry_source_info), + OutputFormat::Terminal(false) + ), r#"Assert status code --> test.hurl:2:10 | @@ -406,7 +418,13 @@ xpath "strong(//head/title)" == "Hello" "\n 4 | xpath \"strong(//head/title)\" == \"Hello\"\n | ^^^^^^^^^^^^^^^^^^^^^^ the XPath expression is not valid\n |" ); assert_eq!( - error_string(filename, content, &error, Some(entry_source_info), false), + error_string( + filename, + content, + &error, + Some(entry_source_info), + OutputFormat::Terminal(false) + ), r#"Invalid XPath expression --> test.hurl:4:7 | @@ -450,7 +468,13 @@ jsonpath "$.count" >= 5 ); assert_eq!( - error_string(filename, content, &error, Some(entry_source_info), false), + error_string( + filename, + content, + &error, + Some(entry_source_info), + OutputFormat::Terminal(false) + ), r#"Assert failure --> test.hurl:4:0 | @@ -486,7 +510,13 @@ HTTP/1.0 200 "\n 3 | ```

Hello

\n | ^ actual value is <

Hello

\n |\n | >\n |" ); assert_eq!( - error_string(filename, content, &error, Some(entry_source_info), false), + error_string( + filename, + content, + &error, + Some(entry_source_info), + OutputFormat::Terminal(false) + ), r#"Assert body value --> test.hurl:3:4 | diff --git a/packages/hurl/src/util/logger.rs b/packages/hurl/src/util/logger.rs index 00ade139087..e86c36b167d 100644 --- a/packages/hurl/src/util/logger.rs +++ b/packages/hurl/src/util/logger.rs @@ -18,7 +18,7 @@ //! Log utilities. use hurl_core::ast::SourceInfo; -use hurl_core::error::{error_string, split_lines, DisplaySourceError}; +use hurl_core::error::{error_string, split_lines, DisplaySourceError, OutputFormat}; use hurl_core::text::{Format, Style, StyledString}; use crate::runner::Value; @@ -205,7 +205,7 @@ impl Logger { content, error, Some(entry_src_info), - self.color, + OutputFormat::Terminal(self.color), ); split_lines(&message).iter().for_each(|l| self.debug(l)); } @@ -274,7 +274,13 @@ impl Logger { } pub fn error_parsing_rich(&mut self, content: &str, error: &E) { - let message = error_string(&self.filename, content, error, None, self.color); + let message = error_string( + &self.filename, + content, + error, + None, + OutputFormat::Terminal(self.color), + ); self.error_rich(&message); } @@ -289,7 +295,7 @@ impl Logger { content, error, Some(entry_src_info), - self.color, + OutputFormat::Terminal(self.color), ); self.error_rich(&message); } diff --git a/packages/hurl_core/src/error/mod.rs b/packages/hurl_core/src/error/mod.rs index 86e7e05eb8d..fd1dfdb0e26 100644 --- a/packages/hurl_core/src/error/mod.rs +++ b/packages/hurl_core/src/error/mod.rs @@ -80,6 +80,13 @@ pub fn add_carets(message: &str, source_info: SourceInfo, content: &[&str]) -> S s } +/// Format used by error_string +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum OutputFormat { + Terminal(bool), // Replace \r\n by \n + Json, +} + /// Returns the string representation of an `error`, given `lines` of content and a `filename`. /// /// The source information where the error occurred can be retrieved in `error`; optionally, @@ -102,7 +109,7 @@ pub fn error_string( content: &str, error: &E, entry_src_info: Option, - colored: bool, + format: OutputFormat, ) -> String { let mut text = String::new(); let lines = split_lines(content); @@ -112,6 +119,7 @@ pub fn error_string( // The number of digits of the lines count. let loc_max_width = max(lines.len().to_string().len(), 2); let separator = "|"; + let colored = format == OutputFormat::Terminal(true); let spaces = " ".repeat(loc_max_width); let prefix = format!("{spaces} {separator}"); @@ -182,7 +190,10 @@ pub fn error_string( text.push_str(&message); - text + match format { + OutputFormat::Terminal(_) => text.replace("\r\n", "\n"), // CRLF must be replaced by LF in the terminal + OutputFormat::Json => text, + } } pub fn add_line_info_prefix( @@ -366,7 +377,13 @@ HTTP 200 ); assert_eq!( - error_string(filename, content, &error, None, false), + error_string( + filename, + content, + &error, + None, + OutputFormat::Terminal(false) + ), r#"Assert body value --> test.hurl:4:1 | diff --git a/packages/hurl_core/src/parser/error.rs b/packages/hurl_core/src/parser/error.rs index cbff9c174a1..42817f98f80 100644 --- a/packages/hurl_core/src/parser/error.rs +++ b/packages/hurl_core/src/parser/error.rs @@ -314,7 +314,7 @@ fn levenshtein_distance(s1: &str, s2: &str) -> usize { #[cfg(test)] mod tests { use super::*; - use crate::error::error_string; + use crate::error::{error_string, OutputFormat}; #[test] fn test_levenshtein() { @@ -350,7 +350,13 @@ mod tests { kind: ParseErrorKind::UrlInvalidStart, }; assert_eq!( - error_string(filename, content, &error, None, false), + error_string( + filename, + content, + &error, + None, + OutputFormat::Terminal(false) + ), r#"Parsing URL --> test.hurl:1:5 |