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 class DestructorTestingObject {
26 public:
~DestructorTestingObject()27 ~DestructorTestingObject() {
28 if (valueToFlipWhenDestruct != nullptr) {
29 *valueToFlipWhenDestruct = !*valueToFlipWhenDestruct;
30 }
31 }
32
setValueToFlipWhenDestruct(bool * value)33 void setValueToFlipWhenDestruct(bool *value) {
34 valueToFlipWhenDestruct = value;
35 }
36
37 private:
38 bool *valueToFlipWhenDestruct = nullptr;
39 };
40
TEST(Optional,ShouldDestructContainedObject)41 TEST(Optional, ShouldDestructContainedObject) {
42 bool destructed = false;
43 {
44 Optional<DestructorTestingObject> object(DestructorTestingObject{});
45 object.value().setValueToFlipWhenDestruct(&destructed);
46 }
47 EXPECT_TRUE(destructed);
48 }
49
TEST(Optional,NoValueByDefault)50 TEST(Optional, NoValueByDefault) {
51 Optional<int> myInt;
52 EXPECT_FALSE(myInt.has_value());
53 }
54
TEST(Optional,NonDefaultValueByDefault)55 TEST(Optional, NonDefaultValueByDefault) {
56 Optional<int> myInt(0x1337);
57 EXPECT_TRUE(myInt.has_value());
58 EXPECT_EQ(*myInt, 0x1337);
59 }
60
TEST(Optional,NonDefaultMovedValueByDefault)61 TEST(Optional, NonDefaultMovedValueByDefault) {
62 Optional<int> myInt(std::move(0x1337));
63 EXPECT_TRUE(myInt.has_value());
64 EXPECT_EQ(*myInt, 0x1337);
65 }
66
TEST(Optional,CopyConstruct)67 TEST(Optional, CopyConstruct) {
68 Optional<int> myInt(0x1337);
69 Optional<int> myNewInt(myInt);
70 EXPECT_TRUE(myNewInt.has_value());
71 EXPECT_EQ(*myNewInt, 0x1337);
72 }
73
TEST(Optional,CopyConstructConst)74 TEST(Optional, CopyConstructConst) {
75 const Optional<int> myInt(0x1337);
76 Optional<int> myNewInt(myInt);
77 EXPECT_TRUE(myNewInt.has_value());
78 EXPECT_EQ(*myNewInt, 0x1337);
79 }
80
TEST(Optional,CopyAssignAndRead)81 TEST(Optional, CopyAssignAndRead) {
82 Optional<int> myInt;
83 EXPECT_FALSE(myInt.has_value());
84 myInt = 0x1337;
85 EXPECT_EQ(*myInt, 0x1337);
86 EXPECT_TRUE(myInt.has_value());
87 myInt.reset();
88 EXPECT_FALSE(myInt.has_value());
89 }
90
TEST(Optional,MoveAssignAndRead)91 TEST(Optional, MoveAssignAndRead) {
92 Optional<int> myInt;
93 EXPECT_FALSE(myInt.has_value());
94 myInt = std::move(0xcafe);
95 EXPECT_TRUE(myInt.has_value());
96 EXPECT_EQ(*myInt, 0xcafe);
97 }
98
TEST(Optional,OptionalMoveAssignAndRead)99 TEST(Optional, OptionalMoveAssignAndRead) {
100 Optional<int> myInt(0x1337);
101 Optional<int> myMovedInt;
102 EXPECT_FALSE(myMovedInt.has_value());
103 myMovedInt = std::move(myInt);
104 EXPECT_TRUE(myInt.has_value());
105 EXPECT_TRUE(myMovedInt.has_value());
106 EXPECT_EQ(*myMovedInt, 0x1337);
107 }
108
TEST(Optional,OptionalCopyAssignAndRead)109 TEST(Optional, OptionalCopyAssignAndRead) {
110 Optional<int> myInt(0x1337);
111 Optional<int> myCopiedInt;
112 EXPECT_FALSE(myCopiedInt.has_value());
113 myCopiedInt = myInt;
114 EXPECT_TRUE(myInt.has_value());
115 EXPECT_TRUE(myCopiedInt.has_value());
116 EXPECT_EQ(*myInt, 0x1337);
117 EXPECT_EQ(*myCopiedInt, 0x1337);
118 }
119
120 static constexpr int kInvalidValue = -1;
121
122 class MovableButNonCopyable : public chre::NonCopyable {
123 public:
124 MovableButNonCopyable() = default;
MovableButNonCopyable(int value)125 MovableButNonCopyable(int value) : mValue(value) {}
MovableButNonCopyable(MovableButNonCopyable && other)126 MovableButNonCopyable(MovableButNonCopyable&& other) {
127 mValue = other.mValue;
128 other.mValue = kInvalidValue;
129 }
130
operator =(MovableButNonCopyable && other)131 MovableButNonCopyable& operator=(MovableButNonCopyable&& other) {
132 assert(mMagic == kConstructedMagic);
133 mValue = other.mValue;
134 other.mValue = kInvalidValue;
135 return *this;
136 }
137
~MovableButNonCopyable()138 ~MovableButNonCopyable() {
139 mMagic = kUninitializedMagic;
140 mValue = kUninitializedMagic;
141 }
142
getValue() const143 int getValue() const {
144 return mValue;
145 }
146
147 private:
148 static constexpr int kConstructedMagic = 0xfeedc0fe;
149 static constexpr int kUninitializedMagic = 0xdeadbeef;
150
151 int mMagic = kConstructedMagic;
152 int mValue = kInvalidValue;
153 };
154
TEST(Optional,UninitializedAssignment)155 TEST(Optional, UninitializedAssignment) {
156 constexpr int kValue1 = 0xd00d;
157 constexpr int kValue2 = 0xcafe;
158 MovableButNonCopyable transferee1(kValue1);
159 MovableButNonCopyable transferee2(kValue2);
160
161 Optional<MovableButNonCopyable> container;
162 EXPECT_FALSE(container.has_value());
163
164 container = std::move(transferee1);
165 EXPECT_TRUE(container.has_value());
166 EXPECT_EQ(container->getValue(), kValue1);
167 EXPECT_EQ(transferee1.getValue(), kInvalidValue);
168
169 container.reset();
170 EXPECT_FALSE(container.has_value());
171
172 container = std::move(transferee2);
173 EXPECT_TRUE(container.has_value());
174 EXPECT_EQ(container->getValue(), kValue2);
175 EXPECT_EQ(transferee2.getValue(), kInvalidValue);
176 }
177
178 // TODO: should add some tests to cover the possible assignment outcomes between
179 // two Optional instances (e.g. assign one w/o value to one w/value, etc)
180