1 /* 2 * Copyright (c) 2023 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 #include "traits.h" 16 17 #include <gtest/gtest.h> 18 using namespace testing::ext; 19 namespace OHOS::Test { 20 class TraitsTest : public testing::Test { 21 public: 22 class From { 23 public: From()24 From() {} 25 }; 26 class Convertible { 27 public: 28 // Convertible is auto convert type, do not add explicit to stop the type convert. Convertible(const From &)29 Convertible(const From &) {}; Convertible()30 Convertible() {} Convertible(Convertible &&)31 Convertible(Convertible &&) noexcept {}; operator =(Convertible &&)32 Convertible &operator=(Convertible &&) noexcept 33 { 34 return *this; 35 } 36 operator From() 37 { 38 return From(); 39 } 40 }; SetUpTestCase(void)41 static void SetUpTestCase(void){}; TearDownTestCase(void)42 static void TearDownTestCase(void){}; SetUp()43 void SetUp(){}; TearDown()44 void TearDown() {} 45 }; 46 47 /** 48 * @tc.name: same_index_of_v 49 * @tc.desc: 50 * @tc.type: FUNC 51 * @tc.require: 52 * @tc.author: Sven Wang 53 */ 54 HWTEST_F(TraitsTest, same_index_of_v, TestSize.Level0) 55 { 56 auto index = Traits::same_index_of_v<int32_t, int32_t, double, std::vector<uint8_t>>; 57 ASSERT_EQ(index, 0); 58 index = Traits::same_index_of_v<std::string, int32_t, double, std::vector<uint8_t>>; 59 ASSERT_EQ(index, 3); 60 index = Traits::same_index_of_v<std::string>; 61 ASSERT_EQ(index, 0); 62 } 63 64 /** 65 * @tc.name: same_in_v 66 * @tc.desc: 67 * @tc.type: FUNC 68 * @tc.require: 69 * @tc.author: Sven Wang 70 */ 71 HWTEST_F(TraitsTest, same_in_v, TestSize.Level0) 72 { 73 auto exist = Traits::same_in_v<int32_t, int32_t, double, std::vector<uint8_t>>; 74 ASSERT_TRUE(exist); 75 exist = Traits::same_in_v<std::string, int32_t, double, std::vector<uint8_t>>; 76 ASSERT_FALSE(exist); 77 exist = Traits::same_in_v<std::string>; 78 ASSERT_FALSE(exist); 79 } 80 81 /** 82 * @tc.name: convertible_index_of_v 83 * @tc.desc: 84 * @tc.type: FUNC 85 * @tc.require: 86 * @tc.author: Sven Wang 87 */ 88 HWTEST_F(TraitsTest, convertible_index_of_v, TestSize.Level0) 89 { 90 auto index = Traits::convertible_index_of_v<int32_t, int16_t, double, std::vector<uint8_t>>; 91 ASSERT_EQ(index, 0); 92 index = Traits::convertible_index_of_v<std::string, int16_t, const char *, std::vector<uint8_t>>; 93 ASSERT_EQ(index, 1); 94 index = Traits::convertible_index_of_v<std::string, int16_t, std::vector<uint8_t>>; 95 ASSERT_EQ(index, 2); 96 index = Traits::convertible_index_of_v<std::string>; 97 ASSERT_EQ(index, 0); 98 } 99 100 /** 101 * @tc.name: convertible_in_v 102 * @tc.desc: 103 * @tc.type: FUNC 104 * @tc.require: 105 * @tc.author: Sven Wang 106 */ 107 HWTEST_F(TraitsTest, convertible_in_v, TestSize.Level0) 108 { 109 auto convertible = Traits::convertible_in_v<int32_t, int16_t, double, std::vector<uint8_t>>; 110 ASSERT_TRUE(convertible); 111 convertible = Traits::convertible_in_v<std::string, int16_t, const char *, std::vector<uint8_t>>; 112 ASSERT_TRUE(convertible); 113 convertible = Traits::convertible_in_v<std::string, int16_t, std::vector<uint8_t>>; 114 ASSERT_FALSE(convertible); 115 convertible = Traits::convertible_in_v<std::string>; 116 ASSERT_FALSE(convertible); 117 } 118 119 /** 120 * @tc.name: variant_size_of_v 121 * @tc.desc: 122 * @tc.type: FUNC 123 * @tc.require: 124 * @tc.author: Sven Wang 125 */ 126 HWTEST_F(TraitsTest, variant_size_of_v, TestSize.Level0) 127 { 128 std::variant<std::monostate, int64_t, bool, double, std::string, std::vector<uint8_t>> value; 129 auto size = Traits::variant_size_of_v<decltype(value)>; 130 ASSERT_EQ(size, 6); 131 std::variant<int64_t> value2; 132 size = Traits::variant_size_of_v<decltype(value2)>; 133 ASSERT_EQ(size, 1); 134 } 135 136 /** 137 * @tc.name: variant_index_of_v 138 * @tc.desc: 139 * @tc.type: FUNC 140 * @tc.require: 141 * @tc.author: Sven Wang 142 */ 143 HWTEST_F(TraitsTest, variant_index_of_v, TestSize.Level0) 144 { 145 std::variant<std::monostate, int64_t, bool, double, std::string, std::vector<uint8_t>> value; 146 auto index = Traits::variant_index_of_v<std::monostate, decltype(value)>; 147 ASSERT_EQ(index, 0); 148 index = Traits::variant_index_of_v<int64_t, decltype(value)>; 149 ASSERT_EQ(index, 1); 150 index = Traits::variant_index_of_v<bool, decltype(value)>; 151 ASSERT_EQ(index, 2); 152 index = Traits::variant_index_of_v<double, decltype(value)>; 153 ASSERT_EQ(index, 3); 154 index = Traits::variant_index_of_v<std::string, decltype(value)>; 155 ASSERT_EQ(index, 4); 156 index = Traits::variant_index_of_v<std::vector<uint8_t>, decltype(value)>; 157 ASSERT_EQ(index, 5); 158 index = Traits::variant_index_of_v<char *, decltype(value)>; 159 ASSERT_EQ(index, 6); 160 } 161 162 /** 163 * @tc.name: get_if_same_type 164 * @tc.desc: 165 * @tc.type: FUNC 166 * @tc.require: 167 * @tc.author: Sven Wang 168 */ 169 HWTEST_F(TraitsTest, get_if_same_type, TestSize.Level0) 170 { 171 // 1. When the _Tp is a type in the ..._Types, the get_if is equal to the std::get_if. 172 std::variant<std::monostate, int64_t, double, const char *> value; 173 auto *nil = Traits::get_if<std::monostate>(&value); 174 ASSERT_NE(nil, nullptr); 175 auto *number = Traits::get_if<int64_t>(&value); 176 ASSERT_EQ(number, nullptr); 177 value = int64_t(1); 178 number = Traits::get_if<int64_t>(&value); 179 ASSERT_NE(number, nullptr); 180 ASSERT_EQ(*number, 1); 181 value = 1.5; 182 auto *dVal = Traits::get_if<double>(&value); 183 ASSERT_NE(dVal, nullptr); 184 ASSERT_DOUBLE_EQ(*dVal, 1.5); 185 value = "test case"; 186 auto *charPtr = Traits::get_if<const char *>(&value); 187 ASSERT_NE(charPtr, nullptr); 188 ASSERT_TRUE(strcmp(*charPtr, "test case") == 0); 189 } 190 /** 191 * @tc.name: get_if_convertible_type 192 * @tc.desc: 193 * @tc.type: FUNC 194 * @tc.require: 195 * @tc.author: Sven Wang 196 */ 197 HWTEST_F(TraitsTest, get_if_convertible_type, TestSize.Level0) 198 { 199 // 2. When the _Tp is not a type in the ..._Types but someone in the ...Types can convert to _Tp implicitly, 200 // the get_if will return it. 201 std::variant<std::monostate, int64_t, double, const char *, From> value; 202 value = int64_t(1); 203 auto *fVal = Traits::get_if<double>(&value); 204 ASSERT_EQ(fVal, nullptr); 205 206 value = "test case"; 207 auto *strVal = Traits::get_if<std::string>(&value); 208 ASSERT_NE(strVal, nullptr); 209 ASSERT_TRUE(strcmp(*strVal, "test case") == 0); 210 211 value = From(); 212 auto *toVal = Traits::get_if<Convertible>(&value); 213 ASSERT_NE(toVal, nullptr); 214 215 std::variant<std::monostate, int64_t, double, const char *, Convertible> val2; 216 val2 = Convertible(); 217 auto *fromVal = Traits::get_if<From>(&val2); 218 ASSERT_NE(fromVal, nullptr); 219 } 220 221 /** 222 * @tc.name: get_if_invalid_type 223 * @tc.desc: 224 * @tc.type: FUNC 225 * @tc.require: 226 * @tc.author: Sven Wang 227 */ 228 HWTEST_F(TraitsTest, get_if_invalid_type, TestSize.Level0) 229 { 230 // 3. When the _Tp is not a type in the ..._Types and can't convert, the get_if will return nullptr. 231 std::variant<std::monostate, int64_t, double, const char *> value; 232 auto *unknown = Traits::get_if<std::vector<uint8_t>>(&value); 233 ASSERT_EQ(unknown, nullptr); 234 value = int64_t(9); 235 unknown = Traits::get_if<std::vector<uint8_t>>(&value); 236 ASSERT_EQ(unknown, nullptr); 237 value = 1.5; 238 unknown = Traits::get_if<std::vector<uint8_t>>(&value); 239 ASSERT_EQ(unknown, nullptr); 240 value = "test case"; 241 unknown = Traits::get_if<std::vector<uint8_t>>(&value); 242 ASSERT_EQ(unknown, nullptr); 243 } 244 } // namespace OHOS::Test 245