1
0
Fork 0
mirror of https://github.com/imjasonh/testscript-rs synced 2026-07-08 17:16:38 +00:00
testscript-rs/tests/edge_cases.rs
Jason Hall 448cf615db
add GHA workflow (#1)
* 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>
2025-09-26 19:08:48 -04:00

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");
}