From 3c15882f4e47299d9a1e94c901456f0bd97ef430 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Thu, 18 May 2023 08:03:57 -0700 Subject: [PATCH] Extract a test helper to its own library. (#2828) This is a convenient test helper for anything that can use injected streams. Extract this to where it can be used by other tests and add some basic tests, mostly documenting how it works. --- common/BUILD | 20 ++++++++++ common/test_raw_ostream.h | 41 +++++++++++++++++++++ common/test_raw_ostream_test.cpp | 63 ++++++++++++++++++++++++++++++++ toolchain/driver/BUILD | 1 + toolchain/driver/driver_test.cpp | 56 +++++++--------------------- 5 files changed, 138 insertions(+), 43 deletions(-) create mode 100644 common/test_raw_ostream.h create mode 100644 common/test_raw_ostream_test.cpp diff --git a/common/BUILD b/common/BUILD index 95aabaeb49a9..6952dd3143a1 100644 --- a/common/BUILD +++ b/common/BUILD @@ -146,6 +146,26 @@ cc_test( ], ) +cc_library( + name = "test_raw_ostream", + testonly = 1, + hdrs = ["test_raw_ostream.h"], + deps = [ + ":ostream", + "@com_google_googletest//:gtest", + ], +) + +cc_test( + name = "test_raw_ostream_test", + srcs = ["test_raw_ostream_test.cpp"], + deps = [ + ":test_raw_ostream", + "//common:gtest_main", + "@com_google_googletest//:gtest", + ], +) + cc_library( name = "vlog", srcs = ["vlog_internal.h"], diff --git a/common/test_raw_ostream.h b/common/test_raw_ostream.h new file mode 100644 index 000000000000..50e54b2de09b --- /dev/null +++ b/common/test_raw_ostream.h @@ -0,0 +1,41 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#ifndef CARBON_COMMON_TEST_RAW_OSTREAM_H_ +#define CARBON_COMMON_TEST_RAW_OSTREAM_H_ + +#include + +#include + +#include "common/ostream.h" + +namespace Carbon::Testing { + +// A raw_ostream that makes it easy to repeatedly check streamed output. +class TestRawOstream : public llvm::raw_string_ostream { + public: + explicit TestRawOstream() : llvm::raw_string_ostream(buffer_) {} + + ~TestRawOstream() override { + if (!buffer_.empty()) { + ADD_FAILURE() << "Unchecked output:\n" << buffer_; + } + } + + // Flushes the stream and returns the contents so far, clearing the stream + // back to empty. + auto TakeStr() -> std::string { + std::string result = std::move(buffer_); + buffer_.clear(); + return result; + } + + private: + std::string buffer_; +}; + +} // namespace Carbon::Testing + +#endif // CARBON_COMMON_TEST_RAW_OSTREAM_H_ diff --git a/common/test_raw_ostream_test.cpp b/common/test_raw_ostream_test.cpp new file mode 100644 index 000000000000..e4c84034da3f --- /dev/null +++ b/common/test_raw_ostream_test.cpp @@ -0,0 +1,63 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + +#include "common/test_raw_ostream.h" + +#include +#include + +namespace Carbon::Testing { +namespace { + +using ::testing::HasSubstr; +using ::testing::StrEq; + +TEST(TestRawOstreamTest, Basics) { + TestRawOstream os; + + os << "test 1"; + EXPECT_THAT(os.TakeStr(), StrEq("test 1")); + + os << "test" + << " " + << "2"; + EXPECT_THAT(os.TakeStr(), StrEq("test 2")); + + os << "test"; + os << " "; + os << "3"; + EXPECT_THAT(os.TakeStr(), StrEq("test 3")); +} + +TEST(TestRawOstreamTest, MultipleStreams) { + TestRawOstream os1; + TestRawOstream os2; + + os1 << "test "; + os2 << "test stream 2"; + os1 << "stream 1"; + EXPECT_THAT(os1.TakeStr(), StrEq("test stream 1")); + EXPECT_THAT(os2.TakeStr(), StrEq("test stream 2")); +} + +TEST(TestRawOstreamTest, MultipleLines) { + TestRawOstream os; + + os << "test line 1\n"; + os << "test line 2\n"; + os << "test line 3\n"; + EXPECT_THAT(os.TakeStr(), StrEq("test line 1\ntest line 2\ntest line 3\n")); +} + +TEST(TestRawOstreamTest, Substring) { + TestRawOstream os; + + os << "test line 1\n"; + os << "test line 2\n"; + os << "test line 3\n"; + EXPECT_THAT(os.TakeStr(), HasSubstr("test line 2")); +} + +} // namespace +} // namespace Carbon::Testing diff --git a/toolchain/driver/BUILD b/toolchain/driver/BUILD index fce89fb4bd1f..ea36288d3752 100644 --- a/toolchain/driver/BUILD +++ b/toolchain/driver/BUILD @@ -33,6 +33,7 @@ cc_test( deps = [ ":driver", "//common:gtest_main", + "//common:test_raw_ostream", "//toolchain/common:yaml_test_helpers", "//toolchain/diagnostics:diagnostic_emitter", "//toolchain/lexer:tokenized_buffer_test_helpers", diff --git a/toolchain/driver/driver_test.cpp b/toolchain/driver/driver_test.cpp index c67493f79d6c..c4f06cb50e03 100644 --- a/toolchain/driver/driver_test.cpp +++ b/toolchain/driver/driver_test.cpp @@ -7,6 +7,7 @@ #include #include +#include "common/test_raw_ostream.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/SourceMgr.h" @@ -20,40 +21,9 @@ using ::testing::ElementsAre; using ::testing::HasSubstr; using ::testing::StrEq; -/// A raw_ostream that makes it easy to repeatedly check streamed output. -class RawTestOstream : public llvm::raw_ostream { - public: - ~RawTestOstream() override { - flush(); - if (!buffer_.empty()) { - ADD_FAILURE() << "Unchecked output:\n" << buffer_; - } - } - - /// Flushes the stream and returns the contents so far, clearing the stream - /// back to empty. - auto TakeStr() -> std::string { - flush(); - std::string result = std::move(buffer_); - buffer_.clear(); - return result; - } - - private: - void write_impl(const char* ptr, size_t size) override { - buffer_.append(ptr, ptr + size); - } - - [[nodiscard]] auto current_pos() const -> uint64_t override { - return buffer_.size(); - } - - std::string buffer_; -}; - TEST(DriverTest, FullCommandErrors) { - RawTestOstream test_output_stream; - RawTestOstream test_error_stream; + TestRawOstream test_output_stream; + TestRawOstream test_error_stream; Driver driver = Driver(test_output_stream, test_error_stream); EXPECT_FALSE(driver.RunFullCommand({})); @@ -67,8 +37,8 @@ TEST(DriverTest, FullCommandErrors) { } TEST(DriverTest, Help) { - RawTestOstream test_output_stream; - RawTestOstream test_error_stream; + TestRawOstream test_output_stream; + TestRawOstream test_error_stream; Driver driver = Driver(test_output_stream, test_error_stream); EXPECT_TRUE(driver.RunHelpSubcommand(ConsoleDiagnosticConsumer(), {})); @@ -87,8 +57,8 @@ TEST(DriverTest, Help) { } TEST(DriverTest, HelpErrors) { - RawTestOstream test_output_stream; - RawTestOstream test_error_stream; + TestRawOstream test_output_stream; + TestRawOstream test_error_stream; Driver driver = Driver(test_output_stream, test_error_stream); EXPECT_FALSE(driver.RunHelpSubcommand(ConsoleDiagnosticConsumer(), {"foo"})); @@ -122,8 +92,8 @@ auto CreateTestFile(llvm::StringRef text) -> std::string { } TEST(DriverTest, DumpTokens) { - RawTestOstream test_output_stream; - RawTestOstream test_error_stream; + TestRawOstream test_output_stream; + TestRawOstream test_error_stream; Driver driver = Driver(test_output_stream, test_error_stream); auto test_file_path = CreateTestFile("Hello World"); @@ -164,8 +134,8 @@ TEST(DriverTest, DumpTokens) { } TEST(DriverTest, DumpErrors) { - RawTestOstream test_output_stream; - RawTestOstream test_error_stream; + TestRawOstream test_output_stream; + TestRawOstream test_error_stream; Driver driver = Driver(test_output_stream, test_error_stream); EXPECT_FALSE(driver.RunDumpSubcommand(ConsoleDiagnosticConsumer(), {"foo"})); @@ -189,8 +159,8 @@ TEST(DriverTest, DumpErrors) { } TEST(DriverTest, DumpParseTree) { - RawTestOstream test_output_stream; - RawTestOstream test_error_stream; + TestRawOstream test_output_stream; + TestRawOstream test_error_stream; Driver driver = Driver(test_output_stream, test_error_stream); auto test_file_path = CreateTestFile("var v: Int = 42;");