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