Replace EXPECT_STDOUT and EXPECT_STDERR with a single macro EXPECT_WRITE.

This commit is contained in:
Victor Zverovich 2014-05-05 08:35:59 -07:00
parent 098f8ac343
commit 0aacd0cf6d
3 changed files with 48 additions and 29 deletions

View File

@ -1815,8 +1815,7 @@ TEST(FormatIntTest, FormatDec) {
#ifdef FMT_USE_FILE_DESCRIPTORS
TEST(FormatTest, PrintColored) {
EXPECT_STDOUT(
fmt::PrintColored(fmt::RED, "Hello, {}!\n") << "world",
EXPECT_WRITE(stdout, fmt::PrintColored(fmt::RED, "Hello, {}!\n") << "world",
"\x1b[31mHello, world!\n\x1b[0m");
}

View File

@ -83,17 +83,20 @@ class SingleEvaluationTest : public ::testing::Test {
SingleEvaluationTest() {
p_ = s_;
a_ = 0;
b_ = 0;
}
static const char* const s_;
static const char* p_;
static int a_;
static int b_;
};
const char* const SingleEvaluationTest::s_ = "01234";
const char* SingleEvaluationTest::p_;
int SingleEvaluationTest::a_;
int SingleEvaluationTest::b_;
void ThrowNothing() {}
@ -109,10 +112,11 @@ TEST_F(SingleEvaluationTest, FailedEXPECT_THROW_MSG) {
EXPECT_EQ(s_ + 1, p_);
}
// Tests that when EXPECT_STDOUT fails, it evaluates its message argument
// Tests that when EXPECT_WRITE fails, it evaluates its message argument
// exactly once.
TEST_F(SingleEvaluationTest, FailedEXPECT_STDOUT) {
EXPECT_NONFATAL_FAILURE(EXPECT_STDOUT(std::printf("test"), p_++), "01234");
TEST_F(SingleEvaluationTest, FailedEXPECT_WRITE) {
EXPECT_NONFATAL_FAILURE(
EXPECT_WRITE(stdout, std::printf("test"), p_++), "01234");
EXPECT_EQ(s_ + 1, p_);
}
@ -122,29 +126,55 @@ TEST_F(SingleEvaluationTest, ExceptionTests) {
EXPECT_THROW_MSG({ // NOLINT
a_++;
ThrowException();
}, std::exception, "test");
}, std::exception, (b_++, "test"));
EXPECT_EQ(1, a_);
EXPECT_EQ(1, b_);
// failed EXPECT_THROW_MSG, throws different type
EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG({ // NOLINT
a_++;
ThrowException();
}, std::logic_error, "test"), "throws a different type");
}, std::logic_error, (b_++, "test")), "throws a different type");
EXPECT_EQ(2, a_);
EXPECT_EQ(2, b_);
// failed EXPECT_THROW_MSG, throws an exception with different message
EXPECT_NONFATAL_FAILURE(EXPECT_THROW_MSG({ // NOLINT
a_++;
ThrowException();
}, std::exception, "other"), "throws an exception with a different message");
}, std::exception, (b_++, "other")),
"throws an exception with a different message");
EXPECT_EQ(3, a_);
EXPECT_EQ(3, b_);
// failed EXPECT_THROW_MSG, throws nothing
EXPECT_NONFATAL_FAILURE(
EXPECT_THROW_MSG(a_++, std::exception, "test"), "throws nothing");
EXPECT_THROW_MSG(a_++, std::exception, (b_++, "test")), "throws nothing");
EXPECT_EQ(4, a_);
EXPECT_EQ(4, b_);
}
// Tests that assertion arguments are evaluated exactly once.
TEST_F(SingleEvaluationTest, WriteTests) {
// successful EXPECT_WRITE
EXPECT_WRITE(stdout, { // NOLINT
a_++;
std::printf("test");
}, (b_++, "test"));
EXPECT_EQ(1, a_);
EXPECT_EQ(1, b_);
// failed EXPECT_WRITE
EXPECT_NONFATAL_FAILURE(EXPECT_WRITE(stdout, { // NOLINT
a_++;
std::printf("test");
}, (b_++, "other")), "Actual: test");
EXPECT_EQ(2, a_);
EXPECT_EQ(2, b_);
}
// TODO: test EXPECT_STD*
// Tests that the compiler will not complain about unreachable code in the
// EXPECT_THROW_MSG macro.
TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) {
@ -291,11 +321,11 @@ TEST_F(BufferedFileTest, CloseFileInDtor) {
TEST_F(BufferedFileTest, CloseErrorInDtor) {
BufferedFile *f = new BufferedFile(OpenFile(".travis.yml"));
// The close function must be called inside EXPECT_STDERR, otherwise
// The close function must be called inside EXPECT_WRITE, otherwise
// the system may recycle closed file descriptor when redirecting the
// output in EXPECT_STDERR and the second close will break output
// redirection.
EXPECT_STDERR(close(fileno(f->get())); delete f,
EXPECT_WRITE(stderr, close(fileno(f->get())); delete f,
FormatSystemErrorMessage(EBADF, "cannot close file") + "\n");
}
@ -380,11 +410,11 @@ TEST(FileTest, CloseFileInDtor) {
TEST(FileTest, CloseErrorInDtor) {
File *f = new File(".travis.yml", File::RDONLY);
#ifndef _WIN32
// The close function must be called inside EXPECT_STDERR, otherwise
// The close function must be called inside EXPECT_WRITE, otherwise
// the system may recycle closed file descriptor when redirecting the
// output in EXPECT_STDERR and the second close will break output
// redirection.
EXPECT_STDERR(FMT_POSIX(close(f->descriptor())); delete f,
EXPECT_WRITE(stderr, FMT_POSIX(close(f->descriptor())); delete f,
FormatSystemErrorMessage(EBADF, "cannot close file") + "\n");
#else
close(f->descriptor());
@ -404,10 +434,6 @@ TEST(FileTest, Close) {
TEST(FileTest, CloseError) {
File f(".travis.yml", File::RDONLY);
#ifndef _WIN32
// The close function must be called inside EXPECT_STDERR, otherwise
// the system may recycle closed file descriptor when redirecting the
// output in EXPECT_STDERR and the second close will break output
// redirection.
close(f.descriptor());
EXPECT_SYSTEM_ERROR(f.close(), EBADF, "cannot close file");
EXPECT_EQ(-1, f.descriptor());
@ -615,11 +641,11 @@ TEST(OutputRedirectTest, ErrorInDtor) {
// Put a character in a file buffer.
EXPECT_EQ('x', fputc('x', f.get()));
#ifndef _WIN32
// The close function must be called inside EXPECT_STDERR, otherwise
// The close function must be called inside EXPECT_WRITE, otherwise
// the system may recycle closed file descriptor when redirecting the
// output in EXPECT_STDERR and the second close will break output
// redirection.
EXPECT_STDERR(close(write_fd); delete redir,
EXPECT_WRITE(stderr, close(write_fd); delete redir,
FormatSystemErrorMessage(EBADF, "cannot flush stream"));
#else
close(write_fd);
@ -628,8 +654,6 @@ TEST(OutputRedirectTest, ErrorInDtor) {
write_dup.dup2(write_fd); // "undo" close or dtor of BufferedFile will fail
}
// TODO: test EXPECT_STDOUT and EXPECT_STDERR
// TODO: compile both in C++11 & C++98 mode
#endif

View File

@ -337,7 +337,7 @@ class OutputRedirect {
std::string RestoreAndRead();
};
#define FMT_TEST_PRINT_(statement, expected_output, file, fail) \
#define FMT_TEST_WRITE_(statement, expected_output, file, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::AssertionResult gtest_ar = ::testing::AssertionSuccess()) { \
std::string gtest_expected_output = expected_output; \
@ -355,13 +355,9 @@ class OutputRedirect {
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
fail(gtest_ar.failure_message())
// Tests that the statement prints the expected output to stdout.
#define EXPECT_STDOUT(statement, expected_output) \
FMT_TEST_PRINT_(statement, expected_output, stdout, GTEST_NONFATAL_FAILURE_)
// Tests that the statement prints the expected output to stderr.
#define EXPECT_STDERR(statement, expected_output) \
FMT_TEST_PRINT_(statement, expected_output, stderr, GTEST_NONFATAL_FAILURE_)
// Tests that the statement writes the expected output to file.
#define EXPECT_WRITE(file, statement, expected_output) \
FMT_TEST_WRITE_(statement, expected_output, file, GTEST_NONFATAL_FAILURE_)
#endif // FMT_USE_FILE_DESCRIPTORS