initial commit
This commit is contained in:
254
tests/interpreter_tests.rs
Normal file
254
tests/interpreter_tests.rs
Normal file
@@ -0,0 +1,254 @@
|
||||
use rush::interpreter::executor::Executor;
|
||||
use rush::parser::Parser;
|
||||
use rush::runtime::environment::Environment;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_variable_assignment() {
|
||||
// Test variable assignment functionality
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse("name = \"test\"");
|
||||
assert!(result.is_ok());
|
||||
|
||||
let program = result.unwrap();
|
||||
let mut env = Environment::new();
|
||||
let mut executor = Executor::new(&mut env);
|
||||
|
||||
for stmt in program.statements {
|
||||
executor.execute_node(stmt);
|
||||
}
|
||||
|
||||
assert_eq!(env.get_variable("name"), Some(&"test".to_string()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_simple_command() {
|
||||
// Test basic command execution doesn't panic
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse("echo \"test\"");
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_script_parsing() {
|
||||
// Test the parsing of a complete .rsh script
|
||||
let script = r#"
|
||||
name = "Louis"
|
||||
echo "Hello" $name
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
let program = result.unwrap();
|
||||
assert!(program.statements.len() >= 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_undefined_variable_detection() {
|
||||
// Test that using an undefined variable is caught
|
||||
let script = r#"
|
||||
echo "Hello" $undefined_var
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_err());
|
||||
let err_msg = format!("{:?}", result.unwrap_err());
|
||||
assert!(err_msg.contains("undefined_var"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_out_of_order_variable_detection() {
|
||||
// Test that using a variable before it's defined is caught
|
||||
let script = r#"
|
||||
echo "Hello" $name
|
||||
name = "Louis"
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_err());
|
||||
let err_msg = format!("{:?}", result.unwrap_err());
|
||||
assert!(err_msg.contains("name"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_valid_variable_order() {
|
||||
// Test that defining before using works correctly
|
||||
let script = r#"
|
||||
name = "Louis"
|
||||
echo "Hello" $name
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_for_loop_variable_scope() {
|
||||
// Test that for loop variables are properly scoped
|
||||
let script = r#"
|
||||
for i in 1 2 3 {
|
||||
echo "Number:" $i
|
||||
}
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_for_loop_variable_isolation() {
|
||||
// Test that for loop variables don't leak to outer scope
|
||||
let script = r#"
|
||||
for i in 1 2 3 {
|
||||
echo "Inside:" $i
|
||||
}
|
||||
echo "Outside:" $i
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_err());
|
||||
let err_msg = format!("{:?}", result.unwrap_err());
|
||||
assert!(err_msg.contains("i"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parallel_block_variable_access() {
|
||||
// Test that parallel blocks can access outer scope variables
|
||||
let script = r#"
|
||||
name = "Test"
|
||||
|
||||
parallel {
|
||||
run { echo "Task 1:" $name }
|
||||
run { echo "Task 2:" $name }
|
||||
}
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parallel_block_undefined_variable() {
|
||||
// Test that parallel blocks catch undefined variables
|
||||
let script = r#"
|
||||
parallel {
|
||||
run { echo "Task:" $undefined }
|
||||
}
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_workers_block_variable_access() {
|
||||
// Test that workers blocks can access outer scope variables
|
||||
let script = r#"
|
||||
msg = "Worker"
|
||||
|
||||
workers 2 {
|
||||
echo $msg "Task 1"
|
||||
echo $msg "Task 2"
|
||||
}
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_workers_with_for_loop() {
|
||||
// Test that workers can contain for loops with variables
|
||||
let script = r#"
|
||||
prefix = "Item"
|
||||
|
||||
workers 2 {
|
||||
for num in 1 2 3 {
|
||||
echo $prefix $num
|
||||
}
|
||||
}
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested_for_loops() {
|
||||
// Test nested for loops with proper scoping
|
||||
let script = r#"
|
||||
for i in 1 2 {
|
||||
for j in a b {
|
||||
echo $i $j
|
||||
}
|
||||
}
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple_variables() {
|
||||
// Test multiple variable definitions and usage
|
||||
let script = r#"
|
||||
user = "Alice"
|
||||
project = "RushShell"
|
||||
version = "1.0"
|
||||
|
||||
echo $user "is working on" $project "version" $version
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_for_loop_with_outer_variables() {
|
||||
// Test for loops can access both loop vars and outer vars
|
||||
let script = r#"
|
||||
prefix = "Item"
|
||||
|
||||
for num in 1 2 3 {
|
||||
echo $prefix $num
|
||||
}
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_comprehensive_variable_usage() {
|
||||
// Test a comprehensive script with all variable features
|
||||
let script = r#"
|
||||
user = "Alice"
|
||||
project = "RushShell"
|
||||
|
||||
echo "Welcome" $user "to" $project
|
||||
|
||||
for item in "docs" "tests" "src" {
|
||||
echo $user "is checking" $item
|
||||
}
|
||||
|
||||
parallel {
|
||||
run { echo "Parallel 1:" $user }
|
||||
run { echo "Parallel 2:" $project }
|
||||
}
|
||||
|
||||
workers 2 {
|
||||
for num in 1 2 {
|
||||
echo $project "worker task" $num
|
||||
}
|
||||
}
|
||||
|
||||
echo "Done with" $project
|
||||
"#;
|
||||
let parser = Parser::new();
|
||||
let result = parser.parse(script);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user