//! 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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> = 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 ); } } }