use rok_utils::{
apply, compose, memoize, or_default, pipe, retry, tap, Lazy, RokError, RokResultExt,
};
#[test]
fn error_enum() {
let err = RokError::NotFound("User #42".into());
assert_eq!(err.code(), "E_NOT_FOUND");
assert_eq!(err.status(), 404);
assert!(err.is_self_handled());
let err = RokError::Unauthorized("token".into());
assert_eq!(err.code(), "E_UNAUTHORIZED");
assert_eq!(err.status(), 401);
let err = RokError::ValidationFailure {
field: "email".into(),
reason: "invalid".into(),
};
assert_eq!(err.code(), "E_VALIDATION_FAILURE");
assert_eq!(err.status(), 422);
let err = RokError::Internal("oops".into());
assert_eq!(err.status(), 500);
}
#[test]
fn error_result_ext() {
let result: Result<i32, RokError> = Ok(42);
assert_eq!(result.unwrap(), 42);
let result: Result<i32, RokError> = Err(RokError::NotFound("test".into()));
let with_context = result.context("failed");
assert!(matches!(with_context, Err(RokError::Wrapped { .. })));
}
#[test]
fn fp_pipe() {
let result = pipe(1, vec![|x| x + 1, |x| x * 2]);
assert_eq!(result, 4);
}
#[test]
fn fp_compose() {
let add_one = |x: i32| x + 1;
let double = |x: i32| x * 2;
let composed = compose(double, add_one);
assert_eq!(composed(5), 12);
}
#[test]
fn fp_tap() {
let mut captured = 0;
let _ = tap(42, |v| captured = *v);
assert_eq!(captured, 42);
}
#[test]
fn fp_apply() {
let result = apply(5, |x| x * 3);
assert_eq!(result, 15);
}
#[test]
fn fp_or_default() {
assert_eq!(or_default(Some(42)), 42);
assert_eq!(or_default(None::<i32>), 0);
}
#[test]
fn fp_retry_success() {
let result = retry(3, || Ok::<i32, i32>(42));
assert_eq!(result.unwrap(), 42);
}
#[test]
fn fp_retry_eventual() {
let mut attempts = 0;
let result = retry(3, &mut || {
attempts += 1;
if attempts < 3 {
Err(1)
} else {
Ok(42)
}
});
assert_eq!(result.unwrap(), 42);
assert_eq!(attempts, 3);
}
#[test]
fn fp_lazy() {
let lazy: Lazy<i32, fn() -> i32> = Lazy::new(|| 42);
assert_eq!(*lazy.get(), 42);
assert_eq!(*lazy.get(), 42);
}
#[test]
fn fp_memoize() {
let memoized = memoize(|x: i32| x * 2);
assert_eq!(memoized(5), 10);
assert_eq!(memoized(5), 10);
assert_eq!(memoized(3), 6);
assert_eq!(memoized(3), 6);
}
#[cfg(feature = "json")]
use rok_utils::types::{
deep_equal, get_path, is_array, is_bool, is_defined, is_null, is_number, is_object, is_string,
set_path,
};
#[cfg(feature = "json")]
#[test]
fn json_type_guards() {
use serde_json::json;
assert!(is_string(&json!("hello")));
assert!(!is_string(&json!(42)));
assert!(is_number(&json!(42)));
assert!(!is_number(&json!("hello")));
assert!(is_bool(&json!(true)));
assert!(!is_bool(&json!(42)));
assert!(is_array(&json!([1, 2, 3])));
assert!(!is_array(&json!(42)));
assert!(is_object(&json!({"a": 1})));
assert!(!is_object(&json!([1, 2])));
assert!(is_null(&json!(null)));
assert!(!is_null(&json!(42)));
assert!(is_defined(&json!(42)));
assert!(!is_defined(&json!(null)));
}
#[cfg(feature = "json")]
#[test]
fn json_deep_equal() {
use serde_json::json;
assert!(deep_equal(&json!({"a": 1}), &json!({"a": 1})));
assert!(!deep_equal(&json!({"a": 1}), &json!({"a": 2})));
assert!(deep_equal(&json!([1, 2, 3]), &json!([1, 2, 3])));
}
#[cfg(feature = "json")]
#[test]
fn json_get_path() {
use serde_json::json;
let val = json!({"user": {"name": "Alice", "age": 30}});
assert_eq!(get_path(&val, "user.name"), Some(&json!("Alice")));
assert_eq!(get_path(&val, "user.age"), Some(&json!(30)));
assert_eq!(get_path(&val, "user.foo"), None);
}
#[cfg(feature = "json")]
#[test]
fn json_set_path() {
use serde_json::json;
let val = json!({"a": 1});
let result = set_path(val, "b", json!(2));
assert_eq!(result.get("b"), Some(&json!(2)));
}