Home | History | Annotate | Download | only in tests
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "mojo/public/cpp/bindings/map.h"
      6 
      7 #include <stddef.h>
      8 #include <stdint.h>
      9 #include <utility>
     10 
     11 #include "mojo/public/cpp/bindings/array.h"
     12 #include "mojo/public/cpp/bindings/string.h"
     13 #include "mojo/public/cpp/bindings/tests/container_test_util.h"
     14 #include "mojo/public/cpp/bindings/tests/map_common_test.h"
     15 #include "testing/gtest/include/gtest/gtest.h"
     16 
     17 namespace mojo {
     18 namespace test {
     19 
     20 namespace {
     21 
     22 using MapTest = testing::Test;
     23 
     24 MAP_COMMON_TEST(Map, NullAndEmpty)
     25 MAP_COMMON_TEST(Map, InsertWorks)
     26 MAP_COMMON_TEST(Map, TestIndexOperator)
     27 MAP_COMMON_TEST(Map, TestIndexOperatorAsRValue)
     28 MAP_COMMON_TEST(Map, TestIndexOperatorMoveOnly)
     29 MAP_COMMON_TEST(Map, MapArrayClone)
     30 MAP_COMMON_TEST(Map, ArrayOfMap)
     31 
     32 TEST_F(MapTest, ConstructedFromArray) {
     33   Array<String> keys(kStringIntDataSize);
     34   Array<int> values(kStringIntDataSize);
     35   for (size_t i = 0; i < kStringIntDataSize; ++i) {
     36     keys[i] = kStringIntData[i].string_data;
     37     values[i] = kStringIntData[i].int_data;
     38   }
     39 
     40   Map<String, int> map(std::move(keys), std::move(values));
     41 
     42   for (size_t i = 0; i < kStringIntDataSize; ++i) {
     43     EXPECT_EQ(kStringIntData[i].int_data,
     44               map.at(mojo::String(kStringIntData[i].string_data)));
     45   }
     46 }
     47 
     48 TEST_F(MapTest, DecomposeMapTo) {
     49   Array<String> keys(kStringIntDataSize);
     50   Array<int> values(kStringIntDataSize);
     51   for (size_t i = 0; i < kStringIntDataSize; ++i) {
     52     keys[i] = kStringIntData[i].string_data;
     53     values[i] = kStringIntData[i].int_data;
     54   }
     55 
     56   Map<String, int> map(std::move(keys), std::move(values));
     57   EXPECT_EQ(kStringIntDataSize, map.size());
     58 
     59   Array<String> keys2;
     60   Array<int> values2;
     61   map.DecomposeMapTo(&keys2, &values2);
     62   EXPECT_EQ(0u, map.size());
     63 
     64   EXPECT_EQ(kStringIntDataSize, keys2.size());
     65   EXPECT_EQ(kStringIntDataSize, values2.size());
     66 
     67   for (size_t i = 0; i < kStringIntDataSize; ++i) {
     68     // We are not guaranteed that the copies have the same sorting as the
     69     // originals.
     70     String key = kStringIntData[i].string_data;
     71     int value = kStringIntData[i].int_data;
     72 
     73     bool found = false;
     74     for (size_t j = 0; j < keys2.size(); ++j) {
     75       if (keys2[j] == key) {
     76         EXPECT_EQ(value, values2[j]);
     77         found = true;
     78         break;
     79       }
     80     }
     81 
     82     EXPECT_TRUE(found);
     83   }
     84 }
     85 
     86 TEST_F(MapTest, Insert_Copyable) {
     87   ASSERT_EQ(0u, CopyableType::num_instances());
     88   mojo::Map<mojo::String, CopyableType> map;
     89   std::vector<CopyableType*> value_ptrs;
     90 
     91   for (size_t i = 0; i < kStringIntDataSize; ++i) {
     92     const char* key = kStringIntData[i].string_data;
     93     CopyableType value;
     94     value_ptrs.push_back(value.ptr());
     95     map.insert(key, value);
     96     ASSERT_EQ(i + 1, map.size());
     97     ASSERT_EQ(i + 1, value_ptrs.size());
     98     EXPECT_EQ(map.size() + 1, CopyableType::num_instances());
     99     EXPECT_TRUE(map.at(key).copied());
    100     EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
    101     map.at(key).ResetCopied();
    102     EXPECT_TRUE(map);
    103   }
    104 
    105   // std::map doesn't have a capacity() method like std::vector so this test is
    106   // a lot more boring.
    107 
    108   map = nullptr;
    109   EXPECT_EQ(0u, CopyableType::num_instances());
    110 }
    111 
    112 TEST_F(MapTest, Insert_MoveOnly) {
    113   ASSERT_EQ(0u, MoveOnlyType::num_instances());
    114   mojo::Map<mojo::String, MoveOnlyType> map;
    115   std::vector<MoveOnlyType*> value_ptrs;
    116 
    117   for (size_t i = 0; i < kStringIntDataSize; ++i) {
    118     const char* key = kStringIntData[i].string_data;
    119     MoveOnlyType value;
    120     value_ptrs.push_back(value.ptr());
    121     map.insert(key, std::move(value));
    122     ASSERT_EQ(i + 1, map.size());
    123     ASSERT_EQ(i + 1, value_ptrs.size());
    124     EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances());
    125     EXPECT_TRUE(map.at(key).moved());
    126     EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
    127     map.at(key).ResetMoved();
    128     EXPECT_TRUE(map);
    129   }
    130 
    131   // std::map doesn't have a capacity() method like std::vector so this test is
    132   // a lot more boring.
    133 
    134   map = nullptr;
    135   EXPECT_EQ(0u, MoveOnlyType::num_instances());
    136 }
    137 
    138 TEST_F(MapTest, IndexOperator_MoveOnly) {
    139   ASSERT_EQ(0u, MoveOnlyType::num_instances());
    140   mojo::Map<mojo::String, MoveOnlyType> map;
    141   std::vector<MoveOnlyType*> value_ptrs;
    142 
    143   for (size_t i = 0; i < kStringIntDataSize; ++i) {
    144     const char* key = kStringIntData[i].string_data;
    145     MoveOnlyType value;
    146     value_ptrs.push_back(value.ptr());
    147     map[key] = std::move(value);
    148     ASSERT_EQ(i + 1, map.size());
    149     ASSERT_EQ(i + 1, value_ptrs.size());
    150     EXPECT_EQ(map.size() + 1, MoveOnlyType::num_instances());
    151     EXPECT_TRUE(map.at(key).moved());
    152     EXPECT_EQ(value_ptrs[i], map.at(key).ptr());
    153     map.at(key).ResetMoved();
    154     EXPECT_TRUE(map);
    155   }
    156 
    157   // std::map doesn't have a capacity() method like std::vector so this test is
    158   // a lot more boring.
    159 
    160   map = nullptr;
    161   EXPECT_EQ(0u, MoveOnlyType::num_instances());
    162 }
    163 
    164 TEST_F(MapTest, STLToMojo) {
    165   std::map<std::string, int> stl_data;
    166   for (size_t i = 0; i < kStringIntDataSize; ++i)
    167     stl_data[kStringIntData[i].string_data] = kStringIntData[i].int_data;
    168 
    169   Map<String, int32_t> mojo_data = Map<String, int32_t>::From(stl_data);
    170   for (size_t i = 0; i < kStringIntDataSize; ++i) {
    171     EXPECT_EQ(kStringIntData[i].int_data,
    172               mojo_data.at(kStringIntData[i].string_data));
    173   }
    174 }
    175 
    176 TEST_F(MapTest, MojoToSTL) {
    177   Map<String, int32_t> mojo_map;
    178   for (size_t i = 0; i < kStringIntDataSize; ++i)
    179     mojo_map.insert(kStringIntData[i].string_data, kStringIntData[i].int_data);
    180 
    181   std::map<std::string, int> stl_map =
    182       mojo_map.To<std::map<std::string, int>>();
    183   for (size_t i = 0; i < kStringIntDataSize; ++i) {
    184     auto it = stl_map.find(kStringIntData[i].string_data);
    185     ASSERT_TRUE(it != stl_map.end());
    186     EXPECT_EQ(kStringIntData[i].int_data, it->second);
    187   }
    188 }
    189 
    190 TEST_F(MapTest, MoveFromAndToSTLMap_Copyable) {
    191   std::map<int32_t, CopyableType> map1;
    192   map1.insert(std::make_pair(123, CopyableType()));
    193   map1[123].ResetCopied();
    194 
    195   Map<int32_t, CopyableType> mojo_map(std::move(map1));
    196   ASSERT_EQ(1u, mojo_map.size());
    197   ASSERT_NE(mojo_map.end(), mojo_map.find(123));
    198   ASSERT_FALSE(mojo_map[123].copied());
    199 
    200   std::map<int32_t, CopyableType> map2(mojo_map.PassStorage());
    201   ASSERT_EQ(1u, map2.size());
    202   ASSERT_NE(map2.end(), map2.find(123));
    203   ASSERT_FALSE(map2[123].copied());
    204 
    205   ASSERT_EQ(0u, mojo_map.size());
    206   ASSERT_TRUE(mojo_map.is_null());
    207 }
    208 
    209 TEST_F(MapTest, MoveFromAndToSTLMap_MoveOnly) {
    210   std::map<int32_t, MoveOnlyType> map1;
    211   map1.insert(std::make_pair(123, MoveOnlyType()));
    212 
    213   Map<int32_t, MoveOnlyType> mojo_map(std::move(map1));
    214   ASSERT_EQ(1u, mojo_map.size());
    215   ASSERT_NE(mojo_map.end(), mojo_map.find(123));
    216 
    217   std::map<int32_t, MoveOnlyType> map2(mojo_map.PassStorage());
    218   ASSERT_EQ(1u, map2.size());
    219   ASSERT_NE(map2.end(), map2.find(123));
    220 
    221   ASSERT_EQ(0u, mojo_map.size());
    222   ASSERT_TRUE(mojo_map.is_null());
    223 }
    224 
    225 }  // namespace
    226 }  // namespace test
    227 }  // namespace mojo
    228