v0.12.0
Pre-releaseBreaking changes
Matcher trait definition
The Matcher trait definition has changed:
Pre 0.12.0
pub trait Matcher {
type ActualT: Debug + ?Sized;
fn matches(&self, actual: &Self::ActualT) -> MatcherResult;
}
0.12.0
pub trait Matcher<ActualT: Debug + Copy> {
fn matches(&self, actual: ActualT) -> MatcherResult;
}
This makes the trait implementation more generic in three ways:
- A single struct can implement
Matcherfor multiple types, sinceActualis now a generic type parameter. ActualTcan be passed as value if it implementsCopy, which solved #351.- When
ActualTis a reference, theMatcherimplementation can put constraint on its lifetime, which solved #323.
We tried to make sure this change had as limited an impact on users of the library as possible. Often, the library can be updated without changes on the tests. However, there are two areas requiring changes:
Matcher implementation
Obviously, libraries implementing their own matcher will need to update their implementation to match the new trait definition. For instance:
Pre 0.12.0
#[derive(Debug)]
enum MyEnum {
...
}
struct MyEnumMatcher { ... }
impl Matcher for MyEnumMatcher {
type ActualT = MyEnumMatcher;
fn matches(&self, actual: &Self::ActualT) -> MatcherResult {
match actual {
...
}
}
}
will become:
#[derive(Debug)]
enum MyEnum {
...
}
#[derive(MatcherBase)]
struct MyEnumMatcher { ... }
impl Matcher<&MyEnum> for MyEnumMatcher {
fn matches(&self, actual: &MyEnum) -> MatcherResult {
match actual {
...
}
}
}
If MyEnum implements Copy, it is appropriate to also implement Matcher<MyEnum>.
MatcherBase is a super trait to Matcher which allow the usage of .and(...) and .or(...).
eq(...) often becomes eq(&...)
The eq(...) matcher now expects a type matching the actual reference-ness. In other words, you may get error:
no implementation for `&MyStruct == MyStruct`
for instance from a test like:
#[derive(Debug, PartialEq)]
struct MyStruct {...}
let actual = MyStruct {...};
let expected = MyStruct {...};
verify_that!(actual, eq(expected))
The issue is that actual is auto-ref to match the Copy bound from the matcher. However, verify_that! is not able to auto-ref expected which stays a MyStruct. The simple solution is to add a & before expected.
verify_that!(actual, eq(&expected))
Even if the snippet above compiles, it will look strange to the reader, as it seems to compare a MyStruct to a &MyStruct.
There are two solutions here:
- Add
&toactualas well, since the auto-ref will detect that another&is not necessary.verify_that!(&actual, eq(&expected)) - Use
verify_eq!()which supports auto-ref on bothactualandexpected.verify_eq!(actual, expected).
Changes to property! and matches_pattern!
Receiver reference-ness
property! and matches_pattern! now requires that the receiver must also be referenced in the declaration to match the method definition. In other words, fn method1(&self) -> ... requires matches_pattern!(&MyStruct { method1(): ....}) and property!(&MyStruct.method1(), ...).
Dereference not necessary
Previously, property! and matches_pattern! required to add a * to "dereference" the method returned value.
Pre 0.12.0
#[derive(Debug)]
struct MyStruct{
field: Field
};
impl MyStruct{
fn field(&self) -> &Field {&self.field}
}
verify_that!(MyStruct{...}, matches_pattern!(MyStruct{*field(): field_matcher()}))
In 0.12.0, this is not necessary nor supported
verify_that!(MyStruct{...}, matches_pattern!(&MyStruct{field(): field_matcher()}))
New features
expect_eq!(..., ...) and friends
GoogleTest now provides macros similar to assert_eq!() and friends with verify_ and expect_ behavior.
auto_eq
Most macro matchers now automatically inject eq() matchers if the parameters they are expecting does not implement Matcher.
For instance:
#[derive(Debug)]
struct MyStruct {
field1: String,
field2: String,
}
verify_that!(actual, matches_pattern!(MyStruct{field1: "field1", field2: "my field2"}))
Generalized .into_test_result()?
.into_test_result() now extends all std::result::Result and Option which simplifies error handling in test arrangements.
matches_pattern!(...) binding modes
matches_pattern!(...) now supports both move and reference binding modes, to be more consistent with Rust pattern matching.
For instance,
struct MyStruct {
field1: String,
field2: String
}
verify_that!(actual, matches_pattern!(MyStruct{field1: "something", field2: "else"}))
verify_that!(actual, matches_pattern!(&MyStruct{field1: ref "something", field2: ref "else"}))
This is useful, if you prefer to capture some fields by reference, with the ref keyword, and some by value (they would need to implement Copy).
Full Changelog: v0.11.0...v0.12.0