diff --git a/rust/gtest_matchers_impl.rs b/rust/gtest_matchers_impl.rs index 0dc833a758..c52f98b231 100644 --- a/rust/gtest_matchers_impl.rs +++ b/rust/gtest_matchers_impl.rs @@ -30,6 +30,22 @@ where } } +impl Matcher for MessageMatcher +where + T: MatcherEq + Copy, +{ + fn matches(&self, actual: T) -> MatcherResult { + actual.matches(&self.expected).into() + } + + fn describe(&self, matcher_result: MatcherResult) -> Description { + match matcher_result { + MatcherResult::Match => format!("is equal to {:?}", self.expected).into(), + MatcherResult::NoMatch => format!("is not equal to {:?}", self.expected).into(), + } + } +} + pub fn proto_eq(expected: T) -> MessageMatcher { MessageMatcher { expected } } diff --git a/rust/test/shared/gtest_matchers_test.rs b/rust/test/shared/gtest_matchers_test.rs index a74add5726..0cd09d260b 100644 --- a/rust/test/shared/gtest_matchers_test.rs +++ b/rust/test/shared/gtest_matchers_test.rs @@ -11,7 +11,9 @@ google3::import! { use googletest::prelude::*; use paste::paste; +use protobuf::proto; use protobuf_gtest_matchers::proto_eq; +use unittest_proto3_rust_proto::test_all_types::NestedMessage; use unittest_proto3_rust_proto::TestAllTypes as TestAllTypesProto3; use unittest_rust_proto::TestAllTypes; @@ -52,3 +54,25 @@ macro_rules! generate_not_eq_msgs_tests { generate_eq_msgs_tests!((TestAllTypes, editions), (TestAllTypesProto3, proto3)); generate_not_eq_msgs_tests!((TestAllTypes, editions), (TestAllTypesProto3, proto3)); + +#[gtest] +fn proto_eq_works_on_view() { + // This exercises the `impl Matcher for MessageMatcher + // where T: MatcherEq + Copy` implementation. + let msg = proto!(TestAllTypesProto3 { + repeated_nested_message: [ + NestedMessage { bb: 10 }, + NestedMessage { bb: 20 }, + NestedMessage { bb: 30 } + ] + }); + + expect_that!( + msg.repeated_nested_message(), + unordered_elements_are![ + proto_eq(proto!(NestedMessage { bb: 10 }).as_view()), + proto_eq(proto!(NestedMessage { bb: 20 }).as_view()), + proto_eq(proto!(NestedMessage { bb: 30 }).as_view()), + ] + ); +}