use docker_wrapper::prerequisites::ensure_docker;
use docker_wrapper::{DockerCommand, ImagesCommand};
async fn ensure_docker_or_skip() {
match ensure_docker().await {
Ok(_) => {}
Err(_) => {
println!("Docker not available - skipping images integration test");
}
}
}
#[tokio::test]
async fn test_images_prerequisites_validation() {
match ensure_docker().await {
Ok(info) => {
println!("Images: Prerequisites OK - Docker {}", info.version.version);
assert!(!info.version.version.is_empty());
}
Err(e) => {
println!("Images: Prerequisites failed (expected in some CI): {e}");
}
}
}
#[tokio::test]
async fn test_images_command_builder() {
let images_cmd = ImagesCommand::new()
.repository("nginx")
.all()
.digests()
.filter("dangling=false")
.format_json()
.no_trunc()
.quiet();
let args = images_cmd.build_command_args();
assert!(args.contains(&"--all".to_string()));
assert!(args.contains(&"--digests".to_string()));
assert!(args.contains(&"--filter".to_string()));
assert!(args.contains(&"dangling=false".to_string()));
assert!(args.contains(&"--format".to_string()));
assert!(args.contains(&"json".to_string()));
assert!(args.contains(&"--no-trunc".to_string()));
assert!(args.contains(&"--quiet".to_string()));
assert!(args.contains(&"nginx".to_string()));
assert_eq!(args.last(), Some(&"nginx".to_string()));
assert_eq!(images_cmd.get_repository(), Some("nginx"));
assert!(images_cmd.is_all());
assert!(images_cmd.is_digests());
assert!(images_cmd.is_no_trunc());
assert!(images_cmd.is_quiet());
assert_eq!(images_cmd.get_format(), Some("json"));
assert_eq!(images_cmd.get_filters(), &["dangling=false"]);
println!("Images: Command builder validation passed");
}
#[tokio::test]
async fn test_images_list_all() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: List all test passed");
assert!(output.success());
println!("Found {} images", output.image_count());
if !output.is_empty() {
let image_ids = output.image_ids();
assert!(!image_ids.is_empty());
for id in image_ids {
assert!(!id.is_empty());
}
}
}
Err(e) => {
println!("Images: List all test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_quiet_mode() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new().quiet();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: Quiet mode test passed");
assert!(output.success());
if !output.is_empty() {
let image_ids = output.image_ids();
assert!(!image_ids.is_empty());
for image in &output.images {
assert_eq!(image.repository, "<unknown>");
assert_eq!(image.tag, "<unknown>");
assert!(!image.image_id.is_empty());
}
}
}
Err(e) => {
println!("Images: Quiet mode test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_with_all_flag() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new().all();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: All flag test passed");
assert!(output.success());
println!(
"Found {} images (including intermediate)",
output.image_count()
);
}
Err(e) => {
println!("Images: All flag test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_with_digests() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new().digests();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: Digests test passed");
assert!(output.success());
if !output.is_empty() {
println!("Found {} images with digest info", output.image_count());
}
}
Err(e) => {
println!("Images: Digests test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_with_filters() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new()
.filter("dangling=false")
.filter("reference=*nginx*");
match images_cmd.execute().await {
Ok(output) => {
println!("Images: Filters test passed");
assert!(output.success());
println!("Found {} filtered images", output.image_count());
}
Err(e) => {
println!("Images: Filters test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_dangling_filter() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new().filter("dangling=true");
match images_cmd.execute().await {
Ok(output) => {
println!("Images: Dangling filter test passed");
assert!(output.success());
println!("Found {} dangling images", output.image_count());
}
Err(e) => {
println!("Images: Dangling filter test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_json_format() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new().format_json();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: JSON format test passed");
assert!(output.success());
if !output.is_empty() {
assert!(!output.images.is_empty());
for image in &output.images {
assert_ne!(image.repository, "<unknown>");
assert!(!image.image_id.is_empty());
}
}
}
Err(e) => {
println!("Images: JSON format test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_with_repository_filter() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new().repository("alpine");
match images_cmd.execute().await {
Ok(output) => {
println!("Images: Repository filter test passed");
assert!(output.success());
if !output.is_empty() {
for image in &output.images {
assert!(image.repository.contains("alpine") || image.repository == "<none>");
}
}
println!("Found {} alpine images", output.image_count());
}
Err(e) => {
println!("Images: Repository filter test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_no_trunc() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new().no_trunc();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: No-trunc test passed");
assert!(output.success());
if !output.is_empty() {
for image in &output.images {
if image.image_id.starts_with("sha256:") {
assert!(image.image_id.len() > 20);
}
}
}
}
Err(e) => {
println!("Images: No-trunc test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_tree_mode() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new().tree();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: Tree mode test passed");
assert!(output.success());
println!("Tree mode executed successfully");
}
Err(e) => {
println!("Images: Tree mode test failed (may be expected - experimental feature): {e}");
}
}
}
#[tokio::test]
async fn test_images_multiple_filters() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new()
.filters(vec!["dangling=false", "reference=*"])
.quiet();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: Multiple filters test passed");
assert!(output.success());
println!(
"Found {} images with multiple filters",
output.image_count()
);
}
Err(e) => {
println!("Images: Multiple filters test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_output_analysis() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new().format_json();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: Output analysis test passed");
assert!(output.success());
if !output.is_empty() {
let image_ids = output.image_ids();
assert_eq!(image_ids.len(), output.image_count());
if let Some(first_image) = output.images.first() {
let filtered = output.filter_by_repository(&first_image.repository);
assert!(!filtered.is_empty());
}
println!(
"Output analysis completed for {} images",
output.image_count()
);
} else {
println!("No images found for analysis");
}
}
Err(e) => {
println!("Images: Output analysis test failed (may be expected): {e}");
}
}
}
#[tokio::test]
async fn test_images_extensibility() {
let mut images_cmd = ImagesCommand::new();
images_cmd
.arg("--experimental-feature")
.arg("value")
.args(vec!["--custom", "option"]);
println!("Images: Extensibility test passed");
}
#[tokio::test]
async fn test_images_format_variations() {
ensure_docker_or_skip().await;
let test_cases = vec![
("table", ImagesCommand::new().format_table()),
("json", ImagesCommand::new().format_json()),
(
"custom",
ImagesCommand::new().format("{{.Repository}}:{{.Tag}}"),
),
];
for (format_name, images_cmd) in test_cases {
match images_cmd.execute().await {
Ok(output) => {
println!("Images: {format_name} format test passed");
assert!(output.success());
}
Err(e) => {
println!("Images: {format_name} format test failed (may be expected): {e}");
}
}
}
}
#[tokio::test]
async fn test_images_command_validation() {
let test_cases = vec![
(ImagesCommand::new(), 0), (ImagesCommand::new().all(), 1), (ImagesCommand::new().quiet().no_trunc(), 2), (ImagesCommand::new().repository("nginx").digests(), 2), ];
for (images_cmd, min_args) in test_cases {
let args = images_cmd.build_command_args();
assert!(args.len() >= min_args);
if let Some(repo) = images_cmd.get_repository() {
assert_eq!(args.last(), Some(&repo.to_string()));
}
}
println!("Images: Command validation test passed");
}
#[tokio::test]
async fn test_images_empty_result_handling() {
ensure_docker_or_skip().await;
let images_cmd = ImagesCommand::new()
.repository("nonexistent-image-that-should-not-exist")
.quiet();
match images_cmd.execute().await {
Ok(output) => {
println!("Images: Empty result test passed");
assert!(output.success());
if output.is_empty() {
assert_eq!(output.image_count(), 0);
assert!(output.image_ids().is_empty());
println!("Correctly handled empty image list");
}
}
Err(e) => {
println!("Images: Empty result test failed (may be expected): {e}");
}
}
}