unimock/
error.rs

1use crate::alloc::{Box, String};
2use crate::{debug, mismatch::Mismatches, MockFnInfo};
3
4pub(crate) type MockResult<T> = Result<T, MockError>;
5
6#[derive(Clone)]
7pub(crate) enum MockError {
8    Downcast {
9        fn_call: debug::FnActualCall,
10        pattern: debug::CallPatternDebug,
11    },
12    NoMockImplementation {
13        fn_call: debug::FnActualCall,
14    },
15    NoMatcherFunction {
16        fn_call: debug::FnActualCall,
17        pattern: debug::CallPatternDebug,
18    },
19    NoMatchingCallPatterns {
20        fn_call: debug::FnActualCall,
21        mismatches: Mismatches,
22    },
23    NoOutputAvailableForCallPattern {
24        fn_call: debug::FnActualCall,
25        pattern: debug::CallPatternDebug,
26    },
27    MockNeverCalled {
28        info: MockFnInfo,
29    },
30    CallOrderNotMatchedForMockFn {
31        fn_call: debug::FnActualCall,
32        actual_call_order: CallOrder,
33        expected: Option<debug::CallPatternDebug>,
34    },
35    InputsNotMatchedInCallOrder {
36        fn_call: debug::FnActualCall,
37        actual_call_order: CallOrder,
38        pattern: debug::CallPatternDebug,
39        mismatches: Mismatches,
40    },
41    CannotReturnValueMoreThanOnce {
42        fn_call: debug::FnActualCall,
43        pattern: debug::CallPatternDebug,
44    },
45    FailedVerification(String),
46    CannotUnmock {
47        info: MockFnInfo,
48    },
49    NoDefaultImpl {
50        info: MockFnInfo,
51    },
52    NotAnswered {
53        info: MockFnInfo,
54    },
55    ExplicitPanic {
56        fn_call: debug::FnActualCall,
57        pattern: debug::CallPatternDebug,
58        msg: Box<str>,
59    },
60}
61
62impl core::fmt::Display for MockError {
63    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
64        match self {
65            Self::Downcast { fn_call, pattern } => {
66                write!(f, "{fn_call}: Fatal: Failed to downcast in {pattern}.")
67            }
68            Self::NoMockImplementation { fn_call } => {
69                write!(f, "{fn_call}: No mock implementation found.")
70            }
71            Self::NoMatcherFunction { fn_call, pattern } => {
72                write!(
73                    f,
74                    "{fn_call}: No function supplied for matching inputs for {pattern}."
75                )
76            }
77            Self::NoMatchingCallPatterns {
78                fn_call,
79                mismatches,
80            } => {
81                write!(f, "{fn_call}: No matching call patterns. {mismatches}")
82            }
83            Self::NoOutputAvailableForCallPattern { fn_call, pattern } => {
84                write!(
85                    f,
86                    "{fn_call}: No output available for after matching {pattern}."
87                )
88            }
89            Self::MockNeverCalled { info } => {
90                write!(
91                    f,
92                    "Mock for {path} was never called. Dead mocks should be removed.",
93                    path = info.path
94                )
95            }
96            Self::CallOrderNotMatchedForMockFn {
97                fn_call,
98                actual_call_order,
99                expected,
100            } => {
101                if let Some(expected) = expected {
102                    write!(f, "{fn_call}: Method matched in wrong order. Expected a call matching {expected}.")
103                } else {
104                    write!(f, "{fn_call}: Ordered call ({actual_call_order}) out of range: There were no more ordered call patterns in line for selection.")
105                }
106            }
107            Self::InputsNotMatchedInCallOrder {
108                fn_call,
109                actual_call_order,
110                pattern,
111                mismatches,
112            } => {
113                write!(f, "{fn_call}: Method invoked in the correct order ({actual_call_order}), but inputs didn't match {pattern}. {mismatches}")
114            }
115            Self::CannotReturnValueMoreThanOnce { fn_call, pattern } => {
116                write!(f, "{fn_call}: Cannot return value more than once from {pattern}, because of missing Clone bound. Try using `.each_call()` or explicitly quantifying the response.")
117            }
118            Self::FailedVerification(message) => write!(f, "{message}"),
119            Self::CannotUnmock { info } => {
120                write!(
121                    f,
122                    "{path} cannot be unmocked as there is no function available to call.",
123                    path = info.path
124                )
125            }
126            Self::NoDefaultImpl { info } => {
127                write!(
128                    f,
129                    "{path} has not been set up with default implementation delegation.",
130                    path = info.path
131                )
132            }
133            Self::NotAnswered { info } => {
134                write!(
135                    f,
136                    "{path} did not apply the answer function, this is a bug.",
137                    path = info.path
138                )
139            }
140            Self::ExplicitPanic {
141                fn_call,
142                pattern,
143                msg,
144            } => write!(f, "{fn_call}: Explicit panic from {pattern}: {msg}"),
145        }
146    }
147}
148
149#[derive(Clone)]
150pub struct CallOrder(pub usize);
151
152impl core::fmt::Display for CallOrder {
153    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
154        write!(f, "{}", self.0 + 1)
155    }
156}