cli_testing_specialist/cli/
commands.rs

1use clap::{Parser, Subcommand, ValueEnum};
2use clap_complete::Shell;
3use std::path::PathBuf;
4
5/// CLI Testing Specialist - Comprehensive testing framework for CLI tools
6#[derive(Parser, Debug)]
7#[command(
8    name = "cli-test",
9    version,
10    about = "Comprehensive CLI testing framework",
11    long_about = "Analyzes CLI tools, generates BATS test suites, and produces detailed security reports"
12)]
13pub struct Cli {
14    /// Subcommand to execute
15    #[command(subcommand)]
16    pub command: Commands,
17
18    /// Enable verbose output
19    #[arg(short, long, global = true)]
20    pub verbose: bool,
21}
22
23/// Available subcommands
24#[derive(Subcommand, Debug)]
25pub enum Commands {
26    /// Analyze a CLI tool and extract its structure
27    #[command(about = "Analyze CLI tool structure and options")]
28    Analyze {
29        /// Path to the CLI binary to analyze
30        #[arg(value_name = "BINARY")]
31        binary: PathBuf,
32
33        /// Output JSON file path
34        #[arg(short, long, default_value = "cli-analysis.json")]
35        output: PathBuf,
36
37        /// Maximum recursion depth for subcommands
38        #[arg(short, long, default_value = "3")]
39        depth: u8,
40
41        /// Enable parallel processing
42        #[arg(long)]
43        parallel: bool,
44    },
45
46    /// Generate test cases from analysis results
47    #[command(about = "Generate BATS test suites from analysis")]
48    Generate {
49        /// Analysis JSON file path
50        #[arg(value_name = "ANALYSIS")]
51        analysis: PathBuf,
52
53        /// Output directory for test files
54        #[arg(short, long, default_value = "test-output")]
55        output: PathBuf,
56
57        /// Test categories to generate (comma-separated or "all")
58        #[arg(short, long, default_value = "all")]
59        categories: String,
60
61        /// Include resource-intensive tests (directory-traversal, large-scale performance)
62        /// These tests may require significant /tmp space and memory
63        #[arg(long)]
64        include_intensive: bool,
65    },
66
67    /// Run BATS tests and generate reports
68    #[command(about = "Execute BATS tests and generate reports")]
69    Run {
70        /// Test directory containing BATS files
71        #[arg(value_name = "TEST_DIR")]
72        test_dir: PathBuf,
73
74        /// Report format to generate
75        #[arg(short, long, default_value = "markdown")]
76        format: ReportFormat,
77
78        /// Output directory for reports
79        #[arg(short, long, default_value = "reports")]
80        output: PathBuf,
81
82        /// Timeout per test suite in seconds (default: 300)
83        #[arg(short = 't', long, default_value = "300")]
84        timeout: u64,
85
86        /// Skip specific test categories (comma-separated)
87        #[arg(short = 's', long)]
88        skip: Option<String>,
89    },
90
91    /// Validate analysis JSON file
92    #[command(about = "Validate analysis JSON file structure")]
93    Validate {
94        /// Analysis JSON file to validate
95        #[arg(value_name = "FILE")]
96        file: PathBuf,
97    },
98
99    /// Generate shell completion scripts
100    #[command(about = "Generate shell completion scripts")]
101    Completion {
102        /// Shell type to generate completion for
103        #[arg(value_name = "SHELL")]
104        shell: Shell,
105    },
106}
107
108/// Report output format
109#[derive(ValueEnum, Clone, Debug)]
110pub enum ReportFormat {
111    /// Markdown format
112    Markdown,
113
114    /// JSON format
115    Json,
116
117    /// HTML format
118    Html,
119
120    /// JUnit XML format
121    Junit,
122
123    /// All formats
124    All,
125}
126
127impl ReportFormat {
128    /// Get file extension for this format
129    pub fn extension(&self) -> &'static str {
130        match self {
131            Self::Markdown => "md",
132            Self::Json => "json",
133            Self::Html => "html",
134            Self::Junit => "xml",
135            Self::All => "all",
136        }
137    }
138}
139
140#[cfg(test)]
141mod tests {
142    use super::*;
143
144    #[test]
145    fn test_report_format_extension() {
146        assert_eq!(ReportFormat::Markdown.extension(), "md");
147        assert_eq!(ReportFormat::Json.extension(), "json");
148        assert_eq!(ReportFormat::Html.extension(), "html");
149        assert_eq!(ReportFormat::Junit.extension(), "xml");
150    }
151}