crush-cli 0.1.0

Command-line interface for the Crush compression library
use assert_cmd::Command;
use std::fs;
use std::io::Write;
use std::time::Duration;
use tempfile::TempDir;

/// Helper to get the crush binary command
#[allow(deprecated)] // cargo_bin is deprecated but still functional
fn crush_cmd() -> Command {
    Command::cargo_bin("crush").expect("Failed to find crush binary")
}

/// T052 [US2] Integration test for "Cancelling..." message timing (<100ms)
///
/// Tests that when Ctrl+C is sent during an operation, the "Cancelling operation..."
/// message appears immediately (within 100ms) to provide user feedback.
///
/// NOTE: This is a manual test case as programmatic SIGINT sending is complex
#[test]
#[ignore] // Manual test - requires user to press Ctrl+C
fn test_cancelling_message_appears_immediately() {
    // This test is documented for manual validation
    // To test manually:
    // 1. Create a large file: `dd if=/dev/zero of=large.bin bs=1M count=100`
    // 2. Run: `crush compress large.bin`
    // 3. Press Ctrl+C during compression
    // 4. Verify "Cancelling operation..." appears immediately in stderr
    // 5. Verify operation exits with code 130 (Unix) or 2 (Windows)
}

/// T053 [US2] Integration test for "Operation cancelled" final message
///
/// Tests that when an operation is interrupted, the final message says
/// "Operation cancelled" (not just "Operation interrupted")
///
/// NOTE: This is tested manually since programmatic cancellation is complex.
/// The message is verified by checking the CliError::Interrupted Display impl.
#[test]
#[ignore] // Manual verification - check error message in crush-cli/src/error.rs
fn test_operation_cancelled_message() {
    // To verify manually:
    // 1. Check crush-cli/src/error.rs
    // 2. Verify CliError::Interrupted displays as "Operation cancelled"
    // 3. Or run a compress operation, press Ctrl+C, and check stderr contains "Operation cancelled"
}

/// T054 [US2] Integration test for "Press Ctrl+C to cancel" hint display
///
/// Tests that the hint functionality is implemented for large file operations.
///
/// NOTE: The hint only appears when stderr is a terminal. In test environments
/// where stderr is captured/piped, the hint is suppressed (correct behavior).
/// The actual hint logic is tested in the feedback module unit tests.
#[test]
fn test_cancel_hint_functionality_exists() -> Result<(), Box<dyn std::error::Error>> {
    // This test verifies that large file operations complete successfully
    // The hint display logic is tested in crush-cli/src/feedback.rs unit tests
    // The hint appears only when:
    // 1. File size > 1MB (tested in feedback::should_show_hint)
    // 2. stderr is a terminal (tested in feedback::show_cancel_hint)

    let dir = TempDir::new()?;
    let input = dir.path().join("large.txt");
    let output = dir.path().join("large.txt.crush");

    // Create a large file
    let mut file = fs::File::create(&input)?;
    let data = vec![b'x'; 2 * 1024 * 1024]; // 2MB
    file.write_all(&data)?;
    drop(file);

    // Verify compression works (hint code doesn't break anything)
    crush_cmd()
        .arg("compress")
        .arg(&input)
        .arg("-o")
        .arg(&output)
        .timeout(Duration::from_secs(30))
        .assert()
        .success();

    // Verify output file was created
    assert!(output.exists(), "Compressed file should exist");

    Ok(())
}

/// Manual test for visual verification of the cancel hint
#[test]
#[ignore] // Manual test - run with a real terminal to see the hint
fn test_cancel_hint_displayed_manual() -> Result<(), Box<dyn std::error::Error>> {
    // To test manually:
    // 1. Create a large file: dd if=/dev/zero of=large.bin bs=1M count=10
    // 2. Run: crush compress large.bin
    // 3. Verify you see "ℹ️  Press Ctrl+C to cancel this operation" message
    // 4. Press Ctrl+C and verify operation cancels gracefully

    Ok(())
}