sal/rhai/tests/integration_tests.rs
Mahmoud-Emad 8012a66250
Some checks are pending
Rhai Tests / Run Rhai Tests (push) Waiting to run
feat: Add Rhai scripting support
- Add new `sal-rhai` crate for Rhai scripting integration
- Integrate Rhai with existing SAL modules
- Improve error handling for Rhai scripts and SAL functions
- Add comprehensive unit and integration tests for `sal-rhai`
2025-06-23 16:23:51 +03:00

262 lines
8.7 KiB
Rust

//! Integration tests for sal-rhai package
//!
//! These tests verify that the sal-rhai package correctly integrates all SAL modules
//! and provides proper Rhai scripting functionality.
use rhai::Engine;
use sal_rhai::{register, Array, Dynamic};
use std::fs;
use tempfile::TempDir;
/// Test that the register function works without errors
#[test]
fn test_register_function() {
let mut engine = Engine::new();
let result = register(&mut engine);
assert!(
result.is_ok(),
"Failed to register SAL modules: {:?}",
result
);
}
/// Test that all major SAL modules are registered and accessible
#[test]
fn test_all_modules_registered() {
let mut engine = Engine::new();
register(&mut engine).expect("Failed to register SAL modules");
// Test OS module functions
let result = engine.eval::<bool>(r#"exist("Cargo.toml")"#);
assert!(
result.is_ok(),
"OS module 'exist' function not working: {:?}",
result
);
assert!(result.unwrap(), "Cargo.toml should exist");
// Test process module functions
let result = engine.eval::<String>(r#"which("echo")"#);
assert!(
result.is_ok(),
"Process module 'which' function not working: {:?}",
result
);
// Test text module functions
let result = engine.eval::<String>(r#"dedent(" hello\n world")"#);
assert!(
result.is_ok(),
"Text module 'dedent' function not working: {:?}",
result
);
let dedented = result.unwrap();
assert!(
dedented.contains("hello\nworld"),
"Dedent should remove indentation"
);
// Test utility function
let result = engine.eval::<bool>(r#"is_def_fn("test")"#);
if result.is_ok() {
assert!(result.unwrap(), "is_def_fn should return true");
} else {
// If the function is not found, that's acceptable for this test
let error_str = result.unwrap_err().to_string();
assert!(
error_str.contains("ErrorFunctionNotFound") || error_str.contains("Function not found"),
"Should be a function not found error: {}",
error_str
);
}
}
/// Test file operations through Rhai
#[test]
fn test_file_operations() {
let mut engine = Engine::new();
register(&mut engine).expect("Failed to register SAL modules");
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let test_file = temp_dir.path().join("test_file.txt");
let test_content = "Hello, SAL Rhai!";
// Write test content to file
fs::write(&test_file, test_content).expect("Failed to write test file");
// Test file existence
let script = format!(r#"exist("{}")"#, test_file.display());
let result = engine.eval::<bool>(&script);
assert!(result.is_ok(), "File existence check failed: {:?}", result);
assert!(result.unwrap(), "Test file should exist");
// Test file size
let script = format!(r#"file_size("{}")"#, test_file.display());
let result = engine.eval::<i64>(&script);
assert!(result.is_ok(), "File size check failed: {:?}", result);
assert_eq!(
result.unwrap(),
test_content.len() as i64,
"File size should match content length"
);
}
/// Test directory operations through Rhai
#[test]
fn test_directory_operations() {
let mut engine = Engine::new();
register(&mut engine).expect("Failed to register SAL modules");
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let test_dir = temp_dir.path().join("test_subdir");
// Create directory using Rhai
let script = format!(r#"mkdir("{}")"#, test_dir.display());
let result = engine.eval::<String>(&script);
assert!(result.is_ok(), "Directory creation failed: {:?}", result);
assert!(test_dir.exists(), "Directory should be created");
// Delete directory using Rhai
let script = format!(r#"delete("{}")"#, test_dir.display());
let result = engine.eval::<String>(&script);
assert!(result.is_ok(), "Directory deletion failed: {:?}", result);
assert!(!test_dir.exists(), "Directory should be deleted");
}
/// Test process management through Rhai
#[test]
fn test_process_management() {
let mut engine = Engine::new();
register(&mut engine).expect("Failed to register SAL modules");
// Test process listing
let result = engine.eval::<Array>(r#"process_list("")"#);
assert!(result.is_ok(), "Process listing failed: {:?}", result);
let processes = result.unwrap();
assert!(!processes.is_empty(), "Process list should not be empty");
// Test command execution
#[cfg(target_os = "windows")]
let script = r#"run_command("echo Hello World")"#;
#[cfg(any(target_os = "macos", target_os = "linux"))]
let script = r#"run_command("echo 'Hello World'")"#;
let result = engine.eval::<Dynamic>(&script);
assert!(result.is_ok(), "Command execution failed: {:?}", result);
}
/// Test error handling in Rhai integration
#[test]
fn test_error_handling() {
let mut engine = Engine::new();
register(&mut engine).expect("Failed to register SAL modules");
// Test error when accessing non-existent file
let result = engine.eval::<i64>(r#"file_size("non_existent_file_xyz123.txt")"#);
assert!(result.is_err(), "Should return error for non-existent file");
let error = result.unwrap_err();
let error_str = error.to_string();
assert!(
error_str.contains("No files found")
|| error_str.contains("File not found")
|| error_str.contains("File system error"),
"Error message should indicate file not found: {}",
error_str
);
}
/// Test core exec function with string content
#[test]
fn test_exec_function_with_string() {
let mut engine = Engine::new();
register(&mut engine).expect("Failed to register SAL modules");
// Test executing Rhai code as string
let script = r#"exec("let x = 42; x * 2")"#;
let result = engine.eval::<i64>(script);
assert!(
result.is_ok(),
"Exec function with string failed: {:?}",
result
);
assert_eq!(result.unwrap(), 84, "Exec should return 42 * 2 = 84");
}
/// Test exec function with file
#[test]
fn test_exec_function_with_file() {
let mut engine = Engine::new();
register(&mut engine).expect("Failed to register SAL modules");
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let script_file = temp_dir.path().join("test_script.rhai");
let script_content = "let result = 10 + 20; result";
// Write script to file
fs::write(&script_file, script_content).expect("Failed to write script file");
// Test executing script from file
let exec_script = format!(r#"exec("{}")"#, script_file.display());
let result = engine.eval::<i64>(&exec_script);
assert!(
result.is_ok(),
"Exec function with file failed: {:?}",
result
);
assert_eq!(result.unwrap(), 30, "Script should return 10 + 20 = 30");
}
/// Test that all module registration functions are accessible
#[test]
fn test_module_registration_functions() {
let mut engine = Engine::new();
// Test individual module registration (these should not fail)
assert!(sal_rhai::register_os_module(&mut engine).is_ok());
assert!(sal_rhai::register_process_module(&mut engine).is_ok());
assert!(sal_rhai::register_git_module(&mut engine).is_ok());
assert!(sal_rhai::register_crypto_module(&mut engine).is_ok());
assert!(sal_rhai::register_redisclient_module(&mut engine).is_ok());
assert!(sal_rhai::register_postgresclient_module(&mut engine).is_ok());
assert!(sal_rhai::register_mycelium_module(&mut engine).is_ok());
assert!(sal_rhai::register_text_module(&mut engine).is_ok());
assert!(sal_rhai::register_net_module(&mut engine).is_ok());
assert!(sal_rhai::register_zinit_module(&mut engine).is_ok());
}
/// Test cross-module functionality
#[test]
fn test_cross_module_functionality() {
let mut engine = Engine::new();
register(&mut engine).expect("Failed to register SAL modules");
let _temp_dir = TempDir::new().expect("Failed to create temp directory");
// Use text module to create content, then OS module to write and verify
let script = format!(
r#"
let content = dedent(" Hello\n World");
let prefixed = prefix(content, ">> ");
// File operations would need to be implemented for full cross-module test
prefixed
"#
);
let result = engine.eval::<String>(&script);
assert!(
result.is_ok(),
"Cross-module functionality failed: {:?}",
result
);
let output = result.unwrap();
assert!(
output.contains(">> Hello"),
"Should contain prefixed content"
);
assert!(
output.contains(">> World"),
"Should contain prefixed content"
);
}