Add custom matchers for ProxiedWithPresence.

We continue our foray into googletest-rust [1], this time with homegrown matchers.

Our unit tests will now be able to check is_unset() and is_set() for all types that implement ProxiedWithPresence. In practice, this boils down to [u8] and ProtoStr.

Note that we've broken out matchers_upb and matchers_cpp, similar to what was done with aliasing here [2].

[1] https://github.com/google/googletest-rust
[2] 9a0bc392b3 (diff-08e5182ff36ad340a3bfb628995524a2a36a89b59a514ba027b0f25e048dd5c3R90)

PiperOrigin-RevId: 573895179
pull/14374/head
Hong Shin 1 year ago committed by Copybara-Service
parent 93014791ca
commit 6424bcad0a
  1. 30
      rust/test/shared/BUILD
  2. 49
      rust/test/shared/accessors_test.rs
  3. 58
      rust/test/shared/matchers.rs

@ -14,7 +14,31 @@
# Once we have a couple of these tests we will investigate ways to remove boilerplate (for example
# by introducing a build macro that registers 2 rust_test targets).
load("@rules_rust//rust:defs.bzl", "rust_test")
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
rust_library(
name = "matchers_upb",
srcs = ["matchers.rs"],
aliases = {
"//rust:protobuf_upb": "protobuf",
},
deps = [
"//third_party/gtest_rust/googletest",
"//rust:protobuf_upb",
],
)
rust_library(
name = "matchers_cpp",
srcs = ["matchers.rs"],
aliases = {
"//rust:protobuf_cpp": "protobuf",
},
deps = [
"//third_party/gtest_rust/googletest",
"//rust:protobuf_cpp",
],
)
rust_test(
name = "child_parent_upb_test",
@ -125,6 +149,7 @@ rust_test(
srcs = ["accessors_test.rs"],
aliases = {
"//rust:protobuf_cpp": "protobuf",
"//rust/test/shared:matchers_cpp": "matchers",
},
tags = [
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
@ -134,6 +159,7 @@ rust_test(
"//third_party/gtest_rust/googletest",
"//rust:protobuf_cpp",
"//rust/test:unittest_cc_rust_proto",
"//rust/test/shared:matchers_cpp",
],
)
@ -142,6 +168,7 @@ rust_test(
srcs = ["accessors_test.rs"],
aliases = {
"//rust:protobuf_upb": "protobuf",
"//rust/test/shared:matchers_upb": "matchers",
},
tags = [
# TODO: Enable testing on arm once we support sanitizers for Rust on Arm.
@ -151,6 +178,7 @@ rust_test(
"//third_party/gtest_rust/googletest",
"//rust:protobuf_upb",
"//rust/test:unittest_upb_rust_proto",
"//rust/test/shared:matchers_upb",
],
)

@ -8,6 +8,7 @@
//! Tests covering accessors for singular bool, int32, int64, and bytes fields.
use googletest::prelude::*;
use matchers::{is_set, is_unset};
use protobuf::Optional;
use unittest_proto::proto2_unittest::{TestAllTypes, TestAllTypes_};
@ -199,10 +200,10 @@ fn test_optional_bool_accessors() {
#[test]
fn test_optional_bytes_accessors() {
let mut msg = TestAllTypes::new();
assert_that!(msg.optional_bytes(), eq(b""));
assert_that!(*msg.optional_bytes(), empty());
assert_that!(msg.optional_bytes_opt(), eq(Optional::Unset(&b""[..])));
assert_that!(msg.optional_bytes_mut().get(), eq(b""));
assert_that!(msg.optional_bytes_mut().is_unset(), eq(true));
assert_that!(*msg.optional_bytes_mut().get(), empty());
assert_that!(msg.optional_bytes_mut(), is_unset());
{
let s = Vec::from(&b"hello world"[..]);
@ -210,34 +211,34 @@ fn test_optional_bytes_accessors() {
}
assert_that!(msg.optional_bytes(), eq(b"hello world"));
assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b"hello world"[..])));
assert_that!(msg.optional_bytes_mut().is_set(), eq(true));
assert_that!(msg.optional_bytes_mut(), is_set());
assert_that!(msg.optional_bytes_mut().get(), eq(b"hello world"));
msg.optional_bytes_mut().or_default().set(b"accessors_test");
assert_that!(msg.optional_bytes(), eq(b"accessors_test"));
assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b"accessors_test"[..])));
assert_that!(msg.optional_bytes_mut().is_set(), eq(true));
assert_that!(msg.optional_bytes_mut(), is_set());
assert_that!(msg.optional_bytes_mut().get(), eq(b"accessors_test"));
assert_that!(msg.optional_bytes_mut().or_default().get(), eq(b"accessors_test"));
msg.optional_bytes_mut().clear();
assert_that!(msg.optional_bytes(), eq(b""));
assert_that!(*msg.optional_bytes(), empty());
assert_that!(msg.optional_bytes_opt(), eq(Optional::Unset(&b""[..])));
assert_that!(msg.optional_bytes_mut().is_unset(), eq(true));
assert_that!(msg.optional_bytes_mut(), is_unset());
msg.optional_bytes_mut().set(b"");
assert_that!(msg.optional_bytes(), eq(b""));
assert_that!(*msg.optional_bytes(), empty());
assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b""[..])));
msg.optional_bytes_mut().clear();
msg.optional_bytes_mut().or_default();
assert_that!(msg.optional_bytes(), eq(b""));
assert_that!(*msg.optional_bytes(), empty());
assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b""[..])));
msg.optional_bytes_mut().or_default().set(b"\xffbinary\x85non-utf8");
assert_that!(msg.optional_bytes(), eq(b"\xffbinary\x85non-utf8"));
assert_that!(msg.optional_bytes_opt(), eq(Optional::Set(&b"\xffbinary\x85non-utf8"[..])));
assert_that!(msg.optional_bytes_mut().is_set(), eq(true));
assert_that!(msg.optional_bytes_mut(), is_set());
assert_that!(msg.optional_bytes_mut().get(), eq(b"\xffbinary\x85non-utf8"));
assert_that!(msg.optional_bytes_mut().or_default().get(), eq(b"\xffbinary\x85non-utf8"));
}
@ -248,7 +249,7 @@ fn test_nonempty_default_bytes_accessors() {
assert_that!(msg.default_bytes(), eq(b"world"));
assert_that!(msg.default_bytes_opt(), eq(Optional::Unset(&b"world"[..])));
assert_that!(msg.default_bytes_mut().get(), eq(b"world"));
assert_that!(msg.default_bytes_mut().is_unset(), eq(true));
assert_that!(msg.default_bytes_mut(), is_unset());
{
let s = String::from("hello world");
@ -256,23 +257,23 @@ fn test_nonempty_default_bytes_accessors() {
}
assert_that!(msg.default_bytes(), eq(b"hello world"));
assert_that!(msg.default_bytes_opt(), eq(Optional::Set(&b"hello world"[..])));
assert_that!(msg.default_bytes_mut().is_set(), eq(true));
assert_that!(msg.default_bytes_mut(), is_set());
assert_that!(msg.default_bytes_mut().get(), eq(b"hello world"));
msg.default_bytes_mut().or_default().set(b"accessors_test");
assert_that!(msg.default_bytes(), eq(b"accessors_test"));
assert_that!(msg.default_bytes_opt(), eq(Optional::Set(&b"accessors_test"[..])));
assert_that!(msg.default_bytes_mut().is_set(), eq(true));
assert_that!(msg.default_bytes_mut(), is_set());
assert_that!(msg.default_bytes_mut().get(), eq(b"accessors_test"));
assert_that!(msg.default_bytes_mut().or_default().get(), eq(b"accessors_test"));
msg.default_bytes_mut().clear();
assert_that!(msg.default_bytes(), eq(b"world"));
assert_that!(msg.default_bytes_opt(), eq(Optional::Unset(&b"world"[..])));
assert_that!(msg.default_bytes_mut().is_unset(), eq(true));
assert_that!(msg.default_bytes_mut(), is_unset());
msg.default_bytes_mut().set(b"");
assert_that!(msg.default_bytes(), eq(b""));
assert_that!(*msg.default_bytes(), empty());
assert_that!(msg.default_bytes_opt(), eq(Optional::Set(&b""[..])));
msg.default_bytes_mut().clear();
@ -283,7 +284,7 @@ fn test_nonempty_default_bytes_accessors() {
msg.default_bytes_mut().or_default().set(b"\xffbinary\x85non-utf8");
assert_that!(msg.default_bytes(), eq(b"\xffbinary\x85non-utf8"));
assert_that!(msg.default_bytes_opt(), eq(Optional::Set(&b"\xffbinary\x85non-utf8"[..])));
assert_that!(msg.default_bytes_mut().is_set(), eq(true));
assert_that!(msg.default_bytes_mut(), is_set());
assert_that!(msg.default_bytes_mut().get(), eq(b"\xffbinary\x85non-utf8"));
assert_that!(msg.default_bytes_mut().or_default().get(), eq(b"\xffbinary\x85non-utf8"));
}
@ -294,7 +295,7 @@ fn test_optional_string_accessors() {
assert_that!(msg.optional_string(), eq(""));
assert_that!(msg.optional_string_opt(), eq(Optional::Unset("".into())));
assert_that!(msg.optional_string_mut().get(), eq(""));
assert_that!(msg.optional_string_mut().is_unset(), eq(true));
assert_that!(msg.optional_string_mut(), is_unset());
{
let s = String::from("hello world");
@ -302,20 +303,20 @@ fn test_optional_string_accessors() {
}
assert_that!(msg.optional_string(), eq("hello world"));
assert_that!(msg.optional_string_opt(), eq(Optional::Set("hello world".into())));
assert_that!(msg.optional_string_mut().is_set(), eq(true));
assert_that!(msg.optional_string_mut(), is_set());
assert_that!(msg.optional_string_mut().get(), eq("hello world"));
msg.optional_string_mut().or_default().set("accessors_test");
assert_that!(msg.optional_string(), eq("accessors_test"));
assert_that!(msg.optional_string_opt(), eq(Optional::Set("accessors_test".into())));
assert_that!(msg.optional_string_mut().is_set(), eq(true));
assert_that!(msg.optional_string_mut(), is_set());
assert_that!(msg.optional_string_mut().get(), eq("accessors_test"));
assert_that!(msg.optional_string_mut().or_default().get(), eq("accessors_test"));
msg.optional_string_mut().clear();
assert_that!(msg.optional_string(), eq(""));
assert_that!(msg.optional_string_opt(), eq(Optional::Unset("".into())));
assert_that!(msg.optional_string_mut().is_unset(), eq(true));
assert_that!(msg.optional_string_mut(), is_unset());
msg.optional_string_mut().set("");
assert_that!(msg.optional_string(), eq(""));
@ -333,7 +334,7 @@ fn test_nonempty_default_string_accessors() {
assert_that!(msg.default_string(), eq("hello"));
assert_that!(msg.default_string_opt(), eq(Optional::Unset("hello".into())));
assert_that!(msg.default_string_mut().get(), eq("hello"));
assert_that!(msg.default_string_mut().is_unset(), eq(true));
assert_that!(msg.default_string_mut(), is_unset());
{
let s = String::from("hello world");
@ -341,20 +342,20 @@ fn test_nonempty_default_string_accessors() {
}
assert_that!(msg.default_string(), eq("hello world"));
assert_that!(msg.default_string_opt(), eq(Optional::Set("hello world".into())));
assert_that!(msg.default_string_mut().is_set(), eq(true));
assert_that!(msg.default_string_mut(), is_set());
assert_that!(msg.default_string_mut().get(), eq("hello world"));
msg.default_string_mut().or_default().set("accessors_test");
assert_that!(msg.default_string(), eq("accessors_test"));
assert_that!(msg.default_string_opt(), eq(Optional::Set("accessors_test".into())));
assert_that!(msg.default_string_mut().is_set(), eq(true));
assert_that!(msg.default_string_mut(), is_set());
assert_that!(msg.default_string_mut().get(), eq("accessors_test"));
assert_that!(msg.default_string_mut().or_default().get(), eq("accessors_test"));
msg.default_string_mut().clear();
assert_that!(msg.default_string(), eq("hello"));
assert_that!(msg.default_string_opt(), eq(Optional::Unset("hello".into())));
assert_that!(msg.default_string_mut().is_unset(), eq(true));
assert_that!(msg.default_string_mut(), is_unset());
msg.default_string_mut().set("");
assert_that!(msg.default_string(), eq(""));

@ -0,0 +1,58 @@
use googletest::matcher::MatcherResult;
use googletest::prelude::*;
use protobuf::{AbsentField, Optional, PresentField, ProxiedWithPresence};
use std::marker::PhantomData;
/// ===============================
/// IS_UNSET
/// ===============================
pub fn is_unset<'a, T: std::fmt::Debug + ProxiedWithPresence + ?Sized + 'a>()
-> impl Matcher<ActualT = Optional<PresentField<'a, T>, AbsentField<'a, T>>> {
UnsetMatcher::<T> { _phantom: PhantomData }
}
struct UnsetMatcher<'a, T: ProxiedWithPresence + ?Sized> {
_phantom: PhantomData<PresentField<'a, T>>,
}
impl<'a, T: std::fmt::Debug + ProxiedWithPresence + ?Sized> Matcher for UnsetMatcher<'a, T> {
type ActualT = Optional<PresentField<'a, T>, AbsentField<'a, T>>;
fn matches(&self, actual: &Self::ActualT) -> MatcherResult {
actual.is_unset().into()
}
fn describe(&self, matcher_result: MatcherResult) -> String {
match matcher_result {
MatcherResult::Match => "is not set".to_string(),
MatcherResult::NoMatch => "is set".to_string(),
}
}
}
/// ===============================
/// IS_SET
/// ===============================
pub fn is_set<'a, T: std::fmt::Debug + ProxiedWithPresence + ?Sized + 'a>()
-> impl Matcher<ActualT = Optional<PresentField<'a, T>, AbsentField<'a, T>>> {
SetMatcher::<T> { _phantom: PhantomData }
}
struct SetMatcher<'a, T: ProxiedWithPresence + ?Sized> {
_phantom: PhantomData<PresentField<'a, T>>,
}
impl<'a, T: std::fmt::Debug + ProxiedWithPresence + ?Sized> Matcher for SetMatcher<'a, T> {
type ActualT = Optional<PresentField<'a, T>, AbsentField<'a, T>>;
fn matches(&self, actual: &Self::ActualT) -> MatcherResult {
actual.is_set().into()
}
fn describe(&self, matcher_result: MatcherResult) -> String {
match matcher_result {
MatcherResult::Match => "is set".to_string(),
MatcherResult::NoMatch => "is not set".to_string(),
}
}
}
Loading…
Cancel
Save