Home | History | Annotate | Download | only in tests
      1 
      2 /*
      3  * Copyright (C) 2016 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #include "gtest/gtest.h"
     19 
     20 #include "chre/util/non_copyable.h"
     21 #include "chre/util/optional.h"
     22 
     23 using chre::Optional;
     24 
     25 TEST(Optional, NoValueByDefault) {
     26   Optional<int> myInt;
     27   EXPECT_FALSE(myInt.has_value());
     28 }
     29 
     30 TEST(Optional, NonDefaultValueByDefault) {
     31   Optional<int> myInt(0x1337);
     32   EXPECT_TRUE(myInt.has_value());
     33   EXPECT_EQ(*myInt, 0x1337);
     34 }
     35 
     36 TEST(Optional, NonDefaultMovedValueByDefault) {
     37   Optional<int> myInt(std::move(0x1337));
     38   EXPECT_TRUE(myInt.has_value());
     39   EXPECT_EQ(*myInt, 0x1337);
     40 }
     41 
     42 TEST(Optional, CopyAssignAndRead) {
     43   Optional<int> myInt;
     44   EXPECT_FALSE(myInt.has_value());
     45   myInt = 0x1337;
     46   EXPECT_EQ(*myInt, 0x1337);
     47   EXPECT_TRUE(myInt.has_value());
     48   myInt.reset();
     49   EXPECT_FALSE(myInt.has_value());
     50 }
     51 
     52 TEST(Optional, MoveAssignAndRead) {
     53   Optional<int> myInt;
     54   EXPECT_FALSE(myInt.has_value());
     55   myInt = std::move(0xcafe);
     56   EXPECT_TRUE(myInt.has_value());
     57   EXPECT_EQ(*myInt, 0xcafe);
     58 }
     59 
     60 TEST(Optional, OptionalMoveAssignAndRead) {
     61   Optional<int> myInt(0x1337);
     62   Optional<int> myMovedInt;
     63   EXPECT_FALSE(myMovedInt.has_value());
     64   myMovedInt = std::move(myInt);
     65   EXPECT_TRUE(myInt.has_value());
     66   EXPECT_TRUE(myMovedInt.has_value());
     67   EXPECT_EQ(*myMovedInt, 0x1337);
     68 }
     69 
     70 TEST(Optional, OptionalCopyAssignAndRead) {
     71   Optional<int> myInt(0x1337);
     72   Optional<int> myCopiedInt;
     73   EXPECT_FALSE(myCopiedInt.has_value());
     74   myCopiedInt = myInt;
     75   EXPECT_TRUE(myInt.has_value());
     76   EXPECT_TRUE(myCopiedInt.has_value());
     77   EXPECT_EQ(*myInt, 0x1337);
     78   EXPECT_EQ(*myCopiedInt, 0x1337);
     79 }
     80 
     81 static constexpr int kInvalidValue = -1;
     82 
     83 class MovableButNonCopyable : public chre::NonCopyable {
     84  public:
     85   MovableButNonCopyable() = default;
     86   MovableButNonCopyable(int value) : mValue(value) {}
     87   MovableButNonCopyable(MovableButNonCopyable&& other) {
     88     mValue = other.mValue;
     89     other.mValue = kInvalidValue;
     90   }
     91 
     92   MovableButNonCopyable& operator=(MovableButNonCopyable&& other) {
     93     assert(mMagic == kConstructedMagic);
     94     mValue = other.mValue;
     95     other.mValue = kInvalidValue;
     96     return *this;
     97   }
     98 
     99   ~MovableButNonCopyable() {
    100     mMagic = kUninitializedMagic;
    101     mValue = kUninitializedMagic;
    102   }
    103 
    104   int getValue() const {
    105     return mValue;
    106   }
    107 
    108  private:
    109   static constexpr int kConstructedMagic = 0xfeedc0fe;
    110   static constexpr int kUninitializedMagic = 0xdeadbeef;
    111 
    112   int mMagic = kConstructedMagic;
    113   int mValue = kInvalidValue;
    114 };
    115 
    116 TEST(Optional, UninitializedAssignment) {
    117   constexpr int kValue1 = 0xd00d;
    118   constexpr int kValue2 = 0xcafe;
    119   MovableButNonCopyable transferee1(kValue1);
    120   MovableButNonCopyable transferee2(kValue2);
    121 
    122   Optional<MovableButNonCopyable> container;
    123   EXPECT_FALSE(container.has_value());
    124 
    125   container = std::move(transferee1);
    126   EXPECT_TRUE(container.has_value());
    127   EXPECT_EQ(container->getValue(), kValue1);
    128   EXPECT_EQ(transferee1.getValue(), kInvalidValue);
    129 
    130   container.reset();
    131   EXPECT_FALSE(container.has_value());
    132 
    133   container = std::move(transferee2);
    134   EXPECT_TRUE(container.has_value());
    135   EXPECT_EQ(container->getValue(), kValue2);
    136   EXPECT_EQ(transferee2.getValue(), kInvalidValue);
    137 }
    138 
    139 // TODO: should add some tests to cover the possible assignment outcomes between
    140 // two Optional instances (e.g. assign one w/o value to one w/value, etc)
    141