1
0
Fork 0
mirror of https://github.com/imjasonh/testscript-rs synced 2026-07-08 17:16:38 +00:00
testscript-rs/tests/workdir_root.rs
Copilot 6b5a64703f
Add WorkdirRoot configuration for custom work directories (#27)
- [x] Add `workdir_root` field to `RunParams` struct
- [x] Add `workdir_root` method to `Builder` API  
- [x] Modify `TestEnvironment::new()` to accept optional root directory
- [x] Update `TestEnvironment::new()` to use
`tempfile::TempDir::new_in()` when root is specified
- [x] Add validation for root directory existence and writability
- [x] Add tests for the new workdir_root functionality
- [x] Update documentation and examples
- [x] Address PR feedback: remove unnecessary files and improve tests
- [x] Fix code formatting with cargo fmt
- [x] Add rustfmt.toml configuration and update CLAUDE.md
- [x] Improve basic test to verify actual workdir usage

## Recent Changes

**Enhanced basic functionality test:**
- Modified `test_workdir_root_basic_functionality` to induce a failure
and use `preserve_work_on_failure(true)`
- Test now verifies that the workdir was actually created in the custom
root directory
- Validates that test files exist in the preserved workdir with expected
content
- **Removed** redundant `test_workdir_root_with_preserve_work` test as
the functionality is now covered by the improved basic test

The test suite is now more meaningful and comprehensive, with 4 focused
tests that provide real validation of the workdir_root functionality:
- Basic functionality with actual workdir verification
- Error handling for nonexistent directories  
- Error handling for non-directory paths
- API chaining validation

All tests pass and the implementation properly validates that custom
workdir roots are used as expected.

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: imjasonh <210737+imjasonh@users.noreply.github.com>
Co-authored-by: Jason Hall <jason@chainguard.dev>
2025-09-30 06:57:10 +00:00

160 lines
5 KiB
Rust

//! Tests for workdir root configuration functionality
use std::fs;
use tempfile::TempDir;
use testscript_rs::testscript;
#[test]
fn test_workdir_root_basic_functionality() {
// Create a temporary directory to use as our custom root
let custom_root = TempDir::new().unwrap();
let custom_root_path = custom_root.path();
// Create a test directory structure
let testdata_dir = TempDir::new().unwrap();
let testdata_path = testdata_dir.path().join("testdata");
fs::create_dir(&testdata_path).unwrap();
// Create a test that will fail due to mismatched stdout expectation
let test_content = r#"exec echo "hello"
stdout "goodbye"
-- test_file.txt --
Test content in custom root
"#;
fs::write(testdata_path.join("custom_root_test.txt"), test_content).unwrap();
// Run test with custom workdir root and preserve work on failure
let result = testscript::run(testdata_path.to_string_lossy())
.workdir_root(custom_root_path)
.preserve_work_on_failure(true)
.execute();
// The test should fail due to the mismatched stdout expectation
assert!(
result.is_err(),
"Test should fail due to mismatched stdout expectation. Got: {:?}",
result
);
// Verify that the workdir was created in our custom root and contains expected files
let entries: Vec<_> = fs::read_dir(custom_root_path)
.expect("Custom root should be readable")
.collect::<Result<Vec<_>, _>>()
.expect("Should be able to read directory entries");
assert!(
!entries.is_empty(),
"Custom root should contain test working directories"
);
// Find the test working directory (should start with a temp directory name)
let work_dir = entries
.iter()
.find(|entry| entry.file_type().unwrap().is_dir())
.expect("Should find at least one working directory");
let work_dir_path = work_dir.path();
// Verify that the test file was created in the working directory
let test_file_path = work_dir_path.join("test_file.txt");
assert!(
test_file_path.exists(),
"test_file.txt should exist in the working directory"
);
let test_file_content =
fs::read_to_string(&test_file_path).expect("Should be able to read test_file.txt");
assert_eq!(
test_file_content.trim(),
"Test content in custom root",
"Test file should contain expected content"
);
}
#[test]
fn test_workdir_root_nonexistent_directory() {
let testdata_dir = TempDir::new().unwrap();
let testdata_path = testdata_dir.path().join("testdata");
fs::create_dir(&testdata_path).unwrap();
let test_content = r#"exec echo "test"
stdout "test"
"#;
fs::write(testdata_path.join("simple_test.txt"), test_content).unwrap();
// Try to use a non-existent directory as workdir root
let nonexistent_path = "/this/path/does/not/exist";
let result = testscript::run(testdata_path.to_string_lossy())
.workdir_root(nonexistent_path)
.execute();
assert!(
result.is_err(),
"Expected error for non-existent workdir root"
);
let error_msg = format!("{:?}", result.unwrap_err());
assert!(
error_msg.contains("does not exist"),
"Error should mention directory doesn't exist"
);
}
#[test]
fn test_workdir_root_not_a_directory() {
let temp_dir = TempDir::new().unwrap();
// Create a file (not directory) to test the validation
let file_path = temp_dir.path().join("not_a_directory.txt");
fs::write(&file_path, "this is a file").unwrap();
let testdata_dir = TempDir::new().unwrap();
let testdata_path = testdata_dir.path().join("testdata");
fs::create_dir(&testdata_path).unwrap();
let test_content = r#"exec echo "test"
stdout "test"
"#;
fs::write(testdata_path.join("simple_test.txt"), test_content).unwrap();
// Try to use a file as workdir root
let result = testscript::run(testdata_path.to_string_lossy())
.workdir_root(&file_path)
.execute();
assert!(
result.is_err(),
"Expected error for file used as workdir root"
);
let error_msg = format!("{:?}", result.unwrap_err());
assert!(
error_msg.contains("not a directory"),
"Error should mention path is not a directory"
);
}
#[test]
fn test_workdir_root_api_chaining() {
// Test that the API method exists and can be chained
let custom_root = TempDir::new().unwrap();
let testdata_dir = TempDir::new().unwrap();
let testdata_path = testdata_dir.path().join("testdata");
fs::create_dir(&testdata_path).unwrap();
let test_content = r#"exec echo "chaining test"
stdout "chaining test"
"#;
fs::write(testdata_path.join("chain_test.txt"), test_content).unwrap();
let result = testscript::run(testdata_path.to_string_lossy())
.workdir_root(custom_root.path())
.workdir_root(custom_root.path()) // Can be called multiple times
.preserve_work_on_failure(false)
.execute();
assert!(result.is_ok(), "API chaining test failed: {:?}", result);
}