| // Copyright 2017-2020 The Verible Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "common/util/bijective_map.h" |
| |
| #include <string> |
| |
| #include "gmock/gmock.h" |
| #include "gtest/gtest.h" |
| #include "common/strings/compare.h" |
| #include "common/util/logging.h" |
| |
| namespace verible { |
| namespace { |
| |
| using TestMapType = BijectiveMap<std::string, int>; |
| |
| TEST(BijectiveMapTest, DefaultCtor) { |
| TestMapType m; |
| EXPECT_EQ(m.size(), 0); |
| EXPECT_TRUE(m.empty()); |
| EXPECT_FALSE(m.find_forward("a")); |
| EXPECT_FALSE(m.find_reverse(1)); |
| EXPECT_TRUE(m.forward_view().empty()); |
| EXPECT_TRUE(m.reverse_view().empty()); |
| } |
| |
| TEST(BijectiveMapTest, OneElement) { |
| TestMapType m; |
| EXPECT_TRUE(m.insert("a", 1)); |
| EXPECT_EQ(m.size(), 1); |
| EXPECT_FALSE(m.empty()); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_forward("a")), 1); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_reverse(1)), "a"); |
| EXPECT_EQ(m.find_forward("b"), nullptr); |
| EXPECT_EQ(m.find_reverse(2), nullptr); |
| } |
| |
| TEST(BijectiveMapTest, InsertPair) { |
| TestMapType m; |
| EXPECT_TRUE(m.insert(std::make_pair("b", 2))); |
| EXPECT_EQ(m.size(), 1); |
| EXPECT_FALSE(m.empty()); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_forward("b")), 2); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_reverse(2)), "b"); |
| EXPECT_EQ(m.find_forward("a"), nullptr); |
| EXPECT_EQ(m.find_reverse(1), nullptr); |
| } |
| |
| TEST(BijectiveMapTest, InsertKeyAlreadyExists) { |
| TestMapType m; |
| EXPECT_TRUE(m.insert("a", 1)); |
| EXPECT_FALSE(m.insert("a", 3)); |
| EXPECT_EQ(m.size(), 1); |
| } |
| |
| TEST(BijectiveMapTest, InsertValueAlreadyExists) { |
| TestMapType m; |
| EXPECT_TRUE(m.insert("a", 1)); |
| EXPECT_FALSE(m.insert("z", 1)); |
| EXPECT_EQ(m.size(), 1); |
| } |
| |
| TEST(BijectiveMapTest, InsertNewPairs) { |
| TestMapType m; |
| EXPECT_TRUE(m.insert("a", 1)); |
| EXPECT_TRUE(m.insert("z", 4)); |
| EXPECT_EQ(m.size(), 2); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_forward("a")), 1); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_reverse(1)), "a"); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_forward("z")), 4); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_reverse(4)), "z"); |
| EXPECT_EQ(m.find_forward("b"), nullptr); |
| EXPECT_EQ(m.find_reverse(3), nullptr); |
| } |
| |
| static std::function<int()> LoopGeneratorGenerator( |
| const std::vector<int>& values) { |
| return [=]() { // fake random generator |
| static const std::vector<int> v(values); |
| static std::vector<int>::const_iterator iter = v.begin(); |
| if (iter == v.end()) { |
| iter = v.begin(); |
| } // loop |
| return *iter++; |
| }; |
| } |
| |
| TEST(BijectiveMapTest, InsertRandom) { |
| TestMapType m; |
| auto gen = LoopGeneratorGenerator({1, 1, 2, 2, 3, 3}); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.insert_using_value_generator("b", gen)), 1); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.insert_using_value_generator("b", gen)), 1); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.insert_using_value_generator("g", gen)), 2); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.insert_using_value_generator("g", gen)), 2); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.insert_using_value_generator("f", gen)), 3); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.insert_using_value_generator("f", gen)), 3); |
| } |
| |
| #if 0 // TODO(b/152331548): make work with C++11 |
| // Testing heterogenous lookup: internally stored std::string, supporting |
| // copy-less lookup with absl::string_view. |
| using StringMapType = BijectiveMap<std::string, std::string, StringViewCompare, |
| StringViewCompare>; |
| |
| TEST(BijectiveMapTest, HeterogeneousStringLookup) { |
| StringMapType m; |
| EXPECT_TRUE(m.insert("a", "G")); |
| EXPECT_TRUE(m.insert("z", "Q")); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_forward(absl::string_view("a"))), "G"); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_reverse(absl::string_view("G"))), "a"); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_forward(absl::string_view("z"))), "Q"); |
| EXPECT_EQ(*ABSL_DIE_IF_NULL(m.find_reverse(absl::string_view("Q"))), "z"); |
| EXPECT_EQ(m.find_forward(absl::string_view("b")), nullptr); |
| EXPECT_EQ(m.find_reverse(absl::string_view("3")), nullptr); |
| } |
| #endif |
| |
| } // namespace |
| } // namespace verible |