cli_testing_specialist/generator/
test_generator_trait.rs

1use crate::error::Result;
2use crate::types::analysis::CliAnalysis;
3use crate::types::test_case::TestCategory;
4
5/// Common interface for all test generators
6///
7/// This trait provides a unified interface for generating tests in different formats:
8/// - BatsGenerator: Generates BATS shell test scripts
9/// - AssertCmdGenerator: Generates Rust tests using assert_cmd crate
10/// - SnapboxGenerator: Generates snapshot tests (future implementation)
11///
12/// Design rationale:
13/// - Maintainability: Single source of truth for test generation logic
14/// - Extensibility: Easy to add new test formats (e.g., pytest, Go tests)
15/// - Consistency: All generators follow the same pattern
16pub trait TestGenerator {
17    /// Generate tests for a specific category
18    ///
19    /// # Arguments
20    ///
21    /// * `analysis` - CLI analysis results containing subcommands, options, etc.
22    /// * `category` - Test category (basic, security, help, etc.)
23    ///
24    /// # Returns
25    ///
26    /// Generated test code as a String
27    ///
28    /// # Example
29    ///
30    /// ```ignore
31    /// let generator = AssertCmdGenerator::new()?;
32    /// let test_code = generator.generate(&analysis, TestCategory::Basic)?;
33    /// ```
34    fn generate(&self, analysis: &CliAnalysis, category: TestCategory) -> Result<String>;
35
36    /// Generate all test categories
37    ///
38    /// Convenience method to generate tests for all standard categories.
39    ///
40    /// # Arguments
41    ///
42    /// * `analysis` - CLI analysis results
43    ///
44    /// # Returns
45    ///
46    /// Map of category name to generated test code
47    fn generate_all(&self, analysis: &CliAnalysis) -> Result<Vec<(TestCategory, String)>> {
48        let categories = TestCategory::standard_categories();
49        let mut results = Vec::new();
50
51        for category in categories {
52            let test_code = self.generate(analysis, category)?;
53            results.push((category, test_code));
54        }
55
56        Ok(results)
57    }
58
59    /// Get the file extension for generated test files
60    ///
61    /// # Returns
62    ///
63    /// File extension (e.g., "bats", "rs", "snap")
64    fn file_extension(&self) -> &str;
65
66    /// Get the generator name
67    ///
68    /// # Returns
69    ///
70    /// Human-readable name (e.g., "BATS", "assert_cmd", "snapbox")
71    fn name(&self) -> &str;
72}
73
74/// Factory function to create a test generator by name
75///
76/// # Arguments
77///
78/// * `format` - Generator format name ("bats", "assert_cmd", "snapbox")
79///
80/// # Returns
81///
82/// Boxed TestGenerator instance
83///
84/// # Example
85///
86/// ```ignore
87/// let generator = create_generator("assert_cmd")?;
88/// let test_code = generator.generate(&analysis, TestCategory::Security)?;
89/// ```
90pub fn create_generator(format: &str) -> Result<Box<dyn TestGenerator>> {
91    match format.to_lowercase().as_str() {
92        "bats" => {
93            // Use existing BatsGenerator (to be refactored to implement TestGenerator)
94            Err(crate::error::CliTestError::InvalidFormat(
95                "BATS generator not yet refactored to use TestGenerator trait".to_string(),
96            ))
97        }
98        "assert_cmd" | "assert-cmd" => {
99            // Create AssertCmdGenerator
100            Err(crate::error::CliTestError::InvalidFormat(
101                "AssertCmdGenerator not yet implemented".to_string(),
102            ))
103        }
104        "snapbox" => {
105            // Future implementation
106            Err(crate::error::CliTestError::InvalidFormat(
107                "Snapbox generator not yet implemented".to_string(),
108            ))
109        }
110        _ => Err(crate::error::CliTestError::InvalidFormat(format!(
111            "Unknown generator format: {}",
112            format
113        ))),
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120
121    #[test]
122    fn test_create_generator_invalid_format() {
123        let result = create_generator("invalid");
124        assert!(result.is_err());
125    }
126
127    #[test]
128    fn test_create_generator_not_implemented() {
129        // These should fail until implemented
130        assert!(create_generator("bats").is_err());
131        assert!(create_generator("assert_cmd").is_err());
132        assert!(create_generator("snapbox").is_err());
133    }
134}