//! 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::(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::(r#"which("echo")"#); assert!( result.is_ok(), "Process module 'which' function not working: {:?}", result ); // Test text module functions let result = engine.eval::(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::(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::(&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::(&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::(&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::(&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::(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::(&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::(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::(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::(&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::(&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" ); }