blob: b0c1f6b65347228c9ef5a9e9974ad56b1da6d7c6 [file] [log] [blame]
// Copyright 2014 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 "mojo/public/cpp/bindings/array.h"
#include "mojo/public/cpp/bindings/lib/array_serialization.h"
#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
#include "mojo/public/cpp/environment/environment.h"
#include "mojo/public/interfaces/bindings/tests/sample_service.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace mojo {
namespace test {
namespace {
// Tests that basic Array operations work.
TEST(ArrayTest, Basic) {
Array<char> array(8);
for (size_t i = 0; i < array.size(); ++i) {
char val = static_cast<char>(i*2);
array[i] = val;
EXPECT_EQ(val, array.at(i));
}
}
// Tests that basic Array<bool> operations work.
TEST(ArrayTest, Bool) {
Array<bool> array(64);
for (size_t i = 0; i < array.size(); ++i) {
bool val = i % 3 == 0;
array[i] = val;
EXPECT_EQ(val, array.at(i));
}
}
// Tests that Array<ScopedMessagePipeHandle> supports transferring handles.
TEST(ArrayTest, Handle) {
ScopedMessagePipeHandle pipe0, pipe1;
CreateMessagePipe(&pipe0, &pipe1);
Array<ScopedMessagePipeHandle> handles(2);
handles[0] = pipe0.Pass();
handles[1].reset(pipe1.release());
EXPECT_FALSE(pipe0.is_valid());
EXPECT_FALSE(pipe1.is_valid());
Array<ScopedMessagePipeHandle> handles2 = handles.Pass();
EXPECT_TRUE(handles2[0].is_valid());
EXPECT_TRUE(handles2[1].is_valid());
pipe0 = handles2[0].Pass();
EXPECT_TRUE(pipe0.is_valid());
EXPECT_FALSE(handles2[0].is_valid());
}
// Tests that Array<ScopedMessagePipeHandle> supports closing handles.
TEST(ArrayTest, HandlesAreClosed) {
ScopedMessagePipeHandle pipe0, pipe1;
CreateMessagePipe(&pipe0, &pipe1);
MojoHandle pipe0_value = pipe0.get().value();
MojoHandle pipe1_value = pipe1.get().value();
{
Array<ScopedMessagePipeHandle> handles(2);
handles[0] = pipe0.Pass();
handles[1].reset(pipe1.release());
}
// We expect the pipes to have been closed.
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe0_value));
EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(pipe1_value));
}
TEST(ArrayTest, Serialization_ArrayOfPOD) {
Array<int32_t> array(4);
for (size_t i = 0; i < array.size(); ++i)
array[i] = static_cast<int32_t>(i);
size_t size = GetSerializedSize_(array);
EXPECT_EQ(8U + 4*4U, size);
internal::FixedBuffer buf(size);
internal::Array_Data<int32_t>* data;
Serialize_(array.Pass(), &buf, &data);
Array<int32_t> array2;
Deserialize_(data, &array2);
EXPECT_EQ(4U, array2.size());
for (size_t i = 0; i < array2.size(); ++i)
EXPECT_EQ(static_cast<int32_t>(i), array2[i]);
}
TEST(ArrayTest, Serialization_ArrayOfArrayOfPOD) {
Array<Array<int32_t> > array(2);
for (size_t j = 0; j < array.size(); ++j) {
Array<int32_t> inner(4);
for (size_t i = 0; i < inner.size(); ++i)
inner[i] = static_cast<int32_t>(i + (j * 10));
array[j] = inner.Pass();
}
size_t size = GetSerializedSize_(array);
EXPECT_EQ(8U + 2*8U + 2*(8U + 4*4U), size);
internal::FixedBuffer buf(size);
internal::Array_Data<internal::Array_Data<int32_t>*>* data;
Serialize_(array.Pass(), &buf, &data);
Array<Array<int32_t> > array2;
Deserialize_(data, &array2);
EXPECT_EQ(2U, array2.size());
for (size_t j = 0; j < array2.size(); ++j) {
const Array<int32_t>& inner = array2[j];
EXPECT_EQ(4U, inner.size());
for (size_t i = 0; i < inner.size(); ++i)
EXPECT_EQ(static_cast<int32_t>(i + (j * 10)), inner[i]);
}
}
TEST(ArrayTest, Serialization_ArrayOfBool) {
Array<bool> array(10);
for (size_t i = 0; i < array.size(); ++i)
array[i] = i % 2 ? true : false;
size_t size = GetSerializedSize_(array);
EXPECT_EQ(8U + 8U, size);
internal::FixedBuffer buf(size);
internal::Array_Data<bool>* data;
Serialize_(array.Pass(), &buf, &data);
Array<bool> array2;
Deserialize_(data, &array2);
EXPECT_EQ(10U, array2.size());
for (size_t i = 0; i < array2.size(); ++i)
EXPECT_EQ(i % 2 ? true : false, array2[i]);
}
TEST(ArrayTest, Serialization_ArrayOfString) {
Array<String> array(10);
for (size_t i = 0; i < array.size(); ++i) {
char c = 'A' + 1;
array[i] = String(&c, 1);
}
size_t size = GetSerializedSize_(array);
EXPECT_EQ(8U + // array header
10*8U + // array payload (10 pointers)
10*(8U + // string header
8U), // string length of 1 padded to 8
size);
internal::FixedBuffer buf(size);
internal::Array_Data<internal::String_Data*>* data;
Serialize_(array.Pass(), &buf, &data);
Array<String> array2;
Deserialize_(data, &array2);
EXPECT_EQ(10U, array2.size());
for (size_t i = 0; i < array2.size(); ++i) {
char c = 'A' + 1;
EXPECT_EQ(String(&c, 1), array2[i]);
}
}
} // namespace
} // namespace test
} // namespace mojo