Skip to content

Commit 7b58a69

Browse files
committed
Fix rendering of match explanations inside the some, ok and err matchers.
This changes the aforementioned matchers to use the `Description` API to construct match explanations rather than constructing a `String` directly and converting it to a `Description`. Doing this fixes the formatting when the nested matchers is generated by `all!` or `any!`. Fixed #325
1 parent 8cb3b6a commit 7b58a69

File tree

5 files changed

+145
-8
lines changed

5 files changed

+145
-8
lines changed

googletest/src/matchers/err_matcher.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ impl<T: Debug, E: Debug, InnerMatcherT: Matcher<ActualT = E>> Matcher
6161

6262
fn explain_match(&self, actual: &Self::ActualT) -> Description {
6363
match actual {
64-
Err(e) => format!("which is an error {}", self.inner.explain_match(e)).into(),
64+
Err(e) => {
65+
Description::new().text("which is an error").nested(self.inner.explain_match(e))
66+
}
6567
Ok(_) => "which is a success".into(),
6668
}
6769
}
@@ -128,7 +130,8 @@ mod tests {
128130
Value of: Err::<i32, i32>(1)
129131
Expected: is an error which is equal to 2
130132
Actual: Err(1),
131-
which is an error which isn't equal to 2
133+
which is an error
134+
which isn't equal to 2
132135
"
133136
))))
134137
)

googletest/src/matchers/ok_matcher.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ impl<T: Debug, E: Debug, InnerMatcherT: Matcher<ActualT = T>> Matcher
6161

6262
fn explain_match(&self, actual: &Self::ActualT) -> Description {
6363
match actual {
64-
Ok(o) => format!("which is a success {}", self.inner.explain_match(o)).into(),
64+
Ok(o) => {
65+
Description::new().text("which is a success").nested(self.inner.explain_match(o))
66+
}
6567
Err(_) => "which is an error".into(),
6668
}
6769
}
@@ -130,7 +132,8 @@ mod tests {
130132
Value of: Ok::<i32, i32>(1)
131133
Expected: is a success containing a value, which is equal to 2
132134
Actual: Ok(1),
133-
which is a success which isn't equal to 2
135+
which is a success
136+
which isn't equal to 2
134137
"
135138
))))
136139
)

googletest/src/matchers/some_matcher.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ impl<T: Debug, InnerMatcherT: Matcher<ActualT = T>> Matcher for SomeMatcher<T, I
5656

5757
fn explain_match(&self, actual: &Option<T>) -> Description {
5858
match (self.matches(actual), actual) {
59-
(_, Some(t)) => format!("which has a value {}", self.inner.explain_match(t)).into(),
59+
(_, Some(t)) => {
60+
Description::new().text("which has a value").nested(self.inner.explain_match(t))
61+
}
6062
(_, None) => "which is None".into(),
6163
}
6264
}
@@ -119,7 +121,8 @@ mod tests {
119121
Value of: Some(2)
120122
Expected: has a value which is equal to 1
121123
Actual: Some(2),
122-
which has a value which isn't equal to 1
124+
which has a value
125+
which isn't equal to 1
123126
"
124127
))))
125128
)
@@ -150,15 +153,15 @@ mod tests {
150153
fn some_explain_match_with_some_success() -> Result<()> {
151154
verify_that!(
152155
some(eq(1)).explain_match(&Some(1)),
153-
displays_as(eq("which has a value which is equal to 1"))
156+
displays_as(eq("which has a value\n which is equal to 1"))
154157
)
155158
}
156159

157160
#[test]
158161
fn some_explain_match_with_some_fail() -> Result<()> {
159162
verify_that!(
160163
some(eq(1)).explain_match(&Some(2)),
161-
displays_as(eq("which has a value which isn't equal to 1"))
164+
displays_as(eq("which has a value\n which isn't equal to 1"))
162165
)
163166
}
164167
}

googletest/tests/all_matcher_test.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,67 @@ fn all_multiple_failed_assertions() -> Result<()> {
8989
))))
9090
)
9191
}
92+
93+
#[test]
94+
fn formats_error_message_correctly_when_all_is_inside_some() -> Result<()> {
95+
let value = Some(4);
96+
let result = verify_that!(value, some(all![eq(1), eq(2), eq(3)]));
97+
verify_that!(
98+
result,
99+
err(displays_as(contains_substring(indoc!(
100+
"
101+
Value of: value
102+
Expected: has a value which has all the following properties:
103+
* is equal to 1
104+
* is equal to 2
105+
* is equal to 3
106+
Actual: Some(4),
107+
which has a value
108+
* which isn't equal to 1
109+
* which isn't equal to 2
110+
* which isn't equal to 3"
111+
))))
112+
)
113+
}
114+
115+
#[test]
116+
fn formats_error_message_correctly_when_all_is_inside_ok() -> Result<()> {
117+
let value: std::result::Result<i32, std::io::Error> = Ok(4);
118+
let result = verify_that!(value, ok(all![eq(1), eq(2), eq(3)]));
119+
verify_that!(
120+
result,
121+
err(displays_as(contains_substring(indoc!(
122+
"
123+
Value of: value
124+
Expected: is a success containing a value, which has all the following properties:
125+
* is equal to 1
126+
* is equal to 2
127+
* is equal to 3
128+
Actual: Ok(4),
129+
which is a success
130+
* which isn't equal to 1
131+
* which isn't equal to 2
132+
* which isn't equal to 3"
133+
))))
134+
)
135+
}
136+
137+
#[test]
138+
fn formats_error_message_correctly_when_all_is_inside_err() -> Result<()> {
139+
let value: std::result::Result<(), &'static str> = Err("An error");
140+
let result = verify_that!(value, err(all![starts_with("Not"), ends_with("problem")]));
141+
verify_that!(
142+
result,
143+
err(displays_as(contains_substring(indoc!(
144+
r#"
145+
Value of: value
146+
Expected: is an error which has all the following properties:
147+
* starts with prefix "Not"
148+
* ends with suffix "problem"
149+
Actual: Err("An error"),
150+
which is an error
151+
* which does not start with "Not"
152+
* which does not end with "problem""#
153+
))))
154+
)
155+
}

googletest/tests/any_matcher_test.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,67 @@ fn all_multiple_failed_assertions() -> Result<()> {
8989
))))
9090
)
9191
}
92+
93+
#[test]
94+
fn formats_error_message_correctly_when_any_is_inside_some() -> Result<()> {
95+
let value = Some(4);
96+
let result = verify_that!(value, some(any![eq(1), eq(2), eq(3)]));
97+
verify_that!(
98+
result,
99+
err(displays_as(contains_substring(indoc!(
100+
"
101+
Value of: value
102+
Expected: has a value which has at least one of the following properties:
103+
* is equal to 1
104+
* is equal to 2
105+
* is equal to 3
106+
Actual: Some(4),
107+
which has a value
108+
* which isn't equal to 1
109+
* which isn't equal to 2
110+
* which isn't equal to 3"
111+
))))
112+
)
113+
}
114+
115+
#[test]
116+
fn formats_error_message_correctly_when_any_is_inside_ok() -> Result<()> {
117+
let value: std::result::Result<i32, std::io::Error> = Ok(4);
118+
let result = verify_that!(value, ok(any![eq(1), eq(2), eq(3)]));
119+
verify_that!(
120+
result,
121+
err(displays_as(contains_substring(indoc!(
122+
"
123+
Value of: value
124+
Expected: is a success containing a value, which has at least one of the following properties:
125+
* is equal to 1
126+
* is equal to 2
127+
* is equal to 3
128+
Actual: Ok(4),
129+
which is a success
130+
* which isn't equal to 1
131+
* which isn't equal to 2
132+
* which isn't equal to 3"
133+
))))
134+
)
135+
}
136+
137+
#[test]
138+
fn formats_error_message_correctly_when_any_is_inside_err() -> Result<()> {
139+
let value: std::result::Result<(), &'static str> = Err("An error");
140+
let result = verify_that!(value, err(any![starts_with("Not"), ends_with("problem")]));
141+
verify_that!(
142+
result,
143+
err(displays_as(contains_substring(indoc!(
144+
r#"
145+
Value of: value
146+
Expected: is an error which has at least one of the following properties:
147+
* starts with prefix "Not"
148+
* ends with suffix "problem"
149+
Actual: Err("An error"),
150+
which is an error
151+
* which does not start with "Not"
152+
* which does not end with "problem""#
153+
))))
154+
)
155+
}

0 commit comments

Comments
 (0)