| // Copyright (c) 2023 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef QUICHE_COMMON_TEST_TOOLS_MOCK_STREAMS_H_ | |
| #define QUICHE_COMMON_TEST_TOOLS_MOCK_STREAMS_H_ | |
| #include <algorithm> | |
| #include <cstddef> | |
| #include <string> | |
| #include <utility> | |
| #include "absl/status/status.h" | |
| #include "absl/strings/string_view.h" | |
| #include "absl/types/span.h" | |
| #include "quiche/common/platform/api/quiche_test.h" | |
| #include "quiche/common/quiche_stream.h" | |
| namespace quiche::test { | |
| // Mockable stream that stores all of the data into an std::string by default. | |
| class MockWriteStream : public quiche::WriteStream { | |
| public: | |
| MockWriteStream() { | |
| ON_CALL(*this, CanWrite()).WillByDefault(testing::Return(true)); | |
| ON_CALL(*this, Writev(testing::_, testing::_)) | |
| .WillByDefault([&](absl::Span<const absl::string_view> data, | |
| const StreamWriteOptions& options) { | |
| return AppendToData(data, options); | |
| }); | |
| } | |
| MOCK_METHOD(absl::Status, Writev, | |
| (absl::Span<const absl::string_view> data, | |
| const StreamWriteOptions& options), | |
| (override)); | |
| MOCK_METHOD(bool, CanWrite, (), (const, override)); | |
| absl::Status AppendToData(absl::Span<const absl::string_view> data, | |
| const StreamWriteOptions& options) { | |
| for (absl::string_view fragment : data) { | |
| data_.append(fragment.data(), fragment.size()); | |
| } | |
| ProcessOptions(options); | |
| return absl::OkStatus(); | |
| } | |
| void ProcessOptions(const StreamWriteOptions& options) { | |
| fin_written_ |= options.send_fin(); | |
| } | |
| std::string& data() { return data_; } | |
| bool fin_written() { return fin_written_; } | |
| private: | |
| std::string data_; | |
| bool fin_written_ = false; | |
| }; | |
| // Reads stream data from an std::string buffer. | |
| class ReadStreamFromString : public ReadStream { | |
| public: | |
| explicit ReadStreamFromString(std::string* data) : data_(data) {} | |
| ReadResult Read(absl::Span<char> buffer) override { | |
| size_t data_to_copy = std::min(buffer.size(), data_->size()); | |
| std::copy(data_->begin(), data_->begin() + data_to_copy, buffer.begin()); | |
| *data_ = data_->substr(data_to_copy); | |
| return ReadResult{data_to_copy, data_->empty() && fin_}; | |
| } | |
| ReadResult Read(std::string* output) override { | |
| size_t bytes = data_->size(); | |
| output->append(std::move(*data_)); | |
| data_->clear(); | |
| return ReadResult{bytes, fin_}; | |
| } | |
| size_t ReadableBytes() const override { return data_->size(); } | |
| virtual PeekResult PeekNextReadableRegion() const override { | |
| PeekResult result; | |
| result.peeked_data = *data_; | |
| result.fin_next = data_->empty() && fin_; | |
| result.all_data_received = fin_; | |
| return result; | |
| } | |
| bool SkipBytes(size_t bytes) override { | |
| *data_ = data_->substr(bytes); | |
| return data_->empty() && fin_; | |
| } | |
| void set_fin() { fin_ = true; } | |
| private: | |
| std::string* data_; | |
| bool fin_ = false; | |
| }; | |
| } // namespace quiche::test | |
| #endif // QUICHE_COMMON_TEST_TOOLS_MOCK_STREAMS_H_ |