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