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
//! What:
//! Controls for the candidate error value.
//! Why:
//! The cause is what callers branch on and the message is the whole diagnostic,
//! so
//! constructing and printing the error must carry both unchanged.
//!
//! In TS you'd write (pseudocode):
//! ```ts
//! // expect(String(new CandidateError('git-failed', 'x'))).toBe('x');
//! ```
/// Import the error under test.
use super::{CandidateError, CandidateFailure};
/// Printing yields exactly the stored message,
/// and the cause is kept beside it.
#[test]
fn display_prints_exactly_the_message() {
for message in ["git diff-index failed", "two\nlines \"quoted\"", ""] {
let error: CandidateError = CandidateError::new(CandidateFailure::GitFailed, message);
assert_eq!(error.failure, CandidateFailure::GitFailed);
assert_eq!(error.message, message);
// `.to_string()` goes through the `Display` implementation under test.
assert_eq!(error.to_string(), message);
assert_eq!(format!("[{error}]"), format!("[{message}]"));
}
}
/// Errors compare by cause and message,
/// and report no underlying cause.
#[test]
fn errors_compare_by_cause_and_message() {
let stale: CandidateError = CandidateError::new(CandidateFailure::StaleCandidate, "a");
assert_eq!(
stale,
CandidateError::new(CandidateFailure::StaleCandidate, "a")
);
assert_ne!(
stale,
CandidateError::new(CandidateFailure::StaleCandidate, "b")
);
assert_ne!(
stale,
CandidateError::new(CandidateFailure::ReaderEnded, "a")
);
// `&dyn Error` views the value through the standard error interface only.
let general: &dyn std::error::Error = &stale;
assert!(general.source().is_none());
assert_eq!(general.to_string(), "a");
}