Some checks failed
Rhai Tests / Run Rhai Tests (push) Has been cancelled
- Add a new crate `sal-text` for text manipulation utilities. - Integrate `sal-text` into the main `sal` crate. - Remove the previous `text` module from `sal`. This improves organization and allows for independent development of the `sal-text` library.
352 lines
11 KiB
Rust
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 == "users_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/users_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) == "sal_text::replace::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, r"\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, r"\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 == "users_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
|
|
);
|
|
}
|
|
}
|
|
}
|