#[allow(unused_imports)]
use crate::error::Result;
pub mod cli_parser;
pub mod repl_parser;
pub mod type_parser;
pub use cli_parser::CliParser;
pub use repl_parser::{ParsedCommand, ReplParser};
#[cfg(test)]
mod tests {
use super::*;
use crate::config::schema::{
ArgumentDefinition, ArgumentType, CommandDefinition, OptionDefinition,
};
use crate::context::ExecutionContext;
use crate::executor::CommandHandler;
use crate::registry::CommandRegistry;
use std::collections::HashMap;
struct IntegrationTestHandler;
impl CommandHandler for IntegrationTestHandler {
fn execute(
&self,
_context: &mut dyn ExecutionContext,
_args: &HashMap<String, String>,
) -> Result<()> {
Ok(())
}
}
fn create_comprehensive_command() -> CommandDefinition {
CommandDefinition {
name: "analyze".to_string(),
aliases: vec!["analyse".to_string(), "check".to_string()],
description: "Analyze data files".to_string(),
required: false,
arguments: vec![
ArgumentDefinition {
name: "input".to_string(),
arg_type: ArgumentType::Path,
required: true,
description: "Input data file".to_string(),
validation: vec![],
},
ArgumentDefinition {
name: "output".to_string(),
arg_type: ArgumentType::Path,
required: false,
description: "Output report file".to_string(),
validation: vec![],
},
],
options: vec![
OptionDefinition {
name: "verbose".to_string(),
short: Some("v".to_string()),
long: Some("verbose".to_string()),
option_type: ArgumentType::Bool,
required: false,
default: Some("false".to_string()),
description: "Enable verbose output".to_string(),
choices: vec![],
},
OptionDefinition {
name: "iterations".to_string(),
short: Some("i".to_string()),
long: Some("iterations".to_string()),
option_type: ArgumentType::Integer,
required: false,
default: Some("100".to_string()),
description: "Number of iterations".to_string(),
choices: vec![],
},
OptionDefinition {
name: "threshold".to_string(),
short: Some("t".to_string()),
long: Some("threshold".to_string()),
option_type: ArgumentType::Float,
required: false,
default: Some("0.5".to_string()),
description: "Analysis threshold".to_string(),
choices: vec![],
},
],
implementation: "analyze_handler".to_string(),
}
}
#[test]
fn test_cli_parser_integration_minimal() {
let definition = create_comprehensive_command();
let parser = CliParser::new(&definition);
let args = vec!["data.csv".to_string()];
let result = parser.parse(&args).unwrap();
assert_eq!(result.get("input"), Some(&"data.csv".to_string()));
assert_eq!(result.get("verbose"), Some(&"false".to_string()));
assert_eq!(result.get("iterations"), Some(&"100".to_string()));
assert_eq!(result.get("threshold"), Some(&"0.5".to_string()));
}
#[test]
fn test_cli_parser_integration_full() {
let definition = create_comprehensive_command();
let parser = CliParser::new(&definition);
let args = vec![
"data.csv".to_string(),
"report.txt".to_string(),
"--verbose".to_string(),
"--iterations=200".to_string(),
"-t".to_string(),
"0.75".to_string(),
];
let result = parser.parse(&args).unwrap();
assert_eq!(result.get("input"), Some(&"data.csv".to_string()));
assert_eq!(result.get("output"), Some(&"report.txt".to_string()));
assert_eq!(result.get("verbose"), Some(&"true".to_string()));
assert_eq!(result.get("iterations"), Some(&"200".to_string()));
assert_eq!(result.get("threshold"), Some(&"0.75".to_string()));
}
#[test]
fn test_cli_parser_integration_mixed_options() {
let definition = create_comprehensive_command();
let parser = CliParser::new(&definition);
let args = vec![
"--verbose".to_string(),
"data.csv".to_string(),
"-i200".to_string(),
"report.txt".to_string(),
"--threshold".to_string(),
"0.9".to_string(),
];
let result = parser.parse(&args).unwrap();
assert_eq!(result.get("input"), Some(&"data.csv".to_string()));
assert_eq!(result.get("output"), Some(&"report.txt".to_string()));
assert_eq!(result.get("verbose"), Some(&"true".to_string()));
assert_eq!(result.get("iterations"), Some(&"200".to_string()));
assert_eq!(result.get("threshold"), Some(&"0.9".to_string()));
}
#[test]
fn test_repl_parser_integration_simple() {
let mut registry = CommandRegistry::new();
let definition = create_comprehensive_command();
registry
.register(definition, Box::new(IntegrationTestHandler))
.unwrap();
let parser = ReplParser::new(®istry);
let parsed = parser.parse_line("analyze data.csv").unwrap();
assert_eq!(parsed.command_name, "analyze");
assert_eq!(parsed.arguments.get("input"), Some(&"data.csv".to_string()));
}
#[test]
fn test_repl_parser_integration_alias() {
let mut registry = CommandRegistry::new();
let definition = create_comprehensive_command();
registry
.register(definition, Box::new(IntegrationTestHandler))
.unwrap();
let parser = ReplParser::new(®istry);
let parsed = parser.parse_line("check data.csv --verbose").unwrap();
assert_eq!(parsed.command_name, "analyze"); assert_eq!(parsed.arguments.get("input"), Some(&"data.csv".to_string()));
assert_eq!(parsed.arguments.get("verbose"), Some(&"true".to_string()));
}
#[test]
fn test_repl_parser_integration_quoted_paths() {
let mut registry = CommandRegistry::new();
let definition = create_comprehensive_command();
registry
.register(definition, Box::new(IntegrationTestHandler))
.unwrap();
let parser = ReplParser::new(®istry);
let parsed = parser
.parse_line(r#"analyze "/path/with spaces/data.csv" "output report.txt""#)
.unwrap();
assert_eq!(
parsed.arguments.get("input"),
Some(&"/path/with spaces/data.csv".to_string())
);
assert_eq!(
parsed.arguments.get("output"),
Some(&"output report.txt".to_string())
);
}
#[test]
fn test_repl_parser_integration_complex() {
let mut registry = CommandRegistry::new();
let definition = create_comprehensive_command();
registry
.register(definition, Box::new(IntegrationTestHandler))
.unwrap();
let parser = ReplParser::new(®istry);
let parsed = parser
.parse_line(r#"analyse "data file.csv" report.txt -v --iterations=500 -t 0.95"#)
.unwrap();
assert_eq!(parsed.command_name, "analyze");
assert_eq!(
parsed.arguments.get("input"),
Some(&"data file.csv".to_string())
);
assert_eq!(
parsed.arguments.get("output"),
Some(&"report.txt".to_string())
);
assert_eq!(parsed.arguments.get("verbose"), Some(&"true".to_string()));
assert_eq!(parsed.arguments.get("iterations"), Some(&"500".to_string()));
assert_eq!(parsed.arguments.get("threshold"), Some(&"0.95".to_string()));
}
#[test]
fn test_type_parser_integration_all_types() {
use type_parser::parse_value;
assert!(parse_value("hello", ArgumentType::String).is_ok());
assert!(parse_value("42", ArgumentType::Integer).is_ok());
assert!(parse_value("3.14", ArgumentType::Float).is_ok());
assert!(parse_value("true", ArgumentType::Bool).is_ok());
assert!(parse_value("/path/to/file", ArgumentType::Path).is_ok());
}
#[test]
fn test_type_parser_integration_error_propagation() {
let definition = create_comprehensive_command();
let parser = CliParser::new(&definition);
let args = vec![
"data.csv".to_string(),
"--iterations".to_string(),
"not_a_number".to_string(),
];
let result = parser.parse(&args);
assert!(result.is_err());
}
#[test]
fn test_workflow_cli_to_execution() {
let definition = create_comprehensive_command();
let parser = CliParser::new(&definition);
let args = vec!["data.csv".to_string(), "-v".to_string()];
let parsed = parser.parse(&args).unwrap();
assert!(parsed.contains_key("input"));
assert!(parsed.contains_key("verbose"));
assert_eq!(parsed.get("verbose"), Some(&"true".to_string()));
}
#[test]
fn test_workflow_repl_to_execution() {
let mut registry = CommandRegistry::new();
let definition = create_comprehensive_command();
registry
.register(definition, Box::new(IntegrationTestHandler))
.unwrap();
let parser = ReplParser::new(®istry);
let line = "analyze data.csv --verbose --iterations=1000";
let parsed = parser.parse_line(line).unwrap();
assert_eq!(parsed.command_name, "analyze");
assert!(parsed.arguments.contains_key("input"));
assert_eq!(parsed.arguments.get("verbose"), Some(&"true".to_string()));
assert_eq!(
parsed.arguments.get("iterations"),
Some(&"1000".to_string())
);
}
#[test]
fn test_workflow_typo_suggestions() {
let mut registry = CommandRegistry::new();
let definition = create_comprehensive_command();
registry
.register(definition, Box::new(IntegrationTestHandler))
.unwrap();
let parser = ReplParser::new(®istry);
let result = parser.parse_line("analyz data.csv");
assert!(result.is_err());
let error = result.unwrap_err();
let error_msg = format!("{}", error);
assert!(error_msg.contains("Unknown command"));
}
#[test]
fn test_reexports_accessible() {
let definition = create_comprehensive_command();
let _cli_parser = CliParser::new(&definition);
let registry = CommandRegistry::new();
let _repl_parser = ReplParser::new(®istry);
let _parsed = ParsedCommand {
command_name: "test".to_string(),
arguments: HashMap::new(),
};
}
}