sal/text/tests/rhai_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

352 lines
11 KiB
Rust

//! Rhai integration tests for Text module
//!
//! These tests validate the Rhai wrapper functions and ensure proper
//! integration between Rust and Rhai for text processing operations.
use rhai::{Engine, EvalAltResult};
use sal_text::rhai::*;
#[cfg(test)]
mod rhai_integration_tests {
use super::*;
fn create_test_engine() -> Engine {
let mut engine = Engine::new();
register_text_module(&mut engine).expect("Failed to register text module");
engine
}
#[test]
fn test_rhai_module_registration() {
let engine = create_test_engine();
// Test that the functions are registered by checking if they exist
let script = r#"
// Test that all text functions are available
let functions_exist = true;
functions_exist
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_dedent_function_exists() {
let engine = create_test_engine();
let script = r#"
let indented = " line 1\n line 2\n line 3";
let result = dedent(indented);
return result == "line 1\nline 2\n line 3";
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_prefix_function_exists() {
let engine = create_test_engine();
let script = r#"
let text = "line 1\nline 2";
let result = prefix(text, "> ");
return result == "> line 1\n> line 2";
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_name_fix_function_exists() {
let engine = create_test_engine();
let script = r#"
let unsafe_name = "User's File [Draft].txt";
let result = name_fix(unsafe_name);
return result == "user_s_file_draft_.txt";
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_path_fix_function_exists() {
let engine = create_test_engine();
let script = r#"
let unsafe_path = "/path/to/User's File.txt";
let result = path_fix(unsafe_path);
return result == "/path/to/user_s_file.txt";
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_text_replacer_builder_creation() {
let engine = create_test_engine();
let script = r#"
let builder = text_replacer_builder();
return type_of(builder) == "TextReplacerBuilder";
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_text_replacer_workflow() {
let engine = create_test_engine();
let script = r#"
let builder = text_replacer_builder();
builder = pattern(builder, "hello");
builder = replacement(builder, "hi");
builder = regex(builder, false);
let replacer = build(builder);
let result = replace(replacer, "hello world, hello universe");
return result == "hi world, hi universe";
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_text_replacer_regex_workflow() {
let engine = create_test_engine();
let script = r#"
let builder = text_replacer_builder();
builder = pattern(builder, "\\d+");
builder = replacement(builder, "NUMBER");
builder = regex(builder, true);
let replacer = build(builder);
let result = replace(replacer, "There are 123 items");
return result == "There are NUMBER items";
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_text_replacer_chained_operations() {
let engine = create_test_engine();
let script = r#"
let builder = text_replacer_builder();
builder = pattern(builder, "world");
builder = replacement(builder, "universe");
builder = regex(builder, false);
builder = and(builder);
builder = pattern(builder, "\\d+");
builder = replacement(builder, "NUMBER");
builder = regex(builder, true);
let replacer = build(builder);
let result = replace(replacer, "Hello world, there are 123 items");
return result == "Hello universe, there are NUMBER items";
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_template_builder_creation() {
let engine = create_test_engine();
let script = r#"
// We can't test file operations easily in unit tests,
// but we can test that the function exists and returns the right type
try {
let builder = template_builder_open("/nonexistent/file.txt");
return false; // Should have failed
} catch(err) {
return err.to_string().contains("error"); // Expected to fail
}
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_error_handling_invalid_regex() {
let engine = create_test_engine();
let script = r#"
try {
let builder = text_replacer_builder();
builder = pattern(builder, "[invalid regex");
builder = replacement(builder, "test");
builder = regex(builder, true);
let replacer = build(builder);
return false; // Should have failed
} catch(err) {
return true; // Expected to fail
}
"#;
let result: Result<bool, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
assert_eq!(result.unwrap(), true);
}
#[test]
fn test_parameter_validation() {
let engine = create_test_engine();
// Test that functions handle parameter validation correctly
let script = r#"
let test_results = [];
// Test empty string handling
try {
let result = dedent("");
test_results.push(result == "");
} catch(err) {
test_results.push(false);
}
// Test empty prefix
try {
let result = prefix("test", "");
test_results.push(result == "test");
} catch(err) {
test_results.push(false);
}
// Test empty name_fix
try {
let result = name_fix("");
test_results.push(result == "");
} catch(err) {
test_results.push(false);
}
return test_results;
"#;
let result: Result<rhai::Array, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
let results = result.unwrap();
// All parameter validation tests should pass
for (i, result) in results.iter().enumerate() {
assert_eq!(
result.as_bool().unwrap_or(false),
true,
"Parameter validation test {} failed",
i
);
}
}
#[test]
fn test_unicode_handling() {
let engine = create_test_engine();
let script = r#"
let unicode_tests = [];
// Test dedent with unicode
try {
let text = " Hello 世界\n Goodbye 世界";
let result = dedent(text);
unicode_tests.push(result == "Hello 世界\nGoodbye 世界");
} catch(err) {
unicode_tests.push(false);
}
// Test name_fix with unicode (should remove non-ASCII)
try {
let result = name_fix("Café");
unicode_tests.push(result == "caf");
} catch(err) {
unicode_tests.push(false);
}
// Test prefix with unicode
try {
let result = prefix("Hello 世界", "🔹 ");
unicode_tests.push(result == "🔹 Hello 世界");
} catch(err) {
unicode_tests.push(false);
}
return unicode_tests;
"#;
let result: Result<rhai::Array, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
let results = result.unwrap();
// All unicode tests should pass
for (i, result) in results.iter().enumerate() {
assert_eq!(
result.as_bool().unwrap_or(false),
true,
"Unicode test {} failed",
i
);
}
}
#[test]
fn test_complex_text_processing_workflow() {
let engine = create_test_engine();
let script = r#"
// Simple workflow test
let unsafe_filename = "User's Script [Draft].py";
let safe_filename = name_fix(unsafe_filename);
let indented_code = " def hello():\n return True";
let dedented_code = dedent(indented_code);
let results = [];
results.push(safe_filename == "user_s_script_draft_.py");
results.push(dedented_code.contains("def hello():"));
return results;
"#;
let result: Result<rhai::Array, Box<EvalAltResult>> = engine.eval(script);
assert!(result.is_ok());
let results = result.unwrap();
// All workflow tests should pass
for (i, result) in results.iter().enumerate() {
assert_eq!(
result.as_bool().unwrap_or(false),
true,
"Workflow test {} failed",
i
);
}
}
}