fn test_convert_add_to_copy_if_local_malformed_no_args() {
let line = "ADD";
let result = convert_add_to_copy_if_local(line);
assert_eq!(
result, line,
"Malformed ADD (no arguments) should be unchanged"
);
}
#[test]
fn test_convert_add_to_copy_if_local_with_extra_spaces() {
let line = "ADD local_file.txt /app/";
let result = convert_add_to_copy_if_local(line);
assert_eq!(
result, "COPY local_file.txt /app/",
"Should convert ADD to COPY while preserving spacing"
);
}
#[test]
fn test_convert_add_to_copy_if_local_non_docker_line() {
let line = "# This is a comment with ADD in it";
let result = convert_add_to_copy_if_local(line);
assert_eq!(result, line, "Comment lines should not be processed");
}
#[test]
fn test_add_no_install_recommends_happy_path_with_y_flag() {
let line = "RUN apt-get install -y curl";
let result = add_no_install_recommends(line);
assert_eq!(
result, "RUN apt-get install -y --no-install-recommends curl",
"Should add --no-install-recommends after -y flag"
);
}
#[test]
fn test_add_no_install_recommends_without_y_flag() {
let line = "RUN apt-get install python3";
let result = add_no_install_recommends(line);
assert_eq!(
result, "RUN apt-get install --no-install-recommends python3",
"Should add --no-install-recommends after install"
);
}
#[test]
fn test_add_no_install_recommends_already_present() {
let line = "RUN apt-get install -y --no-install-recommends git";
let result = add_no_install_recommends(line);
assert_eq!(result, line, "Should not add flag if already present");
}
#[test]
fn test_add_no_install_recommends_multiple_packages() {
let line = "RUN apt-get install -y curl wget git";
let result = add_no_install_recommends(line);
assert_eq!(
result, "RUN apt-get install -y --no-install-recommends curl wget git",
"Should work with multiple packages"
);
}
#[test]
fn test_add_no_install_recommends_multiple_apt_get_commands() {
let line = "RUN apt-get update && apt-get install -y curl && apt-get install -y git";
let result = add_no_install_recommends(line);
assert!(
result.contains("--no-install-recommends"),
"Should add flag to apt-get install commands"
);
let flag_count = result.matches("--no-install-recommends").count();
assert_eq!(
flag_count, 2,
"Should add flag to both apt-get install commands"
);
}
#[test]
fn test_add_no_install_recommends_apt_install_variant() {
let line = "RUN apt install -y vim";
let result = add_no_install_recommends(line);
assert_eq!(result, line, "apt install (not apt-get) not yet supported");
}
#[test]
fn test_add_no_install_recommends_empty_line() {
let line = "";
let result = add_no_install_recommends(line);
assert_eq!(result, line, "Empty line should be unchanged");
}
#[test]
fn test_add_no_install_recommends_no_apt_get() {
let line = "RUN echo hello";
let result = add_no_install_recommends(line);
assert_eq!(result, line, "Non-apt-get commands should be unchanged");
}
#[test]
fn test_add_no_install_recommends_apt_get_update_only() {
let line = "RUN apt-get update";
let result = add_no_install_recommends(line);
assert_eq!(
result, line,
"apt-get update (without install) should be unchanged"
);
}
#[test]
fn test_add_no_install_recommends_with_continuation() {
let line = "RUN apt-get install -y \\\n curl \\\n wget";
let result = add_no_install_recommends(line);
assert!(
result.contains("--no-install-recommends"),
"Should handle multi-line continuations"
);
}
#[test]
fn test_add_no_install_recommends_comment_line() {
let line = "# RUN apt-get install -y curl";
let result = add_no_install_recommends(line);
assert_eq!(result, line, "Comment lines should not be processed");
}
#[test]
fn test_add_no_install_recommends_install_at_end() {
let line = "RUN apt-get install";
let result = add_no_install_recommends(line);
assert_eq!(
result, "RUN apt-get install --no-install-recommends ",
"Should add flag even if no packages listed"
);
}
#[test]
fn test_add_no_install_recommends_preserves_other_flags() {
let line = "RUN apt-get install -y --fix-missing curl";
let result = add_no_install_recommends(line);
assert!(
result.contains("--fix-missing"),
"Should preserve other flags"
);
assert!(
result.contains("--no-install-recommends"),
"Should add --no-install-recommends"
);
}
#[test]
fn test_add_package_manager_cleanup_apt_get_install() {
let line = "RUN apt-get update && apt-get install -y curl";
let result = add_package_manager_cleanup(line);
assert_eq!(
result, "RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*",
"Should add apt cleanup after install"
);
}
#[test]
fn test_add_package_manager_cleanup_apt_install() {
let line = "RUN apt install -y python3";
let result = add_package_manager_cleanup(line);
assert_eq!(
result, "RUN apt install -y python3 && rm -rf /var/lib/apt/lists/*",
"Should add apt cleanup for 'apt install' variant"
);
}
#[test]
fn test_add_package_manager_cleanup_apk_add() {
let line = "RUN apk add curl";
let result = add_package_manager_cleanup(line);
assert_eq!(
result, "RUN apk add curl && rm -rf /var/cache/apk/*",
"Should add apk cleanup for Alpine"
);
}
#[test]
fn test_add_package_manager_cleanup_already_present_apt() {
let line = "RUN apt-get install -y git && rm -rf /var/lib/apt/lists/*";
let result = add_package_manager_cleanup(line);
assert_eq!(result, line, "Should not add cleanup if already present");
}
#[test]
fn test_add_package_manager_cleanup_already_present_apk() {
let line = "RUN apk add vim && rm -rf /var/cache/apk/*";
let result = add_package_manager_cleanup(line);
assert_eq!(
result, line,
"Should not add cleanup if already present (apk)"
);
}
#[test]
fn test_add_package_manager_cleanup_no_package_manager() {
let line = "RUN echo hello";
let result = add_package_manager_cleanup(line);
assert_eq!(
result, line,
"Non-package-manager commands should be unchanged"
);
}
#[test]
fn test_add_package_manager_cleanup_apt_get_update_only() {
let line = "RUN apt-get update";
let result = add_package_manager_cleanup(line);
assert_eq!(result, line, "apt-get update alone should be unchanged");
}
#[test]
fn test_add_package_manager_cleanup_empty_line() {
let line = "";
let result = add_package_manager_cleanup(line);
assert_eq!(result, line, "Empty line should be unchanged");
}
#[test]
fn test_add_package_manager_cleanup_comment_line() {
let line = "# RUN apt-get install curl";
let result = add_package_manager_cleanup(line);
assert_eq!(result, line, "Comment lines should not be processed");
}
#[test]
fn test_add_package_manager_cleanup_with_trailing_whitespace() {
let line = "RUN apt-get install -y wget ";
let result = add_package_manager_cleanup(line);
assert_eq!(
result, "RUN apt-get install -y wget && rm -rf /var/lib/apt/lists/*",
"Should trim trailing whitespace before adding cleanup"
);
}
#[test]
fn test_add_package_manager_cleanup_multiple_commands() {
let line = "RUN apt-get update && apt-get install -y curl && echo done";
let result = add_package_manager_cleanup(line);
assert!(
result.contains("&& rm -rf /var/lib/apt/lists/*"),
"Should add cleanup even with multiple commands"
);
}
#[test]
fn test_add_package_manager_cleanup_apk_add_multiple_packages() {
let line = "RUN apk add --no-cache curl wget git";
let result = add_package_manager_cleanup(line);
assert_eq!(
result, "RUN apk add --no-cache curl wget git && rm -rf /var/cache/apk/*",
"Should add cleanup for apk with multiple packages"
);
}
#[test]
fn test_add_package_manager_cleanup_partial_match_no_install() {
let line = "RUN apt-get clean";
let result = add_package_manager_cleanup(line);
assert_eq!(
result, line,
"apt-get clean (not install) should be unchanged"
);
}
#[test]
fn test_pin_base_image_version_ubuntu_untagged() {
let line = "FROM ubuntu";
let result = pin_base_image_version(line);
assert_eq!(
result, "FROM ubuntu:22.04",
"Untagged ubuntu should be pinned to 22.04 LTS"
);
}
#[test]
fn test_pin_base_image_version_ubuntu_latest() {
let line = "FROM ubuntu:latest";
let result = pin_base_image_version(line);
assert_eq!(
result, "FROM ubuntu:22.04",
"ubuntu:latest should be pinned to 22.04 LTS"
);
}
#[test]
fn test_pin_base_image_version_ubuntu_already_pinned() {
let line = "FROM ubuntu:20.04";
let result = pin_base_image_version(line);
assert_eq!(result, line, "Already pinned ubuntu should be unchanged");
}
#[test]
fn test_pin_base_image_version_debian() {
let line = "FROM debian";
let result = pin_base_image_version(line);
assert_eq!(
result, "FROM debian:12-slim",
"Untagged debian should be pinned to 12-slim"
);
}
#[test]
fn test_pin_base_image_version_alpine() {
let line = "FROM alpine:latest";
let result = pin_base_image_version(line);
assert_eq!(
result, "FROM alpine:3.19",
"alpine:latest should be pinned to 3.19"
);
}
#[test]
fn test_pin_base_image_version_node() {
let line = "FROM node";
let result = pin_base_image_version(line);
assert_eq!(
result, "FROM node:20-alpine",
"Untagged node should be pinned to 20-alpine"
);
}
#[test]
fn test_pin_base_image_version_python() {
let line = "FROM python:latest";
let result = pin_base_image_version(line);
assert_eq!(
result, "FROM python:3.11-slim",
"python:latest should be pinned to 3.11-slim"
);
}
#[test]
fn test_pin_base_image_version_with_registry_prefix() {
let line = "FROM docker.io/ubuntu";
let result = pin_base_image_version(line);
assert_eq!(
result, "FROM docker.io/ubuntu:22.04",
"Should preserve registry prefix (docker.io/)"
);
}
#[test]
fn test_pin_base_image_version_with_as_alias() {
let line = "FROM ubuntu AS builder";
let result = pin_base_image_version(line);
assert_eq!(
result, "FROM ubuntu:22.04 AS builder",
"Should preserve AS alias"
);
}
#[test]
fn test_pin_base_image_version_unknown_image() {
let line = "FROM mycompany/custom-image";
let result = pin_base_image_version(line);
assert_eq!(result, line, "Unknown images should be unchanged");
}
#[test]
fn test_pin_base_image_version_malformed_no_image() {
let line = "FROM";
let result = pin_base_image_version(line);
assert_eq!(
result, line,
"Malformed FROM (no image) should be unchanged"
);
}
#[test]
fn test_pin_base_image_version_empty_line() {
let line = "";
let result = pin_base_image_version(line);
assert_eq!(result, line, "Empty line should be unchanged");
}
#[test]
fn test_pin_base_image_version_rust() {
let line = "FROM rust:latest";
let result = pin_base_image_version(line);
assert_eq!(
result, "FROM rust:1.75-alpine",
"rust:latest should be pinned to 1.75-alpine"
);
}