xref: /aosp_15_r20/external/fmtlib/test/gtest-extra-test.cc (revision 5c90c05cd622c0a81b57953a4d343e0e489f2e08)
1*5c90c05cSAndroid Build Coastguard Worker // Formatting library for C++ - tests of custom Google Test assertions
2*5c90c05cSAndroid Build Coastguard Worker //
3*5c90c05cSAndroid Build Coastguard Worker // Copyright (c) 2012 - present, Victor Zverovich
4*5c90c05cSAndroid Build Coastguard Worker // All rights reserved.
5*5c90c05cSAndroid Build Coastguard Worker //
6*5c90c05cSAndroid Build Coastguard Worker // For the license information refer to format.h.
7*5c90c05cSAndroid Build Coastguard Worker 
8*5c90c05cSAndroid Build Coastguard Worker #include "gtest-extra.h"
9*5c90c05cSAndroid Build Coastguard Worker 
10*5c90c05cSAndroid Build Coastguard Worker #include <gtest/gtest-spi.h>
11*5c90c05cSAndroid Build Coastguard Worker 
12*5c90c05cSAndroid Build Coastguard Worker #include <cstring>
13*5c90c05cSAndroid Build Coastguard Worker #include <memory>
14*5c90c05cSAndroid Build Coastguard Worker #include <stdexcept>
15*5c90c05cSAndroid Build Coastguard Worker 
16*5c90c05cSAndroid Build Coastguard Worker #include "fmt/os.h"
17*5c90c05cSAndroid Build Coastguard Worker #include "util.h"
18*5c90c05cSAndroid Build Coastguard Worker 
19*5c90c05cSAndroid Build Coastguard Worker // Tests that assertion macros evaluate their arguments exactly once.
20*5c90c05cSAndroid Build Coastguard Worker namespace {
21*5c90c05cSAndroid Build Coastguard Worker class single_evaluation_test : public ::testing::Test {
22*5c90c05cSAndroid Build Coastguard Worker  protected:
single_evaluation_test()23*5c90c05cSAndroid Build Coastguard Worker   single_evaluation_test() {
24*5c90c05cSAndroid Build Coastguard Worker     p_ = s_;
25*5c90c05cSAndroid Build Coastguard Worker     a_ = 0;
26*5c90c05cSAndroid Build Coastguard Worker     b_ = 0;
27*5c90c05cSAndroid Build Coastguard Worker   }
28*5c90c05cSAndroid Build Coastguard Worker 
29*5c90c05cSAndroid Build Coastguard Worker   static const char* const s_;
30*5c90c05cSAndroid Build Coastguard Worker   static const char* p_;
31*5c90c05cSAndroid Build Coastguard Worker 
32*5c90c05cSAndroid Build Coastguard Worker   static int a_;
33*5c90c05cSAndroid Build Coastguard Worker   static int b_;
34*5c90c05cSAndroid Build Coastguard Worker };
35*5c90c05cSAndroid Build Coastguard Worker }  // namespace
36*5c90c05cSAndroid Build Coastguard Worker 
37*5c90c05cSAndroid Build Coastguard Worker const char* const single_evaluation_test::s_ = "01234";
38*5c90c05cSAndroid Build Coastguard Worker const char* single_evaluation_test::p_;
39*5c90c05cSAndroid Build Coastguard Worker int single_evaluation_test::a_;
40*5c90c05cSAndroid Build Coastguard Worker int single_evaluation_test::b_;
41*5c90c05cSAndroid Build Coastguard Worker 
do_nothing()42*5c90c05cSAndroid Build Coastguard Worker void do_nothing() {}
43*5c90c05cSAndroid Build Coastguard Worker 
throw_exception()44*5c90c05cSAndroid Build Coastguard Worker FMT_NORETURN void throw_exception() { throw std::runtime_error("test"); }
45*5c90c05cSAndroid Build Coastguard Worker 
throw_system_error()46*5c90c05cSAndroid Build Coastguard Worker FMT_NORETURN void throw_system_error() {
47*5c90c05cSAndroid Build Coastguard Worker   throw fmt::system_error(EDOM, "test");
48*5c90c05cSAndroid Build Coastguard Worker }
49*5c90c05cSAndroid Build Coastguard Worker 
50*5c90c05cSAndroid Build Coastguard Worker // Tests that when EXPECT_THROW_MSG fails, it evaluates its message argument
51*5c90c05cSAndroid Build Coastguard Worker // exactly once.
TEST_F(single_evaluation_test,failed_expect_throw_msg)52*5c90c05cSAndroid Build Coastguard Worker TEST_F(single_evaluation_test, failed_expect_throw_msg) {
53*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
54*5c90c05cSAndroid Build Coastguard Worker       EXPECT_THROW_MSG(throw_exception(), std::exception, p_++), "01234");
55*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(s_ + 1, p_);
56*5c90c05cSAndroid Build Coastguard Worker }
57*5c90c05cSAndroid Build Coastguard Worker 
58*5c90c05cSAndroid Build Coastguard Worker // Tests that when EXPECT_SYSTEM_ERROR fails, it evaluates its message argument
59*5c90c05cSAndroid Build Coastguard Worker // exactly once.
TEST_F(single_evaluation_test,failed_expect_system_error)60*5c90c05cSAndroid Build Coastguard Worker TEST_F(single_evaluation_test, failed_expect_system_error) {
61*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, p_++),
62*5c90c05cSAndroid Build Coastguard Worker                           "01234");
63*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(s_ + 1, p_);
64*5c90c05cSAndroid Build Coastguard Worker }
65*5c90c05cSAndroid Build Coastguard Worker 
66*5c90c05cSAndroid Build Coastguard Worker // Tests that assertion arguments are evaluated exactly once.
TEST_F(single_evaluation_test,exception_tests)67*5c90c05cSAndroid Build Coastguard Worker TEST_F(single_evaluation_test, exception_tests) {
68*5c90c05cSAndroid Build Coastguard Worker   // successful EXPECT_THROW_MSG
69*5c90c05cSAndroid Build Coastguard Worker   EXPECT_THROW_MSG(
70*5c90c05cSAndroid Build Coastguard Worker       {  // NOLINT
71*5c90c05cSAndroid Build Coastguard Worker         a_++;
72*5c90c05cSAndroid Build Coastguard Worker         throw_exception();
73*5c90c05cSAndroid Build Coastguard Worker       },
74*5c90c05cSAndroid Build Coastguard Worker       std::exception, (b_++, "test"));
75*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(1, a_);
76*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(1, b_);
77*5c90c05cSAndroid Build Coastguard Worker 
78*5c90c05cSAndroid Build Coastguard Worker   // failed EXPECT_THROW_MSG, throws different type
79*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(
80*5c90c05cSAndroid Build Coastguard Worker                               {  // NOLINT
81*5c90c05cSAndroid Build Coastguard Worker                                 a_++;
82*5c90c05cSAndroid Build Coastguard Worker                                 throw_exception();
83*5c90c05cSAndroid Build Coastguard Worker                               },
84*5c90c05cSAndroid Build Coastguard Worker                               std::logic_error, (b_++, "test")),
85*5c90c05cSAndroid Build Coastguard Worker                           "throws a different type");
86*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(2, a_);
87*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(2, b_);
88*5c90c05cSAndroid Build Coastguard Worker 
89*5c90c05cSAndroid Build Coastguard Worker   // failed EXPECT_THROW_MSG, throws an exception with different message
90*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(
91*5c90c05cSAndroid Build Coastguard Worker                               {  // NOLINT
92*5c90c05cSAndroid Build Coastguard Worker                                 a_++;
93*5c90c05cSAndroid Build Coastguard Worker                                 throw_exception();
94*5c90c05cSAndroid Build Coastguard Worker                               },
95*5c90c05cSAndroid Build Coastguard Worker                               std::exception, (b_++, "other")),
96*5c90c05cSAndroid Build Coastguard Worker                           "throws an exception with a different message");
97*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(3, a_);
98*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(3, b_);
99*5c90c05cSAndroid Build Coastguard Worker 
100*5c90c05cSAndroid Build Coastguard Worker   // failed EXPECT_THROW_MSG, throws nothing
101*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
102*5c90c05cSAndroid Build Coastguard Worker       EXPECT_THROW_MSG(a_++, std::exception, (b_++, "test")), "throws nothing");
103*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(4, a_);
104*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(4, b_);
105*5c90c05cSAndroid Build Coastguard Worker }
106*5c90c05cSAndroid Build Coastguard Worker 
TEST_F(single_evaluation_test,system_error_tests)107*5c90c05cSAndroid Build Coastguard Worker TEST_F(single_evaluation_test, system_error_tests) {
108*5c90c05cSAndroid Build Coastguard Worker   // successful EXPECT_SYSTEM_ERROR
109*5c90c05cSAndroid Build Coastguard Worker   EXPECT_SYSTEM_ERROR(
110*5c90c05cSAndroid Build Coastguard Worker       {  // NOLINT
111*5c90c05cSAndroid Build Coastguard Worker         a_++;
112*5c90c05cSAndroid Build Coastguard Worker         throw_system_error();
113*5c90c05cSAndroid Build Coastguard Worker       },
114*5c90c05cSAndroid Build Coastguard Worker       EDOM, (b_++, "test"));
115*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(1, a_);
116*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(1, b_);
117*5c90c05cSAndroid Build Coastguard Worker 
118*5c90c05cSAndroid Build Coastguard Worker   // failed EXPECT_SYSTEM_ERROR, throws different type
119*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(
120*5c90c05cSAndroid Build Coastguard Worker                               {  // NOLINT
121*5c90c05cSAndroid Build Coastguard Worker                                 a_++;
122*5c90c05cSAndroid Build Coastguard Worker                                 throw_exception();
123*5c90c05cSAndroid Build Coastguard Worker                               },
124*5c90c05cSAndroid Build Coastguard Worker                               EDOM, (b_++, "test")),
125*5c90c05cSAndroid Build Coastguard Worker                           "throws a different type");
126*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(2, a_);
127*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(2, b_);
128*5c90c05cSAndroid Build Coastguard Worker 
129*5c90c05cSAndroid Build Coastguard Worker   // failed EXPECT_SYSTEM_ERROR, throws an exception with different message
130*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(
131*5c90c05cSAndroid Build Coastguard Worker                               {  // NOLINT
132*5c90c05cSAndroid Build Coastguard Worker                                 a_++;
133*5c90c05cSAndroid Build Coastguard Worker                                 throw_system_error();
134*5c90c05cSAndroid Build Coastguard Worker                               },
135*5c90c05cSAndroid Build Coastguard Worker                               EDOM, (b_++, "other")),
136*5c90c05cSAndroid Build Coastguard Worker                           "throws an exception with a different message");
137*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(3, a_);
138*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(3, b_);
139*5c90c05cSAndroid Build Coastguard Worker 
140*5c90c05cSAndroid Build Coastguard Worker   // failed EXPECT_SYSTEM_ERROR, throws nothing
141*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(a_++, EDOM, (b_++, "test")),
142*5c90c05cSAndroid Build Coastguard Worker                           "throws nothing");
143*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(4, a_);
144*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(4, b_);
145*5c90c05cSAndroid Build Coastguard Worker }
146*5c90c05cSAndroid Build Coastguard Worker 
147*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_FCNTL
148*5c90c05cSAndroid Build Coastguard Worker // Tests that when EXPECT_WRITE fails, it evaluates its message argument
149*5c90c05cSAndroid Build Coastguard Worker // exactly once.
TEST_F(single_evaluation_test,failed_expect_write)150*5c90c05cSAndroid Build Coastguard Worker TEST_F(single_evaluation_test, failed_expect_write) {
151*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("test"), p_++),
152*5c90c05cSAndroid Build Coastguard Worker                           "01234");
153*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(s_ + 1, p_);
154*5c90c05cSAndroid Build Coastguard Worker }
155*5c90c05cSAndroid Build Coastguard Worker 
156*5c90c05cSAndroid Build Coastguard Worker // Tests that assertion arguments are evaluated exactly once.
TEST_F(single_evaluation_test,write_tests)157*5c90c05cSAndroid Build Coastguard Worker TEST_F(single_evaluation_test, write_tests) {
158*5c90c05cSAndroid Build Coastguard Worker   // successful EXPECT_WRITE
159*5c90c05cSAndroid Build Coastguard Worker   EXPECT_WRITE(
160*5c90c05cSAndroid Build Coastguard Worker       stdout,
161*5c90c05cSAndroid Build Coastguard Worker       {  // NOLINT
162*5c90c05cSAndroid Build Coastguard Worker         a_++;
163*5c90c05cSAndroid Build Coastguard Worker         std::printf("test");
164*5c90c05cSAndroid Build Coastguard Worker       },
165*5c90c05cSAndroid Build Coastguard Worker       (b_++, "test"));
166*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(1, a_);
167*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(1, b_);
168*5c90c05cSAndroid Build Coastguard Worker 
169*5c90c05cSAndroid Build Coastguard Worker   // failed EXPECT_WRITE
170*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(
171*5c90c05cSAndroid Build Coastguard Worker                               stdout,
172*5c90c05cSAndroid Build Coastguard Worker                               {  // NOLINT
173*5c90c05cSAndroid Build Coastguard Worker                                 a_++;
174*5c90c05cSAndroid Build Coastguard Worker                                 std::printf("test");
175*5c90c05cSAndroid Build Coastguard Worker                               },
176*5c90c05cSAndroid Build Coastguard Worker                               (b_++, "other")),
177*5c90c05cSAndroid Build Coastguard Worker                           "Actual: test");
178*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(2, a_);
179*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ(2, b_);
180*5c90c05cSAndroid Build Coastguard Worker }
181*5c90c05cSAndroid Build Coastguard Worker 
182*5c90c05cSAndroid Build Coastguard Worker // Tests EXPECT_WRITE.
TEST(gtest_extra_test,expect_write)183*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_write) {
184*5c90c05cSAndroid Build Coastguard Worker   EXPECT_WRITE(stdout, do_nothing(), "");
185*5c90c05cSAndroid Build Coastguard Worker   EXPECT_WRITE(stdout, std::printf("test"), "test");
186*5c90c05cSAndroid Build Coastguard Worker   EXPECT_WRITE(stderr, std::fprintf(stderr, "test"), "test");
187*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("that"), "this"),
188*5c90c05cSAndroid Build Coastguard Worker                           "Expected: this\n"
189*5c90c05cSAndroid Build Coastguard Worker                           "  Actual: that");
190*5c90c05cSAndroid Build Coastguard Worker }
191*5c90c05cSAndroid Build Coastguard Worker 
TEST(gtest_extra_test,expect_write_streaming)192*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_write_streaming) {
193*5c90c05cSAndroid Build Coastguard Worker   EXPECT_WRITE(stdout, std::printf("test"), "test") << "unexpected failure";
194*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, std::printf("test"), "other")
195*5c90c05cSAndroid Build Coastguard Worker                               << "expected failure",
196*5c90c05cSAndroid Build Coastguard Worker                           "expected failure");
197*5c90c05cSAndroid Build Coastguard Worker }
198*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_USE_FCNTL
199*5c90c05cSAndroid Build Coastguard Worker 
200*5c90c05cSAndroid Build Coastguard Worker // Tests that the compiler will not complain about unreachable code in the
201*5c90c05cSAndroid Build Coastguard Worker // EXPECT_THROW_MSG macro.
TEST(gtest_extra_test,expect_throw_no_unreachable_code_warning)202*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_throw_no_unreachable_code_warning) {
203*5c90c05cSAndroid Build Coastguard Worker   int n = 0;
204*5c90c05cSAndroid Build Coastguard Worker   (void)n;
205*5c90c05cSAndroid Build Coastguard Worker   using std::runtime_error;
206*5c90c05cSAndroid Build Coastguard Worker   EXPECT_THROW_MSG(throw runtime_error(""), runtime_error, "");
207*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(n++, runtime_error, ""), "");
208*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(throw 1, runtime_error, ""), "");
209*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
210*5c90c05cSAndroid Build Coastguard Worker       EXPECT_THROW_MSG(throw runtime_error("a"), runtime_error, "b"), "");
211*5c90c05cSAndroid Build Coastguard Worker }
212*5c90c05cSAndroid Build Coastguard Worker 
213*5c90c05cSAndroid Build Coastguard Worker // Tests that the compiler will not complain about unreachable code in the
214*5c90c05cSAndroid Build Coastguard Worker // EXPECT_SYSTEM_ERROR macro.
TEST(gtest_extra_test,expect_system_error_no_unreachable_code_warning)215*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_system_error_no_unreachable_code_warning) {
216*5c90c05cSAndroid Build Coastguard Worker   int n = 0;
217*5c90c05cSAndroid Build Coastguard Worker   (void)n;
218*5c90c05cSAndroid Build Coastguard Worker   EXPECT_SYSTEM_ERROR(throw fmt::system_error(EDOM, "test"), EDOM, "test");
219*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(n++, EDOM, ""), "");
220*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw 1, EDOM, ""), "");
221*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
222*5c90c05cSAndroid Build Coastguard Worker       EXPECT_SYSTEM_ERROR(throw fmt::system_error(EDOM, "aaa"), EDOM, "bbb"),
223*5c90c05cSAndroid Build Coastguard Worker       "");
224*5c90c05cSAndroid Build Coastguard Worker }
225*5c90c05cSAndroid Build Coastguard Worker 
TEST(gtest_extra_test,expect_throw_behaves_like_single_statement)226*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_throw_behaves_like_single_statement) {
227*5c90c05cSAndroid Build Coastguard Worker   if (::testing::internal::AlwaysFalse())
228*5c90c05cSAndroid Build Coastguard Worker     EXPECT_THROW_MSG(do_nothing(), std::exception, "");
229*5c90c05cSAndroid Build Coastguard Worker 
230*5c90c05cSAndroid Build Coastguard Worker   if (::testing::internal::AlwaysTrue())
231*5c90c05cSAndroid Build Coastguard Worker     EXPECT_THROW_MSG(throw_exception(), std::exception, "test");
232*5c90c05cSAndroid Build Coastguard Worker   else
233*5c90c05cSAndroid Build Coastguard Worker     do_nothing();
234*5c90c05cSAndroid Build Coastguard Worker }
235*5c90c05cSAndroid Build Coastguard Worker 
TEST(gtest_extra_test,expect_system_error_behaves_like_single_statement)236*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_system_error_behaves_like_single_statement) {
237*5c90c05cSAndroid Build Coastguard Worker   if (::testing::internal::AlwaysFalse())
238*5c90c05cSAndroid Build Coastguard Worker     EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, "");
239*5c90c05cSAndroid Build Coastguard Worker 
240*5c90c05cSAndroid Build Coastguard Worker   if (::testing::internal::AlwaysTrue())
241*5c90c05cSAndroid Build Coastguard Worker     EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test");
242*5c90c05cSAndroid Build Coastguard Worker   else
243*5c90c05cSAndroid Build Coastguard Worker     do_nothing();
244*5c90c05cSAndroid Build Coastguard Worker }
245*5c90c05cSAndroid Build Coastguard Worker 
TEST(gtest_extra_test,expect_write_behaves_like_single_statement)246*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_write_behaves_like_single_statement) {
247*5c90c05cSAndroid Build Coastguard Worker   if (::testing::internal::AlwaysFalse())
248*5c90c05cSAndroid Build Coastguard Worker     EXPECT_WRITE(stdout, std::printf("x"), "x");
249*5c90c05cSAndroid Build Coastguard Worker 
250*5c90c05cSAndroid Build Coastguard Worker   if (::testing::internal::AlwaysTrue())
251*5c90c05cSAndroid Build Coastguard Worker     EXPECT_WRITE(stdout, std::printf("x"), "x");
252*5c90c05cSAndroid Build Coastguard Worker   else
253*5c90c05cSAndroid Build Coastguard Worker     do_nothing();
254*5c90c05cSAndroid Build Coastguard Worker }
255*5c90c05cSAndroid Build Coastguard Worker 
256*5c90c05cSAndroid Build Coastguard Worker // Tests EXPECT_THROW_MSG.
TEST(gtest_extra_test,expect_throw_msg)257*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_throw_msg) {
258*5c90c05cSAndroid Build Coastguard Worker   EXPECT_THROW_MSG(throw_exception(), std::exception, "test");
259*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
260*5c90c05cSAndroid Build Coastguard Worker       EXPECT_THROW_MSG(throw_exception(), std::logic_error, "test"),
261*5c90c05cSAndroid Build Coastguard Worker       "Expected: throw_exception() throws an exception of "
262*5c90c05cSAndroid Build Coastguard Worker       "type std::logic_error.\n  Actual: it throws a different type.");
263*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
264*5c90c05cSAndroid Build Coastguard Worker       EXPECT_THROW_MSG(do_nothing(), std::exception, "test"),
265*5c90c05cSAndroid Build Coastguard Worker       "Expected: do_nothing() throws an exception of type std::exception.\n"
266*5c90c05cSAndroid Build Coastguard Worker       "  Actual: it throws nothing.");
267*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
268*5c90c05cSAndroid Build Coastguard Worker       EXPECT_THROW_MSG(throw_exception(), std::exception, "other"),
269*5c90c05cSAndroid Build Coastguard Worker       "throw_exception() throws an exception with a different message.\n"
270*5c90c05cSAndroid Build Coastguard Worker       "Expected: other\n"
271*5c90c05cSAndroid Build Coastguard Worker       "  Actual: test");
272*5c90c05cSAndroid Build Coastguard Worker }
273*5c90c05cSAndroid Build Coastguard Worker 
274*5c90c05cSAndroid Build Coastguard Worker // Tests EXPECT_SYSTEM_ERROR.
TEST(gtest_extra_test,expect_system_error)275*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_system_error) {
276*5c90c05cSAndroid Build Coastguard Worker   EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test");
277*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
278*5c90c05cSAndroid Build Coastguard Worker       EXPECT_SYSTEM_ERROR(throw_exception(), EDOM, "test"),
279*5c90c05cSAndroid Build Coastguard Worker       "Expected: throw_exception() throws an exception of "
280*5c90c05cSAndroid Build Coastguard Worker       "type std::system_error.\n  Actual: it throws a different type.");
281*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
282*5c90c05cSAndroid Build Coastguard Worker       EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, "test"),
283*5c90c05cSAndroid Build Coastguard Worker       "Expected: do_nothing() throws an exception of type std::system_error.\n"
284*5c90c05cSAndroid Build Coastguard Worker       "  Actual: it throws nothing.");
285*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
286*5c90c05cSAndroid Build Coastguard Worker       EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other"),
287*5c90c05cSAndroid Build Coastguard Worker       fmt::format(
288*5c90c05cSAndroid Build Coastguard Worker           "throw_system_error() throws an exception with a different message.\n"
289*5c90c05cSAndroid Build Coastguard Worker           "Expected: {}\n"
290*5c90c05cSAndroid Build Coastguard Worker           "  Actual: {}",
291*5c90c05cSAndroid Build Coastguard Worker           system_error_message(EDOM, "other"),
292*5c90c05cSAndroid Build Coastguard Worker           system_error_message(EDOM, "test")));
293*5c90c05cSAndroid Build Coastguard Worker }
294*5c90c05cSAndroid Build Coastguard Worker 
TEST(gtest_extra_test,expect_throw_msg_streaming)295*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_throw_msg_streaming) {
296*5c90c05cSAndroid Build Coastguard Worker   EXPECT_THROW_MSG(throw_exception(), std::exception, "test")
297*5c90c05cSAndroid Build Coastguard Worker       << "unexpected failure";
298*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
299*5c90c05cSAndroid Build Coastguard Worker       EXPECT_THROW_MSG(throw_exception(), std::exception, "other")
300*5c90c05cSAndroid Build Coastguard Worker           << "expected failure",
301*5c90c05cSAndroid Build Coastguard Worker       "expected failure");
302*5c90c05cSAndroid Build Coastguard Worker }
303*5c90c05cSAndroid Build Coastguard Worker 
TEST(gtest_extra_test,expect_system_error_streaming)304*5c90c05cSAndroid Build Coastguard Worker TEST(gtest_extra_test, expect_system_error_streaming) {
305*5c90c05cSAndroid Build Coastguard Worker   EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test")
306*5c90c05cSAndroid Build Coastguard Worker       << "unexpected failure";
307*5c90c05cSAndroid Build Coastguard Worker   EXPECT_NONFATAL_FAILURE(
308*5c90c05cSAndroid Build Coastguard Worker       EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other")
309*5c90c05cSAndroid Build Coastguard Worker           << "expected failure",
310*5c90c05cSAndroid Build Coastguard Worker       "expected failure");
311*5c90c05cSAndroid Build Coastguard Worker }
312*5c90c05cSAndroid Build Coastguard Worker 
313*5c90c05cSAndroid Build Coastguard Worker #if FMT_USE_FCNTL
314*5c90c05cSAndroid Build Coastguard Worker 
315*5c90c05cSAndroid Build Coastguard Worker using fmt::buffered_file;
316*5c90c05cSAndroid Build Coastguard Worker using fmt::file;
317*5c90c05cSAndroid Build Coastguard Worker 
TEST(output_redirect_test,scoped_redirect)318*5c90c05cSAndroid Build Coastguard Worker TEST(output_redirect_test, scoped_redirect) {
319*5c90c05cSAndroid Build Coastguard Worker   auto pipe = fmt::pipe();
320*5c90c05cSAndroid Build Coastguard Worker   {
321*5c90c05cSAndroid Build Coastguard Worker     buffered_file file(pipe.write_end.fdopen("w"));
322*5c90c05cSAndroid Build Coastguard Worker     std::fprintf(file.get(), "[[[");
323*5c90c05cSAndroid Build Coastguard Worker     {
324*5c90c05cSAndroid Build Coastguard Worker       output_redirect redir(file.get());
325*5c90c05cSAndroid Build Coastguard Worker       std::fprintf(file.get(), "censored");
326*5c90c05cSAndroid Build Coastguard Worker     }
327*5c90c05cSAndroid Build Coastguard Worker     std::fprintf(file.get(), "]]]");
328*5c90c05cSAndroid Build Coastguard Worker   }
329*5c90c05cSAndroid Build Coastguard Worker   EXPECT_READ(pipe.read_end, "[[[]]]");
330*5c90c05cSAndroid Build Coastguard Worker }
331*5c90c05cSAndroid Build Coastguard Worker 
332*5c90c05cSAndroid Build Coastguard Worker // Test that output_redirect handles errors in flush correctly.
TEST(output_redirect_test,flush_error_in_ctor)333*5c90c05cSAndroid Build Coastguard Worker TEST(output_redirect_test, flush_error_in_ctor) {
334*5c90c05cSAndroid Build Coastguard Worker   auto pipe = fmt::pipe();
335*5c90c05cSAndroid Build Coastguard Worker   int write_fd = pipe.write_end.descriptor();
336*5c90c05cSAndroid Build Coastguard Worker   file write_copy = pipe.write_end.dup(write_fd);
337*5c90c05cSAndroid Build Coastguard Worker   buffered_file f = pipe.write_end.fdopen("w");
338*5c90c05cSAndroid Build Coastguard Worker   // Put a character in a file buffer.
339*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ('x', fputc('x', f.get()));
340*5c90c05cSAndroid Build Coastguard Worker   FMT_POSIX(close(write_fd));
341*5c90c05cSAndroid Build Coastguard Worker   std::unique_ptr<output_redirect> redir{nullptr};
342*5c90c05cSAndroid Build Coastguard Worker   EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new output_redirect(f.get())), EBADF,
343*5c90c05cSAndroid Build Coastguard Worker                                "cannot flush stream");
344*5c90c05cSAndroid Build Coastguard Worker   redir.reset(nullptr);
345*5c90c05cSAndroid Build Coastguard Worker   write_copy.dup2(write_fd);  // "undo" close or dtor will fail
346*5c90c05cSAndroid Build Coastguard Worker }
347*5c90c05cSAndroid Build Coastguard Worker 
TEST(output_redirect_test,dup_error_in_ctor)348*5c90c05cSAndroid Build Coastguard Worker TEST(output_redirect_test, dup_error_in_ctor) {
349*5c90c05cSAndroid Build Coastguard Worker   buffered_file f = open_buffered_file();
350*5c90c05cSAndroid Build Coastguard Worker   int fd = (f.descriptor)();
351*5c90c05cSAndroid Build Coastguard Worker   file copy = file::dup(fd);
352*5c90c05cSAndroid Build Coastguard Worker   FMT_POSIX(close(fd));
353*5c90c05cSAndroid Build Coastguard Worker   std::unique_ptr<output_redirect> redir{nullptr};
354*5c90c05cSAndroid Build Coastguard Worker   EXPECT_SYSTEM_ERROR_NOASSERT(
355*5c90c05cSAndroid Build Coastguard Worker       redir.reset(new output_redirect(f.get(), false)), EBADF,
356*5c90c05cSAndroid Build Coastguard Worker       fmt::format("cannot duplicate file descriptor {}", fd));
357*5c90c05cSAndroid Build Coastguard Worker   copy.dup2(fd);  // "undo" close or dtor will fail
358*5c90c05cSAndroid Build Coastguard Worker }
359*5c90c05cSAndroid Build Coastguard Worker 
TEST(output_redirect_test,restore_and_read)360*5c90c05cSAndroid Build Coastguard Worker TEST(output_redirect_test, restore_and_read) {
361*5c90c05cSAndroid Build Coastguard Worker   auto pipe = fmt::pipe();
362*5c90c05cSAndroid Build Coastguard Worker   buffered_file file(pipe.write_end.fdopen("w"));
363*5c90c05cSAndroid Build Coastguard Worker   std::fprintf(file.get(), "[[[");
364*5c90c05cSAndroid Build Coastguard Worker   output_redirect redir(file.get());
365*5c90c05cSAndroid Build Coastguard Worker   std::fprintf(file.get(), "censored");
366*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ("censored", redir.restore_and_read());
367*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ("", redir.restore_and_read());
368*5c90c05cSAndroid Build Coastguard Worker   std::fprintf(file.get(), "]]]");
369*5c90c05cSAndroid Build Coastguard Worker   file = buffered_file();
370*5c90c05cSAndroid Build Coastguard Worker   EXPECT_READ(pipe.read_end, "[[[]]]");
371*5c90c05cSAndroid Build Coastguard Worker }
372*5c90c05cSAndroid Build Coastguard Worker 
373*5c90c05cSAndroid Build Coastguard Worker // Test that OutputRedirect handles errors in flush correctly.
TEST(output_redirect_test,flush_error_in_restore_and_read)374*5c90c05cSAndroid Build Coastguard Worker TEST(output_redirect_test, flush_error_in_restore_and_read) {
375*5c90c05cSAndroid Build Coastguard Worker   auto pipe = fmt::pipe();
376*5c90c05cSAndroid Build Coastguard Worker   int write_fd = pipe.write_end.descriptor();
377*5c90c05cSAndroid Build Coastguard Worker   file write_copy = pipe.write_end.dup(write_fd);
378*5c90c05cSAndroid Build Coastguard Worker   buffered_file f = pipe.write_end.fdopen("w");
379*5c90c05cSAndroid Build Coastguard Worker   output_redirect redir(f.get());
380*5c90c05cSAndroid Build Coastguard Worker   // Put a character in a file buffer.
381*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ('x', fputc('x', f.get()));
382*5c90c05cSAndroid Build Coastguard Worker   FMT_POSIX(close(write_fd));
383*5c90c05cSAndroid Build Coastguard Worker   EXPECT_SYSTEM_ERROR_NOASSERT(redir.restore_and_read(), EBADF,
384*5c90c05cSAndroid Build Coastguard Worker                                "cannot flush stream");
385*5c90c05cSAndroid Build Coastguard Worker   write_copy.dup2(write_fd);  // "undo" close or dtor will fail
386*5c90c05cSAndroid Build Coastguard Worker }
387*5c90c05cSAndroid Build Coastguard Worker 
TEST(output_redirect_test,error_in_dtor)388*5c90c05cSAndroid Build Coastguard Worker TEST(output_redirect_test, error_in_dtor) {
389*5c90c05cSAndroid Build Coastguard Worker   auto pipe = fmt::pipe();
390*5c90c05cSAndroid Build Coastguard Worker   int write_fd = pipe.write_end.descriptor();
391*5c90c05cSAndroid Build Coastguard Worker   file write_copy = pipe.write_end.dup(write_fd);
392*5c90c05cSAndroid Build Coastguard Worker   buffered_file f = pipe.write_end.fdopen("w");
393*5c90c05cSAndroid Build Coastguard Worker   std::unique_ptr<output_redirect> redir(new output_redirect(f.get()));
394*5c90c05cSAndroid Build Coastguard Worker   // Put a character in a file buffer.
395*5c90c05cSAndroid Build Coastguard Worker   EXPECT_EQ('x', fputc('x', f.get()));
396*5c90c05cSAndroid Build Coastguard Worker   EXPECT_WRITE(
397*5c90c05cSAndroid Build Coastguard Worker       stderr,
398*5c90c05cSAndroid Build Coastguard Worker       {
399*5c90c05cSAndroid Build Coastguard Worker         // The close function must be called inside EXPECT_WRITE,
400*5c90c05cSAndroid Build Coastguard Worker         // otherwise the system may recycle closed file descriptor when
401*5c90c05cSAndroid Build Coastguard Worker         // redirecting the output in EXPECT_STDERR and the second close
402*5c90c05cSAndroid Build Coastguard Worker         // will break output redirection.
403*5c90c05cSAndroid Build Coastguard Worker         FMT_POSIX(close(write_fd));
404*5c90c05cSAndroid Build Coastguard Worker         SUPPRESS_ASSERT(redir.reset(nullptr));
405*5c90c05cSAndroid Build Coastguard Worker       },
406*5c90c05cSAndroid Build Coastguard Worker       system_error_message(EBADF, "cannot flush stream"));
407*5c90c05cSAndroid Build Coastguard Worker   write_copy.dup2(write_fd);  // "undo" close or dtor of buffered_file will fail
408*5c90c05cSAndroid Build Coastguard Worker }
409*5c90c05cSAndroid Build Coastguard Worker 
410*5c90c05cSAndroid Build Coastguard Worker #endif  // FMT_USE_FCNTL
411