summaryrefslogtreecommitdiffstats
path: root/runtime/base/variant_map_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/base/variant_map_test.cc')
-rw-r--r--runtime/base/variant_map_test.cc168
1 files changed, 168 insertions, 0 deletions
diff --git a/runtime/base/variant_map_test.cc b/runtime/base/variant_map_test.cc
new file mode 100644
index 0000000..827de46
--- /dev/null
+++ b/runtime/base/variant_map_test.cc
@@ -0,0 +1,168 @@
+/*
+ * 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), \
+ reinterpret_cast<void*>(NULL));
+
+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;
+ };
+
+ const FruitMap::Key<int> FruitMap::Apple;
+ const FruitMap::Key<double> FruitMap::Orange;
+} // 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());
+
+ 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, 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