use ricecoder_cli::commands::{Command, ConfigCommand, GenCommand, InitCommand};
use std::fs;
use std::path::Path;
use tempfile::TempDir;
#[test]
fn test_init_command_creates_agent_directory() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let temp_path = temp_dir.path().to_str().unwrap();
let cmd = InitCommand::new(Some(temp_path.to_string()));
let result = cmd.execute();
assert!(result.is_ok(), "Init command should succeed");
let agent_dir = Path::new(temp_path).join(".agent");
assert!(
agent_dir.exists(),
"Expected .agent directory to be created at {}",
agent_dir.display()
);
assert!(
agent_dir.is_dir(),
"Expected .agent to be a directory, not a file"
);
}
#[test]
fn test_init_command_creates_config_file() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let temp_path = temp_dir.path().to_str().unwrap();
let cmd = InitCommand::new(Some(temp_path.to_string()));
let result = cmd.execute();
assert!(result.is_ok(), "Init command should succeed");
let config_file = Path::new(temp_path).join(".agent/ricecoder.toml");
assert!(
config_file.exists(),
"Expected ricecoder.toml to be created at {}",
config_file.display()
);
assert!(
config_file.is_file(),
"Expected ricecoder.toml to be a file"
);
}
#[test]
fn test_init_command_config_contains_required_sections() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let temp_path = temp_dir.path().to_str().unwrap();
let cmd = InitCommand::new(Some(temp_path.to_string()));
let _ = cmd.execute();
let config_file = Path::new(temp_path).join(".agent/ricecoder.toml");
let content = fs::read_to_string(&config_file).expect("Failed to read ricecoder.toml");
assert!(
content.contains("[project]"),
"Config should contain [project] section"
);
assert!(
content.contains("[providers]"),
"Config should contain [providers] section"
);
assert!(
content.contains("[storage]"),
"Config should contain [storage] section"
);
}
#[test]
fn test_init_command_uses_current_directory_by_default() {
let cmd = InitCommand::new(None);
assert_eq!(cmd.project_path, None);
}
#[test]
fn test_init_command_accepts_custom_path() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let temp_path = temp_dir.path().to_str().unwrap();
let cmd = InitCommand::new(Some(temp_path.to_string()));
assert_eq!(cmd.project_path, Some(temp_path.to_string()));
}
#[test]
fn test_gen_command_validates_spec_file_exists() {
let cmd = GenCommand::new("nonexistent_spec.md".to_string());
let result = cmd.execute();
assert!(
result.is_err(),
"Gen command should fail when spec file doesn't exist"
);
}
#[test]
fn test_gen_command_accepts_valid_spec_file() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let spec_file = temp_dir.path().join("test_spec.md");
fs::write(&spec_file, "# Test Specification\n\nThis is a test spec.")
.expect("Failed to write spec file");
let cmd = GenCommand::new(spec_file.to_str().unwrap().to_string());
let result = cmd.execute();
assert!(
result.is_ok(),
"Gen command should succeed with valid spec file"
);
}
#[test]
fn test_gen_command_rejects_empty_spec_file() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let spec_file = temp_dir.path().join("empty_spec.md");
fs::write(&spec_file, "").expect("Failed to write spec file");
let cmd = GenCommand::new(spec_file.to_str().unwrap().to_string());
let result = cmd.execute();
assert!(
result.is_err(),
"Gen command should fail with empty spec file"
);
}
#[test]
fn test_gen_command_rejects_directory_as_spec() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let temp_path = temp_dir.path().to_str().unwrap();
let cmd = GenCommand::new(temp_path.to_string());
let result = cmd.execute();
assert!(
result.is_err(),
"Gen command should fail when spec path is a directory"
);
}
#[test]
fn test_gen_command_loads_spec_content() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let spec_file = temp_dir.path().join("test_spec.md");
let spec_content = "# Test Specification\n\nGenerate code from this spec.";
fs::write(&spec_file, spec_content).expect("Failed to write spec file");
let cmd = GenCommand::new(spec_file.to_str().unwrap().to_string());
let result = cmd.execute();
assert!(result.is_ok(), "Gen command should load spec successfully");
}
#[test]
fn test_gen_command_with_whitespace_only_spec() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let spec_file = temp_dir.path().join("whitespace_spec.md");
fs::write(&spec_file, " \n\n \t \n").expect("Failed to write spec file");
let cmd = GenCommand::new(spec_file.to_str().unwrap().to_string());
let result = cmd.execute();
assert!(
result.is_err(),
"Gen command should fail with whitespace-only spec file"
);
}
#[test]
fn test_config_command_list_action() {
use ricecoder_cli::commands::config::ConfigAction;
let cmd = ConfigCommand::new(ConfigAction::List);
let result = cmd.execute();
assert!(result.is_ok(), "Config list should succeed");
}
#[test]
fn test_config_command_get_existing_key() {
use ricecoder_cli::commands::config::ConfigAction;
let cmd = ConfigCommand::new(ConfigAction::Get("provider.default".to_string()));
let result = cmd.execute();
assert!(result.is_ok(), "Config get for existing key should succeed");
}
#[test]
fn test_config_command_get_nonexistent_key() {
use ricecoder_cli::commands::config::ConfigAction;
let cmd = ConfigCommand::new(ConfigAction::Get("nonexistent.key".to_string()));
let result = cmd.execute();
assert!(
result.is_ok(),
"Config get for non-existent key should succeed with warning"
);
}
#[test]
fn test_config_command_set_value() {
use ricecoder_cli::commands::config::ConfigAction;
let cmd = ConfigCommand::new(ConfigAction::Set(
"test.key".to_string(),
"test_value".to_string(),
));
let result = cmd.execute();
assert!(result.is_ok(), "Config set should succeed");
}
#[test]
fn test_config_command_set_with_empty_value() {
use ricecoder_cli::commands::config::ConfigAction;
let cmd = ConfigCommand::new(ConfigAction::Set("test.key".to_string(), "".to_string()));
let result = cmd.execute();
assert!(result.is_ok(), "Config set with empty value should succeed");
}
#[test]
fn test_config_command_set_with_special_characters() {
use ricecoder_cli::commands::config::ConfigAction;
let cmd = ConfigCommand::new(ConfigAction::Set(
"test.key".to_string(),
"value with spaces and special chars: !@#$%".to_string(),
));
let result = cmd.execute();
assert!(
result.is_ok(),
"Config set with special characters should succeed"
);
}
#[test]
fn test_init_command_implements_command_trait() {
let cmd = InitCommand::new(None);
let _: &dyn Command = &cmd;
}
#[test]
fn test_gen_command_implements_command_trait() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let spec_file = temp_dir.path().join("test.md");
fs::write(&spec_file, "# Test").expect("Failed to write file");
let cmd = GenCommand::new(spec_file.to_str().unwrap().to_string());
let _: &dyn Command = &cmd;
}
#[test]
fn test_config_command_implements_command_trait() {
use ricecoder_cli::commands::config::ConfigAction;
let cmd = ConfigCommand::new(ConfigAction::List);
let _: &dyn Command = &cmd;
}
#[test]
fn test_init_command_idempotent() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let temp_path = temp_dir.path().to_str().unwrap();
let cmd = InitCommand::new(Some(temp_path.to_string()));
let result1 = cmd.execute();
assert!(result1.is_ok(), "First init should succeed");
let result2 = cmd.execute();
assert!(result2.is_ok(), "Second init should succeed (idempotent)");
}
#[test]
fn test_gen_command_with_various_spec_formats() {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let md_spec = temp_dir.path().join("spec.md");
fs::write(&md_spec, "# Spec\n\nContent").expect("Failed to write");
let cmd = GenCommand::new(md_spec.to_str().unwrap().to_string());
assert!(cmd.execute().is_ok(), "Should handle markdown spec");
let yaml_spec = temp_dir.path().join("spec.yaml");
fs::write(&yaml_spec, "name: test\ndescription: test spec").expect("Failed to write");
let cmd = GenCommand::new(yaml_spec.to_str().unwrap().to_string());
assert!(cmd.execute().is_ok(), "Should handle yaml spec");
let json_spec = temp_dir.path().join("spec.json");
fs::write(&json_spec, r#"{"name": "test"}"#).expect("Failed to write");
let cmd = GenCommand::new(json_spec.to_str().unwrap().to_string());
assert!(cmd.execute().is_ok(), "Should handle json spec");
}
#[test]
fn test_config_command_all_actions_succeed() {
use ricecoder_cli::commands::config::ConfigAction;
let actions = vec![
ConfigAction::List,
ConfigAction::Get("provider.default".to_string()),
ConfigAction::Set("test.key".to_string(), "value".to_string()),
];
for action in actions {
let cmd = ConfigCommand::new(action);
let result = cmd.execute();
assert!(result.is_ok(), "Config action should succeed");
}
}