blob: f858b783f26962bed510d4a4f2e6520c5ed08254 [file]
// 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 "modules/fetch/BytesConsumer.h"
#include "modules/fetch/FetchDataLoader.h"
#include "platform/heap/Handle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "wtf/Deque.h"
#include "wtf/Vector.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,
PassRefPtr<BlobDataHandle>(BlobSizePolicy));
MOCK_METHOD0(drainAsFormData, PassRefPtr<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>;
}
DEFINE_INLINE_VIRTUAL_TRACE() { FetchDataLoader::Client::trace(visitor); }
MOCK_METHOD1(didFetchDataLoadedBlobHandleMock,
void(RefPtr<BlobDataHandle>));
MOCK_METHOD1(didFetchDataLoadedArrayBufferMock, void(DOMArrayBuffer*));
MOCK_METHOD1(didFetchDataLoadedString, void(const String&));
MOCK_METHOD0(didFetchDataLoadStream, void());
MOCK_METHOD0(didFetchDataLoadFailed, void());
void didFetchDataLoadedArrayBuffer(DOMArrayBuffer* arrayBuffer) override {
didFetchDataLoadedArrayBufferMock(arrayBuffer);
}
// In mock methods we use RefPtr<> rather than PassRefPtr<>.
void didFetchDataLoadedBlobHandle(
PassRefPtr<BlobDataHandle> blobDataHandle) override {
didFetchDataLoadedBlobHandleMock(blobDataHandle);
}
};
class Command final {
DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
public:
enum Name {
Data,
Done,
Error,
Wait,
};
explicit Command(Name name) : m_name(name) {}
Command(Name name, const Vector<char>& body) : m_name(name), m_body(body) {}
Command(Name name, const char* body, size_t size) : m_name(name) {
m_body.append(body, size);
}
Command(Name name, const char* body) : Command(name, body, strlen(body)) {}
Name getName() const { return m_name; }
const Vector<char>& body() const { return m_body; }
private:
const Name m_name;
Vector<char> m_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();
// Add a command to this handle. This function must be called BEFORE
// any BytesConsumer methods are called.
void add(const Command& command) { m_commands.append(command); }
Result beginRead(const char** buffer, size_t* available) override;
Result endRead(size_t readSize) 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 m_isCancelled; }
DECLARE_TRACE();
private:
void notifyAsReadable(int notificationToken);
void close();
void error(const Error&);
Member<ExecutionContext> m_executionContext;
Member<BytesConsumer::Client> m_client;
InternalState m_state = InternalState::Waiting;
Deque<Command> m_commands;
size_t m_offset = 0;
BytesConsumer::Error m_error;
int m_notificationToken = 0;
bool m_isCancelled = 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;
std::pair<BytesConsumer::Result, Vector<char>> run();
DEFINE_INLINE_TRACE() {
visitor->trace(m_consumer);
BytesConsumer::Client::trace(visitor);
}
private:
Member<BytesConsumer> m_consumer;
BytesConsumer::Result m_result = BytesConsumer::Result::ShouldWait;
Vector<char> m_data;
};
};
} // namespace blink
#endif // BytesConsumerTestUtil_h