Skip to content

Commit

Permalink
Replaces //cc/testutils:proto_matchers with a more complete copy of t…
Browse files Browse the repository at this point in the history
…he internal versions from the protobuf library. For more context, see: google/googletest#1761

Most immediately, this enables polymorphic proto matching from strings.

E.g., instead of saying

MyProto expected;
ASSERT_OK(ParseTextProto("[contents]", &expected);
EXPECT_THAT(result, EqualsProto(expected));

We can now say

EXPECT_THAT(result, EqualsProto("[contents]"));

PiperOrigin-RevId: 521847154
  • Loading branch information
nickgeorge authored and copybara-github committed Apr 4, 2023
1 parent 24ff6a4 commit 414d2f1
Show file tree
Hide file tree
Showing 11 changed files with 884 additions and 131 deletions.
1 change: 1 addition & 0 deletions cc/google/fhir/fhir_path/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ cc_test(
],
deps = [
":utils",
"//cc/google/fhir/status",
"//cc/google/fhir/testutil:proto_matchers",
"//proto/google/fhir/proto/r4/core:datatypes_cc_proto",
"//proto/google/fhir/proto/r4/core/resources:bundle_and_contained_resource_cc_proto",
Expand Down
49 changes: 25 additions & 24 deletions cc/google/fhir/fhir_path/utils_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "google/protobuf/text_format.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "google/fhir/status/status.h"
#include "google/fhir/testutil/proto_matchers.h"
#include "proto/google/fhir/proto/r4/core/datatypes.pb.h"
#include "proto/google/fhir/proto/r4/core/resources/bundle_and_contained_resource.pb.h"
Expand Down Expand Up @@ -46,25 +47,25 @@ TEST(Utils, RetrieveFieldPrimitive) {
std::vector<const Message*> results;
FHIR_ASSERT_OK(RetrieveField(
primitive, *r4::Boolean::GetDescriptor()->FindFieldByName("value"),
[](const Descriptor*) {return nullptr;}, &results));
[](const Descriptor*) { return nullptr; }, &results));

ASSERT_THAT(results, UnorderedElementsAreArray({EqualsProto(primitive)}));
}

TEST(Utils, RetrieveFieldR4ContainedResource) {
r4::Bundle_Entry entry;
ASSERT_TRUE(
TextFormat::ParseFromString(
R"proto(resource: {
patient: { deceased: { boolean: { value: true } } }
})proto",
&entry));
ASSERT_TRUE(TextFormat::
ParseFromString(
R"pb(resource: {
patient: { deceased: { boolean: { value: true } } }
})pb",
&entry));
r4::Patient patient = entry.resource().patient();

std::vector<const Message*> results;
FHIR_ASSERT_OK(RetrieveField(
entry, *r4::Bundle_Entry::GetDescriptor()->FindFieldByName("resource"),
[](const Descriptor*) {return nullptr;}, &results));
[](const Descriptor*) { return nullptr; }, &results));

ASSERT_THAT(results, UnorderedElementsAreArray({EqualsProto(patient)}));
}
Expand Down Expand Up @@ -102,18 +103,18 @@ TEST(Utils, RetrieveFieldR4WrongAny) {

TEST(Utils, RetrieveFieldStu3ContainedResource) {
stu3::Bundle_Entry entry;
ASSERT_TRUE(
TextFormat::ParseFromString(
R"proto(resource: {
patient: { deceased: { boolean: { value: true } } }
})proto",
&entry));
ASSERT_TRUE(TextFormat::
ParseFromString(
R"pb(resource: {
patient: { deceased: { boolean: { value: true } } }
})pb",
&entry));
stu3::Patient patient = entry.resource().patient();

std::vector<const Message*> results;
FHIR_ASSERT_OK(RetrieveField(
entry, *stu3::Bundle_Entry::GetDescriptor()->FindFieldByName("resource"),
[](const Descriptor*) {return nullptr;}, &results));
[](const Descriptor*) { return nullptr; }, &results));

ASSERT_THAT(results, UnorderedElementsAreArray({EqualsProto(patient)}));
}
Expand All @@ -127,7 +128,7 @@ TEST(Utils, RetrieveFieldR4Choice) {
std::vector<const Message*> results;
FHIR_ASSERT_OK(RetrieveField(
patient, *r4::Patient::GetDescriptor()->FindFieldByName("deceased"),
[](const Descriptor*) {return nullptr;}, &results));
[](const Descriptor*) { return nullptr; }, &results));

ASSERT_THAT(results, UnorderedElementsAreArray({EqualsProto(deceased)}));
}
Expand Down Expand Up @@ -188,24 +189,24 @@ TEST(Utils, RetrieveFieldStu3Choice) {
std::vector<const Message*> results;
FHIR_ASSERT_OK(RetrieveField(
patient, *stu3::Patient::GetDescriptor()->FindFieldByName("deceased"),
[](const Descriptor*) {return nullptr;}, &results));
[](const Descriptor*) { return nullptr; }, &results));

ASSERT_THAT(results, UnorderedElementsAreArray({EqualsProto(deceased)}));
}

TEST(Utils, RetrieveFieldRepeated) {
r4::Patient patient;
ASSERT_TRUE(TextFormat::ParseFromString(
R"proto(communication: { preferred: { value: true } }
communication: { preferred: { value: false } })proto",
R"pb(communication: { preferred: { value: true } }
communication: { preferred: { value: false } })pb",
&patient));
r4::Patient_Communication communication1 = patient.communication(0);
r4::Patient_Communication communication2 = patient.communication(1);

std::vector<const Message*> results;
FHIR_ASSERT_OK(RetrieveField(
patient, *r4::Patient::GetDescriptor()->FindFieldByName("communication"),
[](const Descriptor*) {return nullptr;}, &results));
[](const Descriptor*) { return nullptr; }, &results));

ASSERT_THAT(results,
UnorderedElementsAreArray(
Expand All @@ -227,10 +228,10 @@ TEST(Utils, FindFieldByJsonName) {
}

TEST(Utils, HasFieldWithJsonName) {
EXPECT_TRUE(HasFieldWithJsonName(stu3::ContainedResource::descriptor(),
"deceased"));
EXPECT_TRUE(HasFieldWithJsonName(r4::ContainedResource::descriptor(),
"deceased"));
EXPECT_TRUE(
HasFieldWithJsonName(stu3::ContainedResource::descriptor(), "deceased"));
EXPECT_TRUE(
HasFieldWithJsonName(r4::ContainedResource::descriptor(), "deceased"));
}

} // namespace
Expand Down
19 changes: 10 additions & 9 deletions cc/google/fhir/r4/codeable_concepts_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ using ::google::fhir::r4::core::CodeableConcept;
using ::google::fhir::r4::core::Coding;
using ::google::fhir::r4::testing::TestObservation;
using ::google::fhir::testutil::EqualsProto;
using ::google::fhir::testutil::IgnoringRepeatedFieldOrdering;
using ::testing::ElementsAre;

const TestObservation::CodeableConceptForCode GetConcept() {
Expand Down Expand Up @@ -396,7 +397,7 @@ TEST(CodeableConceptsTest, CopyCodeableConcept) {
}
)pb");
TestObservation::CodeableConceptForCode concept_for_code =
PARSE_FHIR_PROTO(R"proto(
PARSE_FHIR_PROTO(R"pb(
# inlined system
sys_a {
code { value: "acode" },
Expand All @@ -422,9 +423,9 @@ TEST(CodeableConceptsTest, CopyCodeableConcept) {
url { value: "baz" }
value { integer { value: 5 } }
}
)proto");
)pb");
TestObservation::CodeableConceptForCategory concept_for_cat =
PARSE_FHIR_PROTO(R"proto(
PARSE_FHIR_PROTO(R"pb(
coding {
system { value: "http://sysa.org" }
code { value: "acode" }
Expand All @@ -450,24 +451,24 @@ TEST(CodeableConceptsTest, CopyCodeableConcept) {
url { value: "baz" }
value { integer { value: 5 } }
}
)proto");
)pb");

CodeableConcept profiled_to_unprofiled;
FHIR_ASSERT_OK(
CopyCodeableConcept(concept_for_code, &profiled_to_unprofiled));
ASSERT_THAT(codeable_concept,
testutil::EqualsProtoIgnoringReordering(profiled_to_unprofiled));
ASSERT_THAT(codeable_concept, IgnoringRepeatedFieldOrdering(
EqualsProto(profiled_to_unprofiled)));

TestObservation::CodeableConceptForCode unprofiled_to_profiled;
FHIR_ASSERT_OK(
CopyCodeableConcept(codeable_concept, &unprofiled_to_profiled));
ASSERT_THAT(concept_for_code,
testutil::EqualsProtoIgnoringReordering(unprofiled_to_profiled));
ASSERT_THAT(concept_for_code, IgnoringRepeatedFieldOrdering(
EqualsProto(unprofiled_to_profiled)));

TestObservation::CodeableConceptForCategory profiled_to_profiled;
FHIR_ASSERT_OK(CopyCodeableConcept(concept_for_code, &profiled_to_profiled));
ASSERT_THAT(concept_for_cat,
testutil::EqualsProtoIgnoringReordering(profiled_to_profiled));
IgnoringRepeatedFieldOrdering(EqualsProto(profiled_to_profiled)));
}

TEST(CodeableConceptsTest, AddCodingFromStrings) {
Expand Down
12 changes: 7 additions & 5 deletions cc/google/fhir/r4/json_format_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ namespace {
using namespace ::google::fhir::r4::core; // NOLINT
using ::google::fhir::r4::OperationOutcomeErrorHandler;
using ::google::fhir::testutil::EqualsProto;
using ::google::fhir::testutil::EqualsProtoIgnoringReordering;
using ::google::fhir::testutil::IgnoringRepeatedFieldOrdering;
using internal::JsonEq;
using ::testing::Eq;

Expand All @@ -231,8 +231,8 @@ absl::StatusOr<R> ParseJsonToProto(const std::string& json_path) {
std::string json = ReadFile(json_path);
absl::TimeZone tz;
absl::LoadTimeZone(kTimeZoneString, &tz);
FHIR_ASSIGN_OR_RETURN(R resource, JsonFhirStringToProtoWithoutValidating<R>(
json, tz));
FHIR_ASSIGN_OR_RETURN(R resource,
JsonFhirStringToProtoWithoutValidating<R>(json, tz));

if (INVALID_RECORDS.find(json_path) == INVALID_RECORDS.end()) {
FHIR_RETURN_IF_ERROR(
Expand Down Expand Up @@ -1864,7 +1864,8 @@ TEST(JsonFormatR4Test, ParserErrorHandlerAggregatesErrorsAndFatalsParseFails) {
FHIR_ASSERT_STATUS(
merge_status,
"Merge failure when parsing JSON. See ErrorHandler for more info.");
EXPECT_THAT(outcome, EqualsProtoIgnoringReordering(expected_outcome));
EXPECT_THAT(outcome,
IgnoringRepeatedFieldOrdering(EqualsProto(expected_outcome)));
}

TEST(JsonFormatR4Test,
Expand Down Expand Up @@ -1900,7 +1901,8 @@ TEST(JsonFormatR4Test,
// Merge succeeds despite data issues.
FHIR_ASSERT_OK(merge_status);

EXPECT_THAT(outcome, EqualsProtoIgnoringReordering(expected_outcome));
EXPECT_THAT(outcome,
IgnoringRepeatedFieldOrdering(EqualsProto(expected_outcome)));
}

} // namespace
Expand Down
12 changes: 7 additions & 5 deletions cc/google/fhir/r4/profiles_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ using ::google::fhir::r4::testing::TestObservation;
using ::google::fhir::r4::testing::TestObservationLvl2;
using ::google::fhir::r4::testing::TestPatient;
using ::google::fhir::testutil::EqualsProto;
using ::google::fhir::testutil::EqualsProtoIgnoringReordering;
using ::google::fhir::testutil::IgnoringRepeatedFieldOrdering;

template <class B>
B GetUnprofiled(const std::string& filename) {
Expand Down Expand Up @@ -90,12 +90,14 @@ void TestUpConvert(const std::string& filename) {
// Ignore conversion OperationOutcome structure for bi-directional tests;
// failure modes are tested elsewhere.
FHIR_ASSERT_OK(result.status());
EXPECT_THAT(unprofiled, EqualsProtoIgnoringReordering(expected_unprofiled));
EXPECT_THAT(unprofiled,
IgnoringRepeatedFieldOrdering(EqualsProto(expected_unprofiled)));

// Test deprecated method as well.
unprofiled.Clear();
FHIR_ASSERT_OK(ConvertToProfileLenientR4(profiled, &unprofiled));
EXPECT_THAT(unprofiled, EqualsProtoIgnoringReordering(expected_unprofiled));
EXPECT_THAT(unprofiled,
IgnoringRepeatedFieldOrdering(EqualsProto(expected_unprofiled)));
}

template <class B, class P>
Expand Down Expand Up @@ -189,7 +191,7 @@ TEST(ProfilesTest, NormalizeBundle) {
absl::StatusOr<r4::testing::Bundle> normalized =
NormalizeR4(unnormalized_bundle);
EXPECT_THAT(normalized.value(),
EqualsProtoIgnoringReordering(expected_normalized));
IgnoringRepeatedFieldOrdering(EqualsProto(expected_normalized)));
}

TEST(ProfilesTest, ProfileOfProfile) {
Expand Down Expand Up @@ -262,7 +264,7 @@ TEST(ProfilesTest, ContainedResourcesWithUnmatchedProfileNames) {
FHIR_ASSERT_OK(
ConvertToProfileR4(entry.resource().patient(), &test_patient_roundtrip));
EXPECT_THAT(test_patient_roundtrip,
EqualsProtoIgnoringReordering(test_patient));
IgnoringRepeatedFieldOrdering(EqualsProto(test_patient)));
}

// TODO(b/237447770): Reenable once PrimitiveHandler can wrap profiled
Expand Down
8 changes: 5 additions & 3 deletions cc/google/fhir/r4/resource_validation_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ namespace {

using namespace ::google::fhir::r4::core; // NOLINT
using ::google::fhir::r4::fhirproto::ValidationOutcome;
using ::google::fhir::testutil::EqualsProtoIgnoringReordering;
using ::google::fhir::testutil::EqualsProto;
using ::google::fhir::testutil::IgnoringRepeatedFieldOrdering;

template <typename T>
void ValidTest(const absl::string_view name, const bool has_resource_id = true,
Expand All @@ -63,7 +64,7 @@ void ValidTest(const absl::string_view name, const bool has_resource_id = true,
GetReferenceProtoToResource<::google::fhir::r4::core::Reference>(
resource));
}
EXPECT_THAT(*outcome, EqualsProtoIgnoringReordering(expected));
EXPECT_THAT(*outcome, IgnoringRepeatedFieldOrdering(EqualsProto(expected)));
}

template <typename T>
Expand All @@ -84,7 +85,8 @@ void InvalidTest(absl::string_view name,

ValidationOutcome expected_outcome = ReadProto<ValidationOutcome>(
absl::StrCat("testdata/r4/validation/", name, ".outcome.prototxt"));
EXPECT_THAT(*outcome, EqualsProtoIgnoringReordering(expected_outcome));
EXPECT_THAT(*outcome,
IgnoringRepeatedFieldOrdering(EqualsProto(expected_outcome)));
}

TEST(ResourceValidationTest, MissingRequiredField) {
Expand Down
20 changes: 11 additions & 9 deletions cc/google/fhir/stu3/codeable_concepts_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ namespace {
using ::google::fhir::stu3::proto::CodeableConcept;
using ::google::fhir::stu3::proto::Coding;
using ::google::fhir::stu3::testing::TestObservation;
using ::google::fhir::testutil::EqualsProto;
using ::google::fhir::testutil::IgnoringRepeatedFieldOrdering;
using ::testing::ElementsAre;

const TestObservation::CodeableConceptForCode GetConcept() {
Expand Down Expand Up @@ -391,7 +393,7 @@ TEST(CodeableConceptsTest, CopyCodeableConcept) {
}
)pb");
TestObservation::CodeableConceptForCode concept_for_code =
PARSE_STU3_PROTO(R"proto(
PARSE_STU3_PROTO(R"pb(
# inlined system
sys_a {
code { value: "acode" },
Expand All @@ -417,9 +419,9 @@ TEST(CodeableConceptsTest, CopyCodeableConcept) {
url { value: "baz" }
value { integer { value: 5 } }
}
)proto");
)pb");
TestObservation::CodeableConceptForCategory concept_for_cat =
PARSE_STU3_PROTO(R"proto(
PARSE_STU3_PROTO(R"pb(
coding {
system { value: "http://sysa.org" }
code { value: "acode" }
Expand All @@ -445,24 +447,24 @@ TEST(CodeableConceptsTest, CopyCodeableConcept) {
url { value: "baz" }
value { integer { value: 5 } }
}
)proto");
)pb");

CodeableConcept profiled_to_unprofiled;
FHIR_ASSERT_OK(
CopyCodeableConcept(concept_for_code, &profiled_to_unprofiled));
ASSERT_THAT(codeable_concept,
testutil::EqualsProtoIgnoringReordering(profiled_to_unprofiled));
ASSERT_THAT(codeable_concept, IgnoringRepeatedFieldOrdering(
EqualsProto(profiled_to_unprofiled)));

TestObservation::CodeableConceptForCode unprofiled_to_profiled;
FHIR_ASSERT_OK(
CopyCodeableConcept(codeable_concept, &unprofiled_to_profiled));
ASSERT_THAT(concept_for_code,
testutil::EqualsProtoIgnoringReordering(unprofiled_to_profiled));
ASSERT_THAT(concept_for_code, IgnoringRepeatedFieldOrdering(
EqualsProto(unprofiled_to_profiled)));

TestObservation::CodeableConceptForCategory profiled_to_profiled;
FHIR_ASSERT_OK(CopyCodeableConcept(concept_for_code, &profiled_to_profiled));
ASSERT_THAT(concept_for_cat,
testutil::EqualsProtoIgnoringReordering(profiled_to_profiled));
IgnoringRepeatedFieldOrdering(EqualsProto(profiled_to_profiled)));
}

TEST(CodeableConceptsTest, AddCodingFromStrings) {
Expand Down
10 changes: 6 additions & 4 deletions cc/google/fhir/stu3/profiles_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ using ::google::fhir::stu3::proto::Patient;
using ::google::fhir::stu3::testing::TestObservation;
using ::google::fhir::stu3::testing::TestObservationLvl2;
using ::google::fhir::testutil::EqualsProto;
using ::google::fhir::testutil::EqualsProtoIgnoringReordering;
using ::google::fhir::testutil::IgnoringRepeatedFieldOrdering;

template <class B>
B GetUnprofiled(const std::string& filename) {
Expand Down Expand Up @@ -83,12 +83,14 @@ void TestUpConvert(const std::string& filename) {
// Ignore conversion OperationOutcome structure for bi-directional tests;
// failure modes are tested elsewhere.
EXPECT_TRUE(result.ok());
EXPECT_THAT(unprofiled, EqualsProtoIgnoringReordering(expected_unprofiled));
EXPECT_THAT(unprofiled,
IgnoringRepeatedFieldOrdering(EqualsProto(expected_unprofiled)));

// Test deprecated method as well.
unprofiled.Clear();
FHIR_ASSERT_OK(ConvertToProfileLenientStu3(profiled, &unprofiled));
EXPECT_THAT(unprofiled, EqualsProtoIgnoringReordering(expected_unprofiled));
EXPECT_THAT(unprofiled,
IgnoringRepeatedFieldOrdering(EqualsProto(expected_unprofiled)));
}

template <class B, class P>
Expand Down Expand Up @@ -203,7 +205,7 @@ TEST(ProfilesTest, NormalizeBundle) {
absl::StatusOr<stu3::testing::Bundle> normalized =
NormalizeStu3(unnormalized_bundle);
EXPECT_THAT(normalized.value(),
EqualsProtoIgnoringReordering(expected_normalized));
IgnoringRepeatedFieldOrdering(EqualsProto(expected_normalized)));
}

TEST(ProfilesTest, ProfileOfProfile) {
Expand Down
Loading

0 comments on commit 414d2f1

Please sign in to comment.