1use crate::backend::Assertion;
2use std::cell::RefCell;
3
4#[derive(Debug, Clone)]
6pub enum AssertionEvent {
7 Success(Assertion<()>),
9 Failure(Assertion<()>),
11 SessionCompleted,
13}
14
15type AssertionHandler = Box<dyn Fn(Assertion<()>)>;
18
19thread_local! {
20 static SUCCESS_HANDLERS: RefCell<Vec<AssertionHandler>> = RefCell::new(Vec::new());
21 static FAILURE_HANDLERS: RefCell<Vec<AssertionHandler>> = RefCell::new(Vec::new());
22 static SESSION_COMPLETED_HANDLERS: RefCell<Vec<Box<dyn Fn()>>> = RefCell::new(Vec::new());
23 static INITIALIZED: RefCell<bool> = const { RefCell::new(false) };
24}
25
26pub struct EventEmitter;
28
29impl EventEmitter {
30 pub fn init() {
32 INITIALIZED.with(|initialized| {
33 let mut initialized = initialized.borrow_mut();
34 if !*initialized {
35 *initialized = true;
36 }
37 });
38 }
39
40 pub fn emit(event: AssertionEvent) {
42 match event {
43 AssertionEvent::Success(assertion) => {
44 SUCCESS_HANDLERS.with(|handlers| {
45 let handlers = handlers.borrow();
46 for handler in handlers.iter() {
47 handler(assertion.clone());
48 }
49 });
50 }
51 AssertionEvent::Failure(assertion) => {
52 FAILURE_HANDLERS.with(|handlers| {
53 let handlers = handlers.borrow();
54 for handler in handlers.iter() {
55 handler(assertion.clone());
56 }
57 });
58 }
59 AssertionEvent::SessionCompleted => {
60 SESSION_COMPLETED_HANDLERS.with(|handlers| {
61 let handlers = handlers.borrow();
62 for handler in handlers.iter() {
63 handler();
64 }
65 });
66 }
67 }
68 }
69}
70
71pub fn on_success<F>(handler: F)
73where
74 F: Fn(Assertion<()>) + 'static,
75{
76 SUCCESS_HANDLERS.with(|handlers| {
77 handlers.borrow_mut().push(Box::new(handler));
78 });
79}
80
81pub fn on_failure<F>(handler: F)
83where
84 F: Fn(Assertion<()>) + 'static,
85{
86 FAILURE_HANDLERS.with(|handlers| {
87 handlers.borrow_mut().push(Box::new(handler));
88 });
89}
90
91pub fn on_session_completed<F>(handler: F)
93where
94 F: Fn() + 'static,
95{
96 SESSION_COMPLETED_HANDLERS.with(|handlers| {
97 handlers.borrow_mut().push(Box::new(handler));
98 });
99}
100
101#[doc(hidden)]
104pub fn initialize_event_system() {
105 EventEmitter::init();
106
107 crate::Reporter::init();
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114 use crate::backend::assertions::AssertionStep;
115 use crate::backend::assertions::sentence::AssertionSentence;
116 use std::cell::RefCell;
117 use std::rc::Rc;
118
119 fn create_test_assertion() -> Assertion<()> {
121 let mut assertion = Assertion::new((), "test_value");
122 assertion.steps.push(AssertionStep { sentence: AssertionSentence::new("be", "test assertion"), passed: true, logical_op: None });
123 assertion
124 }
125
126 #[test]
127 fn test_event_emitter_init() {
128 EventEmitter::init();
130
131 INITIALIZED.with(|initialized| {
133 assert_eq!(*initialized.borrow(), true);
134 });
135 }
136
137 #[test]
138 fn test_on_success_handler() {
139 let called = Rc::new(RefCell::new(false));
141 let called_clone = called.clone();
142
143 on_success(move |_| {
145 *called.borrow_mut() = true;
146 });
147
148 let assertion = create_test_assertion();
150 EventEmitter::emit(AssertionEvent::Success(assertion));
151
152 assert_eq!(*called_clone.borrow(), true);
154 }
155
156 #[test]
157 fn test_on_failure_handler() {
158 let called = Rc::new(RefCell::new(false));
160 let called_clone = called.clone();
161
162 on_failure(move |_| {
164 *called.borrow_mut() = true;
165 });
166
167 let assertion = create_test_assertion();
169 EventEmitter::emit(AssertionEvent::Failure(assertion));
170
171 assert_eq!(*called_clone.borrow(), true);
173 }
174
175 #[test]
176 fn test_on_session_completed_handler() {
177 let called = Rc::new(RefCell::new(false));
179 let called_clone = called.clone();
180
181 on_session_completed(move || {
183 *called.borrow_mut() = true;
184 });
185
186 EventEmitter::emit(AssertionEvent::SessionCompleted);
188
189 assert_eq!(*called_clone.borrow(), true);
191 }
192
193 #[test]
194 fn test_multiple_handlers() {
195 let success_count = Rc::new(RefCell::new(0));
197 let success_count_clone = success_count.clone();
198
199 let failure_count = Rc::new(RefCell::new(0));
200 let failure_count_clone = failure_count.clone();
201
202 let session_count = Rc::new(RefCell::new(0));
203 let session_count_clone = session_count.clone();
204
205 for _ in 0..3 {
207 let count = success_count.clone();
208 on_success(move |_| {
209 *count.borrow_mut() += 1;
210 });
211
212 let count = failure_count.clone();
213 on_failure(move |_| {
214 *count.borrow_mut() += 1;
215 });
216
217 let count = session_count.clone();
218 on_session_completed(move || {
219 *count.borrow_mut() += 1;
220 });
221 }
222
223 let assertion = create_test_assertion();
225 EventEmitter::emit(AssertionEvent::Success(assertion.clone()));
226 EventEmitter::emit(AssertionEvent::Failure(assertion));
227 EventEmitter::emit(AssertionEvent::SessionCompleted);
228
229 assert_eq!(*success_count_clone.borrow(), 3);
231 assert_eq!(*failure_count_clone.borrow(), 3);
232 assert_eq!(*session_count_clone.borrow(), 3);
233 }
234
235 #[test]
236 fn test_assertion_event_debug() {
237 let assertion = create_test_assertion();
239 let success_event = AssertionEvent::Success(assertion.clone());
240 let failure_event = AssertionEvent::Failure(assertion);
241 let session_event = AssertionEvent::SessionCompleted;
242
243 assert!(!format!("{:?}", success_event).is_empty());
245 assert!(!format!("{:?}", failure_event).is_empty());
246 assert!(!format!("{:?}", session_event).is_empty());
247 }
248}