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 return ft1->type == ft2->type && ft1->destroy == ft2->destroy && ft1->getPtr == ft2->getPtr &&
33 ft1->move == ft2->move && ft1->copy == ft2->copy && ft1->getConstPtr == ft2->getConstPtr;
34 }
35
36 template <typename T, template <class> class U>
UseStorage()37 bool UseStorage()
38 {
39 auto ft1 = Any::GetFunctionTable<T>();
40 Any::FunctionTable ft2 {
41 .type = U<T>::Type,
42 .destroy = U<T>::Destroy,
43 .copy = U<T>::Copy,
44 .move = U<T>::Move,
45 .getPtr = U<T>::GetPtr,
46 .getConstPtr = U<T>::GetConstPtr
47 };
48 return CompareFunctionTable(ft1, &ft2);
49 }
50
51 class NonTrivialCopyable {
52 public:
NonTrivialCopyable(uint8_t a)53 explicit NonTrivialCopyable(uint8_t a) : a_(a)
54 {
55 }
NonTrivialCopyable(const NonTrivialCopyable & a)56 NonTrivialCopyable(const NonTrivialCopyable& a) : a_(a.a_)
57 {
58 }
operator =(const NonTrivialCopyable & other)59 NonTrivialCopyable& operator=(const NonTrivialCopyable& other)
60 {
61 if (this != &other) {
62 this->a_ = other.a_;
63 }
64 return *this;
65 }
66 uint8_t a_;
67 };
68
69 class NonTrivialNonThrowMove {
70 public:
NonTrivialNonThrowMove(uint8_t a)71 explicit NonTrivialNonThrowMove(uint8_t a) : a_(a)
72 {
73 }
NonTrivialNonThrowMove(const NonTrivialNonThrowMove & a)74 explicit NonTrivialNonThrowMove(const NonTrivialNonThrowMove& a) : a_(a.a_)
75 {
76 }
operator =(const NonTrivialNonThrowMove & other)77 NonTrivialNonThrowMove& operator=(const NonTrivialNonThrowMove& other)
78 {
79 if (this != &other) {
80 a_ = other.a_;
81 }
82 return *this;
83 }
NonTrivialNonThrowMove(NonTrivialNonThrowMove && t)84 NonTrivialNonThrowMove(NonTrivialNonThrowMove&& t) noexcept
85 {
86 a_ = t.a_;
87 }
operator =(NonTrivialNonThrowMove && other)88 NonTrivialNonThrowMove& operator=(NonTrivialNonThrowMove&& other)
89 {
90 a_ = other.a_;
91 return *this;
92 }
93 uint8_t a_;
94 };
95
96 HWTEST(AnyTest, testAnyUseTrivial, TestSize.Level1)
97 {
98 auto tmp = UseStorage<uint8_t, Any::TrivialStackFunctionTable>();
99 ASSERT_TRUE(tmp);
100 tmp = UseStorage<int8_t, Any::TrivialStackFunctionTable>();
101 ASSERT_TRUE(tmp);
102 tmp = UseStorage<uint16_t, Any::TrivialStackFunctionTable>();
103 ASSERT_TRUE(tmp);
104 tmp = UseStorage<int16_t, Any::TrivialStackFunctionTable>();
105 ASSERT_TRUE(tmp);
106 tmp = UseStorage<uint32_t, Any::TrivialStackFunctionTable>();
107 ASSERT_TRUE(tmp);
108 tmp = UseStorage<int32_t, Any::TrivialStackFunctionTable>();
109 ASSERT_TRUE(tmp);
110 tmp = UseStorage<uint64_t, Any::TrivialStackFunctionTable>();
111 ASSERT_TRUE(tmp);
112 tmp = UseStorage<int64_t, Any::TrivialStackFunctionTable>();
113 ASSERT_TRUE(tmp);
114 tmp = UseStorage<NonTrivialCopyable, Any::TrivialStackFunctionTable>();
115 ASSERT_FALSE(tmp);
116 }
117
118 HWTEST(AnyTest, testAnyUseStack, TestSize.Level1)
119 {
120 auto tmp = UseStorage<NonTrivialCopyable, Any::StackFunctionTable>();
121 ASSERT_FALSE(tmp);
122 tmp = UseStorage<NonTrivialNonThrowMove, Any::StackFunctionTable>();
123 ASSERT_TRUE(tmp);
124 tmp = UseStorage<std::shared_ptr<int>, Any::StackFunctionTable>();
125 ASSERT_TRUE(tmp);
126 }
127
128 HWTEST(AnyTest, testAnyUseHeap, TestSize.Level1)
129 {
130 auto tmp = UseStorage<NonTrivialCopyable, Any::HeapFunctionTable>();
131 ASSERT_TRUE(tmp);
132 }
133
134 HWTEST(AnyTest, testAnyCast, TestSize.Level1)
135 {
136 const int number = 12;
137 auto a = Any(number);
138 int* i = AnyCast<int>(&a);
139 ASSERT_TRUE(*i == number);
140 a = std::string("hello");
141 auto& ra = AnyCast<std::string&>(a);
142 ra[1] = 'o';
143 const auto& refString = AnyCast<const std::string&>(a);
144 ASSERT_STREQ(refString.c_str(), "hollo");
145 auto copyString = AnyCast<std::string>(a);
146 copyString[1] = 'l';
147 ASSERT_STREQ(refString.c_str(), "hollo");
148 ASSERT_STREQ(copyString.c_str(), "hlllo");
149
150 ASSERT_THROW(AnyCast<std::string>("test"), BadAnyCast);
151 ASSERT_THROW(AnyCast<char*>("test"), BadAnyCast);
152 }
153
154 class Star {
155 std::string name_;
156 int id_;
157
158 public:
Star(std::string name,int id)159 Star(std::string name, int id) : name_ {std::move(name)}, id_ {id}
160 {
161 }
162
operator ==(const Star & other) const163 bool operator==(const Star& other) const
164 {
165 return name_ == other.name_ && id_ == other.id_;
166 }
167 };
168
169 HWTEST(AnyTest, testAnyEmplace, TestSize.Level1)
170 {
171 Any celestial;
172 celestial.Emplace<Star>("Procyon", 2943);
173 Star star1("Procyon", 2943);
174 const auto* star = AnyCast<Star>(&celestial);
175 ASSERT_TRUE(star1 == (*star));
176
177 Any av;
178 av.Emplace<std::vector<char>>({'C', '+', '+', '1', '7'});
179 const auto* va = AnyCast<std::vector<char>>(&av);
180 std::vector<char> vector1({'C', '+', '+', '1', '7'});
181 ASSERT_TRUE(vector1 == (*va));
182 }
183
184 HWTEST(AnyTest, testMakeAny, TestSize.Level1)
185 {
186 Star star1("Procyon", 2943);
187 Any celestial = MakeAny<Star, std::string, int32_t>("Procyon", 2943);
188 ASSERT_TRUE(AnyCast<Star>(celestial) == star1);
189
190 std::vector<char> vector1({'C', '+', '+', '1', '7'});
191 Any av = MakeAny<std::vector<char>>({'C', '+', '+', '1', '7'});
192 ASSERT_TRUE(AnyCast<std::vector<char>>(av) == vector1);
193 }
194
195 HWTEST(AnyTest, testType, TestSize.Level1)
196 {
197 Any test = "test";
198 ASSERT_TRUE(test.Type() == typeid(const char*));
199 ASSERT_NE(test.Type(), typeid(char*));
200 ASSERT_NE(test.Type(), typeid(char*));
201 }
202
203 HWTEST(AnyTest, testSwap, TestSize.Level1)
204 {
205 NonTrivialNonThrowMove n1(100);
206 Any a1 = n1;
207 Any a2 = 4;
208 a1.Swap(a2);
209 ASSERT_TRUE(AnyCast<int32_t>(a1) == 4);
210 ASSERT_EQ(AnyCast<NonTrivialNonThrowMove>(a2).a_, n1.a_);
211
212 a2 = "test";
213 const Star star("star", 100);
214 a1 = star;
215 a2.Swap(a1);
216 ASSERT_STREQ(AnyCast<const char*>(a1), "test");
217 ASSERT_TRUE(AnyCast<Star>(a2) == star);
218
219 std::swap(a1, a2);
220 ASSERT_STREQ(AnyCast<const char*>(a2), "test");
221 ASSERT_TRUE(AnyCast<Star>(a1) == star);
222 }
223
224 HWTEST(AnyTest, testHasValue_Reset, TestSize.Level1)
225 {
226 Any a;
227 ASSERT_FALSE(a.HasValue());
228 a = "test";
229 ASSERT_TRUE(a.HasValue());
230 a.Reset();
231 ASSERT_FALSE(a.HasValue());
232 }
233 } // namespace Test
234 } // namespace Media
235 } // namespace OHOS