| Index: content/browser/webui/i18n_source_stream_unittest.cc
|
| diff --git a/content/browser/webui/i18n_source_stream_unittest.cc b/content/browser/webui/i18n_source_stream_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..76ebf694ddace05c6c1be40942e429b9f8bca551
|
| --- /dev/null
|
| +++ b/content/browser/webui/i18n_source_stream_unittest.cc
|
| @@ -0,0 +1,221 @@
|
| +// 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.
|
| +
|
| +#include <utility>
|
| +
|
| +#include "content/browser/webui/i18n_source_stream.h"
|
| +#include "net/base/io_buffer.h"
|
| +#include "net/base/test_completion_callback.h"
|
| +#include "net/filter/mock_source_stream.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +namespace content {
|
| +
|
| +namespace {
|
| +
|
| +// These constants are rather arbitrary, though the offsets and other sizes must
|
| +// be less than kBufferSize.
|
| +const int kBufferSize = 256;
|
| +const int kSmallBufferSize = 1;
|
| +
|
| +const int kShortReplacementOffset = 5;
|
| +const char kShortReplacementKey[] = "a";
|
| +const char kShortReplacementToken[] = "$i18n{a}";
|
| +const char kShortReplacementValue[] = "short";
|
| +
|
| +const int kLongReplacementOffset = 33;
|
| +const char kLongReplacementKey[] = "aLongerReplacementName";
|
| +const char kLongReplacementToken[] = "$i18n{aLongerReplacementName}";
|
| +const char kLongReplacementValue[] = "second replacement";
|
| +
|
| +const int kSourceSize =
|
| + 50 + arraysize(kShortReplacementToken) + arraysize(kLongReplacementToken);
|
| +const int kResultSize =
|
| + 50 + arraysize(kShortReplacementValue) + arraysize(kLongReplacementValue);
|
| +
|
| +struct I18nTestParam {
|
| + I18nTestParam(int buf_size, net::MockSourceStream::Mode read_mode)
|
| + : buffer_size(buf_size), mode(read_mode) {}
|
| +
|
| + const int buffer_size;
|
| + const net::MockSourceStream::Mode mode;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class I18nSourceStreamTest : public ::testing::TestWithParam<I18nTestParam> {
|
| + protected:
|
| + I18nSourceStreamTest() : output_buffer_size_(GetParam().buffer_size) {}
|
| +
|
| + // Helpful function to initialize the test fixture.
|
| + void Init() {
|
| + source_data_len_ = kBufferSize;
|
| + for (size_t i = 0; i < source_data_len_; i++)
|
| + source_data_[i] = i % 256;
|
| +
|
| + // Inserts must be done last to first as they appear in the buffer.
|
| + InsertText(source_data_, source_data_len_, kLongReplacementOffset,
|
| + kLongReplacementToken);
|
| + InsertText(source_data_, source_data_len_, kShortReplacementOffset,
|
| + kShortReplacementToken);
|
| +
|
| + result_data_len_ = kBufferSize;
|
| + for (size_t i = 0; i < result_data_len_; i++)
|
| + result_data_[i] = i % 256;
|
| +
|
| + // Inserts must be done last to first as they appear in the buffer.
|
| + InsertText(result_data_, result_data_len_, kLongReplacementOffset,
|
| + kLongReplacementValue);
|
| + InsertText(result_data_, result_data_len_, kShortReplacementOffset,
|
| + kShortReplacementValue);
|
| +
|
| + output_buffer_ = new net::IOBuffer(output_buffer_size_);
|
| + std::unique_ptr<net::MockSourceStream> source(new net::MockSourceStream());
|
| + source_ = source.get();
|
| +
|
| + replacements_[kShortReplacementKey] = kShortReplacementValue;
|
| + replacements_[kLongReplacementKey] = kLongReplacementValue;
|
| + stream_ = I18nSourceStream::Create(
|
| + std::move(source), net::SourceStream::TYPE_NONE, &replacements_);
|
| + }
|
| +
|
| + // If MockSourceStream::Mode is ASYNC, completes 1 read from |mock_stream| and
|
| + // wait for |callback| to complete. If Mode is not ASYNC, does nothing and
|
| + // returns |previous_result|.
|
| + int CompleteReadIfAsync(int previous_result,
|
| + net::TestCompletionCallback* callback,
|
| + net::MockSourceStream* mock_stream) {
|
| + if (GetParam().mode == net::MockSourceStream::ASYNC) {
|
| + EXPECT_EQ(net::ERR_IO_PENDING, previous_result);
|
| + mock_stream->CompleteNextRead();
|
| + return callback->WaitForResult();
|
| + }
|
| + return previous_result;
|
| + }
|
| +
|
| + void InsertText(char* buffer,
|
| + size_t buffer_length,
|
| + size_t offset,
|
| + const char* text) {
|
| + // Intended to be dead simple so that it can be confirmed
|
| + // as correct by hand.
|
| + size_t text_length = strlen(text);
|
| + memmove(buffer + offset + text_length, buffer + offset,
|
| + buffer_length - offset - text_length);
|
| + memcpy(buffer + offset, text, text_length);
|
| + }
|
| +
|
| + char* source_data() { return source_data_; }
|
| + size_t source_data_len() { return source_data_len_; }
|
| +
|
| + char* result_data() { return result_data_; }
|
| + size_t result_data_len() { return result_data_len_; }
|
| +
|
| + net::IOBuffer* output_buffer() { return output_buffer_.get(); }
|
| + char* output_data() { return output_buffer_->data(); }
|
| + size_t output_buffer_size() { return output_buffer_size_; }
|
| +
|
| + net::MockSourceStream* source() { return source_; }
|
| + I18nSourceStream* stream() { return stream_.get(); }
|
| +
|
| + // Reads from |stream_| until an error occurs or the EOF is reached.
|
| + // When an error occurs, returns the net error code. When an EOF is reached,
|
| + // returns the number of bytes read and appends data read to |output|.
|
| + int ReadStream(std::string* output) {
|
| + int bytes_read = 0;
|
| + while (true) {
|
| + net::TestCompletionCallback callback;
|
| + int rv = stream_->Read(output_buffer(), output_buffer_size(),
|
| + callback.callback());
|
| + if (rv == net::ERR_IO_PENDING)
|
| + rv = CompleteReadIfAsync(rv, &callback, source());
|
| + if (rv == net::OK)
|
| + break;
|
| + if (rv < net::OK)
|
| + return rv;
|
| + EXPECT_GT(rv, net::OK);
|
| + bytes_read += rv;
|
| + output->append(output_data(), rv);
|
| + }
|
| + return bytes_read;
|
| + }
|
| +
|
| + private:
|
| + char source_data_[kBufferSize];
|
| + size_t source_data_len_;
|
| +
|
| + char result_data_[kBufferSize];
|
| + size_t result_data_len_;
|
| +
|
| + scoped_refptr<net::IOBuffer> output_buffer_;
|
| + const int output_buffer_size_;
|
| +
|
| + net::MockSourceStream* source_;
|
| + std::unique_ptr<I18nSourceStream> stream_;
|
| +
|
| + ui::TemplateReplacements replacements_;
|
| +};
|
| +
|
| +INSTANTIATE_TEST_CASE_P(
|
| + I18nSourceStreamTests,
|
| + I18nSourceStreamTest,
|
| + ::testing::Values(I18nTestParam(kBufferSize, net::MockSourceStream::SYNC),
|
| + I18nTestParam(kSmallBufferSize,
|
| + net::MockSourceStream::SYNC)));
|
| +
|
| +TEST_P(I18nSourceStreamTest, EmptyStream) {
|
| + Init();
|
| + source()->AddReadResult("", 0, net::OK, GetParam().mode);
|
| + std::string actual_output;
|
| + int result = ReadStream(&actual_output);
|
| + EXPECT_EQ(net::OK, result);
|
| + EXPECT_EQ("i18n", stream()->Description());
|
| +}
|
| +
|
| +TEST_P(I18nSourceStreamTest, NoTranslations) {
|
| + Init();
|
| + const char kText[] = "This text has no i18n replacements.";
|
| + size_t kTextLength = strlen(kText);
|
| + source()->AddReadResult(kText, kTextLength, net::OK, GetParam().mode);
|
| + source()->AddReadResult(kText + kTextLength, 0, net::OK, GetParam().mode);
|
| + std::string actual_output;
|
| + int rv = ReadStream(&actual_output);
|
| + EXPECT_EQ(static_cast<int>(kTextLength), rv);
|
| + EXPECT_EQ(std::string(kText, kTextLength), actual_output);
|
| + EXPECT_EQ("i18n", stream()->Description());
|
| +}
|
| +
|
| +TEST_P(I18nSourceStreamTest, I18nOneRead) {
|
| + Init();
|
| + source()->AddReadResult(source_data(), kSourceSize, net::OK, GetParam().mode);
|
| + source()->AddReadResult(source_data() + kSourceSize, 0, net::OK,
|
| + GetParam().mode);
|
| + std::string actual_output;
|
| + int rv = ReadStream(&actual_output);
|
| + EXPECT_EQ(static_cast<int>(kResultSize), rv);
|
| + EXPECT_EQ(std::string(result_data(), kResultSize), actual_output);
|
| + EXPECT_EQ("i18n", stream()->Description());
|
| +}
|
| +
|
| +TEST_P(I18nSourceStreamTest, I18nInMultipleReads) {
|
| + Init();
|
| + size_t chunk_size = 5;
|
| + size_t written = 0;
|
| + while (written + chunk_size < kSourceSize) {
|
| + source()->AddReadResult(source_data() + written, chunk_size, net::OK,
|
| + GetParam().mode);
|
| + written += chunk_size;
|
| + }
|
| + source()->AddReadResult(source_data() + written, kSourceSize - written,
|
| + net::OK, GetParam().mode);
|
| + source()->AddReadResult(source_data() + kSourceSize, 0, net::OK,
|
| + GetParam().mode);
|
| + std::string actual_output;
|
| + int rv = ReadStream(&actual_output);
|
| + EXPECT_EQ(static_cast<int>(kResultSize), rv);
|
| + EXPECT_EQ(std::string(result_data(), kResultSize), actual_output);
|
| + EXPECT_EQ("i18n", stream()->Description());
|
| +}
|
| +
|
| +} // namespace content
|
|
|