1 /*
2 * Copyright (c) 2021-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <cstdlib>
17 #include <memory>
18 #include <string>
19 #include "gtest/gtest.h"
20 #define private public
21 #define protected public
22 #include "plugin/common/any.h"
23
24 using namespace testing::ext;
25
26 namespace OHOS {
27 namespace Media {
28 namespace Test {
29 using namespace OHOS::Media::Plugin;
CompareFunctionTable(const Any::FunctionTable * ft1,const Any::FunctionTable * ft2)30 bool CompareFunctionTable(const Any::FunctionTable* ft1, const Any::FunctionTable* ft2)
31 {
32 #ifndef HST_ANY_WITH_NO_RTTI
33 return ft1->type == ft2->type && ft1->destroy == ft2->destroy && ft1->getPtr == ft2->getPtr &&
34 ft1->move == ft2->move && ft1->copy == ft2->copy && ft1->getConstPtr == ft2->getConstPtr;
35 #else
36 return ft1->type_name == ft2->type_name && ft1->destroy == ft2->destroy && ft1->getPtr == ft2->getPtr &&
37 ft1->move == ft2->move && ft1->copy == ft2->copy && ft1->getConstPtr == ft2->getConstPtr;
38 #endif
39 }
40
41 template <typename T, template <class> class U>
UseStorage()42 bool UseStorage()
43 {
44 auto ft1 = Any::GetFunctionTable<T>();
45 Any::FunctionTable ft2 {
46 #ifndef HST_ANY_WITH_NO_RTTI
47 .type = U<T>::Type,
48 #else
49 .type_name = U<T>::TypeName,
50 #endif
51 .destroy = U<T>::Destroy,
52 .copy = U<T>::Copy,
53 .move = U<T>::Move,
54 .getPtr = U<T>::GetPtr,
55 .getConstPtr = U<T>::GetConstPtr
56 };
57 return CompareFunctionTable(ft1, &ft2);
58 }
59
60 class NonTrivialCopyable {
61 public:
NonTrivialCopyable(uint8_t a)62 explicit NonTrivialCopyable(uint8_t a) : a_(a)
63 {
64 }
NonTrivialCopyable(const NonTrivialCopyable & a)65 NonTrivialCopyable(const NonTrivialCopyable& a) : a_(a.a_)
66 {
67 }
operator =(const NonTrivialCopyable & other)68 NonTrivialCopyable& operator=(const NonTrivialCopyable& other)
69 {
70 if (this != &other) {
71 this->a_ = other.a_;
72 }
73 return *this;
74 }
75 uint8_t a_;
76 };
77
78 class NonTrivialNonThrowMove {
79 public:
NonTrivialNonThrowMove(uint8_t a)80 explicit NonTrivialNonThrowMove(uint8_t a) : a_(a)
81 {
82 }
NonTrivialNonThrowMove(const NonTrivialNonThrowMove & a)83 explicit NonTrivialNonThrowMove(const NonTrivialNonThrowMove& a) : a_(a.a_)
84 {
85 }
operator =(const NonTrivialNonThrowMove & other)86 NonTrivialNonThrowMove& operator=(const NonTrivialNonThrowMove& other)
87 {
88 if (this != &other) {
89 a_ = other.a_;
90 }
91 return *this;
92 }
NonTrivialNonThrowMove(NonTrivialNonThrowMove && t)93 NonTrivialNonThrowMove(NonTrivialNonThrowMove&& t) noexcept
94 {
95 a_ = t.a_;
96 }
operator =(NonTrivialNonThrowMove && other)97 NonTrivialNonThrowMove& operator=(NonTrivialNonThrowMove&& other)
98 {
99 a_ = other.a_;
100 return *this;
101 }
102 uint8_t a_;
103 };
104
105 HWTEST(AnyTest, testAnyUseTrivial, TestSize.Level1)
106 {
107 auto tmp = UseStorage<uint8_t, Any::TrivialStackFunctionTable>();
108 ASSERT_TRUE(tmp);
109 tmp = UseStorage<int8_t, Any::TrivialStackFunctionTable>();
110 ASSERT_TRUE(tmp);
111 tmp = UseStorage<uint16_t, Any::TrivialStackFunctionTable>();
112 ASSERT_TRUE(tmp);
113 tmp = UseStorage<int16_t, Any::TrivialStackFunctionTable>();
114 ASSERT_TRUE(tmp);
115 tmp = UseStorage<uint32_t, Any::TrivialStackFunctionTable>();
116 ASSERT_TRUE(tmp);
117 tmp = UseStorage<int32_t, Any::TrivialStackFunctionTable>();
118 ASSERT_TRUE(tmp);
119 tmp = UseStorage<uint64_t, Any::TrivialStackFunctionTable>();
120 ASSERT_TRUE(tmp);
121 tmp = UseStorage<int64_t, Any::TrivialStackFunctionTable>();
122 ASSERT_TRUE(tmp);
123 tmp = UseStorage<NonTrivialCopyable, Any::TrivialStackFunctionTable>();
124 ASSERT_FALSE(tmp);
125 }
126
127 HWTEST(AnyTest, testAnyUseStack, TestSize.Level1)
128 {
129 auto tmp = UseStorage<NonTrivialCopyable, Any::StackFunctionTable>();
130 ASSERT_FALSE(tmp);
131 tmp = UseStorage<NonTrivialNonThrowMove, Any::StackFunctionTable>();
132 ASSERT_TRUE(tmp);
133 tmp = UseStorage<std::shared_ptr<int>, Any::StackFunctionTable>();
134 ASSERT_TRUE(tmp);
135 }
136
137 HWTEST(AnyTest, testAnyUseHeap, TestSize.Level1)
138 {
139 auto tmp = UseStorage<NonTrivialCopyable, Any::HeapFunctionTable>();
140 ASSERT_TRUE(tmp);
141 }
142
143 HWTEST(AnyTest, testAnyCast, TestSize.Level1)
144 {
145 const int number = 12;
146 auto a = Any(number);
147 int* i = AnyCast<int>(&a);
148 ASSERT_TRUE(*i == number);
149 a = std::string("hello");
150 auto& ra = AnyCast<std::string&>(a);
151 ra[1] = 'o';
152 const auto& refString = AnyCast<const std::string&>(a);
153 ASSERT_STREQ(refString.c_str(), "hollo");
154 auto copyString = AnyCast<std::string>(a);
155 copyString[1] = 'l';
156 ASSERT_STREQ(refString.c_str(), "hollo");
157 ASSERT_STREQ(copyString.c_str(), "hlllo");
158
159 ASSERT_THROW(AnyCast<std::string>("test"), BadAnyCast);
160 ASSERT_THROW(AnyCast<char*>("test"), BadAnyCast);
161 }
162
163 class Star {
164 std::string name_;
165 int id_;
166
167 public:
Star(std::string name,int id)168 Star(std::string name, int id) : name_ {std::move(name)}, id_ {id}
169 {
170 }
171
operator ==(const Star & other) const172 bool operator==(const Star& other) const
173 {
174 return name_ == other.name_ && id_ == other.id_;
175 }
176 };
177
178 HWTEST(AnyTest, testAnyEmplace, TestSize.Level1)
179 {
180 Any celestial;
181 celestial.Emplace<Star>("Procyon", 2943);
182 Star star1("Procyon", 2943);
183 const auto* star = AnyCast<Star>(&celestial);
184 ASSERT_TRUE(star1 == (*star));
185
186 Any av;
187 av.Emplace<std::vector<char>>({'C', '+', '+', '1', '7'});
188 const auto* va = AnyCast<std::vector<char>>(&av);
189 std::vector<char> vector1({'C', '+', '+', '1', '7'});
190 ASSERT_TRUE(vector1 == (*va));
191 }
192
193 HWTEST(AnyTest, testMakeAny, TestSize.Level1)
194 {
195 Star star1("Procyon", 2943);
196 Any celestial = MakeAny<Star, std::string, int32_t>("Procyon", 2943);
197 ASSERT_TRUE(AnyCast<Star>(celestial) == star1);
198
199 std::vector<char> vector1({'C', '+', '+', '1', '7'});
200 Any av = MakeAny<std::vector<char>>({'C', '+', '+', '1', '7'});
201 ASSERT_TRUE(AnyCast<std::vector<char>>(av) == vector1);
202 }
203
204 HWTEST(AnyTest, testSwap, TestSize.Level1)
205 {
206 NonTrivialNonThrowMove n1(100);
207 Any a1 = n1;
208 Any a2 = 4;
209 a1.Swap(a2);
210 ASSERT_TRUE(AnyCast<int32_t>(a1) == 4);
211 ASSERT_EQ(AnyCast<NonTrivialNonThrowMove>(a2).a_, n1.a_);
212
213 a2 = "test";
214 const Star star("star", 100);
215 a1 = star;
216 a2.Swap(a1);
217 ASSERT_STREQ(AnyCast<const char*>(a1), "test");
218 ASSERT_TRUE(AnyCast<Star>(a2) == star);
219
220 std::swap(a1, a2);
221 ASSERT_STREQ(AnyCast<const char*>(a2), "test");
222 ASSERT_TRUE(AnyCast<Star>(a1) == star);
223 }
224
225 HWTEST(AnyTest, testHasValue_Reset, TestSize.Level1)
226 {
227 Any a;
228 ASSERT_FALSE(a.HasValue());
229 a = "test";
230 ASSERT_TRUE(a.HasValue());
231 a.Reset();
232 ASSERT_FALSE(a.HasValue());
233 }
234 } // namespace Test
235 } // namespace Media
236 } // namespace OHOS