1use crate::error::{TestingError, TestingResult};
4use parking_lot::RwLock;
5use std::sync::Arc;
6
7#[derive(Debug, Clone)]
9pub struct MockCall {
10 pub args: Vec<String>,
12 pub timestamp: std::time::Instant,
14}
15
16#[derive(Debug, Clone)]
18pub enum MockResult<T> {
19 Return(T),
21 Error(String),
23 Sequence(Vec<T>),
25}
26
27impl<T: Clone> MockResult<T> {
28 pub fn return_value(value: T) -> Self {
30 MockResult::Return(value)
31 }
32
33 pub fn error(msg: impl Into<String>) -> Self {
35 MockResult::Error(msg.into())
36 }
37
38 pub fn sequence(values: Vec<T>) -> Self {
40 MockResult::Sequence(values)
41 }
42}
43
44#[derive(Debug, Default)]
46pub struct MockExpectation {
47 pub expected_calls: Option<usize>,
49 pub description: Option<String>,
51}
52
53impl MockExpectation {
54 pub fn new() -> Self {
56 Self::default()
57 }
58
59 pub fn times(mut self, count: usize) -> Self {
61 self.expected_calls = Some(count);
62 self
63 }
64
65 pub fn description(mut self, desc: impl Into<String>) -> Self {
67 self.description = Some(desc.into());
68 self
69 }
70}
71
72pub trait Mock: Send + Sync {
74 fn calls(&self) -> Vec<MockCall>;
76
77 fn call_count(&self) -> usize;
79
80 fn verify(&self) -> TestingResult<()>;
82
83 fn reset(&self);
85}
86
87pub struct MockBuilder<T> {
89 result: Option<MockResult<T>>,
90 expectation: MockExpectation,
91 calls: Arc<RwLock<Vec<MockCall>>>,
92}
93
94impl<T: Clone + Send + Sync + 'static> MockBuilder<T> {
95 pub fn new() -> Self {
97 Self { result: None, expectation: MockExpectation::default(), calls: Arc::new(RwLock::new(Vec::new())) }
98 }
99
100 pub fn return_value(mut self, value: T) -> Self {
102 self.result = Some(MockResult::return_value(value));
103 self
104 }
105
106 pub fn error(mut self, msg: impl Into<String>) -> Self {
108 self.result = Some(MockResult::error(msg));
109 self
110 }
111
112 pub fn sequence(mut self, values: Vec<T>) -> Self {
114 self.result = Some(MockResult::sequence(values));
115 self
116 }
117
118 pub fn expect(mut self, expectation: MockExpectation) -> Self {
120 self.expectation = expectation;
121 self
122 }
123
124 pub fn build(self) -> MockFn<T> {
126 MockFn {
127 result: self.result,
128 expectation: self.expectation,
129 calls: self.calls,
130 sequence_index: Arc::new(RwLock::new(0)),
131 }
132 }
133}
134
135impl<T: Clone + Send + Sync + 'static> Default for MockBuilder<T> {
136 fn default() -> Self {
137 Self::new()
138 }
139}
140
141pub struct MockFn<T> {
143 result: Option<MockResult<T>>,
144 expectation: MockExpectation,
145 calls: Arc<RwLock<Vec<MockCall>>>,
146 sequence_index: Arc<RwLock<usize>>,
147}
148
149impl<T: Clone> MockFn<T> {
150 pub fn call(&self, args: Vec<String>) -> TestingResult<T> {
152 {
153 let mut calls = self.calls.write();
154 calls.push(MockCall { args, timestamp: std::time::Instant::now() });
155 }
156
157 match &self.result {
158 Some(MockResult::Return(v)) => Ok(v.clone()),
159 Some(MockResult::Error(e)) => Err(TestingError::MockError(e.clone())),
160 Some(MockResult::Sequence(values)) => {
161 let mut idx = self.sequence_index.write();
162 if *idx < values.len() {
163 let value = values[*idx].clone();
164 *idx += 1;
165 Ok(value)
166 }
167 else {
168 Err(TestingError::MockError("Mock sequence exhausted".to_string()))
169 }
170 }
171 None => Err(TestingError::MockError("No mock result configured".to_string())),
172 }
173 }
174
175 pub async fn call_async(&self, args: Vec<String>) -> TestingResult<T> {
177 self.call(args)
178 }
179}
180
181impl<T: Clone + Send + Sync + 'static> Mock for MockFn<T> {
182 fn calls(&self) -> Vec<MockCall> {
183 self.calls.read().clone()
184 }
185
186 fn call_count(&self) -> usize {
187 self.calls.read().len()
188 }
189
190 fn verify(&self) -> TestingResult<()> {
191 let actual_calls = self.call_count();
192
193 if let Some(expected) = self.expectation.expected_calls
194 && actual_calls != expected
195 {
196 return Err(TestingError::AssertionFailed(format!("Expected {} calls, but got {}", expected, actual_calls)));
197 }
198
199 Ok(())
200 }
201
202 fn reset(&self) {
203 let mut calls = self.calls.write();
204 calls.clear();
205 let mut idx = self.sequence_index.write();
206 *idx = 0;
207 }
208}
209
210pub fn verify<M: Mock>(mock: &M) -> TestingResult<()> {
212 mock.verify()
213}