1 /*
2  Tests of custom Google Test assertions.
3 
4  Copyright (c) 2012-2014, Victor Zverovich
5  All rights reserved.
6 
7  Redistribution and use in source and binary forms, with or without
8  modification, are permitted provided that the following conditions are met:
9 
10  1. Redistributions of source code must retain the above copyright notice, this
11     list of conditions and the following disclaimer.
12  2. Redistributions in binary form must reproduce the above copyright notice,
13     this list of conditions and the following disclaimer in the documentation
14     and/or other materials provided with the distribution.
15 
16  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "gtest-extra.h"
29 
30 #include <cstring>
31 #include <algorithm>
32 #include <stdexcept>
33 #include <gtest/gtest-spi.h>
34 
35 #if defined(_WIN32) && !defined(__MINGW32__)
36 # include <crtdbg.h>  // for _CrtSetReportMode
37 #endif  // _WIN32
38 
39 #include "util.h"
40 
41 using testing::internal::scoped_ptr;
42 
43 namespace {
44 
45 // This is used to suppress coverity warnings about untrusted values.
sanitize(const std::string & s)46 std::string sanitize(const std::string &s) {
47   std::string result;
48   for (std::string::const_iterator i = s.begin(), end = s.end(); i != end; ++i)
49     result.push_back(static_cast<char>(*i & 0xff));
50   return result;
51 }
52 
53 // Tests that assertion macros evaluate their arguments exactly once.
54 class SingleEvaluationTest : public ::testing::Test {
55  protected:
SingleEvaluationTest()56   SingleEvaluationTest() {
57     p_ = s_;
58     a_ = 0;
59     b_ = 0;
60   }
61 
62   static const char* const s_;
63   static const char* p_;
64 
65   static int a_;
66   static int b_;
67 };
68 
69 const char* const SingleEvaluationTest::s_ = "01234";
70 const char* SingleEvaluationTest::p_;
71 int SingleEvaluationTest::a_;
72 int SingleEvaluationTest::b_;
73 
do_nothing()74 void do_nothing() {}
75 
throw_exception()76 void throw_exception() {
77   throw std::runtime_error("test");
78 }
79 
throw_system_error()80 void throw_system_error() {
81   throw fmt::SystemError(EDOM, "test");
82 }
83 
84 // Tests that when EXPECT_THROW_MSG fails, it evaluates its message argument
85 // exactly once.
TEST_F(SingleEvaluationTest,FailedEXPECT_THROW_MSG)86 TEST_F(SingleEvaluationTest, FailedEXPECT_THROW_MSG) {
87   EXPECT_NONFATAL_FAILURE(
88       EXPECT_THROW_MSG(throw_exception(), std::exception, p_++), "01234");
89   EXPECT_EQ(s_ + 1, p_);
90 }
91 
92 // Tests that when EXPECT_SYSTEM_ERROR fails, it evaluates its message argument
93 // exactly once.
TEST_F(SingleEvaluationTest,FailedEXPECT_SYSTEM_ERROR)94 TEST_F(SingleEvaluationTest, FailedEXPECT_SYSTEM_ERROR) {
95   EXPECT_NONFATAL_FAILURE(
96       EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, p_++), "01234");
97   EXPECT_EQ(s_ + 1, p_);
98 }
99 
100 // Tests that when EXPECT_WRITE fails, it evaluates its message argument
101 // exactly once.
TEST_F(SingleEvaluationTest,FailedEXPECT_WRITE)102 TEST_F(SingleEvaluationTest, FailedEXPECT_WRITE) {
103   EXPECT_NONFATAL_FAILURE(
104       EXPECT_WRITE(stdout, std::printf("test"), p_++), "01234");
105   EXPECT_EQ(s_ + 1, p_);
106 }
107 
108 // Tests that assertion arguments are evaluated exactly once.
TEST_F(SingleEvaluationTest,ExceptionTests)109 TEST_F(SingleEvaluationTest, ExceptionTests) {
110   // successful EXPECT_THROW_MSG
111   EXPECT_THROW_MSG({  // NOLINT
112     a_++;
113     throw_exception();
114   }, std::exception, (b_++, "test"));
115   EXPECT_EQ(1, a_);
116   EXPECT_EQ(1, b_);
117 
118   // failed EXPECT_THROW_MSG, throws different type
119   EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG({  // NOLINT
120     a_++;
121     throw_exception();
122   }, std::logic_error, (b_++, "test")), "throws a different type");
123   EXPECT_EQ(2, a_);
124   EXPECT_EQ(2, b_);
125 
126   // failed EXPECT_THROW_MSG, throws an exception with different message
127   EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG({  // NOLINT
128     a_++;
129     throw_exception();
130   }, std::exception, (b_++, "other")),
131       "throws an exception with a different message");
132   EXPECT_EQ(3, a_);
133   EXPECT_EQ(3, b_);
134 
135   // failed EXPECT_THROW_MSG, throws nothing
136   EXPECT_NONFATAL_FAILURE(
137       EXPECT_THROW_MSG(a_++, std::exception, (b_++, "test")), "throws nothing");
138   EXPECT_EQ(4, a_);
139   EXPECT_EQ(4, b_);
140 }
141 
TEST_F(SingleEvaluationTest,SystemErrorTests)142 TEST_F(SingleEvaluationTest, SystemErrorTests) {
143   // successful EXPECT_SYSTEM_ERROR
144   EXPECT_SYSTEM_ERROR({  // NOLINT
145     a_++;
146     throw_system_error();
147   }, EDOM, (b_++, "test"));
148   EXPECT_EQ(1, a_);
149   EXPECT_EQ(1, b_);
150 
151   // failed EXPECT_SYSTEM_ERROR, throws different type
152   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR({  // NOLINT
153     a_++;
154     throw_exception();
155   }, EDOM, (b_++, "test")), "throws a different type");
156   EXPECT_EQ(2, a_);
157   EXPECT_EQ(2, b_);
158 
159   // failed EXPECT_SYSTEM_ERROR, throws an exception with different message
160   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR({  // NOLINT
161     a_++;
162     throw_system_error();
163   }, EDOM, (b_++, "other")),
164       "throws an exception with a different message");
165   EXPECT_EQ(3, a_);
166   EXPECT_EQ(3, b_);
167 
168   // failed EXPECT_SYSTEM_ERROR, throws nothing
169   EXPECT_NONFATAL_FAILURE(
170       EXPECT_SYSTEM_ERROR(a_++, EDOM, (b_++, "test")), "throws nothing");
171   EXPECT_EQ(4, a_);
172   EXPECT_EQ(4, b_);
173 }
174 
175 // Tests that assertion arguments are evaluated exactly once.
TEST_F(SingleEvaluationTest,WriteTests)176 TEST_F(SingleEvaluationTest, WriteTests) {
177   // successful EXPECT_WRITE
178   EXPECT_WRITE(stdout, {  // NOLINT
179     a_++;
180     std::printf("test");
181   }, (b_++, "test"));
182   EXPECT_EQ(1, a_);
183   EXPECT_EQ(1, b_);
184 
185   // failed EXPECT_WRITE
186   EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, {  // NOLINT
187     a_++;
188     std::printf("test");
189   }, (b_++, "other")), "Actual: test");
190   EXPECT_EQ(2, a_);
191   EXPECT_EQ(2, b_);
192 }
193 
194 // Tests that the compiler will not complain about unreachable code in the
195 // EXPECT_THROW_MSG macro.
TEST(ExpectThrowTest,DoesNotGenerateUnreachableCodeWarning)196 TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) {
197   int n = 0;
198   using std::runtime_error;
199   EXPECT_THROW_MSG(throw runtime_error(""), runtime_error, "");
200   EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(n++, runtime_error, ""), "");
201   EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(throw 1, runtime_error, ""), "");
202   EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG(
203       throw runtime_error("a"), runtime_error, "b"), "");
204 }
205 
206 // Tests that the compiler will not complain about unreachable code in the
207 // EXPECT_SYSTEM_ERROR macro.
TEST(ExpectSystemErrorTest,DoesNotGenerateUnreachableCodeWarning)208 TEST(ExpectSystemErrorTest, DoesNotGenerateUnreachableCodeWarning) {
209   int n = 0;
210   EXPECT_SYSTEM_ERROR(throw fmt::SystemError(EDOM, "test"), EDOM, "test");
211   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(n++, EDOM, ""), "");
212   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(throw 1, EDOM, ""), "");
213   EXPECT_NONFATAL_FAILURE(EXPECT_SYSTEM_ERROR(
214       throw fmt::SystemError(EDOM, "aaa"), EDOM, "bbb"), "");
215 }
216 
TEST(AssertionSyntaxTest,ExceptionAssertionBehavesLikeSingleStatement)217 TEST(AssertionSyntaxTest, ExceptionAssertionBehavesLikeSingleStatement) {
218   if (::testing::internal::AlwaysFalse())
219     EXPECT_THROW_MSG(do_nothing(), std::exception, "");
220 
221   if (::testing::internal::AlwaysTrue())
222     EXPECT_THROW_MSG(throw_exception(), std::exception, "test");
223   else
224     do_nothing();
225 }
226 
TEST(AssertionSyntaxTest,SystemErrorAssertionBehavesLikeSingleStatement)227 TEST(AssertionSyntaxTest, SystemErrorAssertionBehavesLikeSingleStatement) {
228   if (::testing::internal::AlwaysFalse())
229     EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, "");
230 
231   if (::testing::internal::AlwaysTrue())
232     EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test");
233   else
234     do_nothing();
235 }
236 
TEST(AssertionSyntaxTest,WriteAssertionBehavesLikeSingleStatement)237 TEST(AssertionSyntaxTest, WriteAssertionBehavesLikeSingleStatement) {
238   if (::testing::internal::AlwaysFalse())
239     EXPECT_WRITE(stdout, std::printf("x"), "x");
240 
241   if (::testing::internal::AlwaysTrue())
242     EXPECT_WRITE(stdout, std::printf("x"), "x");
243   else
244     do_nothing();
245 }
246 
247 // Tests EXPECT_THROW_MSG.
TEST(ExpectTest,EXPECT_THROW_MSG)248 TEST(ExpectTest, EXPECT_THROW_MSG) {
249   EXPECT_THROW_MSG(throw_exception(), std::exception, "test");
250   EXPECT_NONFATAL_FAILURE(
251       EXPECT_THROW_MSG(throw_exception(), std::logic_error, "test"),
252       "Expected: throw_exception() throws an exception of "
253       "type std::logic_error.\n  Actual: it throws a different type.");
254   EXPECT_NONFATAL_FAILURE(
255       EXPECT_THROW_MSG(do_nothing(), std::exception, "test"),
256       "Expected: do_nothing() throws an exception of type std::exception.\n"
257       "  Actual: it throws nothing.");
258   EXPECT_NONFATAL_FAILURE(
259       EXPECT_THROW_MSG(throw_exception(), std::exception, "other"),
260       "throw_exception() throws an exception with a different message.\n"
261       "Expected: other\n"
262       "  Actual: test");
263 }
264 
265 // Tests EXPECT_SYSTEM_ERROR.
TEST(ExpectTest,EXPECT_SYSTEM_ERROR)266 TEST(ExpectTest, EXPECT_SYSTEM_ERROR) {
267   EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test");
268   EXPECT_NONFATAL_FAILURE(
269       EXPECT_SYSTEM_ERROR(throw_exception(), EDOM, "test"),
270       "Expected: throw_exception() throws an exception of "
271       "type fmt::SystemError.\n  Actual: it throws a different type.");
272   EXPECT_NONFATAL_FAILURE(
273       EXPECT_SYSTEM_ERROR(do_nothing(), EDOM, "test"),
274       "Expected: do_nothing() throws an exception of type fmt::SystemError.\n"
275       "  Actual: it throws nothing.");
276   EXPECT_NONFATAL_FAILURE(
277       EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other"),
278       fmt::format(
279           "throw_system_error() throws an exception with a different message.\n"
280           "Expected: {}\n"
281           "  Actual: {}",
282           format_system_error(EDOM, "other"),
283           format_system_error(EDOM, "test")));
284 }
285 
286 // Tests EXPECT_WRITE.
TEST(ExpectTest,EXPECT_WRITE)287 TEST(ExpectTest, EXPECT_WRITE) {
288   EXPECT_WRITE(stdout, do_nothing(), "");
289   EXPECT_WRITE(stdout, std::printf("test"), "test");
290   EXPECT_WRITE(stderr, std::fprintf(stderr, "test"), "test");
291   EXPECT_NONFATAL_FAILURE(
292       EXPECT_WRITE(stdout, std::printf("that"), "this"),
293       "Expected: this\n"
294       "  Actual: that");
295 }
296 
TEST(StreamingAssertionsTest,EXPECT_THROW_MSG)297 TEST(StreamingAssertionsTest, EXPECT_THROW_MSG) {
298   EXPECT_THROW_MSG(throw_exception(), std::exception, "test")
299       << "unexpected failure";
300   EXPECT_NONFATAL_FAILURE(
301       EXPECT_THROW_MSG(throw_exception(), std::exception, "other")
302       << "expected failure", "expected failure");
303 }
304 
TEST(StreamingAssertionsTest,EXPECT_SYSTEM_ERROR)305 TEST(StreamingAssertionsTest, EXPECT_SYSTEM_ERROR) {
306   EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "test")
307       << "unexpected failure";
308   EXPECT_NONFATAL_FAILURE(
309       EXPECT_SYSTEM_ERROR(throw_system_error(), EDOM, "other")
310       << "expected failure", "expected failure");
311 }
312 
TEST(StreamingAssertionsTest,EXPECT_WRITE)313 TEST(StreamingAssertionsTest, EXPECT_WRITE) {
314   EXPECT_WRITE(stdout, std::printf("test"), "test")
315       << "unexpected failure";
316   EXPECT_NONFATAL_FAILURE(
317       EXPECT_WRITE(stdout, std::printf("test"), "other")
318       << "expected failure", "expected failure");
319 }
320 
TEST(UtilTest,FormatSystemError)321 TEST(UtilTest, FormatSystemError) {
322   fmt::MemoryWriter out;
323   fmt::format_system_error(out, EDOM, "test message");
324   EXPECT_EQ(out.str(), format_system_error(EDOM, "test message"));
325 }
326 
327 #if FMT_USE_FILE_DESCRIPTORS
328 
329 using fmt::BufferedFile;
330 using fmt::ErrorCode;
331 using fmt::File;
332 
TEST(ErrorCodeTest,Ctor)333 TEST(ErrorCodeTest, Ctor) {
334   EXPECT_EQ(0, ErrorCode().get());
335   EXPECT_EQ(42, ErrorCode(42).get());
336 }
337 
TEST(OutputRedirectTest,ScopedRedirect)338 TEST(OutputRedirectTest, ScopedRedirect) {
339   File read_end, write_end;
340   File::pipe(read_end, write_end);
341   {
342     BufferedFile file(write_end.fdopen("w"));
343     std::fprintf(file.get(), "[[[");
344     {
345       OutputRedirect redir(file.get());
346       std::fprintf(file.get(), "censored");
347     }
348     std::fprintf(file.get(), "]]]");
349   }
350   EXPECT_READ(read_end, "[[[]]]");
351 }
352 
353 // Test that OutputRedirect handles errors in flush correctly.
TEST(OutputRedirectTest,FlushErrorInCtor)354 TEST(OutputRedirectTest, FlushErrorInCtor) {
355   File read_end, write_end;
356   File::pipe(read_end, write_end);
357   int write_fd = write_end.descriptor();
358   File write_copy = write_end.dup(write_fd);
359   BufferedFile f = write_end.fdopen("w");
360   // Put a character in a file buffer.
361   EXPECT_EQ('x', fputc('x', f.get()));
362   FMT_POSIX(close(write_fd));
363   scoped_ptr<OutputRedirect> redir;
364   EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new OutputRedirect(f.get())),
365       EBADF, "cannot flush stream");
366   redir.reset();
367   write_copy.dup2(write_fd);  // "undo" close or dtor will fail
368 }
369 
TEST(OutputRedirectTest,DupErrorInCtor)370 TEST(OutputRedirectTest, DupErrorInCtor) {
371   BufferedFile f = open_buffered_file();
372   int fd = (f.fileno)();
373   File copy = File::dup(fd);
374   FMT_POSIX(close(fd));
375   scoped_ptr<OutputRedirect> redir;
376   EXPECT_SYSTEM_ERROR_NOASSERT(redir.reset(new OutputRedirect(f.get())),
377       EBADF, fmt::format("cannot duplicate file descriptor {}", fd));
378   copy.dup2(fd);  // "undo" close or dtor will fail
379 }
380 
TEST(OutputRedirectTest,RestoreAndRead)381 TEST(OutputRedirectTest, RestoreAndRead) {
382   File read_end, write_end;
383   File::pipe(read_end, write_end);
384   BufferedFile file(write_end.fdopen("w"));
385   std::fprintf(file.get(), "[[[");
386   OutputRedirect redir(file.get());
387   std::fprintf(file.get(), "censored");
388   EXPECT_EQ("censored", sanitize(redir.restore_and_read()));
389   EXPECT_EQ("", sanitize(redir.restore_and_read()));
390   std::fprintf(file.get(), "]]]");
391   file = BufferedFile();
392   EXPECT_READ(read_end, "[[[]]]");
393 }
394 
395 // Test that OutputRedirect handles errors in flush correctly.
TEST(OutputRedirectTest,FlushErrorInRestoreAndRead)396 TEST(OutputRedirectTest, FlushErrorInRestoreAndRead) {
397   File read_end, write_end;
398   File::pipe(read_end, write_end);
399   int write_fd = write_end.descriptor();
400   File write_copy = write_end.dup(write_fd);
401   BufferedFile f = write_end.fdopen("w");
402   OutputRedirect redir(f.get());
403   // Put a character in a file buffer.
404   EXPECT_EQ('x', fputc('x', f.get()));
405   FMT_POSIX(close(write_fd));
406   EXPECT_SYSTEM_ERROR_NOASSERT(redir.restore_and_read(),
407       EBADF, "cannot flush stream");
408   write_copy.dup2(write_fd);  // "undo" close or dtor will fail
409 }
410 
TEST(OutputRedirectTest,ErrorInDtor)411 TEST(OutputRedirectTest, ErrorInDtor) {
412   File read_end, write_end;
413   File::pipe(read_end, write_end);
414   int write_fd = write_end.descriptor();
415   File write_copy = write_end.dup(write_fd);
416   BufferedFile f = write_end.fdopen("w");
417   scoped_ptr<OutputRedirect> redir(new OutputRedirect(f.get()));
418   // Put a character in a file buffer.
419   EXPECT_EQ('x', fputc('x', f.get()));
420   EXPECT_WRITE(stderr, {
421       // The close function must be called inside EXPECT_WRITE, otherwise
422       // the system may recycle closed file descriptor when redirecting the
423       // output in EXPECT_STDERR and the second close will break output
424       // redirection.
425       FMT_POSIX(close(write_fd));
426       SUPPRESS_ASSERT(redir.reset());
427   }, format_system_error(EBADF, "cannot flush stream"));
428   write_copy.dup2(write_fd); // "undo" close or dtor of BufferedFile will fail
429 }
430 
431 #endif  // FMT_USE_FILE_DESCRIPTORS
432 
433 }  // namespace
434