blob: f03e20aede7461b06f2533a6a25d0cf937964105 [file] [log] [blame]
// Copyright 2016 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 BytesConsumerTestUtil_h
#define BytesConsumerTestUtil_h
#include "core/fetch/BytesConsumer.h"
#include "core/fetch/FetchDataLoader.h"
#include "platform/heap/Handle.h"
#include "platform/wtf/Deque.h"
#include "platform/wtf/Vector.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace blink {
class ExecutionContext;
class BytesConsumerTestUtil {
STATIC_ONLY(BytesConsumerTestUtil);
public:
class MockBytesConsumer : public BytesConsumer {
public:
static MockBytesConsumer* Create() {
return new ::testing::StrictMock<MockBytesConsumer>();
}
MOCK_METHOD2(BeginRead, Result(const char**, size_t*));
MOCK_METHOD1(EndRead, Result(size_t));
MOCK_METHOD1(DrainAsBlobDataHandle,
scoped_refptr<BlobDataHandle>(BlobSizePolicy));
MOCK_METHOD0(DrainAsFormData, scoped_refptr<EncodedFormData>());
MOCK_METHOD1(SetClient, void(Client*));
MOCK_METHOD0(ClearClient, void());
MOCK_METHOD0(Cancel, void());
MOCK_CONST_METHOD0(GetPublicState, PublicState());
MOCK_CONST_METHOD0(GetError, Error());
String DebugName() const override { return "MockBytesConsumer"; }
protected:
MockBytesConsumer();
};
class MockFetchDataLoaderClient
: public GarbageCollectedFinalized<MockFetchDataLoaderClient>,
public FetchDataLoader::Client {
USING_GARBAGE_COLLECTED_MIXIN(MockFetchDataLoaderClient);
public:
static ::testing::StrictMock<MockFetchDataLoaderClient>* Create() {
return new ::testing::StrictMock<MockFetchDataLoaderClient>;
}
virtual void Trace(blink::Visitor* visitor) {
FetchDataLoader::Client::Trace(visitor);
}
MOCK_METHOD1(DidFetchDataLoadedBlobHandleMock,
void(scoped_refptr<BlobDataHandle>));
MOCK_METHOD1(DidFetchDataLoadedArrayBufferMock, void(DOMArrayBuffer*));
MOCK_METHOD1(DidFetchDataLoadedFormDataMock, void(FormData*));
MOCK_METHOD1(DidFetchDataLoadedString, void(const String&));
MOCK_METHOD0(DidFetchDataLoadStream, void());
MOCK_METHOD0(DidFetchDataLoadFailed, void());
void DidFetchDataLoadedArrayBuffer(DOMArrayBuffer* array_buffer) override {
DidFetchDataLoadedArrayBufferMock(array_buffer);
}
// TODO(yhirano): Remove DidFetchDataLoadedBlobHandleMock.
void DidFetchDataLoadedBlobHandle(
scoped_refptr<BlobDataHandle> blob_data_handle) override {
DidFetchDataLoadedBlobHandleMock(std::move(blob_data_handle));
}
void DidFetchDataLoadedFormData(FormData* FormData) override {
DidFetchDataLoadedFormDataMock(FormData);
}
};
class Command final {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
enum Name {
kData,
kDone,
kError,
kWait,
};
explicit Command(Name name) : name_(name) {}
Command(Name name, const Vector<char>& body) : name_(name), body_(body) {}
Command(Name name, const char* body, size_t size) : name_(name) {
body_.Append(body, size);
}
Command(Name name, const char* body) : Command(name, body, strlen(body)) {}
Name GetName() const { return name_; }
const Vector<char>& Body() const { return body_; }
private:
const Name name_;
Vector<char> body_;
};
// ReplayingBytesConsumer stores commands via |add| and replays the stored
// commends when read.
class ReplayingBytesConsumer final : public BytesConsumer {
public:
// The ExecutionContext is needed to get a WebTaskRunner.
explicit ReplayingBytesConsumer(ExecutionContext*);
~ReplayingBytesConsumer() override;
// Add a command to this handle. This function must be called BEFORE
// any BytesConsumer methods are called.
void Add(const Command& command) { commands_.push_back(command); }
Result BeginRead(const char** buffer, size_t* available) override;
Result EndRead(size_t read_size) override;
void SetClient(Client*) override;
void ClearClient() override;
void Cancel() override;
PublicState GetPublicState() const override;
Error GetError() const override;
String DebugName() const override { return "ReplayingBytesConsumer"; }
bool IsCancelled() const { return is_cancelled_; }
void Trace(blink::Visitor*) override;
private:
void NotifyAsReadable(int notification_token);
void Close();
void MakeErrored(const Error&);
Member<ExecutionContext> execution_context_;
Member<BytesConsumer::Client> client_;
InternalState state_ = InternalState::kWaiting;
Deque<Command> commands_;
size_t offset_ = 0;
BytesConsumer::Error error_;
int notification_token_ = 0;
bool is_cancelled_ = false;
};
class TwoPhaseReader final : public GarbageCollectedFinalized<TwoPhaseReader>,
public BytesConsumer::Client {
USING_GARBAGE_COLLECTED_MIXIN(TwoPhaseReader);
public:
// |consumer| must not have a client when called.
explicit TwoPhaseReader(BytesConsumer* /* consumer */);
void OnStateChange() override;
String DebugName() const override { return "TwoPhaseReader"; }
std::pair<BytesConsumer::Result, Vector<char>> Run();
void Trace(blink::Visitor* visitor) override {
visitor->Trace(consumer_);
BytesConsumer::Client::Trace(visitor);
}
private:
Member<BytesConsumer> consumer_;
BytesConsumer::Result result_ = BytesConsumer::Result::kShouldWait;
Vector<char> data_;
};
static String CharVectorToString(const Vector<char>&);
};
} // namespace blink
#endif // BytesConsumerTestUtil_h