summaryrefslogtreecommitdiff
path: root/libartbase/base/variant_map_test.cc
diff options
context:
space:
mode:
author David Sehr <sehr@google.com> 2018-03-02 12:01:51 -0800
committer David Sehr <sehr@google.com> 2018-03-08 23:23:32 +0000
commit8f4b056427a9d2321e3aa4f21ca8ffb18b3e5ae6 (patch)
treee4d4bd04a04a1e3fc5b210b0c02542d453b84781 /libartbase/base/variant_map_test.cc
parentcedad4bd452f800ada0be930e801cd921319cd11 (diff)
Move most of runtime/base to libartbase/base
Enforce the layering that code in runtime/base should not depend on runtime by separating it into libartbase. Some of the code in runtime/base depends on the Runtime class, so it cannot be moved yet. Also, some of the tests depend on CommonRuntimeTest, which itself needs to be factored (in a subsequent CL). Bug: 22322814 Test: make -j 50 checkbuild make -j 50 test-art-host Change-Id: I8b096c1e2542f829eb456b4b057c71421b77d7e2 Merged-In: c431b9dc4b23cc950eb313695258df5d89f53b22 (cherry picked from commit c431b9dc4b23cc950eb313695258df5d89f53b22)
Diffstat (limited to 'libartbase/base/variant_map_test.cc')
-rw-r--r--libartbase/base/variant_map_test.cc189
1 files changed, 189 insertions, 0 deletions
diff --git a/libartbase/base/variant_map_test.cc b/libartbase/base/variant_map_test.cc
new file mode 100644
index 0000000000..4677b6d3b3
--- /dev/null
+++ b/libartbase/base/variant_map_test.cc
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * 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 "variant_map.h"
+#include "gtest/gtest.h"
+
+#define EXPECT_NULL(expected) EXPECT_EQ(reinterpret_cast<const void*>(expected), \
+ static_cast<void*>(nullptr));
+
+namespace art {
+
+namespace {
+template <typename TValue>
+struct FruitMapKey : VariantMapKey<TValue> {
+ FruitMapKey() {}
+};
+
+struct FruitMap : VariantMap<FruitMap, FruitMapKey> {
+ // This 'using' line is necessary to inherit the variadic constructor.
+ using VariantMap<FruitMap, FruitMapKey>::VariantMap;
+
+ // Make the next '4' usages of Key slightly shorter to type.
+ template <typename TValue>
+ using Key = FruitMapKey<TValue>;
+
+ static const Key<int> Apple;
+ static const Key<double> Orange;
+ static const Key<std::string> Label;
+};
+
+const FruitMap::Key<int> FruitMap::Apple;
+const FruitMap::Key<double> FruitMap::Orange;
+const FruitMap::Key<std::string> FruitMap::Label;
+} // namespace
+
+TEST(VariantMaps, BasicReadWrite) {
+ FruitMap fm;
+
+ EXPECT_NULL(fm.Get(FruitMap::Apple));
+ EXPECT_FALSE(fm.Exists(FruitMap::Apple));
+ EXPECT_NULL(fm.Get(FruitMap::Orange));
+ EXPECT_FALSE(fm.Exists(FruitMap::Orange));
+
+ fm.Set(FruitMap::Apple, 1);
+ EXPECT_NULL(fm.Get(FruitMap::Orange));
+ EXPECT_EQ(1, *fm.Get(FruitMap::Apple));
+ EXPECT_TRUE(fm.Exists(FruitMap::Apple));
+
+ fm.Set(FruitMap::Apple, 5);
+ EXPECT_NULL(fm.Get(FruitMap::Orange));
+ EXPECT_EQ(5, *fm.Get(FruitMap::Apple));
+ EXPECT_TRUE(fm.Exists(FruitMap::Apple));
+
+ fm.Set(FruitMap::Orange, 555.0);
+ EXPECT_EQ(5, *fm.Get(FruitMap::Apple));
+ EXPECT_DOUBLE_EQ(555.0, *fm.Get(FruitMap::Orange));
+ EXPECT_EQ(size_t(2), fm.Size());
+
+ // Simple remove
+ fm.Remove(FruitMap::Apple);
+ EXPECT_FALSE(fm.Exists(FruitMap::Apple));
+
+ fm.Clear();
+ EXPECT_EQ(size_t(0), fm.Size());
+ EXPECT_FALSE(fm.Exists(FruitMap::Orange));
+}
+
+TEST(VariantMaps, SetPreviousValue) {
+ FruitMap fm;
+
+ // Indirect remove by setting yourself again
+ fm.Set(FruitMap::Label, std::string("hello_world"));
+ auto* ptr = fm.Get(FruitMap::Label);
+ ASSERT_TRUE(ptr != nullptr);
+ *ptr = "foobar";
+
+ // Set the value to the same exact pointer which we got out of the map.
+ // This should cleanly 'just work' and not try to delete the value too early.
+ fm.Set(FruitMap::Label, *ptr);
+
+ auto* new_ptr = fm.Get(FruitMap::Label);
+ ASSERT_TRUE(ptr != nullptr);
+ EXPECT_EQ(std::string("foobar"), *new_ptr);
+}
+
+TEST(VariantMaps, RuleOfFive) {
+ // Test empty constructor
+ FruitMap fmEmpty;
+ EXPECT_EQ(size_t(0), fmEmpty.Size());
+
+ // Test empty constructor
+ FruitMap fmFilled;
+ fmFilled.Set(FruitMap::Apple, 1);
+ fmFilled.Set(FruitMap::Orange, 555.0);
+ EXPECT_EQ(size_t(2), fmFilled.Size());
+
+ // Test copy constructor
+ FruitMap fmEmptyCopy(fmEmpty);
+ EXPECT_EQ(size_t(0), fmEmptyCopy.Size());
+
+ // Test copy constructor
+ FruitMap fmFilledCopy(fmFilled);
+ EXPECT_EQ(size_t(2), fmFilledCopy.Size());
+ EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmFilledCopy.Get(FruitMap::Apple));
+ EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmFilledCopy.Get(FruitMap::Orange));
+
+ // Test operator=
+ FruitMap fmFilledCopy2;
+ fmFilledCopy2 = fmFilled;
+ EXPECT_EQ(size_t(2), fmFilledCopy2.Size());
+ EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmFilledCopy2.Get(FruitMap::Apple));
+ EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmFilledCopy2.Get(FruitMap::Orange));
+
+ // Test move constructor
+ FruitMap fmMoved(std::move(fmFilledCopy));
+ EXPECT_EQ(size_t(0), fmFilledCopy.Size());
+ EXPECT_EQ(size_t(2), fmMoved.Size());
+ EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmMoved.Get(FruitMap::Apple));
+ EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmMoved.Get(FruitMap::Orange));
+
+ // Test operator= move
+ FruitMap fmMoved2;
+ fmMoved2.Set(FruitMap::Apple, 12345); // This value will be clobbered after the move
+
+ fmMoved2 = std::move(fmFilledCopy2);
+ EXPECT_EQ(size_t(0), fmFilledCopy2.Size());
+ EXPECT_EQ(size_t(2), fmMoved2.Size());
+ EXPECT_EQ(*fmFilled.Get(FruitMap::Apple), *fmMoved2.Get(FruitMap::Apple));
+ EXPECT_DOUBLE_EQ(*fmFilled.Get(FruitMap::Orange), *fmMoved2.Get(FruitMap::Orange));
+}
+
+TEST(VariantMaps, VariadicConstructors) {
+ // Variadic constructor, 1 kv/pair
+ FruitMap fmApple(FruitMap::Apple, 12345);
+ EXPECT_EQ(size_t(1), fmApple.Size());
+ EXPECT_EQ(12345, *fmApple.Get(FruitMap::Apple));
+
+ // Variadic constructor, 2 kv/pair
+ FruitMap fmAppleAndOrange(FruitMap::Apple, 12345,
+ FruitMap::Orange, 100.0);
+ EXPECT_EQ(size_t(2), fmAppleAndOrange.Size());
+ EXPECT_EQ(12345, *fmAppleAndOrange.Get(FruitMap::Apple));
+ EXPECT_DOUBLE_EQ(100.0, *fmAppleAndOrange.Get(FruitMap::Orange));
+}
+
+TEST(VariantMaps, ReleaseOrDefault) {
+ FruitMap fmAppleAndOrange(FruitMap::Apple, 12345,
+ FruitMap::Orange, 100.0);
+
+ int apple = fmAppleAndOrange.ReleaseOrDefault(FruitMap::Apple);
+ EXPECT_EQ(12345, apple);
+
+ // Releasing will also remove the Apple key.
+ EXPECT_EQ(size_t(1), fmAppleAndOrange.Size());
+
+ // Releasing again yields a default value.
+ int apple2 = fmAppleAndOrange.ReleaseOrDefault(FruitMap::Apple);
+ EXPECT_EQ(0, apple2);
+}
+
+TEST(VariantMaps, GetOrDefault) {
+ FruitMap fm(FruitMap::Apple, 12345);
+
+ // Apple gives the expected value we set.
+ int apple = fm.GetOrDefault(FruitMap::Apple);
+ EXPECT_EQ(12345, apple);
+
+ // Map is still 1.
+ EXPECT_EQ(size_t(1), fm.Size());
+
+ // Orange gives back a default value, since it's not in the map.
+ double orange = fm.GetOrDefault(FruitMap::Orange);
+ EXPECT_DOUBLE_EQ(0.0, orange);
+}
+
+} // namespace art