use qubit_function::{
BoxFunctionOnce,
FunctionOnce,
Predicate,
RcPredicate,
};
#[test]
fn test_function_once_trait_apply() {
let double = |x: &i32| x * 2;
assert_eq!(double.apply(&21), 42);
}
#[test]
fn test_function_once_trait_apply_with_move() {
let value = String::from("hello");
let append = move |s: &String| format!("{} {}", s, value);
assert_eq!(append.apply(&String::from("world")), "world hello");
}
#[test]
fn test_box_function_once_new() {
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
assert_eq!(double.apply(&21), 42);
}
#[test]
fn test_box_function_once_new_allows_non_static_t() {
fn run<'a>(value: &'a str) -> usize {
let func: BoxFunctionOnce<&'a str, usize> =
BoxFunctionOnce::new(|x: &&'a str| x.len());
func.apply(&value)
}
let text = String::from("hello");
assert_eq!(run(text.as_str()), 5);
}
#[test]
fn test_box_function_once_new_allows_non_static_r() {
fn run<'a>(value: &'a str) -> &'a str {
let func: BoxFunctionOnce<&'a str, &'a str> =
BoxFunctionOnce::new(|x: &&'a str| *x);
func.apply(&value)
}
let text = String::from("qubit");
assert_eq!(run(text.as_str()), "qubit");
}
#[test]
fn test_box_function_once_new_with_move() {
let data = vec![1, 2, 3];
let extend = BoxFunctionOnce::new(move |v: &Vec<i32>| {
let mut result = v.clone();
result.extend(data);
result
});
let input = vec![0];
assert_eq!(extend.apply(&input), vec![0, 1, 2, 3]);
}
#[test]
fn test_box_function_once_identity() {
let identity = BoxFunctionOnce::<i32, i32>::identity();
assert_eq!(identity.apply(&42), 42);
}
#[test]
fn test_box_function_once_constant() {
let constant = BoxFunctionOnce::constant("hello");
assert_eq!(constant.apply(&123), "hello");
}
#[test]
fn test_box_function_once_apply() {
let add_one = BoxFunctionOnce::new(|x: &i32| x + 1);
assert_eq!(add_one.apply(&41), 42);
}
#[test]
fn test_box_function_once_and_then() {
let add_one = BoxFunctionOnce::new(|x: &i32| x + 1);
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
let composed = add_one.and_then(double);
assert_eq!(composed.apply(&5), 12); }
#[test]
fn test_box_function_once_and_then_with_move() {
let data1 = vec![1, 2];
let data2 = vec![3, 4];
let extend1 = BoxFunctionOnce::new(move |v: &Vec<i32>| {
let mut result = v.clone();
result.extend(data1);
result
});
let extend2 = BoxFunctionOnce::new(move |v: &Vec<i32>| {
let mut result = v.clone();
result.extend(data2);
result
});
let composed = extend1.and_then(extend2);
let input = vec![0];
assert_eq!(composed.apply(&input), vec![0, 1, 2, 3, 4]);
}
#[test]
fn test_box_function_once_when_or_else() {
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
let identity = BoxFunctionOnce::<i32, i32>::identity();
let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
assert_eq!(conditional.apply(&5), 10);
}
#[test]
fn test_box_function_once_when_or_else_negative() {
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
let identity = BoxFunctionOnce::<i32, i32>::identity();
let conditional = double.when(|x: &i32| *x > 0).or_else(identity);
assert_eq!(conditional.apply(&-5), -5);
}
#[test]
fn test_box_function_once_when_with_closure() {
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
let conditional = double.when(|x: &i32| *x >= 10).or_else(|x: &i32| *x);
assert_eq!(conditional.apply(&15), 30);
}
#[test]
fn test_box_function_once_when_with_predicate() {
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
let is_positive = RcPredicate::new(|x: &i32| *x > 0);
let conditional = double
.when(is_positive.clone())
.or_else(BoxFunctionOnce::<i32, i32>::identity());
assert_eq!(conditional.apply(&5), 10);
assert!(is_positive.test(&3));
}
#[test]
fn test_box_function_once_when_with_move() {
let multiplier = 3;
let double = BoxFunctionOnce::new(move |x: &i32| x * multiplier);
let negate = BoxFunctionOnce::new(|x: &i32| -(*x));
let conditional = double.when(|x: &i32| *x > 0).or_else(negate);
assert_eq!(conditional.apply(&5), 15);
}
#[test]
fn test_function_once_with_zero() {
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
assert_eq!(double.apply(&0), 0);
}
#[test]
fn test_function_once_with_negative() {
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
assert_eq!(double.apply(&-42), -84);
}
#[test]
fn test_function_once_with_max_value() {
let identity = BoxFunctionOnce::<i32, i32>::identity();
assert_eq!(identity.apply(&i32::MAX), i32::MAX);
}
#[test]
fn test_function_once_with_min_value() {
let identity = BoxFunctionOnce::<i32, i32>::identity();
assert_eq!(identity.apply(&i32::MIN), i32::MIN);
}
#[test]
fn test_function_once_chain_multiple() {
let add_one = BoxFunctionOnce::new(|x: &i32| x + 1);
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
let add_ten = BoxFunctionOnce::new(|x: &i32| x + 10);
let composed = add_one.and_then(double).and_then(add_ten);
assert_eq!(composed.apply(&5), 22); }
#[test]
fn test_function_once_with_string() {
let to_upper = BoxFunctionOnce::new(|s: &String| s.to_uppercase());
let input = String::from("hello");
assert_eq!(to_upper.apply(&input), "HELLO");
}
#[test]
fn test_function_once_with_vec() {
let get_len = BoxFunctionOnce::new(|v: &Vec<i32>| v.len());
let vec = vec![1, 2, 3, 4, 5];
assert_eq!(get_len.apply(&vec), 5);
}
#[test]
fn test_function_once_with_option() {
let unwrap_or_zero =
BoxFunctionOnce::new(|opt: &Option<i32>| opt.unwrap_or(0));
assert_eq!(unwrap_or_zero.apply(&Some(42)), 42);
}
#[test]
fn test_function_once_with_option_none() {
let unwrap_or_zero =
BoxFunctionOnce::new(|opt: &Option<i32>| opt.unwrap_or(0));
assert_eq!(unwrap_or_zero.apply(&None), 0);
}
#[test]
fn test_conditional_function_once_edge_cases() {
let double = BoxFunctionOnce::new(|x: &i32| x * 2);
let negate = BoxFunctionOnce::new(|x: &i32| -(*x));
let conditional = double.when(|x: &i32| *x >= 0).or_else(negate);
assert_eq!(conditional.apply(&0), 0);
}
#[test]
fn test_function_once_with_moved_vec() {
let data = vec![1, 2, 3];
let func = BoxFunctionOnce::new(move |x: &i32| {
let mut result = data.clone();
result.push(*x);
result
});
assert_eq!(func.apply(&4), vec![1, 2, 3, 4]);
}
#[test]
fn test_function_once_with_moved_string() {
let prefix = String::from("Hello, ");
let func =
BoxFunctionOnce::new(move |s: &String| format!("{}{}", prefix, s));
assert_eq!(func.apply(&String::from("World")), "Hello, World");
}
#[test]
fn test_function_once_with_complex_closure() {
let threshold = 10;
let multiplier = 2;
let func =
BoxFunctionOnce::new(
move |x: &i32| {
if *x > threshold { x * multiplier } else { *x }
},
);
assert_eq!(func.apply(&15), 30);
}
#[test]
fn test_function_once_with_complex_closure_below_threshold() {
let threshold = 10;
let multiplier = 2;
let func =
BoxFunctionOnce::new(
move |x: &i32| {
if *x > threshold { x * multiplier } else { *x }
},
);
assert_eq!(func.apply(&5), 5);
}
#[test]
fn test_function_once_resource_transfer() {
let buffer = vec![1, 2, 3];
let transfer = BoxFunctionOnce::new(move |target: &Vec<i32>| {
let mut result = target.clone();
result.extend(buffer);
result
});
let target = vec![0];
let result = transfer.apply(&target);
assert_eq!(result, vec![0, 1, 2, 3]);
}
#[test]
fn test_function_once_with_box() {
let data = Box::new(42);
let func = BoxFunctionOnce::new(move |x: &i32| *data + *x);
assert_eq!(func.apply(&8), 50);
}
#[test]
fn test_function_once_with_rc() {
use std::rc::Rc;
let data = Rc::new(vec![1, 2, 3]);
let func = BoxFunctionOnce::new(move |x: &i32| data.len() + (*x as usize));
assert_eq!(func.apply(&2), 5);
}