1// Copyright (C) 2011 The Libphonenumber Authors
2//
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// Author: Philippe Liard
16
17#include "phonenumbers/stringutil.h"
18
19#include <string>
20#include <vector>
21
22#include <gtest/gtest.h>
23
24using std::string;
25using std::vector;
26
27namespace i18n {
28namespace phonenumbers {
29
30// Test operator+(const string&, int).
31TEST(StringUtilTest, OperatorPlus) {
32  EXPECT_EQ("hello10", string("hello") + 10);
33}
34
35// Test SimpleItoa implementation.
36TEST(StringUtilTest, SimpleItoa) {
37  EXPECT_EQ("10", SimpleItoa(10));
38}
39
40TEST(StringUtilTest, HasPrefixString) {
41  EXPECT_TRUE(HasPrefixString("hello world", "hello"));
42  EXPECT_FALSE(HasPrefixString("hello world", "hellO"));
43}
44
45TEST(StringUtilTest, FindNthWithEmptyString) {
46  EXPECT_EQ(string::npos, FindNth("", 'a', 1));
47}
48
49TEST(StringUtilTest, FindNthWithNNegative) {
50  EXPECT_EQ(string::npos, FindNth("hello world", 'o', -1));
51}
52
53TEST(StringUtilTest, FindNthWithNTooHigh) {
54  EXPECT_EQ(string::npos, FindNth("hello world", 'o', 3));
55}
56
57TEST(StringUtilTest, FindNth) {
58  EXPECT_EQ(7U, FindNth("hello world", 'o', 2));
59}
60
61TEST(StringUtilTest, SplitStringUsingWithEmptyString) {
62  vector<string> result;
63  SplitStringUsing("", ':', &result);
64  EXPECT_EQ(0U, result.size());
65}
66
67TEST(StringUtilTest, SplitStringUsing) {
68  vector<string> result;
69  SplitStringUsing(":hello:world:", ':', &result);
70  EXPECT_EQ(2U, result.size());
71  EXPECT_EQ("hello", result[0]);
72  EXPECT_EQ("world", result[1]);
73}
74
75TEST(StringUtilTest, SplitStringUsingIgnoresEmptyToken) {
76  vector<string> result;
77  SplitStringUsing("hello::world", ':', &result);
78  EXPECT_EQ(2U, result.size());
79  EXPECT_EQ("hello", result[0]);
80  EXPECT_EQ("world", result[1]);
81}
82
83// Test TryStripPrefixString.
84TEST(StringUtilTest, TryStripPrefixString) {
85  string s;
86
87  EXPECT_TRUE(TryStripPrefixString("hello world", "hello", &s));
88  EXPECT_EQ(" world", s);
89  s.clear();
90
91  EXPECT_FALSE(TryStripPrefixString("hello world", "helloa", &s));
92  s.clear();
93
94  EXPECT_TRUE(TryStripPrefixString("hello world", "", &s));
95  EXPECT_EQ("hello world", s);
96  s.clear();
97
98  EXPECT_FALSE(TryStripPrefixString("", "hello", &s));
99  s.clear();
100}
101
102// Test HasSuffixString.
103TEST(StringUtilTest, HasSuffixString) {
104  EXPECT_TRUE(HasSuffixString("hello world", "hello world"));
105  EXPECT_TRUE(HasSuffixString("hello world", "world"));
106  EXPECT_FALSE(HasSuffixString("hello world", "world!"));
107  EXPECT_TRUE(HasSuffixString("hello world", ""));
108  EXPECT_FALSE(HasSuffixString("", "hello"));
109}
110
111// Test safe_strto32.
112TEST(StringUtilTest, safe_strto32) {
113  int32 n;
114
115  safe_strto32("0", &n);
116  EXPECT_EQ(0, n);
117
118  safe_strto32("16", &n);
119  EXPECT_EQ(16, n);
120
121  safe_strto32("2147483647", &n);
122  EXPECT_EQ(2147483647, n);
123
124  safe_strto32("-2147483648", &n);
125  EXPECT_EQ(-2147483648LL, n);
126}
127
128// Test safe_strtou64.
129TEST(StringUtilTest, safe_strtou64) {
130  uint64 n;
131
132  safe_strtou64("0", &n);
133  EXPECT_EQ(0U, n);
134
135  safe_strtou64("16", &n);
136  EXPECT_EQ(16U, n);
137
138  safe_strtou64("18446744073709551615", &n);
139  EXPECT_EQ(18446744073709551615ULL, n);
140}
141
142// Test strrmm.
143TEST(StringUtilTest, strrmm) {
144  string input("hello");
145
146  strrmm(&input, "");
147  EXPECT_EQ(input, input);
148
149  string empty;
150  strrmm(&empty, "");
151  EXPECT_EQ("", empty);
152
153  strrmm(&empty, "aa");
154  EXPECT_EQ("", empty);
155
156  strrmm(&input, "h");
157  EXPECT_EQ("ello", input);
158
159  strrmm(&input, "el");
160  EXPECT_EQ("o", input);
161}
162
163// Test GlobalReplaceSubstring.
164TEST(StringUtilTest, GlobalReplaceSubstring) {
165  string input("hello");
166
167  EXPECT_EQ(0, GlobalReplaceSubstring("aaa", "", &input));
168  EXPECT_EQ("hello", input);
169
170  EXPECT_EQ(0, GlobalReplaceSubstring("", "aaa", &input));
171  EXPECT_EQ("hello", input);
172
173  EXPECT_EQ(0, GlobalReplaceSubstring("", "", &input));
174  EXPECT_EQ("hello", input);
175
176  EXPECT_EQ(0, GlobalReplaceSubstring("aaa", "bbb", &input));
177  EXPECT_EQ("hello", input);
178
179  EXPECT_EQ(1, GlobalReplaceSubstring("o", "o world", &input));
180  ASSERT_EQ("hello world", input);
181
182  EXPECT_EQ(2, GlobalReplaceSubstring("o", "O", &input));
183  EXPECT_EQ("hellO wOrld", input);
184}
185
186// Test the StringHolder class.
187TEST(StringUtilTest, StringHolder) {
188  // Test with C string.
189  static const char cstring[] = "aaa";
190  StringHolder sh1(cstring);
191  EXPECT_EQ(cstring, sh1.GetCString());
192
193  // Test with absl::string_view.
194  string s = "aaa";
195  StringHolder sh2(s);
196  EXPECT_EQ(cstring, sh2.GetString());
197
198  // Test GetLength().
199  string s2 = "hello";
200  StringHolder sh3(s2);
201  EXPECT_EQ(5U, sh3.Length());
202
203  // Test with uint64.
204  StringHolder sh4(42);
205  static const char cstring2[] = "42";;
206  EXPECT_EQ(cstring2, sh4.GetString());
207}
208
209// Test the operator+=(string& lhs, const StringHolder& rhs) implementation.
210TEST(StringUtilTest, OperatorPlusEquals) {
211  // Test with a const char* string to append.
212  string s = "h";
213  static const char append1[] = "ello";
214  s += StringHolder(append1);   // force StringHolder usage
215
216  EXPECT_EQ("hello", s);
217
218  // Test with a std::string to append.
219  s = "h";
220  string append2 = "ello";
221  s += StringHolder(append2);   // force StringHolder usage
222
223  EXPECT_EQ("hello", s);
224}
225
226// Test the StrCat implementations
227TEST(StringUtilTest, StrCat) {
228  string s;
229
230  // Test with 2 arguments.
231  s = StrCat("a", "b");
232  EXPECT_EQ("ab", s);
233
234  // Test with 3 arguments.
235  s = StrCat("a", "b", "c");
236  EXPECT_EQ("abc", s);
237
238  // Test with 4 arguments.
239  s = StrCat("a", "b", "c", "d");
240  EXPECT_EQ("abcd", s);
241
242  // Test with 5 arguments.
243  s = StrCat("a", "b", "c", "d", "e");
244  EXPECT_EQ("abcde", s);
245
246  // Test with 6 arguments.
247  s = StrCat("a", "b", "c", "d", "e", "f");
248  EXPECT_EQ("abcdef", s);
249
250  // Test with 7 arguments.
251  s = StrCat("a", "b", "c", "d", "e", "f", "g");
252  EXPECT_EQ("abcdefg", s);
253
254  // Test with 8 arguments.
255  s = StrCat("a", "b", "c", "d", "e", "f", "g", "h");
256  EXPECT_EQ("abcdefgh", s);
257
258  // Test with 9 arguments.
259  s = StrCat("a", "b", "c", "d", "e", "f", "g", "h", "i");
260  EXPECT_EQ("abcdefghi", s);
261
262  // Test with 11 arguments.
263  s = StrCat("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k");
264  EXPECT_EQ("abcdefghijk", s);
265}
266
267// Test the StrAppend implementations.
268TEST(StringUtilTest, StrAppend) {
269  string s;
270
271  // Test with 1 argument.
272  StrAppend(&s, "a");
273  ASSERT_EQ("a", s);
274
275  // Test with 2 arguments.
276  StrAppend(&s, "b", "c");
277  ASSERT_EQ("abc", s);
278
279  // Test with 3 arguments.
280  StrAppend(&s, "d", "e", "f");
281  ASSERT_EQ("abcdef", s);
282
283  // Test with 4 arguments.
284  StrAppend(&s, "g", "h", "i", "j");
285  ASSERT_EQ("abcdefghij", s);
286
287  // Test with 5 arguments.
288  StrAppend(&s, "k", "l", "m", "n", "o");
289  ASSERT_EQ("abcdefghijklmno", s);
290
291  // Test with int argument.
292  StrAppend(&s, 42);
293  ASSERT_EQ("abcdefghijklmno42", s);
294}
295
296}  // namespace phonenumbers
297}  // namespace i18n
298