use crate::{
maybe_println,
util,
workspace::ManifestPath,
Verbosity,
VerbosityFlags,
};
use anyhow::Result;
use colored::Colorize;
use std::{
convert::TryFrom,
path::PathBuf,
};
#[derive(Debug, clap::Args)]
#[clap(name = "test")]
pub struct TestCommand {
#[clap(long, parse(from_os_str))]
manifest_path: Option<PathBuf>,
#[clap(flatten)]
verbosity: VerbosityFlags,
}
impl TestCommand {
pub fn exec(&self) -> Result<TestResult> {
let manifest_path = ManifestPath::try_from(self.manifest_path.as_ref())?;
let verbosity = TryFrom::<&VerbosityFlags>::try_from(&self.verbosity)?;
execute(&manifest_path, verbosity)
}
}
pub struct TestResult {
pub stdout: Vec<u8>,
pub verbosity: Verbosity,
}
impl TestResult {
pub fn display(&self) -> Result<String> {
Ok(String::from_utf8(self.stdout.clone())?)
}
}
pub(crate) fn execute(
manifest_path: &ManifestPath,
verbosity: Verbosity,
) -> Result<TestResult> {
util::assert_channel()?;
maybe_println!(
verbosity,
" {} {}",
format!("[{}/{}]", 1, 1).bold(),
"Running tests".bright_green().bold()
);
let stdout =
util::invoke_cargo("test", &[""], manifest_path.directory(), verbosity, vec![])?;
Ok(TestResult { stdout, verbosity })
}
#[cfg(feature = "test-ci-only")]
#[cfg(test)]
mod tests_ci_only {
use crate::{
util::tests::with_new_contract_project,
Verbosity,
};
use regex::Regex;
#[test]
fn passing_tests_yield_stdout() {
with_new_contract_project(|manifest_path| {
let ok_output_pattern =
Regex::new(r"test result: ok. \d+ passed; 0 failed; \d+ ignored")
.expect("regex pattern compilation failed");
let res = super::execute(&manifest_path, Verbosity::Default)
.expect("test execution failed");
assert!(ok_output_pattern.is_match(&String::from_utf8_lossy(&res.stdout)));
Ok(())
})
}
}