Index: mojo/public/cpp/bindings/tests/map_common_test.h |
diff --git a/mojo/public/cpp/bindings/tests/map_common_test.h b/mojo/public/cpp/bindings/tests/map_common_test.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..6128bf4e9a0943388f9bd0c1e211072b98fefd86 |
--- /dev/null |
+++ b/mojo/public/cpp/bindings/tests/map_common_test.h |
@@ -0,0 +1,230 @@ |
+// 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 "mojo/public/cpp/bindings/array.h" |
+#include "mojo/public/cpp/bindings/lib/fixed_buffer.h" |
+#include "mojo/public/cpp/bindings/lib/serialization.h" |
+#include "mojo/public/cpp/bindings/lib/validate_params.h" |
+#include "mojo/public/cpp/bindings/map.h" |
+#include "mojo/public/cpp/bindings/string.h" |
+#include "mojo/public/cpp/bindings/tests/container_test_util.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace WTF { |
+class String; |
+} |
+ |
+namespace mojo { |
+ |
+template <typename T> |
+class WTFArray; |
+ |
+template <typename K, typename V> |
+class WTFMap; |
+ |
+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; |
+ |
+} // namespace |
+ |
+template <template <typename...> class MapType> |
+struct TypeTraits; |
+ |
+template <> |
+struct TypeTraits<Map> { |
+ using StringType = mojo::String; |
+ template <typename T> |
+ using ArrayType = Array<T>; |
+}; |
+ |
+template <> |
+struct TypeTraits<WTFMap> { |
+ using StringType = WTF::String; |
+ template <typename T> |
+ using ArrayType = WTFArray<T>; |
+}; |
+ |
+// Common tests for both mojo::Map and mojo::WTFMap. |
+template <template <typename...> class MapType> |
+class MapCommonTest { |
+ public: |
+ using StringType = typename TypeTraits<MapType>::StringType; |
+ template <typename T> |
+ using ArrayType = typename TypeTraits<MapType>::template ArrayType<T>; |
+ |
+ // Tests null and empty maps. |
+ static void NullAndEmpty() { |
+ MapType<char, char> map0; |
+ EXPECT_TRUE(map0.empty()); |
+ EXPECT_FALSE(map0.is_null()); |
+ map0 = nullptr; |
+ EXPECT_TRUE(map0.is_null()); |
+ EXPECT_FALSE(map0.empty()); |
+ |
+ MapType<char, char> map1(nullptr); |
+ EXPECT_TRUE(map1.is_null()); |
+ EXPECT_FALSE(map1.empty()); |
+ map1.SetToEmpty(); |
+ EXPECT_TRUE(map1.empty()); |
+ EXPECT_FALSE(map1.is_null()); |
+ } |
+ |
+ // Tests that basic Map operations work. |
+ static void InsertWorks() { |
+ MapType<StringType, 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)); |
+ } |
+ } |
+ |
+ static void TestIndexOperator() { |
+ MapType<StringType, int> map; |
+ for (size_t i = 0; i < kStringIntDataSize; ++i) |
+ map[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)); |
+ } |
+ } |
+ |
+ static void TestIndexOperatorAsRValue() { |
+ MapType<StringType, 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[kStringIntData[i].string_data]); |
+ } |
+ } |
+ |
+ static void TestIndexOperatorMoveOnly() { |
+ ASSERT_EQ(0u, MoveOnlyType::num_instances()); |
+ MapType<StringType, ArrayType<int32_t>> map; |
+ |
+ for (size_t i = 0; i < kStringIntDataSize; ++i) { |
+ const char* key = kStringIntData[i].string_data; |
+ ArrayType<int32_t> array(1); |
+ array[0] = kStringIntData[i].int_data; |
+ map[key] = std::move(array); |
+ EXPECT_TRUE(map); |
+ } |
+ |
+ // We now read back that data, to test the behavior of operator[]. |
+ for (size_t i = 0; i < kStringIntDataSize; ++i) { |
+ auto& value = map[kStringIntData[i].string_data]; |
+ ASSERT_EQ(1u, value.size()); |
+ EXPECT_EQ(kStringIntData[i].int_data, value[0]); |
+ } |
+ } |
+ |
+ static void MapArrayClone() { |
+ MapType<StringType, ArrayType<StringType>> m; |
+ for (size_t i = 0; i < kStringIntDataSize; ++i) { |
+ ArrayType<StringType> s(1); |
+ s[0] = StringType(kStringIntData[i].string_data); |
+ m.insert(kStringIntData[i].string_data, std::move(s)); |
+ } |
+ |
+ MapType<StringType, ArrayType<StringType>> m2 = m.Clone(); |
+ |
+ for (size_t i = 0; i < kStringIntDataSize; ++i) { |
+ ASSERT_NE(m2.end(), m2.find(kStringIntData[i].string_data)); |
+ ASSERT_EQ(1u, m2[kStringIntData[i].string_data].size()); |
+ EXPECT_EQ(StringType(kStringIntData[i].string_data), |
+ m2[kStringIntData[i].string_data][0]); |
+ } |
+ } |
+ |
+ static void ArrayOfMap() { |
+ { |
+ using MojomType = Array<Map<int32_t, int8_t>>; |
+ using UserType = ArrayType<MapType<int32_t, int8_t>>; |
+ |
+ UserType array(1); |
+ array[0].insert(1, 42); |
+ |
+ mojo::internal::SerializationContext context; |
+ size_t size = |
+ mojo::internal::PrepareToSerialize<MojomType>(array, &context); |
+ mojo::internal::FixedBufferForTesting buf(size); |
+ typename MojomType::Data_* data; |
+ mojo::internal::ContainerValidateParams validate_params( |
+ 0, false, |
+ new mojo::internal::ContainerValidateParams( |
+ new mojo::internal::ContainerValidateParams(0, false, nullptr), |
+ new mojo::internal::ContainerValidateParams(0, false, nullptr))); |
+ |
+ mojo::internal::Serialize<MojomType>(array, &buf, &data, &validate_params, |
+ &context); |
+ |
+ UserType deserialized_array; |
+ mojo::internal::Deserialize<MojomType>(data, &deserialized_array, |
+ &context); |
+ |
+ ASSERT_EQ(1u, deserialized_array.size()); |
+ ASSERT_EQ(1u, deserialized_array[0].size()); |
+ ASSERT_EQ(42, deserialized_array[0].at(1)); |
+ } |
+ |
+ { |
+ using MojomType = Array<Map<String, Array<bool>>>; |
+ using UserType = ArrayType<MapType<StringType, ArrayType<bool>>>; |
+ |
+ UserType array(1); |
+ ArrayType<bool> map_value(2); |
+ map_value[0] = false; |
+ map_value[1] = true; |
+ array[0].insert("hello world", std::move(map_value)); |
+ |
+ mojo::internal::SerializationContext context; |
+ size_t size = |
+ mojo::internal::PrepareToSerialize<MojomType>(array, &context); |
+ mojo::internal::FixedBufferForTesting buf(size); |
+ typename MojomType::Data_* data; |
+ mojo::internal::ContainerValidateParams validate_params( |
+ 0, false, |
+ new mojo::internal::ContainerValidateParams( |
+ new mojo::internal::ContainerValidateParams( |
+ 0, false, new mojo::internal::ContainerValidateParams( |
+ 0, false, nullptr)), |
+ new mojo::internal::ContainerValidateParams( |
+ 0, false, new mojo::internal::ContainerValidateParams( |
+ 0, false, nullptr)))); |
+ mojo::internal::Serialize<MojomType>(array, &buf, &data, &validate_params, |
+ &context); |
+ |
+ UserType deserialized_array; |
+ mojo::internal::Deserialize<MojomType>(data, &deserialized_array, |
+ &context); |
+ |
+ ASSERT_EQ(1u, deserialized_array.size()); |
+ ASSERT_EQ(1u, deserialized_array[0].size()); |
+ ASSERT_FALSE(deserialized_array[0].at("hello world")[0]); |
+ ASSERT_TRUE(deserialized_array[0].at("hello world")[1]); |
+ } |
+ } |
+}; |
+ |
+#define MAP_COMMON_TEST(MapType, test_name) \ |
+ TEST_F(MapType##Test, test_name) { MapCommonTest<MapType>::test_name(); } |
+ |
+} // namespace test |
+} // namespace mojo |