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