use docker_wrapper::{ensure_docker, DockerCommand, SearchCommand};
async fn setup_docker() -> Result<(), Box<dyn std::error::Error>> {
ensure_docker().await?;
Ok(())
}
#[tokio::test]
async fn test_search_command_validation() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("alpine");
assert_eq!(search.get_term(), "alpine");
assert_eq!(search.get_limit(), None);
assert!(search.get_filters().is_empty());
assert!(!search.is_no_trunc());
let args = search.build_command_args();
assert!(args.contains(&"search".to_string()));
assert!(args.contains(&"alpine".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_command_with_limit() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("redis").limit(5);
assert_eq!(search.get_limit(), Some(5));
let args = search.build_command_args();
assert!(args.contains(&"--limit".to_string()));
assert!(args.contains(&"5".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_command_with_filters() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("nginx")
.filter("stars=100")
.filter("is-official=true");
assert_eq!(search.get_filters(), &["stars=100", "is-official=true"]);
let args = search.build_command_args();
assert!(args.contains(&"--filter".to_string()));
assert!(args.contains(&"stars=100".to_string()));
assert!(args.contains(&"is-official=true".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_command_with_format() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("ubuntu").format_json();
assert_eq!(search.get_format(), Some("json"));
let args = search.build_command_args();
assert!(args.contains(&"--format".to_string()));
assert!(args.contains(&"json".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_command_no_trunc() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("postgres").no_trunc();
assert!(search.is_no_trunc());
let args = search.build_command_args();
assert!(args.contains(&"--no-trunc".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_command_all_options() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("mysql")
.limit(3)
.filter("stars=50")
.filter("is-official=true")
.no_trunc()
.format("table");
let args = search.build_command_args();
assert!(args.contains(&"--limit".to_string()));
assert!(args.contains(&"3".to_string()));
assert!(args.contains(&"--filter".to_string()));
assert!(args.contains(&"stars=50".to_string()));
assert!(args.contains(&"is-official=true".to_string()));
assert!(args.contains(&"--no-trunc".to_string()));
assert!(args.contains(&"--format".to_string()));
assert!(args.contains(&"table".to_string()));
assert!(args.contains(&"mysql".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_command_builder_pattern() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("golang")
.limit(10)
.filter("is-official=true")
.format_json();
assert_eq!(search.get_term(), "golang");
assert_eq!(search.get_limit(), Some(10));
assert!(search
.get_filters()
.contains(&"is-official=true".to_string()));
assert_eq!(search.get_format(), Some("json"));
Ok(())
}
#[tokio::test]
async fn test_search_command_display() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("node")
.limit(5)
.filter("stars=25")
.no_trunc()
.format("json");
let display = format!("{search}");
assert!(display.contains("docker search"));
assert!(display.contains("--limit 5"));
assert!(display.contains("--filter stars=25"));
assert!(display.contains("--no-trunc"));
assert!(display.contains("--format json"));
assert!(display.contains("node"));
Ok(())
}
#[tokio::test]
async fn test_search_command_extensibility() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let mut search = SearchCommand::new("python");
search
.arg("--verbose")
.args(vec!["--debug"])
.flag("--no-trunc")
.option("--limit", "3")
.option("--format", "json")
.option("--filter", "stars=20");
let args = search.build_command_args();
assert_eq!(args[0], "search");
assert_eq!(search.get_term(), "python");
assert!(args.contains(&"--no-trunc".to_string()));
assert!(args.contains(&"--limit".to_string()));
assert!(args.contains(&"3".to_string()));
assert!(args.contains(&"--format".to_string()));
assert!(args.contains(&"json".to_string()));
assert!(args.contains(&"--filter".to_string()));
assert!(args.contains(&"stars=20".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_prerequisites_validation() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("test");
let args = search.build_command_args();
assert_eq!(args[0], "search");
Ok(())
}
#[tokio::test]
async fn test_search_various_terms() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let test_cases = vec![
("redis", "Popular database"),
("nginx", "Web server"),
("ubuntu", "Operating system"),
("alpine", "Minimal Linux"),
("mysql", "Database server"),
];
for (term, _description) in test_cases {
let search = SearchCommand::new(term);
assert_eq!(search.get_term(), term);
let args = search.build_command_args();
assert!(args.contains(&term.to_string()));
}
Ok(())
}
#[tokio::test]
async fn test_search_filter_combinations() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("java").filters(vec![
"stars=10",
"is-official=true",
"is-automated=false",
]);
assert_eq!(search.get_filters().len(), 3);
assert!(search.get_filters().contains(&"stars=10".to_string()));
assert!(search
.get_filters()
.contains(&"is-official=true".to_string()));
assert!(search
.get_filters()
.contains(&"is-automated=false".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_format_options() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let formats = vec!["table", "json", "{{.Name}}: {{.Description}}"];
for format in formats {
let search = SearchCommand::new("test").format(format);
assert_eq!(search.get_format(), Some(format));
let args = search.build_command_args();
assert!(args.contains(&format.to_string()));
}
Ok(())
}
#[tokio::test]
async fn test_search_limit_variations() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let limits = vec![1, 5, 10, 25, 100];
for limit in limits {
let search = SearchCommand::new("test").limit(limit);
assert_eq!(search.get_limit(), Some(limit));
let args = search.build_command_args();
assert!(args.contains(&limit.to_string()));
}
Ok(())
}
#[tokio::test]
async fn test_search_command_name() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("test");
let args = search.build_command_args();
assert_eq!(args[0], "search");
Ok(())
}
#[tokio::test]
async fn test_search_default_construction() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::default();
assert_eq!(search.get_term(), "");
assert_eq!(search.get_limit(), None);
assert!(search.get_filters().is_empty());
assert_eq!(search.get_format(), None);
assert!(!search.is_no_trunc());
Ok(())
}
#[tokio::test]
async fn test_search_argument_order() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search = SearchCommand::new("test")
.limit(5)
.filter("stars=10")
.format("json")
.no_trunc();
let args = search.build_command_args();
let search_pos = args.iter().position(|s| s == "search").unwrap();
let term_pos = args.iter().position(|s| s == "test").unwrap();
assert!(search_pos < term_pos);
assert_eq!(args.last(), Some(&"test".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_edge_cases() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search_empty = SearchCommand::new("");
assert_eq!(search_empty.get_term(), "");
let search_specific = SearchCommand::new("redis:alpine");
assert_eq!(search_specific.get_term(), "redis:alpine");
let search_complex = SearchCommand::new("nginx").filter("stars=100");
assert!(search_complex
.get_filters()
.contains(&"stars=100".to_string()));
Ok(())
}
#[tokio::test]
async fn test_search_multiple_filters() -> Result<(), Box<dyn std::error::Error>> {
setup_docker().await?;
let search1 = SearchCommand::new("test")
.filter("stars=5")
.filter("is-official=true");
let search2 = SearchCommand::new("test").filters(vec!["stars=5", "is-official=true"]);
assert_eq!(search1.get_filters(), search2.get_filters());
assert_eq!(search1.get_filters().len(), 2);
Ok(())
}