trimdown 0.1.6

Fast file compression tool for Office documents (PPTX, DOCX, XLSX), PDFs, videos, images, OpenDocument formats, and archives with streaming support
Documentation
use std::fs;
use std::path::PathBuf;
use tempfile::TempDir;
use trimdown::{
    check_output_exists, create_progress_bar, generate_output_path, get_media_files,
    report_compression_stats,
};
use trimdown::{Cli, PdfMethod, PdfQuality};

#[test]
fn test_create_progress_bar() {
    let pb = create_progress_bar(100, "Test message");
    assert_eq!(pb.length(), Some(100));
}

#[test]
fn test_get_media_files() {
    let temp_dir = TempDir::new().unwrap();
    let media_dir = temp_dir.path().join("media");
    fs::create_dir_all(&media_dir).unwrap();

    // Create test files
    fs::File::create(media_dir.join("image.jpg")).unwrap();
    fs::File::create(media_dir.join("video.mp4")).unwrap();
    fs::File::create(media_dir.join("document.txt")).unwrap();

    let (images, videos) = get_media_files(&media_dir);
    assert_eq!(images.len(), 1);
    assert_eq!(videos.len(), 1);
    assert_eq!(
        images[0].file_name().unwrap().to_str().unwrap(),
        "image.jpg"
    );
    assert_eq!(
        videos[0].file_name().unwrap().to_str().unwrap(),
        "video.mp4"
    );
}

#[test]
fn test_generate_output_path() {
    let input = PathBuf::from("/path/to/input.pdf");

    // With no output specified
    let output = generate_output_path(
        &input,
        None,
        &Cli {
            command: None,
            input: Some(PathBuf::from("/path/to/input.pdf")),
            output: None,
            folder: false,
            quality: 85,
            max_width: 1920,
            video_crf: 28,
            video_max_width: 1920,
            pdf_quality: PdfQuality::Ebook,
            pdf_method: PdfMethod::Auto,
            force: false,
            verbose: false,
            dry_run: false,
            preset: None,
            parallel: false,
        preserve_metadata: false,
        streaming: false,
        memory_limit: None,
        },
    );
    assert_eq!(
        output.file_name().unwrap().to_str().unwrap(),
        "input_compressed.pdf"
    );

    // With output specified
    let specified = PathBuf::from("/path/to/output.pdf");
    let output = generate_output_path(
        &input,
        Some(&specified),
        &Cli {
            command: None,
            input: Some(PathBuf::from("/path/to/input.pdf")),
            output: None,
            folder: false,
            quality: 85,
            max_width: 1920,
            video_crf: 28,
            video_max_width: 1920,
            pdf_quality: PdfQuality::Ebook,
            pdf_method: PdfMethod::Auto,
            force: false,
            verbose: false,
            dry_run: false,
            preset: None,
            parallel: false,
        preserve_metadata: false,
        streaming: false,
        memory_limit: None,
        },
    );
    assert_eq!(output, specified);
}

#[test]
fn test_check_output_exists() {
    let temp_dir = TempDir::new().unwrap();
    let existing_path = temp_dir.path().join("exists.pdf");
    fs::File::create(&existing_path).unwrap();

    let non_existing_path = temp_dir.path().join("not_exists.pdf");

    let cli = Cli {
        command: None,
        input: Some(PathBuf::from("/dummy/input.pdf")),
        output: None,
        folder: false,
        quality: 85,
        max_width: 1920,
        video_crf: 28,
        video_max_width: 1920,
        pdf_quality: PdfQuality::Ebook,
        pdf_method: PdfMethod::Auto,
        force: false,
        verbose: false,
        dry_run: false,
        preset: None,
        parallel: false,
    preserve_metadata: false,
    streaming: false,
    memory_limit: None,
    };

    // Existing file with force=false should error
    assert!(check_output_exists(&existing_path, &cli).is_err());

    // Existing file with force=true should pass
    let cli_with_force = Cli {
        command: cli.command.clone(),
        input: cli.input.clone(),
        output: cli.output.clone(),
        folder: cli.folder,
        quality: cli.quality,
        max_width: cli.max_width,
        video_crf: cli.video_crf,
        video_max_width: cli.video_max_width,
        pdf_quality: cli.pdf_quality.clone(),
        pdf_method: cli.pdf_method.clone(),
        force: true,
        verbose: cli.verbose,
        dry_run: cli.dry_run,
        preset: cli.preset.clone(),
        parallel: cli.parallel,
        preserve_metadata: cli.preserve_metadata,
        streaming: cli.streaming,
        memory_limit: cli.memory_limit,
    };
    assert!(check_output_exists(&existing_path, &cli_with_force).is_ok());

    // Non-existing file should pass
    assert!(check_output_exists(&non_existing_path, &cli).is_ok());

    // Dry run should pass even with existing file
    let cli_dry_run = Cli {
        command: None,
        input: cli.input.clone(),
        output: cli.output.clone(),
        folder: cli.folder,
        quality: cli.quality,
        max_width: cli.max_width,
        video_crf: cli.video_crf,
        video_max_width: cli.video_max_width,
        pdf_quality: cli.pdf_quality.clone(),
        pdf_method: cli.pdf_method.clone(),
        force: cli.force,
        verbose: cli.verbose,
        dry_run: true,
        preset: cli.preset.clone(),
        parallel: cli.parallel,
        preserve_metadata: cli.preserve_metadata,
        streaming: cli.streaming,
        memory_limit: cli.memory_limit,
    };
    assert!(check_output_exists(&existing_path, &cli_dry_run).is_ok());
}

#[test]
fn test_report_compression_stats() {
    let temp_dir = TempDir::new().unwrap();
    let input_path = temp_dir.path().join("input.pdf");
    let output_path = temp_dir.path().join("output.pdf");

    // Create test files with known sizes
    fs::write(&input_path, vec![0u8; 1000]).unwrap();
    fs::write(&output_path, vec![0u8; 500]).unwrap();

    let result = report_compression_stats(&input_path, &output_path, "Test");
    assert!(result.is_ok());

    let (original, compressed, ratio) = result.unwrap();
    assert_eq!(original, 1000);
    assert_eq!(compressed, 500);
    assert_eq!(ratio, 50.0);
}