use rhai::{Engine, EvalAltResult}; use sal_redisclient::rhai::*; #[cfg(test)] mod rhai_integration_tests { use super::*; fn create_test_engine() -> Engine { let mut engine = Engine::new(); register_redisclient_module(&mut engine).expect("Failed to register redisclient module"); engine } #[test] fn test_rhai_module_registration() { let engine = create_test_engine(); // Test that the functions are registered let script = r#" // Just test that the functions exist and can be called // We don't test actual Redis operations here since they require a server true "#; let result: Result> = engine.eval(script); assert!(result.is_ok()); assert_eq!(result.unwrap(), true); } #[test] fn test_rhai_redis_functions_exist() { let engine = create_test_engine(); // Test that all expected functions are registered by attempting to call them // We expect them to either succeed or fail with Redis connection errors, // but NOT with "function not found" errors let function_tests = [ ("redis_ping()", "redis_ping"), ("redis_set(\"test\", \"value\")", "redis_set"), ("redis_get(\"test\")", "redis_get"), ("redis_del(\"test\")", "redis_del"), ("redis_hset(\"hash\", \"field\", \"value\")", "redis_hset"), ("redis_hget(\"hash\", \"field\")", "redis_hget"), ("redis_hgetall(\"hash\")", "redis_hgetall"), ("redis_hdel(\"hash\", \"field\")", "redis_hdel"), ("redis_rpush(\"list\", \"value\")", "redis_rpush"), ("redis_llen(\"list\")", "redis_llen"), ("redis_lrange(\"list\", 0, -1)", "redis_lrange"), ("redis_reset()", "redis_reset"), ]; for (script, func_name) in &function_tests { let result = engine.eval::(script); // The function should be registered - if not, we'd get "Function not found" // If Redis is not available, we might get connection errors, which is fine if let Err(err) = result { let error_msg = err.to_string(); assert!( !error_msg.contains("Function not found") && !error_msg.contains("Variable not found"), "Function {} should be registered but got: {}", func_name, error_msg ); } // If it succeeds, that's even better - the function is registered and working } } #[test] fn test_rhai_function_signatures() { let engine = create_test_engine(); // Test function signatures by calling them with mock/invalid data // This verifies they're properly registered and have correct parameter counts // Test functions that should fail gracefully with invalid Redis connection let test_cases = vec![ ( "redis_set(\"test\", \"value\")", "redis_set should accept 2 string parameters", ), ( "redis_get(\"test\")", "redis_get should accept 1 string parameter", ), ( "redis_del(\"test\")", "redis_del should accept 1 string parameter", ), ( "redis_hset(\"hash\", \"field\", \"value\")", "redis_hset should accept 3 string parameters", ), ( "redis_hget(\"hash\", \"field\")", "redis_hget should accept 2 string parameters", ), ( "redis_hgetall(\"hash\")", "redis_hgetall should accept 1 string parameter", ), ( "redis_hdel(\"hash\", \"field\")", "redis_hdel should accept 2 string parameters", ), ( "redis_rpush(\"list\", \"value\")", "redis_rpush should accept 2 string parameters", ), ( "redis_llen(\"list\")", "redis_llen should accept 1 string parameter", ), ( "redis_lrange(\"list\", 0, -1)", "redis_lrange should accept string and 2 integers", ), ]; for (script, description) in test_cases { let result = engine.eval::(script); // We expect these to either succeed (if Redis is available) or fail with Redis connection error // But they should NOT fail with "function not found" or "wrong number of parameters" if let Err(err) = result { let error_msg = err.to_string(); assert!( !error_msg.contains("Function not found") && !error_msg.contains("wrong number of arguments") && !error_msg.contains("expects") && !error_msg.contains("parameters"), "{}: Got parameter error: {}", description, error_msg ); } } } // Helper function to check if Redis is available for integration tests fn is_redis_available() -> bool { match sal_redisclient::get_redis_client() { Ok(_) => true, Err(_) => false, } } #[test] fn test_rhai_redis_ping_integration() { if !is_redis_available() { println!("Skipping Redis integration test - Redis server not available"); return; } let engine = create_test_engine(); let script = r#" let result = redis_ping(); result == "PONG" "#; let result: Result> = engine.eval(script); if result.is_ok() { assert_eq!(result.unwrap(), true); } else { println!("Redis ping test failed: {:?}", result.err()); } } #[test] fn test_rhai_redis_set_get_integration() { if !is_redis_available() { println!("Skipping Redis integration test - Redis server not available"); return; } let engine = create_test_engine(); let script = r#" // Set a test value redis_set("rhai_test_key", "rhai_test_value"); // Get the value back let value = redis_get("rhai_test_key"); // Clean up redis_del("rhai_test_key"); value == "rhai_test_value" "#; let result: Result> = engine.eval(script); if result.is_ok() { assert_eq!(result.unwrap(), true); } else { println!("Redis set/get test failed: {:?}", result.err()); } } }