1*3f982cf4SFabien Sanglard // Copyright 2020 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard
5*3f982cf4SFabien Sanglard #include "util/flat_map.h"
6*3f982cf4SFabien Sanglard
7*3f982cf4SFabien Sanglard #include <chrono>
8*3f982cf4SFabien Sanglard
9*3f982cf4SFabien Sanglard #include "absl/strings/string_view.h"
10*3f982cf4SFabien Sanglard #include "gtest/gtest.h"
11*3f982cf4SFabien Sanglard
12*3f982cf4SFabien Sanglard namespace openscreen {
13*3f982cf4SFabien Sanglard
14*3f982cf4SFabien Sanglard namespace {
15*3f982cf4SFabien Sanglard
16*3f982cf4SFabien Sanglard const FlatMap<int, absl::string_view> kSimpleFlatMap{{-1, "bar"},
17*3f982cf4SFabien Sanglard {123, "foo"},
18*3f982cf4SFabien Sanglard {10000, "baz"},
19*3f982cf4SFabien Sanglard {0, ""}};
20*3f982cf4SFabien Sanglard
21*3f982cf4SFabien Sanglard } // namespace
22*3f982cf4SFabien Sanglard
TEST(FlatMapTest,Find)23*3f982cf4SFabien Sanglard TEST(FlatMapTest, Find) {
24*3f982cf4SFabien Sanglard EXPECT_EQ(kSimpleFlatMap.begin(), kSimpleFlatMap.find(-1));
25*3f982cf4SFabien Sanglard EXPECT_EQ("bar", kSimpleFlatMap.find(-1)->second);
26*3f982cf4SFabien Sanglard EXPECT_EQ("foo", kSimpleFlatMap.find(123)->second);
27*3f982cf4SFabien Sanglard EXPECT_EQ("baz", kSimpleFlatMap.find(10000)->second);
28*3f982cf4SFabien Sanglard EXPECT_EQ("", kSimpleFlatMap.find(0)->second);
29*3f982cf4SFabien Sanglard EXPECT_EQ(kSimpleFlatMap.end(), kSimpleFlatMap.find(2));
30*3f982cf4SFabien Sanglard }
31*3f982cf4SFabien Sanglard
32*3f982cf4SFabien Sanglard // Since it is backed by a vector, we don't expose an operator[] due
33*3f982cf4SFabien Sanglard // to potential confusion. If the type of Key is int or std::size_t, do
34*3f982cf4SFabien Sanglard // you want the std::pair<Key, Value> or just the Value?
TEST(FlatMapTest,Access)35*3f982cf4SFabien Sanglard TEST(FlatMapTest, Access) {
36*3f982cf4SFabien Sanglard EXPECT_EQ("bar", kSimpleFlatMap[0].second);
37*3f982cf4SFabien Sanglard EXPECT_EQ("foo", kSimpleFlatMap[1].second);
38*3f982cf4SFabien Sanglard EXPECT_EQ("baz", kSimpleFlatMap[2].second);
39*3f982cf4SFabien Sanglard EXPECT_EQ("", kSimpleFlatMap[3].second);
40*3f982cf4SFabien Sanglard
41*3f982cf4SFabien Sanglard // NOTE: vector doesn't do any range checking for operator[], only at().
42*3f982cf4SFabien Sanglard EXPECT_EQ("bar", kSimpleFlatMap.at(0).second);
43*3f982cf4SFabien Sanglard EXPECT_EQ("foo", kSimpleFlatMap.at(1).second);
44*3f982cf4SFabien Sanglard EXPECT_EQ("baz", kSimpleFlatMap.at(2).second);
45*3f982cf4SFabien Sanglard EXPECT_EQ("", kSimpleFlatMap.at(3).second);
46*3f982cf4SFabien Sanglard // The error message varies widely depending on how the test is run.
47*3f982cf4SFabien Sanglard // NOTE: Google Test doesn't support death tests on some platforms, such
48*3f982cf4SFabien Sanglard // as iOS.
49*3f982cf4SFabien Sanglard #if defined(GTEST_HAS_DEATH_TEST)
50*3f982cf4SFabien Sanglard EXPECT_DEATH(kSimpleFlatMap.at(31337), ".*");
51*3f982cf4SFabien Sanglard #endif
52*3f982cf4SFabien Sanglard }
53*3f982cf4SFabien Sanglard
TEST(FlatMapTest,ErasureAndEmplacement)54*3f982cf4SFabien Sanglard TEST(FlatMapTest, ErasureAndEmplacement) {
55*3f982cf4SFabien Sanglard auto mutable_vector = kSimpleFlatMap;
56*3f982cf4SFabien Sanglard EXPECT_NE(mutable_vector.find(-1), mutable_vector.end());
57*3f982cf4SFabien Sanglard mutable_vector.erase_key(-1);
58*3f982cf4SFabien Sanglard EXPECT_EQ(mutable_vector.find(-1), mutable_vector.end());
59*3f982cf4SFabien Sanglard
60*3f982cf4SFabien Sanglard mutable_vector.emplace_back(-1, "bar");
61*3f982cf4SFabien Sanglard EXPECT_NE(mutable_vector.find(-1), mutable_vector.end());
62*3f982cf4SFabien Sanglard
63*3f982cf4SFabien Sanglard // We absolutely should fail to erase something that's not there.
64*3f982cf4SFabien Sanglard #if defined(GTEST_HAS_DEATH_TEST)
65*3f982cf4SFabien Sanglard EXPECT_DEATH(mutable_vector.erase_key(12345),
66*3f982cf4SFabien Sanglard ".*failed to erase: element not found.*");
67*3f982cf4SFabien Sanglard #endif
68*3f982cf4SFabien Sanglard }
69*3f982cf4SFabien Sanglard
TEST(FlatMapTest,Mutation)70*3f982cf4SFabien Sanglard TEST(FlatMapTest, Mutation) {
71*3f982cf4SFabien Sanglard FlatMap<int, int> mutable_vector{{1, 2}};
72*3f982cf4SFabien Sanglard EXPECT_EQ(2, mutable_vector[0].second);
73*3f982cf4SFabien Sanglard
74*3f982cf4SFabien Sanglard mutable_vector[0].second = 3;
75*3f982cf4SFabien Sanglard EXPECT_EQ(3, mutable_vector[0].second);
76*3f982cf4SFabien Sanglard }
77*3f982cf4SFabien Sanglard
TEST(FlatMapTest,GenerallyBehavesLikeAVector)78*3f982cf4SFabien Sanglard TEST(FlatMapTest, GenerallyBehavesLikeAVector) {
79*3f982cf4SFabien Sanglard EXPECT_EQ(kSimpleFlatMap, kSimpleFlatMap);
80*3f982cf4SFabien Sanglard EXPECT_TRUE(kSimpleFlatMap == kSimpleFlatMap);
81*3f982cf4SFabien Sanglard
82*3f982cf4SFabien Sanglard for (auto& entry : kSimpleFlatMap) {
83*3f982cf4SFabien Sanglard if (entry.first != 0) {
84*3f982cf4SFabien Sanglard EXPECT_LT(0u, entry.second.size());
85*3f982cf4SFabien Sanglard }
86*3f982cf4SFabien Sanglard }
87*3f982cf4SFabien Sanglard
88*3f982cf4SFabien Sanglard FlatMap<int, int> simple;
89*3f982cf4SFabien Sanglard simple.emplace_back(1, 10);
90*3f982cf4SFabien Sanglard EXPECT_EQ(simple, (FlatMap<int, int>{{1, 10}}));
91*3f982cf4SFabien Sanglard
92*3f982cf4SFabien Sanglard auto it = simple.find(1);
93*3f982cf4SFabien Sanglard ASSERT_NE(it, simple.end());
94*3f982cf4SFabien Sanglard simple.erase(it);
95*3f982cf4SFabien Sanglard EXPECT_EQ(simple.find(1), simple.end());
96*3f982cf4SFabien Sanglard }
97*3f982cf4SFabien Sanglard
TEST(FlatMapTest,CanUseNonDefaultConstructibleThings)98*3f982cf4SFabien Sanglard TEST(FlatMapTest, CanUseNonDefaultConstructibleThings) {
99*3f982cf4SFabien Sanglard class NonDefaultConstructible {
100*3f982cf4SFabien Sanglard public:
101*3f982cf4SFabien Sanglard NonDefaultConstructible(int x, int y) : x_(x), y_(y) {}
102*3f982cf4SFabien Sanglard
103*3f982cf4SFabien Sanglard int x() { return x_; }
104*3f982cf4SFabien Sanglard
105*3f982cf4SFabien Sanglard int y() { return y_; }
106*3f982cf4SFabien Sanglard
107*3f982cf4SFabien Sanglard private:
108*3f982cf4SFabien Sanglard int x_;
109*3f982cf4SFabien Sanglard int y_;
110*3f982cf4SFabien Sanglard };
111*3f982cf4SFabien Sanglard
112*3f982cf4SFabien Sanglard FlatMap<int, NonDefaultConstructible> flat_map;
113*3f982cf4SFabien Sanglard flat_map.emplace_back(3, NonDefaultConstructible(2, 3));
114*3f982cf4SFabien Sanglard auto it = flat_map.find(3);
115*3f982cf4SFabien Sanglard ASSERT_TRUE(it != flat_map.end());
116*3f982cf4SFabien Sanglard EXPECT_GT(it->second.y(), it->second.x());
117*3f982cf4SFabien Sanglard }
118*3f982cf4SFabien Sanglard } // namespace openscreen
119