bare-script 0.1.1

The type-safe scripting authority for Rust. A framework for building robust shell commands and automation with 'Parse, don't validate' philosophy.
Documentation
//! Integration tests for bare-script.

#![allow(unused_imports)]

use bare_script::sync::CommandBuilder;
use thiserror::Error as _;
use tokio as _;

/// Test basic command execution.
#[test]
fn test_basic_execute() {
    #[cfg(windows)]
    let output = {
        CommandBuilder::new("cmd")
            .args(["/C", "echo hello"])
            .capture_output()
            .execute()
    };

    #[cfg(not(windows))]
    let output = {
        CommandBuilder::new("echo")
            .arg("hello")
            .capture_output()
            .execute()
    };

    assert!(output.is_ok());
    let output = output.unwrap();
    assert!(output.success());
}

/// Test argument passing.
#[test]
fn test_args() {
    #[cfg(windows)]
    let output = {
        CommandBuilder::new("cmd")
            .args(["/C", "echo hello world"])
            .capture_output()
            .execute()
    };

    #[cfg(not(windows))]
    let output = {
        CommandBuilder::new("echo")
            .arg("hello")
            .arg("world")
            .capture_output()
            .execute()
    };

    assert!(output.is_ok());
    let output = output.unwrap();
    assert!(output.stdout_str().contains("hello"));
}

/// Test environment variables.
#[test]
fn test_env() {
    #[cfg(windows)]
    let output = {
        CommandBuilder::new("cmd")
            .args(["/C", "echo %TEST_VAR%"])
            .env("TEST_VAR", "test_value")
            .capture_output()
            .execute()
    };

    #[cfg(not(windows))]
    let output = {
        CommandBuilder::new("sh")
            .args(["-c", "echo $TEST_VAR"])
            .env("TEST_VAR", "test_value")
            .capture_output()
            .execute()
    };

    assert!(output.is_ok());
    let output = output.unwrap();
    assert!(output.stdout_str().contains("test_value"));
}

/// Test working directory.
#[test]
fn test_current_dir() {
    use std::env;

    let current_dir = env::current_dir().expect("Failed to get current dir");

    #[cfg(windows)]
    let output = {
        CommandBuilder::new("cmd")
            .args(["/C", "cd"])
            .current_dir(&current_dir)
            .capture_output()
            .execute()
    };

    #[cfg(not(windows))]
    let output = {
        CommandBuilder::new("pwd")
            .current_dir(&current_dir)
            .capture_output()
            .execute()
    };

    assert!(output.is_ok());
}

/// Test timeout functionality.
#[test]
fn test_timeout() {
    use std::time::Duration;

    #[cfg(windows)]
    let result = {
        CommandBuilder::new("cmd")
            .args(["/C", "ping -n 10 127.0.0.1"])
            .capture_output()
            .execute_with_timeout(Duration::from_millis(100))
    };

    #[cfg(not(windows))]
    let result = {
        CommandBuilder::new("sleep")
            .arg("10")
            .capture_output()
            .execute_with_timeout(Duration::from_millis(100))
    };

    // Should timeout
    assert!(result.is_err());
    let err = result.unwrap_err();
    assert!(matches!(err, bare_script::ScriptError::Timeout(_)));
}

/// Test exit code handling.
#[test]
fn test_exit_code() {
    #[cfg(windows)]
    let output = {
        CommandBuilder::new("cmd")
            .args(["/C", "exit 42"])
            .capture_output()
            .execute()
    };

    #[cfg(not(windows))]
    let output = {
        CommandBuilder::new("sh")
            .args(["-c", "exit 42"])
            .capture_output()
            .execute()
    };

    assert!(output.is_ok());
    let output = output.unwrap();
    assert!(!output.success());
    assert_eq!(output.code(), Some(42));
}

/// Test pipeline functionality.
#[test]
fn test_pipeline() {
    use bare_script::sync::Pipeline;

    #[cfg(windows)]
    let output = {
        Pipeline::new("cmd")
            .args(["/C", "echo hello world"])
            .pipe("findstr")
            .arg("hello")
            .capture_output()
            .execute()
    };

    #[cfg(not(windows))]
    let output = {
        Pipeline::new("echo")
            .arg("hello world")
            .pipe("grep")
            .arg("hello")
            .capture_output()
            .execute()
    };

    assert!(output.is_ok());
    let output = output.unwrap();
    assert!(output.stdout_str().contains("hello"));
}

/// Test stdin/stdout/stderr configuration.
#[test]
fn test_stdio_config() {
    #[cfg(windows)]
    let output = {
        CommandBuilder::new("cmd")
            .args(["/C", "echo test"])
            .null_stdin()
            .inherit_stdout()
            .null_stderr()
            .execute()
    };

    #[cfg(not(windows))]
    let output = {
        CommandBuilder::new("echo")
            .arg("test")
            .null_stdin()
            .inherit_stdout()
            .null_stderr()
            .execute()
    };

    // This should work even with null stdin
    assert!(output.is_ok());
}