Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1334)

Unified Diff: mojo/public/cpp/bindings/tests/map_unittest.cc

Issue 611633002: mojom: Add associative arrays to the mojom language. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved test classes to their own shared file. Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mojo/public/cpp/bindings/tests/map_unittest.cc
diff --git a/mojo/public/cpp/bindings/tests/map_unittest.cc b/mojo/public/cpp/bindings/tests/map_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..159afb9578e0381da85f6ff5a811ca77398de8c9
--- /dev/null
+++ b/mojo/public/cpp/bindings/tests/map_unittest.cc
@@ -0,0 +1,338 @@
+// 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/bindings_internal.h"
+#include "mojo/public/cpp/bindings/lib/fixed_buffer.h"
+#include "mojo/public/cpp/bindings/map.h"
+#include "mojo/public/cpp/bindings/string.h"
+#include "mojo/public/cpp/bindings/struct_ptr.h"
+#include "mojo/public/cpp/bindings/tests/container_test_util.h"
+#include "mojo/public/cpp/environment/environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace test {
+
+namespace {
+
+struct StringIntData {
+ const char* string_data;
+ int int_data;
+} kStringIntData[] = {
+ {"one", 1},
+ {"two", 2},
+ {"three", 3},
+ {"four", 4},
+};
+
+const size_t kStringIntDataSize = 4;
+
+class MapTest : public testing::Test {
+ public:
+ virtual ~MapTest() {}
+
+ private:
+ Environment env_;
+};
+
+// Tests that basic Map operations work.
+TEST_F(MapTest, InsertWorks) {
+ Map<String, int> map;
+ for (size_t i = 0; i < kStringIntDataSize; ++i)
+ map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data);
+
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ EXPECT_EQ(kStringIntData[i].int_data,
+ map.at(kStringIntData[i].string_data));
+ }
+}
+
+TEST_F(MapTest, ConstructedFromArray) {
+ Array<String> keys(kStringIntDataSize);
+ Array<int> values(kStringIntDataSize);
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ keys[i] = kStringIntData[i].string_data;
+ values[i] = kStringIntData[i].int_data;
+ }
+
+ Map<String, int> map(keys.Pass(), values.Pass());
+
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ EXPECT_EQ(kStringIntData[i].int_data,
+ map.at(mojo::String(kStringIntData[i].string_data)));
+ }
+}
+
+TEST_F(MapTest, DecomposeMapTo) {
+ Array<String> keys(kStringIntDataSize);
+ Array<int> values(kStringIntDataSize);
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ keys[i] = kStringIntData[i].string_data;
+ values[i] = kStringIntData[i].int_data;
+ }
+
+ Map<String, int> map(keys.Pass(), values.Pass());
+ EXPECT_EQ(kStringIntDataSize, map.size());
+
+ Array<String> keys2;
+ Array<int> values2;
+ map.DecomposeMapTo(&keys2, &values2);
+ EXPECT_EQ(0u, map.size());
+
+ EXPECT_EQ(kStringIntDataSize, keys2.size());
+ EXPECT_EQ(kStringIntDataSize, values2.size());
+
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ // We are not guaranteed that the copies have the same sorting as the
+ // originals.
+ String key = kStringIntData[i].string_data;
+ int value = kStringIntData[i].int_data;
+
+ bool found = false;
+ for (size_t j = 0; j < keys2.size(); ++j) {
+ if (keys2[j] == key) {
+ EXPECT_EQ(value, values2[j]);
+ found = true;
+ break;
+ }
+ }
+
+ EXPECT_TRUE(found);
+ }
+}
+
+TEST_F(MapTest, Insert_Copyable) {
+ ASSERT_EQ(0u, CopyableType::num_instances());
+ mojo::Map<mojo::String, CopyableType> map;
+ std::vector<CopyableType*> value_ptrs;
+
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ const char* key = kStringIntData[i].string_data;
+ CopyableType value;
+ value_ptrs.push_back(value.ptr());
+ map.insert(key, value);
+ ASSERT_EQ(i + 1, map.size());
+ ASSERT_EQ(i + 1, value_ptrs.size());
+ EXPECT_EQ(map.size() + 1, CopyableType::num_instances());
+ EXPECT_TRUE(map.at(key).copied());
+ EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
+ map.at(key).ResetCopied();
+ EXPECT_TRUE(map);
+ }
+
+ // std::map doesn't have a capacity() method like std::vector so this test is
+ // a lot more boring.
+
+ map.reset();
+ EXPECT_EQ(0u, CopyableType::num_instances());
+}
+
+TEST_F(MapTest, Insert_MoveOnly) {
+ ASSERT_EQ(0u, MoveOnlyType::num_instances());
+ mojo::Map<mojo::String, MoveOnlyType> map;
+ std::vector<MoveOnlyType*> value_ptrs;
+
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ const char* key = kStringIntData[i].string_data;
+ MoveOnlyType value;
+ value_ptrs.push_back(value.ptr());
+ map.insert(key, value.Pass());
+ ASSERT_EQ(i + 1, map.size());
+ ASSERT_EQ(i + 1, value_ptrs.size());
+ EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances());
+ EXPECT_TRUE(map.at(key).moved());
+ EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
+ map.at(key).ResetMoved();
+ EXPECT_TRUE(map);
+ }
+
+ // std::map doesn't have a capacity() method like std::vector so this test is
+ // a lot more boring.
+
+ map.reset();
+ EXPECT_EQ(0u, CopyableType::num_instances());
+}
+
+TEST_F(MapTest, STLToMojo) {
+ std::map<std::string, int> stl_data;
+ for (size_t i = 0; i < kStringIntDataSize; ++i)
+ stl_data[kStringIntData[i].string_data] = kStringIntData[i].int_data;
+
+ Map<String, int32_t> mojo_data = Map<String, int32_t>::From(stl_data);
+
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ EXPECT_EQ(kStringIntData[i].int_data,
+ mojo_data.at(kStringIntData[i].string_data));
+ }
+}
+
+TEST_F(MapTest, MojoToSTL) {
+ Map<String, int32_t> mojo_map;
+ for (size_t i = 0; i < kStringIntDataSize; ++i)
+ mojo_map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data);
+
+ std::map<std::string, int> stl_map =
+ mojo_map.To<std::map<std::string, int>>();
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ auto it = stl_map.find(kStringIntData[i].string_data);
+ ASSERT_TRUE(it != stl_map.end());
+ EXPECT_EQ(kStringIntData[i].int_data, it->second);
+ }
+}
+
+TEST_F(MapTest, MapArrayClone) {
+ Map<String, Array<String>> m;
+ for (size_t i = 0; i < kStringIntDataSize; ++i) {
+ Array<String> s;
+ s.push_back(kStringIntData[i].string_data);
+ m.insert(kStringIntData[i].string_data, s.Pass());
+ }
+
+ Map<String, Array<String>> m2 = m.Clone();
+
+ for (auto it = m2.begin(); it != m2.end(); ++it) {
+ ASSERT_EQ(1u, it.GetValue().size());
+ EXPECT_EQ(it.GetKey(), it.GetValue().at(0));
+ }
+}
+
+// Data class for an end-to-end test of serialization. Because making a more
+// limited test case tickles a clang compiler bug, we copy a minimal version of
+// what our current cpp bindings do.
+namespace internal {
+
+class ArrayOfMap_Data {
+ public:
+ static ArrayOfMap_Data* New(mojo::internal::Buffer* buf) {
+ return new (buf->Allocate(sizeof(ArrayOfMap_Data))) ArrayOfMap_Data();
+ }
+
+ mojo::internal::StructHeader header_;
+
+ mojo::internal::ArrayPointer<mojo::internal::Map_Data<int32_t, int8_t>*>
+ first;
+ mojo::internal::ArrayPointer<
+ mojo::internal::Map_Data<mojo::internal::String_Data*,
+ mojo::internal::Array_Data<bool>*>*> second;
+
+ private:
+ ArrayOfMap_Data() {
+ header_.num_bytes = sizeof(*this);
+ header_.num_fields = 2;
+ }
+ ~ArrayOfMap_Data(); // NOT IMPLEMENTED
+};
+static_assert(sizeof(ArrayOfMap_Data) == 24, "Bad sizeof(ArrayOfMap_Data)");
+
+} // namespace internal
+
+class ArrayOfMapImpl;
+typedef mojo::StructPtr<ArrayOfMapImpl> ArrayOfMapImplPtr;
+
+class ArrayOfMapImpl {
+ public:
+ typedef internal::ArrayOfMap_Data Data_;
+ static ArrayOfMapImplPtr New() {
+ ArrayOfMapImplPtr rv;
+ mojo::internal::StructHelper<ArrayOfMapImpl>::Initialize(&rv);
+ return rv.Pass();
+ }
+
+ mojo::Array<mojo::Map<int32_t, int8_t>> first;
+ mojo::Array<mojo::Map<mojo::String, mojo::Array<bool>>> second;
+};
+
+size_t GetSerializedSize_(const ArrayOfMapImplPtr& input) {
+ if (!input)
+ return 0;
+ size_t size = sizeof(internal::ArrayOfMap_Data);
+ size += GetSerializedSize_(input->first);
+ size += GetSerializedSize_(input->second);
+ return size;
+}
+
+void Serialize_(ArrayOfMapImplPtr input,
+ mojo::internal::Buffer* buf,
+ internal::ArrayOfMap_Data** output) {
+ if (input) {
+ internal::ArrayOfMap_Data* result = internal::ArrayOfMap_Data::New(buf);
+ mojo::SerializeArray_<mojo::internal::ArrayValidateParams<
+ 0,
+ false,
+ mojo::internal::
+ ArrayValidateParams<0, false, mojo::internal::NoValidateParams>>>(
+ mojo::internal::Forward(input->first), buf, &result->first.ptr);
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ !result->first.ptr,
+ mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
+ "null first field in ArrayOfMapImpl struct");
+ mojo::SerializeArray_<mojo::internal::ArrayValidateParams<
+ 0,
+ false,
+ mojo::internal::ArrayValidateParams<
+ 0,
+ false,
+ mojo::internal::ArrayValidateParams<
+ 0,
+ false,
+ mojo::internal::NoValidateParams>>>>(
+ mojo::internal::Forward(input->second), buf, &result->second.ptr);
+ MOJO_INTERNAL_DLOG_SERIALIZATION_WARNING(
+ !result->second.ptr,
+ mojo::internal::VALIDATION_ERROR_UNEXPECTED_NULL_POINTER,
+ "null second field in ArrayOfMapImpl struct");
+ *output = result;
+ } else {
+ *output = nullptr;
+ }
+}
+
+void Deserialize_(internal::ArrayOfMap_Data* input, ArrayOfMapImplPtr* output) {
+ if (input) {
+ ArrayOfMapImplPtr result(ArrayOfMapImpl::New());
+ Deserialize_(input->first.ptr, &result->first);
+ Deserialize_(input->second.ptr, &result->second);
+ *output = result.Pass();
+ } else {
+ output->reset();
+ }
+}
+
+TEST_F(MapTest, ArrayOfMap) {
+ Array<Map<int32_t, int8_t>> first_array(1);
+ first_array[0].insert(1, 42);
+
+ Array<Map<String, Array<bool>>> second_array(1);
+ Array<bool> map_value(2);
+ map_value[0] = false;
+ map_value[1] = true;
+ second_array[0].insert("hello world", map_value.Pass());
+
+ ArrayOfMapImplPtr to_pass(ArrayOfMapImpl::New());
+ to_pass->first = first_array.Pass();
+ to_pass->second = second_array.Pass();
+
+ size_t size = GetSerializedSize_(to_pass);
+ mojo::internal::FixedBuffer buf(size);
+ internal::ArrayOfMap_Data* data;
+ Serialize_(mojo::internal::Forward(to_pass), &buf, &data);
+
+ ArrayOfMapImplPtr to_receive(ArrayOfMapImpl::New());
+ Deserialize_(data, &to_receive);
+
+ ASSERT_EQ(1u, to_receive->first.size());
+ ASSERT_EQ(1u, to_receive->first[0].size());
+ ASSERT_EQ(42, to_receive->first[0].at(1));
+
+ ASSERT_EQ(1u, to_receive->second.size());
+ ASSERT_EQ(1u, to_receive->second[0].size());
+ ASSERT_FALSE(to_receive->second[0].at("hello world")[0]);
+ ASSERT_TRUE(to_receive->second[0].at("hello world")[1]);
+}
+
+} // namespace
+} // namespace test
+} // namespace mojo
« no previous file with comments | « mojo/public/cpp/bindings/tests/container_test_util.cc ('k') | mojo/public/cpp/bindings/tests/string_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698