- 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.
This commit is contained in:
351
text/tests/rhai_integration_tests.rs
Normal file
351
text/tests/rhai_integration_tests.rs
Normal file
@@ -0,0 +1,351 @@
|
||||
//! 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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user