use std::ops::{Deref, DerefMut};
use std::path::PathBuf;
use std::process::Command;
use clap::{ArgAction, Parser};
use crate::common::CommonOptions;
use crate::heading;
#[derive(Clone, Debug, Default, Parser)]
#[command(
display_order = 1,
after_help = "Run `cargo help test` for more detailed information.\nRun `cargo test -- --help` for test binary options."
)]
#[group(skip)]
pub struct Test {
#[command(flatten)]
pub common: CommonOptions,
#[arg(long, value_name = "PATH", help_heading = heading::MANIFEST_OPTIONS)]
pub manifest_path: Option<PathBuf>,
#[arg(short = 'r', long, help_heading = heading::COMPILATION_OPTIONS)]
pub release: bool,
#[arg(long)]
pub ignore_rust_version: bool,
#[arg(long, help_heading = heading::COMPILATION_OPTIONS)]
pub unit_graph: bool,
#[arg(
short = 'p',
long = "package",
value_name = "SPEC",
action = ArgAction::Append,
num_args=0..=1,
help_heading = heading::PACKAGE_SELECTION,
)]
pub packages: Vec<String>,
#[arg(long, help_heading = heading::PACKAGE_SELECTION)]
pub workspace: bool,
#[arg(
long,
value_name = "SPEC",
action = ArgAction::Append,
help_heading = heading::PACKAGE_SELECTION,
)]
pub exclude: Vec<String>,
#[arg(long, help_heading = heading::PACKAGE_SELECTION)]
pub all: bool,
#[arg(long, help_heading = heading::TARGET_SELECTION)]
pub lib: bool,
#[arg(
long,
value_name = "NAME",
action = ArgAction::Append,
num_args=0..=1,
help_heading = heading::TARGET_SELECTION,
)]
pub bin: Vec<String>,
#[arg(long, help_heading = heading::TARGET_SELECTION)]
pub bins: bool,
#[arg(
long,
value_name = "NAME",
action = ArgAction::Append,
num_args=0..=1,
help_heading = heading::TARGET_SELECTION,
)]
pub example: Vec<String>,
#[arg(long, help_heading = heading::TARGET_SELECTION)]
pub examples: bool,
#[arg(
long,
value_name = "NAME",
action = ArgAction::Append,
help_heading = heading::TARGET_SELECTION,
)]
pub test: Vec<String>,
#[arg(long, help_heading = heading::TARGET_SELECTION)]
pub tests: bool,
#[arg(
long,
value_name = "NAME",
action = ArgAction::Append,
help_heading = heading::TARGET_SELECTION,
)]
pub bench: Vec<String>,
#[arg(long, help_heading = heading::TARGET_SELECTION)]
pub benches: bool,
#[arg(long, help_heading = heading::TARGET_SELECTION)]
pub all_targets: bool,
#[arg(long)]
pub doc: bool,
#[arg(long)]
pub no_run: bool,
#[arg(long)]
pub no_fail_fast: bool,
#[arg(long)]
pub future_incompat_report: bool,
#[arg(value_name = "TESTNAME")]
pub test_name: Option<String>,
#[arg(value_name = "args", trailing_var_arg = true, num_args = 0..)]
pub args: Vec<String>,
}
impl Test {
pub fn command(&self) -> Command {
let mut cmd = CommonOptions::cargo_command();
cmd.arg("test");
self.common.apply(&mut cmd);
if let Some(path) = self.manifest_path.as_ref() {
cmd.arg("--manifest-path").arg(path);
}
if self.release {
cmd.arg("--release");
}
if self.ignore_rust_version {
cmd.arg("--ignore-rust-version");
}
if self.unit_graph {
cmd.arg("--unit-graph");
}
for pkg in &self.packages {
cmd.arg("--package").arg(pkg);
}
if self.workspace {
cmd.arg("--workspace");
}
for item in &self.exclude {
cmd.arg("--exclude").arg(item);
}
if self.all {
cmd.arg("--all");
}
if self.lib {
cmd.arg("--lib");
}
for bin in &self.bin {
cmd.arg("--bin").arg(bin);
}
if self.bins {
cmd.arg("--bins");
}
for example in &self.example {
cmd.arg("--example").arg(example);
}
if self.examples {
cmd.arg("--examples");
}
for test in &self.test {
cmd.arg("--test").arg(test);
}
if self.tests {
cmd.arg("--tests");
}
for bench in &self.bench {
cmd.arg("--bench").arg(bench);
}
if self.benches {
cmd.arg("--benches");
}
if self.all_targets {
cmd.arg("--all-targets");
}
if self.doc {
cmd.arg("--doc");
}
if self.no_run {
cmd.arg("--no-run");
}
if self.no_fail_fast {
cmd.arg("--no-fail-fast");
}
if self.future_incompat_report {
cmd.arg("--future-incompat-report");
}
cmd.arg("--");
if let Some(test_name) = self.test_name.as_ref() {
cmd.arg(test_name);
}
cmd.args(&self.args);
cmd
}
}
impl Deref for Test {
type Target = CommonOptions;
fn deref(&self) -> &Self::Target {
&self.common
}
}
impl DerefMut for Test {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.common
}
}
#[cfg(test)]
mod tests {
use super::Test;
use clap::CommandFactory;
#[test]
fn verify_cli() {
<Test as CommandFactory>::command().debug_assert()
}
}