use super::*;
#[test]
fn test_convert_add_to_copy_local_file() {
assert_eq!(
convert_add_to_copy_if_local("ADD file.txt /app/"),
"COPY file.txt /app/"
);
}
#[test]
fn test_convert_add_to_copy_preserves_url() {
let line = "ADD https://example.com/file.tar.gz /app/";
assert_eq!(convert_add_to_copy_if_local(line), line);
}
#[test]
fn test_convert_add_to_copy_preserves_tarball() {
let line = "ADD archive.tar.gz /app/";
assert_eq!(convert_add_to_copy_if_local(line), line);
let line2 = "ADD data.tgz /app/";
assert_eq!(convert_add_to_copy_if_local(line2), line2);
}
#[test]
fn test_convert_add_to_copy_preserves_comment() {
let line = "# ADD file.txt /app/";
assert_eq!(convert_add_to_copy_if_local(line), line);
}
#[test]
fn test_convert_add_to_copy_non_add_line() {
let line = "COPY file.txt /app/";
assert_eq!(convert_add_to_copy_if_local(line), line);
}
#[test]
fn test_add_no_install_recommends() {
assert_eq!(
add_no_install_recommends("RUN apt-get install -y curl"),
"RUN apt-get install -y --no-install-recommends curl"
);
}
#[test]
fn test_add_no_install_recommends_already_present() {
let line = "RUN apt-get install -y --no-install-recommends curl";
assert_eq!(add_no_install_recommends(line), line);
}
#[test]
fn test_add_no_install_recommends_without_y() {
assert_eq!(
add_no_install_recommends("RUN apt-get install curl"),
"RUN apt-get install --no-install-recommends curl"
);
}
#[test]
fn test_add_no_install_recommends_comment() {
let line = "# apt-get install curl";
assert_eq!(add_no_install_recommends(line), line);
}
#[test]
fn test_add_no_install_recommends_non_apt() {
let line = "RUN yum install curl";
assert_eq!(add_no_install_recommends(line), line);
}
#[test]
fn test_add_package_manager_cleanup_apt() {
assert_eq!(
add_package_manager_cleanup("RUN apt-get install -y curl"),
"RUN apt-get install -y curl && rm -rf /var/lib/apt/lists/*"
);
}
#[test]
fn test_add_package_manager_cleanup_apk() {
assert_eq!(
add_package_manager_cleanup("RUN apk add curl"),
"RUN apk add curl && rm -rf /var/cache/apk/*"
);
}
#[test]
fn test_add_package_manager_cleanup_already_present() {
let line = "RUN apt-get install curl && rm -rf /var/lib/apt/lists/*";
assert_eq!(add_package_manager_cleanup(line), line);
}
#[test]
fn test_add_package_manager_cleanup_comment() {
let line = "# apt-get install curl";
assert_eq!(add_package_manager_cleanup(line), line);
}
#[test]
fn test_add_package_manager_cleanup_other_command() {
let line = "RUN echo hello";
assert_eq!(add_package_manager_cleanup(line), line);
}
#[test]
fn test_pin_base_image_ubuntu() {
assert_eq!(pin_base_image_version("FROM ubuntu"), "FROM ubuntu:22.04");
}
#[test]
fn test_pin_base_image_latest() {
assert_eq!(
pin_base_image_version("FROM alpine:latest"),
"FROM alpine:3.19"
);
}
#[test]
fn test_pin_base_image_already_pinned() {
let line = "FROM python:3.9";
assert_eq!(pin_base_image_version(line), line);
}
#[test]
fn test_pin_base_image_with_as() {
assert_eq!(
pin_base_image_version("FROM node AS builder"),
"FROM node:20-alpine AS builder"
);
}
#[test]
fn test_pin_base_image_with_registry() {
assert_eq!(
pin_base_image_version("FROM docker.io/ubuntu"),
"FROM docker.io/ubuntu:22.04"
);
}
#[test]
fn test_pin_base_image_unknown() {
let line = "FROM mycompany/myimage";
assert_eq!(pin_base_image_version(line), line);
}
#[test]
fn test_pin_base_image_non_from_line() {
let line = "RUN echo hello";
assert_eq!(pin_base_image_version(line), line);
}
#[test]
fn test_parse_size_limit_gb() {
assert_eq!(parse_size_limit("2GB"), Some(2_000_000_000));
assert_eq!(parse_size_limit("1.5gb"), Some(1_500_000_000));
}
#[test]
fn test_parse_size_limit_mb() {
assert_eq!(parse_size_limit("500MB"), Some(500_000_000));
assert_eq!(parse_size_limit("100mb"), Some(100_000_000));
}
#[test]
fn test_parse_size_limit_kb() {
assert_eq!(parse_size_limit("1000KB"), Some(1_000_000));
}
#[test]
fn test_parse_size_limit_invalid() {
assert_eq!(parse_size_limit("invalid"), None);
assert_eq!(parse_size_limit(""), None);
}
#[test]
fn test_estimate_build_time_basic() {
let seconds = estimate_build_time_seconds(5, 0, false, false, false);
assert_eq!(seconds, 5); }
#[test]
fn test_estimate_build_time_with_size() {
let seconds = estimate_build_time_seconds(2, 500_000_000, false, false, false);
assert_eq!(seconds, 2 + 5); }
#[test]
fn test_estimate_build_time_with_package_managers() {
let seconds = estimate_build_time_seconds(1, 0, true, true, true);
assert_eq!(seconds, 1 + 10 + 5 + 5); }
#[test]
fn test_format_build_time_seconds() {
assert_eq!(format_build_time(30), "~30s");
assert_eq!(format_build_time(59), "~59s");
}
#[test]
fn test_format_build_time_minutes() {
assert_eq!(format_build_time(60), "~1m 0s");
assert_eq!(format_build_time(90), "~1m 30s");
assert_eq!(format_build_time(125), "~2m 5s");
}
#[test]
fn test_find_devcontainer_json_not_found() {
let result = find_devcontainer_json(Path::new("/nonexistent/path"));
assert!(result.is_err());
let err = result.unwrap_err();
assert!(err.to_string().contains("No devcontainer.json found"));
}
#[test]
fn test_purify_dockerfile_source_basic() {
let source = "FROM ubuntu\nRUN apt-get install -y curl\nCMD [\"bash\"]";
let purified = purify_dockerfile_source(source, false);
assert!(purified.contains("ubuntu:22.04"));
assert!(purified.contains("--no-install-recommends"));
assert!(purified.contains("rm -rf /var/lib/apt/lists"));
assert!(purified.contains("USER appuser"));
}
#[test]
fn test_purify_dockerfile_source_skip_user() {
let source = "FROM ubuntu\nCMD [\"bash\"]";
let purified = purify_dockerfile_source(source, true);
assert!(!purified.contains("USER appuser"));
}
#[test]
fn test_purify_dockerfile_source_existing_user() {
let source = "FROM ubuntu\nUSER myuser\nCMD [\"bash\"]";
let purified = purify_dockerfile_source(source, false);
assert!(!purified.contains("USER appuser"));
assert!(purified.contains("USER myuser"));
}
#[test]
fn test_purify_dockerfile_source_scratch() {
let source = "FROM scratch\nCOPY binary /\nCMD [\"/binary\"]";
let purified = purify_dockerfile_source(source, false);
assert!(!purified.contains("USER appuser"));
}
#[test]
fn test_dockerfile_has_user_directive() {
assert!(dockerfile_has_user_directive(
"FROM ubuntu\nUSER root\nCMD bash"
));
assert!(!dockerfile_has_user_directive("FROM ubuntu\nCMD bash"));
assert!(dockerfile_has_user_directive("USER nobody"));
}
#[test]
fn test_dockerfile_is_scratch() {
assert!(dockerfile_is_scratch("FROM scratch\nCOPY app /"));
assert!(!dockerfile_is_scratch("FROM ubuntu\nCOPY app /"));
assert!(dockerfile_is_scratch(" FROM scratch "));
}
#[test]
fn test_dockerfile_find_cmd_line() {
assert_eq!(
dockerfile_find_cmd_line("FROM ubuntu\nRUN apt update\nCMD bash"),
Some(2)
);
assert_eq!(
dockerfile_find_cmd_line("FROM ubuntu\nENTRYPOINT [\"app\"]"),
Some(1)
);
assert_eq!(
dockerfile_find_cmd_line("FROM ubuntu\nRUN apt update"),
None
);
}
#[test]
fn test_estimate_build_time_small() {
let time = estimate_build_time_seconds(10, 100_000_000, false, false, false);
assert!(time >= 10); }
#[test]
fn test_estimate_build_time_large() {
let time = estimate_build_time_seconds(20, 1_000_000_000, true, true, true);
assert!(time > 30); }
#[test]
fn test_estimate_build_time_with_apt() {
let no_apt = estimate_build_time_seconds(10, 100_000_000, false, false, false);
let with_apt = estimate_build_time_seconds(10, 100_000_000, true, false, false);
assert!(with_apt > no_apt);
}
#[test]
fn test_estimate_build_time_with_pip() {
let no_pip = estimate_build_time_seconds(10, 100_000_000, false, false, false);
let with_pip = estimate_build_time_seconds(10, 100_000_000, false, true, false);
assert!(with_pip > no_pip);
}
#[test]
fn test_estimate_build_time_with_npm() {
let no_npm = estimate_build_time_seconds(10, 100_000_000, false, false, false);
let with_npm = estimate_build_time_seconds(10, 100_000_000, false, false, true);
assert!(with_npm > no_npm);
}
#[test]
fn test_parse_size_string_gb() {
assert_eq!(parse_size_string("1GB"), Some(1_000_000_000));
assert_eq!(parse_size_string("2.5GB"), Some(2_500_000_000));
assert_eq!(parse_size_string("10GB"), Some(10_000_000_000));
}
#[test]
fn test_parse_size_string_mb() {
assert_eq!(parse_size_string("100MB"), Some(100_000_000));
assert_eq!(parse_size_string("500MB"), Some(500_000_000));
assert_eq!(parse_size_string("1.5MB"), Some(1_500_000));
}
#[test]
fn test_parse_size_string_kb() {
assert_eq!(parse_size_string("1KB"), Some(1_000));
assert_eq!(parse_size_string("500KB"), Some(500_000));
}
#[test]
fn test_parse_size_string_bytes() {
assert_eq!(parse_size_string("1000B"), Some(1000));
assert_eq!(parse_size_string("1000"), Some(1000));
}
#[test]
fn test_parse_size_string_case_insensitive() {
assert_eq!(parse_size_string("1gb"), Some(1_000_000_000));
assert_eq!(parse_size_string("1Gb"), Some(1_000_000_000));
assert_eq!(parse_size_string("1mb"), Some(1_000_000));
}
#[test]
fn test_parse_size_string_with_spaces() {
assert_eq!(parse_size_string(" 1GB "), Some(1_000_000_000));
assert_eq!(parse_size_string("500 MB"), Some(500_000_000));
}
#[test]
fn test_parse_size_string_invalid() {
assert_eq!(parse_size_string("invalid"), None);
assert_eq!(parse_size_string(""), None);
assert_eq!(parse_size_string("GB"), None);
}
#[test]
fn test_format_build_time_estimate_seconds() {
let result = format_build_time_estimate(5, 100_000_000, false, false, false);
assert!(result.starts_with("~"));
assert!(result.contains('s'));
}
#[test]
fn test_format_build_time_estimate_minutes() {
let result = format_build_time_estimate(50, 5_000_000_000, true, true, true);
assert!(result.contains('m'));
}
#[test]
fn test_size_exceeds_limit() {
assert!(size_exceeds_limit(2_000_000_000, 1_000_000_000));
assert!(!size_exceeds_limit(500_000_000, 1_000_000_000));
assert!(!size_exceeds_limit(1_000_000_000, 1_000_000_000));
}
#[test]
fn test_size_percentage_of_limit() {
assert_eq!(size_percentage_of_limit(500_000_000, 1_000_000_000), 50.0);
assert_eq!(
size_percentage_of_limit(1_000_000_000, 1_000_000_000),
100.0
);
assert_eq!(size_percentage_of_limit(250_000_000, 1_000_000_000), 25.0);
}
#[test]
fn test_size_percentage_of_limit_zero() {
assert_eq!(size_percentage_of_limit(100, 0), 100.0);
}
#[test]
fn test_layer_has_slow_operation_apt() {
let (apt, pip, npm) = layer_has_slow_operation("RUN apt-get install -y curl");
assert!(apt);
assert!(!pip);
assert!(!npm);
}
#[test]
fn test_layer_has_slow_operation_pip() {
let (apt, pip, npm) = layer_has_slow_operation("RUN pip install requests");
assert!(!apt);
assert!(pip);
assert!(!npm);
}
#[test]
fn test_layer_has_slow_operation_npm() {
let (apt, pip, npm) = layer_has_slow_operation("RUN npm install express");
assert!(!apt);
assert!(!pip);
assert!(npm);
}
#[test]
fn test_layer_has_slow_operation_yarn() {
let (apt, pip, npm) = layer_has_slow_operation("RUN yarn install");
assert!(!apt);
assert!(!pip);
assert!(npm); }
#[test]
fn test_layer_has_slow_operation_none() {
let (apt, pip, npm) = layer_has_slow_operation("RUN echo hello");
assert!(!apt);
assert!(!pip);
assert!(!npm);
}
#[test]
fn test_layer_has_slow_operation_multiple() {
let (apt, pip, npm) =
layer_has_slow_operation("RUN apt-get install && pip install && npm install");
assert!(apt);
assert!(pip);
assert!(npm);
}
#[test]
fn test_format_size_comparison_within_limit() {
let result = format_size_comparison(500_000_000, 1_000_000_000);
assert!(result.contains("✓"));
assert!(result.contains("Within limit"));
assert!(result.contains("50%"));
}
#[test]
fn test_format_size_comparison_exceeds() {
let result = format_size_comparison(2_000_000_000, 1_000_000_000);
assert!(result.contains("✗"));
assert!(result.contains("EXCEEDS"));
}