1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #include "pw_unit_test/googletest_test_matchers.h"
15
16 #include <cstdlib>
17
18 #include "gtest/gtest-spi.h"
19 #include "pw_status/status.h"
20
21 namespace {
22
23 using ::pw::OkStatus;
24 using ::pw::Result;
25 using ::pw::Status;
26 using ::pw::StatusWithSize;
27 using ::pw::unit_test::IsOkAndHolds;
28 using ::pw::unit_test::StatusIs;
29 using ::testing::Eq;
30 using ::testing::Not;
31
TEST(TestMatchers,AssertOk)32 TEST(TestMatchers, AssertOk) { ASSERT_OK(OkStatus()); }
TEST(TestMatchers,AssertOkStatusWithSize)33 TEST(TestMatchers, AssertOkStatusWithSize) { ASSERT_OK(StatusWithSize(123)); }
TEST(TestMatchers,AssertOkResult)34 TEST(TestMatchers, AssertOkResult) { ASSERT_OK(Result<int>(123)); }
35
TEST(TestMatchers,ExpectOk)36 TEST(TestMatchers, ExpectOk) { EXPECT_OK(OkStatus()); }
TEST(TestMatchers,ExpectOkStatusWithSize)37 TEST(TestMatchers, ExpectOkStatusWithSize) { EXPECT_OK(StatusWithSize(123)); }
TEST(TestMatchers,ExpectOkResult)38 TEST(TestMatchers, ExpectOkResult) { EXPECT_OK(Result<int>(123)); }
39
TEST(TestMatchers,StatusIsSuccess)40 TEST(TestMatchers, StatusIsSuccess) {
41 EXPECT_THAT(OkStatus(), StatusIs(OkStatus()));
42 EXPECT_THAT(Status::Cancelled(), StatusIs(Status::Cancelled()));
43 EXPECT_THAT(Status::Unknown(), StatusIs(Status::Unknown()));
44 EXPECT_THAT(Status::InvalidArgument(), StatusIs(Status::InvalidArgument()));
45 EXPECT_THAT(Status::DeadlineExceeded(), StatusIs(Status::DeadlineExceeded()));
46 EXPECT_THAT(Status::NotFound(), StatusIs(Status::NotFound()));
47 EXPECT_THAT(Status::AlreadyExists(), StatusIs(Status::AlreadyExists()));
48 EXPECT_THAT(Status::PermissionDenied(), StatusIs(Status::PermissionDenied()));
49 EXPECT_THAT(Status::ResourceExhausted(),
50 StatusIs(Status::ResourceExhausted()));
51 EXPECT_THAT(Status::FailedPrecondition(),
52 StatusIs(Status::FailedPrecondition()));
53 EXPECT_THAT(Status::Aborted(), StatusIs(Status::Aborted()));
54 EXPECT_THAT(Status::OutOfRange(), StatusIs(Status::OutOfRange()));
55 EXPECT_THAT(Status::Unimplemented(), StatusIs(Status::Unimplemented()));
56 EXPECT_THAT(Status::Internal(), StatusIs(Status::Internal()));
57 EXPECT_THAT(Status::Unavailable(), StatusIs(Status::Unavailable()));
58 EXPECT_THAT(Status::DataLoss(), StatusIs(Status::DataLoss()));
59 EXPECT_THAT(Status::Unauthenticated(), StatusIs(Status::Unauthenticated()));
60 }
61
TEST(TestMatchers,StatusIsSuccessStatusWithSize)62 TEST(TestMatchers, StatusIsSuccessStatusWithSize) {
63 EXPECT_THAT(StatusWithSize(), StatusIs(OkStatus()));
64 EXPECT_THAT(StatusWithSize::Cancelled(), StatusIs(Status::Cancelled()));
65 EXPECT_THAT(StatusWithSize::Unknown(), StatusIs(Status::Unknown()));
66 EXPECT_THAT(StatusWithSize::InvalidArgument(),
67 StatusIs(Status::InvalidArgument()));
68 EXPECT_THAT(StatusWithSize::DeadlineExceeded(),
69 StatusIs(Status::DeadlineExceeded()));
70 EXPECT_THAT(StatusWithSize::NotFound(), StatusIs(Status::NotFound()));
71 EXPECT_THAT(StatusWithSize::AlreadyExists(),
72 StatusIs(Status::AlreadyExists()));
73 EXPECT_THAT(StatusWithSize::PermissionDenied(),
74 StatusIs(Status::PermissionDenied()));
75 EXPECT_THAT(StatusWithSize::ResourceExhausted(),
76 StatusIs(Status::ResourceExhausted()));
77 EXPECT_THAT(StatusWithSize::FailedPrecondition(),
78 StatusIs(Status::FailedPrecondition()));
79 EXPECT_THAT(StatusWithSize::Aborted(), StatusIs(Status::Aborted()));
80 EXPECT_THAT(StatusWithSize::OutOfRange(), StatusIs(Status::OutOfRange()));
81 EXPECT_THAT(StatusWithSize::Unimplemented(),
82 StatusIs(Status::Unimplemented()));
83 EXPECT_THAT(StatusWithSize::Internal(), StatusIs(Status::Internal()));
84 EXPECT_THAT(StatusWithSize::Unavailable(), StatusIs(Status::Unavailable()));
85 EXPECT_THAT(StatusWithSize::DataLoss(), StatusIs(Status::DataLoss()));
86 EXPECT_THAT(StatusWithSize::Unauthenticated(),
87 StatusIs(Status::Unauthenticated()));
88 }
89
TEST(TestMatchers,StatusIsSuccessOkResult)90 TEST(TestMatchers, StatusIsSuccessOkResult) {
91 const Result<int> result = 46;
92 EXPECT_THAT(result, StatusIs(OkStatus()));
93 }
94
TEST(TestMatchers,StatusIsSuccessResult)95 TEST(TestMatchers, StatusIsSuccessResult) {
96 EXPECT_THAT(Result<int>(Status::Cancelled()), StatusIs(Status::Cancelled()));
97 EXPECT_THAT(Result<int>(Status::Unknown()), StatusIs(Status::Unknown()));
98 EXPECT_THAT(Result<int>(Status::InvalidArgument()),
99 StatusIs(Status::InvalidArgument()));
100 EXPECT_THAT(Result<int>(Status::DeadlineExceeded()),
101 StatusIs(Status::DeadlineExceeded()));
102 EXPECT_THAT(Result<int>(Status::NotFound()), StatusIs(Status::NotFound()));
103 EXPECT_THAT(Result<int>(Status::AlreadyExists()),
104 StatusIs(Status::AlreadyExists()));
105 EXPECT_THAT(Result<int>(Status::PermissionDenied()),
106 StatusIs(Status::PermissionDenied()));
107 EXPECT_THAT(Result<int>(Status::ResourceExhausted()),
108 StatusIs(Status::ResourceExhausted()));
109 EXPECT_THAT(Result<int>(Status::FailedPrecondition()),
110 StatusIs(Status::FailedPrecondition()));
111 EXPECT_THAT(Result<int>(Status::Aborted()), StatusIs(Status::Aborted()));
112 EXPECT_THAT(Result<int>(Status::OutOfRange()),
113 StatusIs(Status::OutOfRange()));
114 EXPECT_THAT(Result<int>(Status::Unimplemented()),
115 StatusIs(Status::Unimplemented()));
116 EXPECT_THAT(Result<int>(Status::Internal()), StatusIs(Status::Internal()));
117 EXPECT_THAT(Result<int>(Status::Unavailable()),
118 StatusIs(Status::Unavailable()));
119 EXPECT_THAT(Result<int>(Status::DataLoss()), StatusIs(Status::DataLoss()));
120 EXPECT_THAT(Result<int>(Status::Unauthenticated()),
121 StatusIs(Status::Unauthenticated()));
122 }
123
TEST(IsOkAndHolds,StatusWithSize)124 TEST(IsOkAndHolds, StatusWithSize) {
125 const auto status_with_size = StatusWithSize{OkStatus(), 42};
126 EXPECT_THAT(status_with_size, IsOkAndHolds(Eq(42u)));
127 }
128
TEST(IsOkAndHolds,Result)129 TEST(IsOkAndHolds, Result) {
130 auto value = Result<int>{42};
131 EXPECT_THAT(value, IsOkAndHolds(Eq(42)));
132 }
133
TEST(IsOkAndHolds,BadStatusWithSize)134 TEST(IsOkAndHolds, BadStatusWithSize) {
135 const auto status_with_size = StatusWithSize{Status::InvalidArgument(), 0};
136 EXPECT_THAT(status_with_size, Not(IsOkAndHolds(Eq(42u))));
137 }
138
TEST(IsOkAndHolds,WrongStatusWithSize)139 TEST(IsOkAndHolds, WrongStatusWithSize) {
140 const auto status_with_size = StatusWithSize{OkStatus(), 100};
141 EXPECT_THAT(status_with_size, IsOkAndHolds(Not(Eq(42u))));
142 EXPECT_THAT(status_with_size, Not(IsOkAndHolds(Eq(42u))));
143 }
144
TEST(IsOkAndHolds,BadResult)145 TEST(IsOkAndHolds, BadResult) {
146 const auto value = Result<int>{Status::InvalidArgument()};
147 EXPECT_THAT(value, Not(IsOkAndHolds(Eq(42))));
148 }
149
TEST(IsOkAndHolds,WrongResult)150 TEST(IsOkAndHolds, WrongResult) {
151 const auto value = Result<int>{100};
152 EXPECT_THAT(value, IsOkAndHolds(Not(Eq(42))));
153 EXPECT_THAT(value, Not(IsOkAndHolds(Eq(42))));
154 }
155
TEST(AssertOkAndAssign,AssignsOkValueToNewLvalue)156 TEST(AssertOkAndAssign, AssignsOkValueToNewLvalue) {
157 const auto value = Result<int>(5);
158 ASSERT_OK_AND_ASSIGN(int declare_and_assign, value);
159 EXPECT_EQ(5, declare_and_assign);
160 }
161
TEST(AssertOkAndAssign,AssignsOkValueToExistingLvalue)162 TEST(AssertOkAndAssign, AssignsOkValueToExistingLvalue) {
163 const auto value = Result<int>(5);
164 int existing_value = 0;
165 ASSERT_OK_AND_ASSIGN(existing_value, value);
166 EXPECT_EQ(5, existing_value);
167 }
168
TEST(AssertOkAndAssign,AssignsExistingLvalueToConstReference)169 TEST(AssertOkAndAssign, AssignsExistingLvalueToConstReference) {
170 const auto value = Result<int>(5);
171 ASSERT_OK_AND_ASSIGN(const auto& ref, value);
172 EXPECT_EQ(5, ref);
173 }
174
AssertOkAndAssignInternally(Result<int> my_result_name)175 void AssertOkAndAssignInternally(Result<int> my_result_name) {
176 ASSERT_OK_AND_ASSIGN([[maybe_unused]] int _unused, my_result_name);
177 }
178
TEST(AssertOkAndAssign,AssertFailsOnNonOkStatus)179 TEST(AssertOkAndAssign, AssertFailsOnNonOkStatus) {
180 EXPECT_FATAL_FAILURE(AssertOkAndAssignInternally(Status::InvalidArgument()),
181 "`my_result_name` is not OK: INVALID_ARGUMENT");
182 }
183
184 class CopyMoveCounter {
185 public:
186 CopyMoveCounter() = delete;
CopyMoveCounter(int & copies,int & moves)187 CopyMoveCounter(int& copies, int& moves) : copies_(&copies), moves_(&moves) {}
CopyMoveCounter(const CopyMoveCounter & other)188 CopyMoveCounter(const CopyMoveCounter& other)
189 : copies_(other.copies_), moves_(other.moves_) {
190 ++(*copies_);
191 }
CopyMoveCounter(CopyMoveCounter && other)192 CopyMoveCounter(CopyMoveCounter&& other)
193 : copies_(other.copies_), moves_(other.moves_) {
194 ++(*moves_);
195 }
operator =(const CopyMoveCounter & other)196 CopyMoveCounter& operator=(const CopyMoveCounter& other) {
197 copies_ = other.copies_;
198 moves_ = other.moves_;
199 ++(*copies_);
200 return *this;
201 }
operator =(CopyMoveCounter && other)202 CopyMoveCounter& operator=(CopyMoveCounter&& other) {
203 copies_ = other.copies_;
204 moves_ = other.moves_;
205 ++(*moves_);
206 return *this;
207 }
208
209 private:
210 int* copies_;
211 int* moves_;
212 };
213
TEST(AssertOkAndAssign,OkRvalueDoesNotCopy)214 TEST(AssertOkAndAssign, OkRvalueDoesNotCopy) {
215 int copies = 0;
216 int moves = 0;
217 ASSERT_OK_AND_ASSIGN([[maybe_unused]] CopyMoveCounter cm,
218 Result(CopyMoveCounter(copies, moves)));
219 EXPECT_EQ(copies, 0);
220 EXPECT_EQ(moves, 2);
221 }
222
TEST(AssertOkAndAssign,OkLvalueMovedDoesNotCopy)223 TEST(AssertOkAndAssign, OkLvalueMovedDoesNotCopy) {
224 int copies = 0;
225 int moves = 0;
226 Result result(CopyMoveCounter(copies, moves));
227 ASSERT_OK_AND_ASSIGN([[maybe_unused]] CopyMoveCounter cm, std::move(result));
228 EXPECT_EQ(copies, 0);
229 EXPECT_EQ(moves, 3);
230 }
231
TEST(AssertOkAndAssign,OkLvalueCopiesOnce)232 TEST(AssertOkAndAssign, OkLvalueCopiesOnce) {
233 int copies = 0;
234 int moves = 0;
235 Result result(CopyMoveCounter(copies, moves));
236 ASSERT_OK_AND_ASSIGN([[maybe_unused]] CopyMoveCounter cm, result);
237 EXPECT_EQ(copies, 1);
238 EXPECT_EQ(moves, 2);
239 }
240
241 // The following test is commented out and is only for checking what
242 // failure cases would look like. For example, when uncommenting the test,
243 // the output is:
244 //
245 // ERR pw_unit_test/googletest_test_matchers_test.cc:50: Failure
246 // ERR Expected:
247 // ERR Actual: Value of: OkStatus()
248 // Expected: has status UNKNOWN
249 // Actual: 4-byte object <00-00 00-00>, which has status OK
250
251 // ERR pw_unit_test/googletest_test_matchers_test.cc:51: Failure
252 // ERR Expected:
253 // ERR Actual: Value of: Status::Unknown()
254 // Expected: is OK
255 // Actual: 4-byte object <02-00 00-00>, which has status UNKNOWN
256
257 // ERR pw_unit_test/googletest_test_matchers_test.cc:52: Failure
258 // ERR Expected:
259 // ERR Actual: Value of: Status::Unknown()
260 // Expected: is OK
261 // Actual: 4-byte object <02-00 00-00>, which has status UNKNOWN
262 //
263 // TEST(TestMatchers, SampleFailures) {
264 // EXPECT_THAT(OkStatus(), StatusIs(Status::Unknown()));
265 // EXPECT_OK(Status::Unknown());
266 // ASSERT_OK(Status::Unknown());
267 // }
268
269 } // namespace
270