use anyhow::Result;
use colored::Colorize;
use contract_build::{
maybe_println,
util,
Features,
ManifestPath,
Verbosity,
VerbosityFlags,
};
use std::{
convert::TryFrom,
path::PathBuf,
};
#[derive(Debug, clap::Args)]
#[clap(name = "test")]
pub struct TestCommand {
#[clap(long, value_parser)]
manifest_path: Option<PathBuf>,
#[clap(flatten)]
verbosity: VerbosityFlags,
#[clap(flatten)]
features: Features,
}
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, &self.features)
}
}
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,
features: &Features,
) -> Result<TestResult> {
maybe_println!(
verbosity,
" {} {}",
format!("[{}/{}]", 1, 1).bold(),
"Running tests".bright_green().bold()
);
let mut args = Vec::new();
features.append_to_args(&mut args);
let stdout =
util::invoke_cargo("test", args, manifest_path.directory(), verbosity, vec![])?;
Ok(TestResult { stdout, verbosity })
}
#[cfg(feature = "test-ci-only")]
#[cfg(test)]
mod tests_ci_only {
use contract_build::{
Features,
ManifestPath,
Verbosity,
};
use regex::Regex;
#[test]
fn passing_tests_yield_stdout() {
let tmp_dir = tempfile::Builder::new()
.prefix("cargo-contract.test.")
.tempdir()
.expect("temporary directory creation failed");
let project_name = "test_project";
contract_build::new_contract_project(project_name, Some(&tmp_dir))
.expect("new project creation failed");
let working_dir = tmp_dir.path().join(project_name);
let manifest_path = ManifestPath::new(working_dir.join("Cargo.toml"))
.expect("invalid 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, &Features::default())
.expect("test execution failed");
assert!(ok_output_pattern.is_match(&String::from_utf8_lossy(&res.stdout)));
}
}