1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// =============================================================================
// Copyright (c) 2025 - 2026 Haixing Hu.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0.
// =============================================================================
//! Comprehensive tests for BiFunction trait and its implementations
use qubit_function::{
ArcBiFunction,
ArcBiPredicate,
BiFunction,
BiFunctionOnce,
BoxBiFunction,
RcBiFunction,
RcBiPredicate,
};
// ============================================================================
// BiFunction Trait Tests - Core Functionality
// ============================================================================
#[test]
fn test_rc_conditional_bi_function_clone() {
let add = RcBiFunction::new(|x: &i32, y: &i32| *x + *y);
let multiply = RcBiFunction::new(|x: &i32, y: &i32| *x * *y);
let conditional = add
.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
.or_else(multiply);
let cloned = conditional.clone();
// Test original
assert_eq!(conditional.apply(&3, &4), 7); // when branch: 3 + 4 = 7
assert_eq!(conditional.apply(&-3, &4), -12); // or_else branch: -3 * 4 = -12
// Test cloned (should behave identically)
assert_eq!(cloned.apply(&3, &4), 7); // when branch: 3 + 4 = 7
assert_eq!(cloned.apply(&-3, &4), -12); // or_else branch: -3 * 4 = -12
}
#[test]
fn test_arc_conditional_bi_function_clone() {
let add = ArcBiFunction::new(|x: &i32, y: &i32| *x + *y);
let multiply = ArcBiFunction::new(|x: &i32, y: &i32| *x * *y);
let conditional = add
.when(|x: &i32, y: &i32| *x > 0 && *y > 0)
.or_else(multiply);
let cloned = conditional.clone();
// Test original
assert_eq!(conditional.apply(&3, &4), 7); // when branch: 3 + 4 = 7
assert_eq!(conditional.apply(&-3, &4), -12); // or_else branch: -3 * 4 = -12
// Test cloned (should behave identically)
assert_eq!(cloned.apply(&3, &4), 7); // when branch: 3 + 4 = 7
assert_eq!(cloned.apply(&-3, &4), -12); // or_else branch: -3 * 4 = -12
}
#[test]
fn test_impl_conditional_function_clone_three_params_macro_coverage() {
// Test to ensure the three-parameter version of
// impl_conditional_function_clone macro is covered This test verifies
// that the macro generates Clone implementations for three-parameter
// structs by testing that RcConditionalBiFunction and
// ArcConditionalBiFunction implement Clone
// Test RcConditionalBiFunction (three parameters: T, U, R)
{
let add = RcBiFunction::new(|x: &i32, y: &i32| *x + *y);
let pred = RcBiPredicate::new(|x: &i32, y: &i32| *x > 0 && *y > 0);
let conditional_rc = add.when(pred);
let cloned_rc = conditional_rc.clone();
// Create or_else to test functionality
let multiply = RcBiFunction::new(|x: &i32, y: &i32| *x * *y);
let func = cloned_rc.or_else(multiply);
// Verify functionality
assert_eq!(func.apply(&3, &4), 7); // when branch
assert_eq!(func.apply(&-3, &4), -12); // or_else branch: -3 * 4 = -12
}
// Test ArcConditionalBiFunction (three parameters: T, U, R)
{
let subtract = ArcBiFunction::new(|x: &i32, y: &i32| *x - *y);
let pred = ArcBiPredicate::new(|x: &i32, y: &i32| *x >= *y);
let conditional_arc = subtract.when(pred);
let cloned_arc = conditional_arc.clone();
// Create or_else to test functionality
let negate = ArcBiFunction::new(|x: &i32, y: &i32| -*x - *y);
let func = cloned_arc.or_else(negate);
// Verify functionality
assert_eq!(func.apply(&5, &3), 2); // when branch: 5 - 3 = 2
assert_eq!(func.apply(&3, &5), -8); // or_else branch: -(3 + 5) = -8
}
}
// ============================================================================
// Advanced Composition Tests
// ============================================================================
// ============================================================================
// Thread Safety Tests for ArcBiFunction
// ============================================================================
#[test]
fn test_arc_bi_function_and_then() {
use qubit_function::ArcFunction;
let add = ArcBiFunction::new(|x: &i32, y: &i32| *x + *y);
let multiply_by_two = ArcFunction::new(|x: &i32| *x * 2);
let chained = add.and_then(multiply_by_two);
assert_eq!(chained.apply(&2, &3), 10); // (2+3) * 2 = 10
}
#[test]
fn test_arc_bi_function_thread_safety() {
use std::thread;
let func = ArcBiFunction::new(|x: &i32, y: &i32| *x + *y);
let func_clone = func.clone();
let handle = thread::spawn(move || func_clone.apply(&10, &20));
let result = handle.join().expect("thread should not panic");
assert_eq!(result, 30);
assert_eq!(func.apply(&10, &20), 30);
}