blob: 4b59a7d5888a7d906377aa8345ad4ca057d3fd88 [file] [log] [blame]
// Copyright 2021 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/encoding/text_encoder.h"
#include <string>
#include <utility>
#include <vector>
#include "cobalt/dom/testing/stub_window.h"
#include "cobalt/script/array_buffer_view.h"
#include "cobalt/script/environment_settings.h"
#include "cobalt/script/typed_arrays.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cobalt {
namespace encoding {
namespace {
//////////////////////////////////////////////////////////////////////////
// TextEncoderTest
//////////////////////////////////////////////////////////////////////////
class TextEncoderTest : public ::testing::Test {
protected:
TextEncoderTest();
~TextEncoderTest();
cobalt::dom::testing::StubWindow stub_window_;
scoped_refptr<TextEncoder> text_encoder_;
};
TextEncoderTest::TextEncoderTest() : text_encoder_(new TextEncoder()) {}
TextEncoderTest::~TextEncoderTest() {}
//////////////////////////////////////////////////////////////////////////
// Test cases
//////////////////////////////////////////////////////////////////////////
TEST_F(TextEncoderTest, Constructor) {
EXPECT_EQ("utf-8", text_encoder_->encoding());
}
TEST_F(TextEncoderTest, Encode) {
std::vector<std::pair<std::string, std::vector<uint8>>> tests = {
{"Hello world!",
{72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33}},
{"Hej! Привет! 你好!",
{72, 101, 106, 33, 32, 208, 159, 209, 128, 208, 184, 208, 178, 208,
181, 209, 130, 33, 32, 228, 189, 160, 229, 165, 189, 239, 188, 129}},
{"Да!", {208, 148, 208, 176, 041}},
};
std::string input;
std::vector<uint8> want;
for (const auto &test : tests) {
std::tie(input, want) = test;
script::Handle<script::Uint8Array> got =
text_encoder_->Encode(stub_window_.environment_settings(), input);
auto *array_got = static_cast<uint8 *>(got->RawData());
// Compare the result against the expectations.
ASSERT_EQ(got->Length(), want.size());
for (uint32 i = 0; i < got->Length(); ++i) {
EXPECT_EQ(array_got[i], want[i]);
}
}
}
TEST_F(TextEncoderTest, EncodeInto) {
struct Result {
std::vector<uint8> bytes;
uint64_t read, written;
};
// Scenario I: Buffer with the right capacity.
std::vector<std::pair<std::string, Result>> tests = {
{"Hello world!",
{{72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33}, 12, 12}},
{"Hej! Привет! 你好!",
{{72, 101, 106, 33, 32, 208, 159, 209, 128, 208, 184, 208, 178, 208,
181, 209, 130, 33, 32, 228, 189, 160, 229, 165, 189, 239, 188, 129},
16,
28}},
{"Да!", {{208, 148, 208, 176, 041}, 3, 5}},
};
Result want;
std::string input;
for (const auto &test : tests) {
std::tie(input, want) = test;
script::Handle<script::Uint8Array> destination = script::Uint8Array::New(
stub_window_.global_environment(), want.bytes.size());
TextEncoderEncodeIntoResult got = text_encoder_->EncodeInto(
stub_window_.environment_settings(), input, destination);
// Verify the read / written values.
ASSERT_TRUE(got.has_read());
ASSERT_TRUE(got.has_written());
EXPECT_EQ(want.read, got.read());
EXPECT_EQ(want.written, got.written());
// Verify the actual data.
auto *array_got = static_cast<uint8 *>(destination->RawData());
ASSERT_LE(got.written(), want.bytes.size());
for (uint32 i = 0; i < got.written(); ++i) {
EXPECT_EQ(array_got[i], want.bytes[i]);
}
}
}
TEST_F(TextEncoderTest, EncodeIntoInsufficientCapacity) {
struct Result {
std::vector<uint8> bytes;
uint64_t read, written;
};
// Scenario II: Intentionally remove last byte from the right capacity.
std::vector<std::pair<std::string, Result>> tests = {
{"Hello world!",
{{72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100}, 11, 11}},
{"Hej! Привет! 你好!",
{{72, 101, 106, 33, 32, 208, 159, 209, 128, 208, 184, 208, 178, 208,
181, 209, 130, 33, 32, 228, 189, 160, 229, 165, 189, 0, 0},
15,
25}},
{"Да!", {{208, 148, 208, 176}, 2, 4}},
};
Result want;
std::string input;
for (const auto &test : tests) {
std::tie(input, want) = test;
script::Handle<script::Uint8Array> destination = script::Uint8Array::New(
stub_window_.global_environment(), want.bytes.size());
TextEncoderEncodeIntoResult got = text_encoder_->EncodeInto(
stub_window_.environment_settings(), input, destination);
// Verify the read / written values.
ASSERT_TRUE(got.has_read());
ASSERT_TRUE(got.has_written());
EXPECT_EQ(want.read, got.read());
EXPECT_EQ(want.written, got.written());
// Verify the actual data.
auto *array_got = static_cast<uint8 *>(destination->RawData());
ASSERT_LE(got.written(), want.bytes.size());
for (uint32 i = 0; i < want.bytes.size(); ++i) {
EXPECT_EQ(array_got[i], want.bytes[i]);
}
}
}
TEST_F(TextEncoderTest, EncodeIntoExtraCapacity) {
struct Result {
std::vector<uint8> bytes;
uint64_t read, written;
};
// Scenario III: Buffer with more capacity.
std::vector<std::pair<std::string, Result>> tests = {
{"Hello world!",
{{72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 0, 0},
12,
12}},
{"Hej! Привет! 你好!",
{{72, 101, 106, 33, 32, 208, 159, 209, 128, 208,
184, 208, 178, 208, 181, 209, 130, 33, 32, 228,
189, 160, 229, 165, 189, 239, 188, 129, 0, 0},
16,
28}},
{"Да!", {{208, 148, 208, 176, 041, 0, 0}, 3, 5}},
};
Result want;
std::string input;
for (const auto &test : tests) {
std::tie(input, want) = test;
script::Handle<script::Uint8Array> destination = script::Uint8Array::New(
stub_window_.global_environment(), want.bytes.size());
TextEncoderEncodeIntoResult got = text_encoder_->EncodeInto(
stub_window_.environment_settings(), input, destination);
// Verify the read / written values.
ASSERT_TRUE(got.has_read());
ASSERT_TRUE(got.has_written());
EXPECT_EQ(want.read, got.read());
EXPECT_EQ(want.written, got.written());
// Verify the actual data.
auto *array_got = static_cast<uint8 *>(destination->RawData());
ASSERT_LE(got.written(), want.bytes.size());
for (uint32 i = 0; i < want.bytes.size(); ++i) {
EXPECT_EQ(array_got[i], want.bytes[i]);
}
}
}
} // namespace
} // namespace encoding
} // namespace cobalt