1
0
Fork 0
mirror of https://github.com/imjasonh/testscript-rs synced 2026-07-08 17:16:38 +00:00
testscript-rs/tests/setup_hook.rs

258 lines
7.7 KiB
Rust
Raw Normal View History

//! Tests for setup hook functionality
use std::fs;
use tempfile::TempDir;
// Tests for setup hook functionality - uses internal APIs
use testscript_rs::run::{run_script, RunParams};
#[test]
fn test_setup_hook_basic() {
let temp_dir = TempDir::new().unwrap();
let script_path = temp_dir.path().join("setup_test.txt");
let script_content = r#"# Test that setup hook ran
exists setup_was_here.txt
exec cat setup_was_here.txt
stdout "Setup ran successfully"
-- other_file.txt --
existing content"#;
fs::write(&script_path, script_content).unwrap();
// Create RunParams with setup hook
let params = RunParams::new().setup(|env| {
// Setup hook creates a file to prove it ran
let setup_file = env.work_dir.join("setup_was_here.txt");
std::fs::write(&setup_file, "Setup ran successfully")?;
Ok(())
});
let result = run_script(&script_path, &params);
assert!(result.is_ok(), "Setup hook test failed: {:?}", result);
}
#[test]
fn test_setup_hook_compile_binary() {
let temp_dir = TempDir::new().unwrap();
let script_path = temp_dir.path().join("binary_test.txt");
let script_content = r#"# Test that setup hook compiled a binary
exists my-tool
exec ./my-tool --help
stdout "Mock CLI Tool""#;
fs::write(&script_path, script_content).unwrap();
// Create RunParams with setup hook that "compiles" a mock binary
let params = RunParams::new().setup(|env| {
// Create a mock binary script for testing
let binary_path = env.work_dir.join("my-tool");
let mock_binary = r#"#!/bin/sh
if [ "$1" = "--help" ]; then
echo "Mock CLI Tool"
echo "Usage: my-tool [options]"
else
echo "Hello from my-tool"
fi"#;
std::fs::write(&binary_path, mock_binary)?;
// Make it executable (on Unix systems)
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let mut perms = std::fs::metadata(&binary_path)?.permissions();
perms.set_mode(0o755);
std::fs::set_permissions(&binary_path, perms)?;
}
Ok(())
});
let result = run_script(&script_path, &params);
// This might fail on Windows or if shell scripting isn't available
if result.is_err() {
println!(
"Binary compilation test failed (expected on some systems): {:?}",
result
);
} else {
println!("Setup hook binary test passed!");
}
}
#[test]
fn test_setup_hook_environment() {
let temp_dir = TempDir::new().unwrap();
let script_path = temp_dir.path().join("env_test.txt");
Allow setting environment variables in setup hook (#44) ## Plan: Support passing env vars into test environment in `setup` - [x] Update `SetupFn` type alias in `params.rs` to accept `&mut TestEnvironment` instead of `&TestEnvironment` - [x] Update `setup` method signature in `params.rs` to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update `setup` method signature in `lib.rs` Builder to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update execution in `execution.rs` to pass `&mut env` to setup function - [x] Update existing test in `setup_hook.rs` to test the new functionality (make it pass) - [x] Add a new focused test to validate setting environment variables in setup hook - [x] Run tests to validate changes - all tests pass - [x] Update documentation examples to show the new capability - [x] Address code review feedback - fix trailing newline inconsistency - [x] Add comprehensive test for environment variable presence/absence to ensure proper isolation - [x] Enhance tests to demonstrate env vars work without sh -c wrapper (using printenv/set) - [x] Format assert statement to single line per style guidelines <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>support passing env vars into the test environment in `setup`</issue_title> > <issue_description>``` > .setup(|env| => { > env.set("FOO", "bar") > } > ``` > > (or similar) > > this should make `FOO` have the value of `bar` in the test environment</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes imjasonh/testscript-rs#43 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/imjasonh/testscript-rs/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: imjasonh <210737+imjasonh@users.noreply.github.com>
2025-12-29 21:29:03 -05:00
// Use sh -c to allow shell variable expansion
let script_content = if cfg!(windows) {
r#"# Test setup hook can modify environment (Windows)
exec cmd /c "echo Value: %TEST_FROM_SETUP%"
stdout "Value: hello_from_setup""#
} else {
r#"# Test setup hook can modify environment (Unix)
exec sh -c "echo Value: $TEST_FROM_SETUP"
stdout "Value: hello_from_setup"#
};
fs::write(&script_path, script_content).unwrap();
// Create RunParams with setup hook that sets an environment variable
let params = RunParams::new().setup(|env| {
Allow setting environment variables in setup hook (#44) ## Plan: Support passing env vars into test environment in `setup` - [x] Update `SetupFn` type alias in `params.rs` to accept `&mut TestEnvironment` instead of `&TestEnvironment` - [x] Update `setup` method signature in `params.rs` to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update `setup` method signature in `lib.rs` Builder to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update execution in `execution.rs` to pass `&mut env` to setup function - [x] Update existing test in `setup_hook.rs` to test the new functionality (make it pass) - [x] Add a new focused test to validate setting environment variables in setup hook - [x] Run tests to validate changes - all tests pass - [x] Update documentation examples to show the new capability - [x] Address code review feedback - fix trailing newline inconsistency - [x] Add comprehensive test for environment variable presence/absence to ensure proper isolation - [x] Enhance tests to demonstrate env vars work without sh -c wrapper (using printenv/set) - [x] Format assert statement to single line per style guidelines <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>support passing env vars into the test environment in `setup`</issue_title> > <issue_description>``` > .setup(|env| => { > env.set("FOO", "bar") > } > ``` > > (or similar) > > this should make `FOO` have the value of `bar` in the test environment</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes imjasonh/testscript-rs#43 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/imjasonh/testscript-rs/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: imjasonh <210737+imjasonh@users.noreply.github.com>
2025-12-29 21:29:03 -05:00
// Now we can modify the environment directly in the setup hook
env.set_env_var("TEST_FROM_SETUP", "hello_from_setup");
Ok(())
});
Allow setting environment variables in setup hook (#44) ## Plan: Support passing env vars into test environment in `setup` - [x] Update `SetupFn` type alias in `params.rs` to accept `&mut TestEnvironment` instead of `&TestEnvironment` - [x] Update `setup` method signature in `params.rs` to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update `setup` method signature in `lib.rs` Builder to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update execution in `execution.rs` to pass `&mut env` to setup function - [x] Update existing test in `setup_hook.rs` to test the new functionality (make it pass) - [x] Add a new focused test to validate setting environment variables in setup hook - [x] Run tests to validate changes - all tests pass - [x] Update documentation examples to show the new capability - [x] Address code review feedback - fix trailing newline inconsistency - [x] Add comprehensive test for environment variable presence/absence to ensure proper isolation - [x] Enhance tests to demonstrate env vars work without sh -c wrapper (using printenv/set) - [x] Format assert statement to single line per style guidelines <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>support passing env vars into the test environment in `setup`</issue_title> > <issue_description>``` > .setup(|env| => { > env.set("FOO", "bar") > } > ``` > > (or similar) > > this should make `FOO` have the value of `bar` in the test environment</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes imjasonh/testscript-rs#43 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/imjasonh/testscript-rs/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: imjasonh <210737+imjasonh@users.noreply.github.com>
2025-12-29 21:29:03 -05:00
let result = run_script(&script_path, &params);
assert!(
result.is_ok(),
"Environment setup test should pass: {:?}",
result
);
}
#[test]
fn test_setup_hook_multiple_env_vars() {
let temp_dir = TempDir::new().unwrap();
let script_path = temp_dir.path().join("multi_env_test.txt");
// Use sh -c to allow shell variable expansion
let script_content = if cfg!(windows) {
r#"# Test setup hook can set multiple environment variables (Windows)
exec cmd /c "echo FOO=%FOO% BAR=%BAR% BAZ=%BAZ%"
stdout "FOO=value1 BAR=value2 BAZ=value3""#
} else {
r#"# Test setup hook can set multiple environment variables (Unix)
exec sh -c "echo FOO=$FOO BAR=$BAR BAZ=$BAZ"
stdout "FOO=value1 BAR=value2 BAZ=value3"#
};
fs::write(&script_path, script_content).unwrap();
// Create RunParams with setup hook that sets multiple environment variables
let params = RunParams::new().setup(|env| {
env.set_env_var("FOO", "value1");
env.set_env_var("BAR", "value2");
env.set_env_var("BAZ", "value3");
Ok(())
});
let result = run_script(&script_path, &params);
Allow setting environment variables in setup hook (#44) ## Plan: Support passing env vars into test environment in `setup` - [x] Update `SetupFn` type alias in `params.rs` to accept `&mut TestEnvironment` instead of `&TestEnvironment` - [x] Update `setup` method signature in `params.rs` to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update `setup` method signature in `lib.rs` Builder to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update execution in `execution.rs` to pass `&mut env` to setup function - [x] Update existing test in `setup_hook.rs` to test the new functionality (make it pass) - [x] Add a new focused test to validate setting environment variables in setup hook - [x] Run tests to validate changes - all tests pass - [x] Update documentation examples to show the new capability - [x] Address code review feedback - fix trailing newline inconsistency - [x] Add comprehensive test for environment variable presence/absence to ensure proper isolation - [x] Enhance tests to demonstrate env vars work without sh -c wrapper (using printenv/set) - [x] Format assert statement to single line per style guidelines <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>support passing env vars into the test environment in `setup`</issue_title> > <issue_description>``` > .setup(|env| => { > env.set("FOO", "bar") > } > ``` > > (or similar) > > this should make `FOO` have the value of `bar` in the test environment</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes imjasonh/testscript-rs#43 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/imjasonh/testscript-rs/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: imjasonh <210737+imjasonh@users.noreply.github.com>
2025-12-29 21:29:03 -05:00
assert!(
result.is_ok(),
"Multiple environment variables test should pass: {:?}",
result
);
}
#[test]
fn test_setup_hook_failure() {
let temp_dir = TempDir::new().unwrap();
let script_path = temp_dir.path().join("fail_test.txt");
let script_content = r#"# This should never run because setup fails
exec echo "Should not execute""#;
fs::write(&script_path, script_content).unwrap();
// Create RunParams with failing setup hook
let params = RunParams::new().setup(|_env| {
Err(testscript_rs::Error::Generic(
"Setup deliberately failed".to_string(),
))
});
let result = run_script(&script_path, &params);
assert!(result.is_err(), "Setup hook should have failed the test");
assert!(result
.unwrap_err()
.to_string()
.contains("Setup deliberately failed"));
}
Allow setting environment variables in setup hook (#44) ## Plan: Support passing env vars into test environment in `setup` - [x] Update `SetupFn` type alias in `params.rs` to accept `&mut TestEnvironment` instead of `&TestEnvironment` - [x] Update `setup` method signature in `params.rs` to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update `setup` method signature in `lib.rs` Builder to accept `Fn(&mut TestEnvironment)` instead of `Fn(&TestEnvironment)` - [x] Update execution in `execution.rs` to pass `&mut env` to setup function - [x] Update existing test in `setup_hook.rs` to test the new functionality (make it pass) - [x] Add a new focused test to validate setting environment variables in setup hook - [x] Run tests to validate changes - all tests pass - [x] Update documentation examples to show the new capability - [x] Address code review feedback - fix trailing newline inconsistency - [x] Add comprehensive test for environment variable presence/absence to ensure proper isolation - [x] Enhance tests to demonstrate env vars work without sh -c wrapper (using printenv/set) - [x] Format assert statement to single line per style guidelines <!-- START COPILOT ORIGINAL PROMPT --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>support passing env vars into the test environment in `setup`</issue_title> > <issue_description>``` > .setup(|env| => { > env.set("FOO", "bar") > } > ``` > > (or similar) > > this should make `FOO` have the value of `bar` in the test environment</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > </comments> > </details> <!-- START COPILOT CODING AGENT SUFFIX --> - Fixes imjasonh/testscript-rs#43 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/imjasonh/testscript-rs/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: imjasonh <210737+imjasonh@users.noreply.github.com>
2025-12-29 21:29:03 -05:00
#[test]
fn test_setup_env_vars_presence_and_absence() {
let temp_dir = TempDir::new().unwrap();
let script_path = temp_dir.path().join("env_presence_test.txt");
// Test that verifies:
// 1. Variables set in setup ARE available in the test
// 2. Variables NOT set in setup are NOT available in the test
let script_content = if cfg!(windows) {
r#"# Test environment variable presence and absence (Windows)
# Check that SET_VAR is available using printenv (no shell needed)
exec cmd /c set SET_VAR
stdout "SET_VAR=value_from_setup"
# Also verify with shell expansion
exec cmd /c "echo SET_VAR=%SET_VAR%"
stdout "SET_VAR=value_from_setup"
# Check that UNSET_VAR is not available
! exec cmd /c set UNSET_VAR"#
} else {
r#"# Test environment variable presence and absence (Unix)
# Check that SET_VAR is available using printenv (no shell needed)
exec printenv SET_VAR
stdout "value_from_setup"
# Also verify with shell expansion
exec sh -c "echo SET_VAR=$SET_VAR"
stdout "SET_VAR=value_from_setup"
# Check that UNSET_VAR is not available
! exec printenv UNSET_VAR"#
};
fs::write(&script_path, script_content).unwrap();
// Create RunParams with setup hook that only sets SET_VAR, not UNSET_VAR
let params = RunParams::new().setup(|env| {
env.set_env_var("SET_VAR", "value_from_setup");
// Deliberately NOT setting UNSET_VAR to verify it's not available
Ok(())
});
let result = run_script(&script_path, &params);
assert!(
result.is_ok(),
"Environment presence/absence test should pass: {:?}",
result
);
}
#[test]
fn test_env_command_prints_all_vars() {
let temp_dir = TempDir::new().unwrap();
let script_path = temp_dir.path().join("env_print_test.txt");
// Test that 'env' without args prints all environment variables
let script_content = r#"# Test env command prints all variables
env VAR1=value1
env VAR2=value2
# The env command should be callable and set variables
# (printing is done to stdout which we can't easily test here,
# but we verify the vars are set by using them)
exec sh -c "echo $VAR1"
stdout "value1"
exec sh -c "echo $VAR2"
stdout "value2"
"#;
fs::write(&script_path, script_content).unwrap();
let params = RunParams::new().setup(|env| {
env.set_env_var("SETUP_VAR", "from_setup");
Ok(())
});
let result = run_script(&script_path, &params);
assert!(result.is_ok(), "Env command test should pass: {:?}", result);
}