Skip to content

Releases: google/googletest-rust

0.7.0

19 May 17:03
Compare
Choose a tag to compare
0.7.0 Pre-release
Pre-release

API changes

  • The matcher size has been renamed to len to be more idiomatic in Rust.

    OLD:

    let value = vec![...];
    verify_that!(value, size(eq(1)))
    

    NEW:

    let value = vec![...];
    verify_that!(value, len(eq(1)))
    
  • The extension traits AndMatcherExt and OrMatcherExt have been removed, their methods and() and or() folded into Matcher. In the vast majority of cases, it should suffice just to remove the imports of AndMatcherExt and OrMatcherExt and instead import Matcher (if not already done).

    OLD:

    use googletest::matchers::{AndMatcherExt, OrMatcherExt};
    
    #[test]
    fn should_work() {
        verify_that!(value, starts_with("Something").and(ends_with("else").or(contains_substring("another thing"))))
    }
    

    NEW:

    use googletest::matcher::Matcher;
    // or, recommended:
    use googletest::prelude::*;
    
    #[test]
    fn should_work() {
        verify_that!(value, starts_with("Something").and(ends_with("else").or(contains_substring("another thing"))))
    }
    

    Importing all symbols in googletest::prelude causes Matcher to be imported.

  • The method Matcher::explain_match now returns just a String. The previous structure MatchExplanation has been removed. This has no effect on the uses of matchers, but does require some minor porting of implementations of the Matcher trait.

    OLD:

    fn explain_match(&self, actual: &Self::ActualT) -> MatchExplanation {
        MatchExplanation(format!("which ..."))
    }
    

    NEW:

    fn explain_match(&self, actual: &Self::ActualT) -> String {
        format!("which ...")
    }
    

New features and other changes

  • GoogleTest Rust now works with rustc 1.59. Previously, the minimum required rustc version was 1.67.

  • The expect_that! and expect_pred! macros as well as the and_log_failure() extension method will now panic if they are invoked without having used the googletest::test attribute. Previously, it was all too easy to forget to annotate the test with #[googletest::test] when using the expect_* family of assertions. The result was that the assertions would not do anything! Now, the test will immediately panic in that situation.

    The assertions will also now panic if invoked in a thread other than that in which one is running the test.

  • The output of the actual value in test assertion failure messages will no longer pretty-print if the value's debug output is a single line of at most 60 characters. This should reduce visual clutter. For example, a value of Some(123) previously would be output:

    Actual: Some(
      123
    )
    

    Now it is output:

    Actual: Some(123)
    
  • Assertion failures now have a newline between the debug output of the value and the further explanation of why an actual value did not match.

  • String comparisons now print a diff output when both the actual and expected values have more than one line. This should make finding the difference between two strings much easier. For example, the following assertion:

    let value = "The first line\nThe second line";
    verify_that!(value, eq("The first line\nThe second lines"))
    

    yields the following diagnostic output:

    Value of: value
    Expected: is equal to "The first line\nThe second line"
    Actual: "The first line\nThe second line"
      which is not equal to "The first line\nThe second line"
    Difference:
     The first line
    +The second line
    -The second lines
    

    This not only works with eq but also with the other string comparison matchers starts_with, ends_with, and contains_substring. It does not work with regular expression matchers, nor with string matchers on which one has applied additional configuration such as ignore_leading_whitespace() or times(...).

  • It is now possible to create composed matchers inside functions without running into problems with inner matchers being dropped too early. For example, previously, the following did not compile:

    fn create_a_matcher(value: u32) -> impl Matcher<ActualT = Vec<u32>> {
        contains_each![eq(value), gt(value)]
    }
    

    Now this and other functions of this sort should compile and work.

  • The matcher displays_as now displays a full match explanation of its inner matcher rather than just showing how the actual value displays. In particular, it will now show a diff if the display value has multiple lines and is matched with one of the string matchers.

0.6.0

05 May 16:39
Compare
Choose a tag to compare
0.6.0 Pre-release
Pre-release

API changes

  • Changed the way the Matcher trait is generic with respect to the type of the actual value from a type parameter to an associated type.

    This should not break any code using matchers, but does affect how matchers are written. First, the Matcher implementation block must now use the associated type.

    OLD:

    impl Matcher<ActualType> for MyMatcher {
        fn matches(&self, actual: &ActualType) -> MatcherResult {...}
    }
    

    NEW:

    impl Matcher for MyMatcher {
        type ActualT = ActualType;
    
        fn matches(&self, actual: &ActualType) -> MatcherResult {...}
    }
    

    When the matcher is generic over the actual type (as is common), then the concrete matcher type must also reference the actual value type. This will often require the use of PhantomData in the struct body.

    OLD:

    struct MyMatcher {...}
    impl<ActualT> Matcher<ActualT> for MyMatcher {
        fn matches(&self, actual: &ActualT) -> MatcherResult {...}
    }
    

    NEW:

    struct MyMatcher<ActualT> {
        ...
        phantom: PhantomData<ActualT>,
    }
    impl<ActualT> Matcher for MyMatcher<ActualT> {
        type ActualT = ActualT;
    
        fn matches(&self, actual: &ActualT) -> MatcherResult {...}
    }
    

    Why did we make this change? This forces the concrete matcher type always to carry the type against which it matches. Doing so solves problems which we discovered where the compiler is unable to perform type inference on certain combinations of matchers due to missing information about that type (see below).

Bug fixes

  • The and() and or() methods now work with strings. Previously, using them with strings would cause compilation to fail due to problems with type inference.

    verify_that!("A string", starts_with("A").and(ends_with("string")))
    

New features

  • The new prelude module makes it easier to include all core functionality and all matchers in one import statement:

    use googletest::prelude::*;
    
    #[test]
    fn should_work() -> Result<()> {
        verify_that!(123, eq(123))
    }
    
  • The eq matcher now outputs a diff of debug output of the actual and expected values when the assertion fails due to their not being equal, if each value is more than one line.

  • The new matcher eq_deref_of works like eq but takes a reference to the expected value. This is useful when one only has a reference to the expected value and it cannot or should not be cloned.

Other changes

  • Many fixes to documentation examples. Examples corresponding to real code should now be correct.
  • Doctests are now enabled on all examples where it makes sense to do so.
  • The module import setup has been simplified, making things easier for external contributors.

0.5.0

17 Apr 13:34
Compare
Choose a tag to compare
0.5.0 Pre-release
Pre-release

New additions

  • The pattern used in matches_pattern! can now accept method invocations:

    impl MyStruct {
        fn get_foo(&self) -> u32 {...}
    }
    verify_that!(value, matches_pattern!(MyStruct {
        get_foo(): eq(5)
    }))
  • The unordered_elements_are!, contains_each!, and is_contained_in! macros now support map data structures such as HashMap and BTreeMap:

    let value = HashMap::from_iter([(1, "One"), (2, "Two")]);
    verify_that!(value, unordered_elements_are![(eq(2), eq("Two")), (eq(1), eq("One"))])
  • The pointwise! matcher now explicitly supports closures, and allows supplying up to three containers:

    verify_that!(value, pointwise!(|v| near(v, 0.1), [1.0, 2.0, 3.0])
    verify_that!(value, pointwise!(near, [1.0, 2.0, 3.0], [0.01, 0.001, 0.1])
  • There is now support for easily mapping errors from the anyhow crate to test results:

    #[test]
    fn invokes_fallible_function() -> Result<()> {
        a_fallible_function().into_test_result()?;
        ...
    }

Other improvements

  • Async tests should now work correctly with the googletest::test attribute (see below).
  • googletest::test should now be compatible with other test attributes such as tokio::test.
  • The syn dependency has been upgraded to major version 2.

API changes

  • The attribute macro google_test has been renamed to test:

    OLD:

    #[googletest::google_test]
    fn should_work() -> Result<()> {...}

    NEW:

    #[googletest::test]
    fn should_work() -> Result<()> {...}

    Downstream tests do not currently have to update their code. The old google_test name has been retained as an alias, but is marked deprecated.

0.4.2

24 Mar 10:38
Compare
Choose a tag to compare
0.4.2 Pre-release
Pre-release

API additions

  • A new method times on the matcher contains_substring allows asserting on the number of times the actual string contains the given substring.
  • The enum MatcherResult can now be converted to and from bool (representing MatcherResult::Matches) via the Into and From traits.

Bugfixes

  • Using both #[google_test] and #[rstest] on a test should no longer result in problems with compilation. This is a partial fix for #77, as much as is possible within this library alone. The rest of clarified in the documentation.

0.4.1

17 Mar 09:22
Compare
Choose a tag to compare
0.4.1 Pre-release
Pre-release

This is a bugfix release from 0.4.0.

Version 0.4.0 contained a regression which broke compilation of downstream tests using the matches_pattern! macro. This version fixes that problem and modifies the testing approach to avoid similar regressions in the future.

It contains no further changes.

0.4.0

10 Mar 16:37
Compare
Choose a tag to compare
0.4.0 Pre-release
Pre-release

New additions

  • The new matcher StrMatcher combines string equality (using eq with String or &str), starts_with, ends_with, and contains_substring and provides common features for all of these. This includes ASCII case-insensitive matching and ignoring leading and trailing whitespace.
  • The new matcher predicate allows matching using an arbitrary predicate on the input.

Other improvements

  • There is now crate-level documentation, including a table of available matchers.
  • The documentation for the declarative macros which generate matchers (all!, matchers_pattern!, unordered_elements_are! and so on) has been improved to more clearly indicate what the arguments should be as well as the types of values against which they match.
  • elements_are!, unordered_elements_are!, pointwise!, and size no longer require the actual value to implement HasSize.
  • Match failure and expectation descriptions are now properly indented.

API changes

  • The minimum supported Rust version is now 1.67.0.

  • The trait HasSize has been removed. The matchers which depended on it now just require the actual value to support IntoIterator.

    If you implemented HasSize for one of your collections, just remove the impl HasSize since it is not needed.

  • The matcher eq_ignoring_ascii_case has been removed. Use eq("...").ignoring_ascii_case() instead:

    OLD:

    verify_that!("ABC", eq_ignoring_ascii_case("abc"))
    

    NEW:

    verify_that!("ABC", eq("abc").ignoring_ascii_case())
    
  • One should no longer take a reference to a slice when using the size macher:

    OLD:

    let value = &[1, 2, 3];
    verify_that(&value[0..1], size(eq(1)))?;
    

    NEW:

    let value = &[1, 2, 3];
    verify_that(value[0..1], size(eq(1)))?;
    

0.3.0

31 Jan 14:47
Compare
Choose a tag to compare
0.3.0 Pre-release
Pre-release

New additions

  • The new macros expect_that! and expect_pred! can be used for non-fatal assertions. They are equivalent to verify_*!(...).and_log_failure().
  • The new macros contains_each! and is_contained_in! allow for matching on containers containing some set of elements, or contained in some superset of elements, specified by matchers. These are analogous to superset_of and subset_of but the arguments are matchers rather than values.
  • There is now an extension method or (in the trait OrMatcherExt) which can be used to express disjunction in matchers: eq(123).or(eq(234)). This is analogous to the existing and method.

Other improvements

  • All assertion macros which produce Result are now annotated with #[must_use] so that the compiler will produce a warning if the result is ignored.
  • Improvements to the readability and usefulness of test assertion failure messages. In particular, actual values are now pretty-printed, redundant display has been removed, and mismatches from nested matchers are more consistently explained.
  • The struct TestAssertionFailure now implements From<T> for all T: std::error::Error, so the ? operator works transparently in tests.
  • Test assertion failure messages for the tuple! macro now produce more detailed information about which tuple elements failed to match.
  • The macros elements_are!, unordered_elements_are! now support trailing commas.
  • Documentation pages for empty and internal-only modules should no longer be published on docs.rs.

API changes

  • The trait Describe has been folded into Matcher and removed. Existing matchers must be updated with the new version. To do this, move the describe method implementation into the impl Matcher block, like so:

    OLD:

    impl Matcher<T> for MyMatcher {
        fn matches(&self, actual: &T) -> MatcherResult {...}
    }
    
    impl Describe for MyMatcher {
        fn describe(&self, matcher_result: MatcherResult) -> String {...}
    }
    

    NEW:

    impl Matcher<T> for MyMatcher {
        fn matches(&self, actual: &T) -> MatcherResult {...}
    
        fn describe(&self, matcher_result: MatcherResult) -> String {...}
    }
    
  • The extension method err_to_test_failure and its associated trait MapErrorToTestFailure are no longer needed and have been removed. The ? operator should now work transparently as long as the Err type of the Result implements std::error::Error (which is standard practice). Calls to err_to_test_failure can be removed:
    OLD:

    #[test]
    fn test_that_something_works() -> Result<()> {
        do_something().err_to_test_failure()?;
        ...
    }
    

    NEW:

    #[test]
    fn test_that_something_works() -> Result<()> {
        do_something()?;
        ...
    }
    

    If the output of such a call is used directly in a return statement or expression, then it should be replaced by Ok(...?):
    OLD:

    fn run_do_something() -> Result<Something> {
        do_something().err_to_test_failure()
    }
    

    NEW:

    fn run_do_something() -> Result<Something> {
        Ok(do_something()?)
    }
    

0.2.0

27 Dec 08:53
Compare
Choose a tag to compare
0.2.0 Pre-release
Pre-release
  • Introduced assert_that! and assert_pred! macros which panic on failure, acting more like other Rust test libraries.
  • Introduced a tuple! matcher macro to match plain (non-struct) tuples by supplying matchers for each entry.
  • Modified contains(...).times(...) to take a matcher rather than a plain count as input. Now one can match on containers containing, say, more than a given number of elements meeting the criteria.
  • Folded the attribute macro #[google_test_wrapper] into #[google_test].