1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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 <gtest/gtest.h>
16 #include <random>
17 #include <string>
18 #include "string_utils.h"
19 
20 namespace {
21 using testing::ext::TestSize;
22 constexpr int ROUNDS = 20;
23 constexpr int STR_MAX_SIZE = 10;
24 constexpr char RANDOM_CHAR_TABLE[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
25 constexpr long RANDOM_CHAR_NUMBER = std::size(RANDOM_CHAR_TABLE) - 1;
26 
27 class StringUtilsTest : public ::testing::Test {
28     std::mt19937 gen_;
29 
30 protected:
31     void SetUp() override {}
32 
33     void TearDown() override {}
34 
RandomInt(int a, int b)35     int RandomInt(int a, int b)
36     {
37         std::uniform_int_distribution<int> distrib(a, b);
38         return distrib(gen_);
39     }
40 
RandomChar()41     char RandomChar()
42     {
43         return RANDOM_CHAR_TABLE[RandomInt(0, RANDOM_CHAR_NUMBER - 1)];
44     }
45 
RandomString(int len)46     std::string RandomString(int len)
47     {
48         std::string str;
49         str.reserve(len);
50         for (int i = 0; i < len; i++) {
51             str.push_back(RandomChar());
52         }
53         return str;
54     }
55 };
56 
57 /*
58  * @tc.name: EndsWithNormal
59  * @tc.desc: test StringUtils::EndsWith with normal case.
60  * @tc.type: FUNC
61  */
HWTEST_F(StringUtilsTest, EndsWithNormal, TestSize.Level1)62 HWTEST_F(StringUtilsTest, EndsWithNormal, TestSize.Level1)
63 {
64     std::string str = "abbcccdefgh.txt";
65     std::string ext = ".txt";
66     EXPECT_TRUE(StringUtils::EndsWith(str, ext));
67     EXPECT_TRUE(StringUtils::EndsWith(str, str));
68     EXPECT_TRUE(StringUtils::EndsWith(ext, ext));
69 }
70 
71 /*
72  * @tc.name: EndsWithFalse
73  * @tc.desc: test StringUtils::EndsWith with false case.
74  * @tc.type: FUNC
75  */
HWTEST_F(StringUtilsTest, EndsWithFalse, TestSize.Level1)76 HWTEST_F(StringUtilsTest, EndsWithFalse, TestSize.Level1)
77 {
78     std::string str = "abbcccdefgh.txt";
79     std::string ext = "txt";
80     EXPECT_FALSE(StringUtils::EndsWith(str, +"."));
81     EXPECT_FALSE(StringUtils::EndsWith(ext, str));
82 }
83 
84 /*
85  * @tc.name: StartsWithNormal
86  * @tc.desc: test StringUtils::StartsWith with normal case.
87  * @tc.type: FUNC
88  */
HWTEST_F(StringUtilsTest, StartsWithNormal, TestSize.Level1)89 HWTEST_F(StringUtilsTest, StartsWithNormal, TestSize.Level1)
90 {
91     std::string str = "abbcccdefgh.txt";
92     std::string pre = "abb";
93     EXPECT_TRUE(StringUtils::StartsWith(str, pre));
94     EXPECT_TRUE(StringUtils::StartsWith(str, "a"));
95     EXPECT_TRUE(StringUtils::StartsWith(str, "ab"));
96 }
97 
98 /*
99  * @tc.name: StartsWithFalse
100  * @tc.desc: test StringUtils::StartsWith with false case.
101  * @tc.type: FUNC
102  */
HWTEST_F(StringUtilsTest, StartsWithFalse, TestSize.Level1)103 HWTEST_F(StringUtilsTest, StartsWithFalse, TestSize.Level1)
104 {
105     std::string str = "abbcccdefgh.txt";
106     std::string pre = "abb";
107     EXPECT_FALSE(StringUtils::StartsWith(str, "b"));
108     EXPECT_FALSE(StringUtils::StartsWith(str, "bb"));
109     EXPECT_FALSE(StringUtils::StartsWith(str, "bbc"));
110 }
111 
112 /*
113  * @tc.name: StartsWithRandomized
114  * @tc.desc: test StringUtils::StartsWith with random input.
115  * @tc.type: FUNC
116  */
HWTEST_F(StringUtilsTest, StartsWithRandomize, TestSize.Level1)117 HWTEST_F(StringUtilsTest, StartsWithRandomize, TestSize.Level1)
118 {
119     for (int i = 0; i < ROUNDS; i++) {
120         std::string str = RandomString(STR_MAX_SIZE);
121         std::string part = str.substr(0, RandomInt(1, static_cast<int>(str.size())));
122         EXPECT_TRUE(StringUtils::StartsWith(str, part));
123 
124         std::string target = RandomString(RandomInt(1, STR_MAX_SIZE));
125         bool isPrefix = (str.substr(0, target.size()) == target);
126         EXPECT_EQ(StringUtils::StartsWith(str, target), isPrefix);
127     }
128 }
129 
130 /*
131  * @tc.name: ContainsNormal
132  * @tc.desc: test StringUtils::Contains with normal input.
133  * @tc.type: FUNC
134  */
HWTEST_F(StringUtilsTest, ContainsNormal, TestSize.Level1)135 HWTEST_F(StringUtilsTest, ContainsNormal, TestSize.Level1)
136 {
137     std::string str = "abbcccdefgh.txt";
138     std::string target = "de";
139     EXPECT_TRUE(StringUtils::Contains(str, target));
140     EXPECT_TRUE(StringUtils::Contains(str, "a"));
141     EXPECT_TRUE(StringUtils::Contains(str, "b"));
142     EXPECT_TRUE(StringUtils::Contains(str, "c"));
143     EXPECT_TRUE(StringUtils::Contains(str, "t"));
144     EXPECT_TRUE(StringUtils::Contains(str, "txt"));
145 }
146 
147 /*
148  * @tc.name: ContainsNormal
149  * @tc.desc: test StringUtils::Contains with false case.
150  * @tc.type: FUNC
151  */
HWTEST_F(StringUtilsTest, ContainsFalse, TestSize.Level1)152 HWTEST_F(StringUtilsTest, ContainsFalse, TestSize.Level1)
153 {
154     std::string str = "abbcccdefgh.txt";
155     std::string target = "de";
156     EXPECT_FALSE(StringUtils::Contains(str, target + "."));
157     EXPECT_FALSE(StringUtils::Contains(str, "a."));
158     EXPECT_FALSE(StringUtils::Contains(str, "b."));
159     EXPECT_FALSE(StringUtils::Contains(str, "c."));
160     EXPECT_FALSE(StringUtils::Contains(str, "t."));
161     EXPECT_FALSE(StringUtils::Contains(str, "txt."));
162 }
163 
164 /*
165  * @tc.name: ContainsRandomize
166  * @tc.desc: test StringUtils::Contains with random input.
167  * @tc.type: FUNC
168  */
HWTEST_F(StringUtilsTest, ContainsRandomize, TestSize.Level1)169 HWTEST_F(StringUtilsTest, ContainsRandomize, TestSize.Level1)
170 {
171     for (int i = 0; i < ROUNDS; i++) {
172         std::string str = RandomString(STR_MAX_SIZE);
173         std::string part = str.substr(RandomInt(1, static_cast<int>(str.size())));
174         EXPECT_TRUE(StringUtils::Contains(str, part));
175 
176         std::string target = RandomString(RandomInt(1, static_cast<int>(str.size())));
177         bool isContains = (str.find(target) != std::string::npos);
178         EXPECT_EQ(StringUtils::Contains(str, target), isContains);
179     }
180 }
181 
182 /*
183  * @tc.name: StripNormal
184  * @tc.desc: test StringUtils::Strip with normal input.
185  * @tc.type: FUNC
186  */
HWTEST_F(StringUtilsTest, StripNormal, TestSize.Level1)187 HWTEST_F(StringUtilsTest, StripNormal, TestSize.Level1)
188 {
189     std::string str = "abbcccdefgh.txt";
190     EXPECT_EQ(StringUtils::Strip(str + " "), str);
191     EXPECT_EQ(StringUtils::Strip(" " + str), str);
192     EXPECT_EQ(StringUtils::Strip(str + "\t"), str);
193     EXPECT_EQ(StringUtils::Strip("\t" + str), str);
194     EXPECT_EQ(StringUtils::Strip(str + "\n"), str);
195     EXPECT_EQ(StringUtils::Strip("\n" + str), str);
196 }
197 
198 /*
199  * @tc.name: StripRandomize
200  * @tc.desc: test StringUtils::Strip with random input.
201  * @tc.type: FUNC
202  */
HWTEST_F(StringUtilsTest, StripRandomize, TestSize.Level1)203 HWTEST_F(StringUtilsTest, StripRandomize, TestSize.Level1)
204 {
205     for (int i = 0; i < ROUNDS; i++) {
206         std::string str = RandomString(STR_MAX_SIZE);
207         std::string original = str;
208         int leftPadding = RandomInt(0, static_cast<int>(str.size()));
209         if (leftPadding > 0) {
210             str = std::string(leftPadding, ' ') + str;
211         }
212 
213         int rightPadding = RandomInt(0, static_cast<int>(str.size()));
214         if (rightPadding > 0) {
215             str += std::string(rightPadding, ' ');
216         }
217         EXPECT_EQ(StringUtils::Strip(str), original);
218     }
219 }
220 
221 /*
222  * @tc.name: JoinNormal
223  * @tc.desc: test StringUtils::Join with normal input.
224  * @tc.type: FUNC
225  */
HWTEST_F(StringUtilsTest, JoinNormal, TestSize.Level1)226 HWTEST_F(StringUtilsTest, JoinNormal, TestSize.Level1)
227 {
228     std::vector<std::string> parts = {"a", "bb", "ccc", "dddd"};
229     std::string joined;
230     for (auto& str : parts) {
231         joined += str;
232         joined += " ";
233     }
234     joined.pop_back();
235     EXPECT_EQ(StringUtils::Join(parts, " "), joined);
236 }
237 
238 /*
239  * @tc.name: JoinRandomize
240  * @tc.desc: test StringUtils::Join with random input.
241  * @tc.type: FUNC
242  */
HWTEST_F(StringUtilsTest, JoinRandomize, TestSize.Level1)243 HWTEST_F(StringUtilsTest, JoinRandomize, TestSize.Level1)
244 {
245     for (int i = 0; i < ROUNDS; i++) {
246         std::vector<std::string> parts;
247         for (int j = 0; j < STR_MAX_SIZE; j++) {
248             parts.push_back(RandomString(RandomInt(1, STR_MAX_SIZE)));
249         }
250         std::string joined;
251         for (auto& str : parts) {
252             joined += str;
253             joined += " ";
254         }
255         joined.pop_back();
256         EXPECT_EQ(StringUtils::Join(parts, " "), joined);
257     }
258 }
259 
260 /*
261  * @tc.name: SplitNormal
262  * @tc.desc: test StringUtils::Split with normal input.
263  * @tc.type: FUNC
264  */
HWTEST_F(StringUtilsTest, SplitNormal, TestSize.Level1)265 HWTEST_F(StringUtilsTest, SplitNormal, TestSize.Level1)
266 {
267     std::vector<std::string> parts = {"a", "bb", "ccc", "dddd"};
268     std::string joined;
269     for (auto& str : parts) {
270         joined += str;
271         joined += " ";
272     }
273     joined.pop_back();
274     EXPECT_EQ(StringUtils::Split(joined, " "), parts);
275 }
276 
277 /*
278  * @tc.name: SplitRandomize
279  * @tc.desc: test StringUtils::Split with random input.
280  * @tc.type: FUNC
281  */
HWTEST_F(StringUtilsTest, SplitRandomize, TestSize.Level1)282 HWTEST_F(StringUtilsTest, SplitRandomize, TestSize.Level1)
283 {
284     for (int i = 0; i < ROUNDS; i++) {
285         std::vector<std::string> parts;
286         for (int j = 0; j < STR_MAX_SIZE; j++) {
287             parts.push_back(RandomString(RandomInt(1, STR_MAX_SIZE)));
288         }
289         std::string joined;
290         for (auto& str : parts) {
291             joined += str;
292             joined += " ";
293         }
294         EXPECT_EQ(StringUtils::Split(joined, " "), parts);
295         joined.pop_back();
296         EXPECT_EQ(StringUtils::Split(joined, " "), parts);
297     }
298 }
299 } // namespace