use flag_rs::{CommandBuilder, CompletionResult, Context};
#[test]
fn test_active_help_in_completions() {
let cmd = CommandBuilder::new("test")
.flag(
flag_rs::Flag::new("verbose")
.short('v')
.usage("Enable verbose output")
.value_type(flag_rs::FlagType::Bool),
)
.subcommand(
CommandBuilder::new("deploy")
.arg_completion(|ctx, _prefix| {
let mut result = CompletionResult::new().add("staging").add("production");
if ctx.flag("verbose").is_none() {
result = result.add_help_text("Tip: Use -v for detailed deployment logs");
}
result = result.add_conditional_help(
"Warning: Production deployments require approval",
|_| true,
);
Ok(result)
})
.build(),
)
.build();
let completion_args = vec![
"__complete".to_string(),
"deploy".to_string(),
String::new(),
];
let result = cmd.handle_completion_request(&completion_args);
assert!(result.is_ok());
let completions = result.unwrap();
assert!(completions.iter().any(|s| s == "staging"));
assert!(completions.iter().any(|s| s == "production"));
assert!(
completions
.iter()
.any(|s| s.contains("Use -v for detailed deployment logs"))
);
assert!(
completions
.iter()
.any(|s| s.contains("Production deployments require approval"))
);
}
#[test]
fn test_conditional_active_help() {
let cmd = CommandBuilder::new("test")
.flag(
flag_rs::Flag::new("format")
.short('f')
.usage("Output format")
.value_type(flag_rs::FlagType::String),
)
.subcommand(
CommandBuilder::new("list")
.arg_completion(|_ctx, _prefix| {
let mut result = CompletionResult::new().add("items").add("details");
result = result.add_conditional_help(
"Use --format json for machine-readable output",
|context| context.flag("format").is_none(),
);
result = result
.add_conditional_help("Table format supports color output", |context| {
context.flag("format").is_some_and(|f| f == "table")
});
Ok(result)
})
.build(),
)
.build();
let args1 = vec!["__complete".to_string(), "list".to_string(), String::new()];
let result1 = cmd.handle_completion_request(&args1).unwrap();
assert!(
result1
.iter()
.any(|s| s.contains("Use --format json for machine-readable output"))
);
assert!(
!result1
.iter()
.any(|s| s.contains("Table format supports color output"))
);
let args2 = vec![
"__complete".to_string(),
"--format".to_string(),
"table".to_string(),
"list".to_string(),
String::new(),
];
let result2 = cmd.handle_completion_request(&args2).unwrap();
assert!(
!result2
.iter()
.any(|s| s.contains("Use --format json for machine-readable output"))
);
assert!(
result2
.iter()
.any(|s| s.contains("Table format supports color output"))
);
}
#[test]
fn test_active_help_with_different_shells() {
let cmd = CommandBuilder::new("test")
.subcommand(
CommandBuilder::new("info")
.arg_completion(|_ctx, _prefix| {
Ok(CompletionResult::new()
.add("version")
.add("license")
.add_help_text("This is a help message"))
})
.build(),
)
.build();
unsafe { std::env::set_var("TEST_COMPLETE", "bash") };
let bash_result = cmd
.handle_completion_request(&["__complete".to_string(), "info".to_string(), String::new()])
.unwrap();
assert!(
bash_result
.iter()
.any(|s| s == "_activehelp_ This is a help message")
);
unsafe { std::env::remove_var("TEST_COMPLETE") };
}
#[test]
fn test_active_help_config() {
use flag_rs::active_help::ActiveHelpConfig;
let config = ActiveHelpConfig::default();
assert!(config.is_enabled());
assert!(config.show_on_double_tab);
assert!(config.show_on_no_completions);
unsafe { std::env::set_var("COBRA_ACTIVE_HELP", "0") };
assert!(!config.is_enabled());
unsafe { std::env::set_var("COBRA_ACTIVE_HELP", "false") };
assert!(!config.is_enabled());
unsafe { std::env::set_var("COBRA_ACTIVE_HELP", "1") };
assert!(config.is_enabled());
unsafe { std::env::remove_var("COBRA_ACTIVE_HELP") };
}
#[test]
fn test_no_active_help_without_context() {
use flag_rs::completion_format::CompletionFormat;
let result = CompletionResult::new()
.add("option1")
.add_help_text("This should not appear without context");
let formatted = CompletionFormat::Bash.format(&result, None);
assert!(formatted.contains(&"option1".to_string()));
assert!(!formatted.iter().any(|s| s.contains("_activehelp_")));
}
#[test]
fn test_active_help_in_flag_completion() {
let cmd = CommandBuilder::new("test")
.flag(
flag_rs::Flag::new("environment")
.short('e')
.usage("Target environment")
.value_type(flag_rs::FlagType::String),
)
.flag_completion("environment", |_ctx, prefix| {
let mut result = CompletionResult::new();
let envs = vec![
("development", "Local development environment"),
("staging", "Pre-production environment"),
("production", "Live production environment"),
];
for (env, desc) in envs {
if env.starts_with(prefix) {
result = result.add_with_description(env, desc);
}
}
if prefix.is_empty() {
result = result.add_help_text("Choose an environment to deploy to");
}
if prefix == "prod" {
result = result.add_help_text(
"Warning: Production deployments are permanent and require approval",
);
}
Ok(result)
})
.build();
let args = vec![
"__complete".to_string(),
"--environment".to_string(),
String::new(),
];
let result = cmd.handle_completion_request(&args).unwrap();
assert!(result.iter().any(|s| s.contains("development")));
assert!(
result
.iter()
.any(|s| s.contains("Choose an environment to deploy to"))
);
let args2 = vec![
"__complete".to_string(),
"--environment".to_string(),
"prod".to_string(),
];
let result2 = cmd.handle_completion_request(&args2).unwrap();
assert!(result2.iter().any(|s| s.contains("production")));
assert!(
result2
.iter()
.any(|s| s.contains("Production deployments are permanent"))
);
}
#[test]
fn test_multiple_active_help_messages() {
use flag_rs::completion_format::CompletionFormat;
let result = CompletionResult::new()
.add("option1")
.add_help_text("First help message")
.add_help_text("Second help message")
.add_conditional_help("Third conditional help", |_| true)
.add_conditional_help("Hidden conditional help", |_| false);
let ctx = Context::new(vec![]);
let formatted = CompletionFormat::Bash.format(&result, Some(&ctx));
let help_count = formatted
.iter()
.filter(|s| s.starts_with("_activehelp_"))
.count();
assert_eq!(help_count, 3); }