Replace EXPECT_STDOUT and EXPECT_STDERR with a single macro EXPECT_WRITE.
This commit is contained in:
parent
098f8ac343
commit
0aacd0cf6d
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user