pub mod curl;
pub mod html;
pub mod human;
pub mod json;
pub mod junit;
pub mod progress;
pub mod redaction;
pub mod tap;
use crate::assert::types::RunResult;
use std::path::PathBuf;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, Default)]
pub struct RenderOptions {
pub only_failed: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum OutputFormat {
Human,
Json,
Junit,
Tap,
Html,
Curl,
CurlAll,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OutputTarget {
pub format: OutputFormat,
pub path: Option<PathBuf>,
}
impl FromStr for OutputFormat {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"human" => Ok(OutputFormat::Human),
"json" => Ok(OutputFormat::Json),
"junit" => Ok(OutputFormat::Junit),
"tap" => Ok(OutputFormat::Tap),
"html" => Ok(OutputFormat::Html),
"curl" => Ok(OutputFormat::Curl),
"curl-all" => Ok(OutputFormat::CurlAll),
other => Err(format!("Unknown output format: '{}'", other)),
}
}
}
impl FromStr for OutputTarget {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (format_raw, path) = match s.split_once('=') {
Some((format, path)) => (format, Some(PathBuf::from(path))),
None => (s, None),
};
let format = format_raw.parse::<OutputFormat>()?;
Ok(Self { format, path })
}
}
impl OutputTarget {
pub fn writes_to_stdout(&self) -> bool {
self.path.is_none() && self.format != OutputFormat::Html
}
}
pub fn render(result: &RunResult, format: OutputFormat) -> String {
render_with_options(result, format, RenderOptions::default())
}
pub fn render_with_options(
result: &RunResult,
format: OutputFormat,
opts: RenderOptions,
) -> String {
match format {
OutputFormat::Human => human::render_with_options(result, opts),
OutputFormat::Json => {
json::render_with_options(result, json::JsonOutputMode::Verbose, opts)
}
OutputFormat::Junit => junit::render(result),
OutputFormat::Tap => tap::render(result),
OutputFormat::Html => html::render(result),
OutputFormat::Curl => curl::render_failures(result),
OutputFormat::CurlAll => curl::render_all(result),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn output_format_from_str() {
assert_eq!("human".parse::<OutputFormat>(), Ok(OutputFormat::Human));
assert_eq!("json".parse::<OutputFormat>(), Ok(OutputFormat::Json));
assert_eq!("junit".parse::<OutputFormat>(), Ok(OutputFormat::Junit));
assert_eq!("tap".parse::<OutputFormat>(), Ok(OutputFormat::Tap));
assert_eq!("html".parse::<OutputFormat>(), Ok(OutputFormat::Html));
assert_eq!("curl".parse::<OutputFormat>(), Ok(OutputFormat::Curl));
assert_eq!(
"curl-all".parse::<OutputFormat>(),
Ok(OutputFormat::CurlAll)
);
assert_eq!("JSON".parse::<OutputFormat>(), Ok(OutputFormat::Json));
assert_eq!("HTML".parse::<OutputFormat>(), Ok(OutputFormat::Html));
assert!("unknown".parse::<OutputFormat>().is_err());
}
#[test]
fn output_target_from_format_only() {
assert_eq!(
"json".parse::<OutputTarget>(),
Ok(OutputTarget {
format: OutputFormat::Json,
path: None,
})
);
}
#[test]
fn output_target_from_format_and_path() {
assert_eq!(
"junit=reports/junit.xml".parse::<OutputTarget>(),
Ok(OutputTarget {
format: OutputFormat::Junit,
path: Some(PathBuf::from("reports/junit.xml")),
})
);
}
#[test]
fn html_without_path_does_not_write_to_stdout() {
let target = "html".parse::<OutputTarget>().unwrap();
assert!(!target.writes_to_stdout());
}
}