mirror of
https://github.com/imjasonh/testscript-rs
synced 2026-07-08 17:16:38 +00:00
* add GHA workflow Signed-off-by: Jason Hall <jason@chainguard.dev> * fix CI Signed-off-by: Jason Hall <jason@chainguard.dev> * update readme Signed-off-by: Jason Hall <jason@chainguard.dev> * add badge Signed-off-by: Jason Hall <jason@chainguard.dev> --------- Signed-off-by: Jason Hall <jason@chainguard.dev>
168 lines
5.1 KiB
Rust
168 lines
5.1 KiB
Rust
//! Edge case tests for testscript-rs parsing and execution
|
|
|
|
use std::fs;
|
|
use tempfile::TempDir;
|
|
use testscript_rs::{parser, run_test};
|
|
|
|
#[test]
|
|
fn test_parse_edge_cases() {
|
|
// Test empty script
|
|
let empty = parser::parse("").unwrap();
|
|
assert_eq!(empty.commands.len(), 0);
|
|
assert_eq!(empty.files.len(), 0);
|
|
|
|
// Test script with only comments
|
|
let comments_only = parser::parse("# Just a comment\n# Another comment").unwrap();
|
|
assert_eq!(comments_only.commands.len(), 0);
|
|
assert_eq!(comments_only.files.len(), 0);
|
|
|
|
// Test script with only files
|
|
let files_only = parser::parse("-- file.txt --\ncontent").unwrap();
|
|
assert_eq!(files_only.commands.len(), 0);
|
|
assert_eq!(files_only.files.len(), 1);
|
|
|
|
// Test commands with complex quoting
|
|
let complex_quotes = r#"exec echo "hello \"world\" with spaces"
|
|
exec echo 'single quotes'
|
|
exec echo "newline\nand\ttab""#;
|
|
let script = parser::parse(complex_quotes).unwrap();
|
|
assert_eq!(script.commands.len(), 3);
|
|
assert_eq!(script.commands[0].args[1], r#"hello "world" with spaces"#);
|
|
assert_eq!(script.commands[2].args[1], "newline\nand\ttab");
|
|
}
|
|
|
|
#[test]
|
|
fn test_parse_malformed_conditions() {
|
|
// Test unclosed condition bracket
|
|
let malformed = parser::parse("[unclosed exec echo hello");
|
|
assert!(malformed.is_err());
|
|
|
|
// Test empty condition
|
|
let empty_condition = parser::parse("[] exec echo hello");
|
|
let script = empty_condition.unwrap();
|
|
assert_eq!(script.commands[0].condition, Some("".to_string()));
|
|
}
|
|
|
|
#[test]
|
|
fn test_files_with_special_names() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let script_path = temp_dir.path().join("special_names.txt");
|
|
|
|
let script_content = r#"# Test files with special characters in names
|
|
cmp file-with-dashes.txt file_with_underscores.txt
|
|
cmp path/to/nested/file.txt another/nested/file.txt
|
|
|
|
-- file-with-dashes.txt --
|
|
content
|
|
|
|
-- file_with_underscores.txt --
|
|
content
|
|
|
|
-- path/to/nested/file.txt --
|
|
nested content
|
|
|
|
-- another/nested/file.txt --
|
|
nested content"#;
|
|
|
|
fs::write(&script_path, script_content).unwrap();
|
|
|
|
let result = run_test(&script_path);
|
|
assert!(
|
|
result.is_ok(),
|
|
"Special file names test failed: {:?}",
|
|
result
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_commands_with_many_args() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let script_path = temp_dir.path().join("many_args.txt");
|
|
|
|
// Test command with many arguments
|
|
let script_content = r#"# Test commands with many arguments
|
|
exec echo arg1 arg2 arg3 "arg with spaces" arg5 arg6
|
|
stdout "arg1 arg2 arg3 arg with spaces arg5 arg6""#;
|
|
|
|
fs::write(&script_path, script_content).unwrap();
|
|
|
|
let result = run_test(&script_path);
|
|
assert!(result.is_ok(), "Many args test failed: {:?}", result);
|
|
}
|
|
|
|
#[test]
|
|
fn test_binary_file_content() {
|
|
// Test that binary content is preserved correctly
|
|
let content_with_binary = "-- binary.dat --\nhello\x00world\x7f\x00";
|
|
let script = parser::parse(content_with_binary).unwrap();
|
|
|
|
assert_eq!(script.files.len(), 1);
|
|
assert_eq!(script.files[0].name, "binary.dat");
|
|
assert_eq!(script.files[0].contents, b"hello\x00world\x7f\x00");
|
|
}
|
|
|
|
#[test]
|
|
fn test_file_with_dashes_in_content() {
|
|
// Test that content with dashes (but not file headers) doesn't confuse parser
|
|
let content = r#"-- config.txt --
|
|
--this is not a file header because no spaces--
|
|
just content with dashes
|
|
--more dashes without spaces--
|
|
- single dash line"#;
|
|
|
|
let script = parser::parse(content).unwrap();
|
|
assert_eq!(script.files.len(), 1);
|
|
assert_eq!(script.files[0].name, "config.txt");
|
|
let expected_content = "--this is not a file header because no spaces--\njust content with dashes\n--more dashes without spaces--\n- single dash line";
|
|
assert_eq!(script.files[0].contents, expected_content.as_bytes());
|
|
}
|
|
|
|
#[test]
|
|
fn test_command_line_numbers() {
|
|
let content = r#"# Comment line 1
|
|
exec echo line2
|
|
# Comment line 3
|
|
stdout line4
|
|
# Comment line 5
|
|
exec echo line6"#;
|
|
|
|
let script = parser::parse(content).unwrap();
|
|
assert_eq!(script.commands.len(), 3);
|
|
assert_eq!(script.commands[0].line_num, 2); // exec echo line2
|
|
assert_eq!(script.commands[1].line_num, 4); // stdout line4
|
|
assert_eq!(script.commands[2].line_num, 6); // exec echo line6
|
|
}
|
|
|
|
#[test]
|
|
fn test_mixed_conditions() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let script_path = temp_dir.path().join("mixed_conditions.txt");
|
|
|
|
let script_content = r#"# Test mixed condition types
|
|
[unix] exec echo "unix"
|
|
[!windows] exec echo "not windows"
|
|
exec echo "always runs"
|
|
[linux] exec echo "linux only"
|
|
[!nonexistent] exec echo "not nonexistent""#;
|
|
|
|
fs::write(&script_path, script_content).unwrap();
|
|
|
|
let result = run_test(&script_path);
|
|
assert!(result.is_ok(), "Mixed conditions test failed: {:?}", result);
|
|
}
|
|
|
|
#[test]
|
|
fn test_empty_command_args() {
|
|
let content = r#"exec
|
|
cmp file1.txt file2.txt
|
|
|
|
-- file1.txt --
|
|
-- file2.txt --"#;
|
|
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let script_path = temp_dir.path().join("empty_args.txt");
|
|
fs::write(&script_path, content).unwrap();
|
|
|
|
let result = run_test(&script_path);
|
|
assert!(result.is_err(), "Empty exec command should fail");
|
|
}
|