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