diff options
Diffstat (limited to 'runtime/base/variant_map_test.cc')
-rw-r--r-- | runtime/base/variant_map_test.cc | 168 |
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 |