1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <fbl/string_piece.h>
6 
7 #include <fbl/algorithm.h>
8 #include <unittest/unittest.h>
9 
10 #include <utility>
11 
12 namespace {
13 
empty_string_test()14 bool empty_string_test() {
15     BEGIN_TEST;
16 
17     fbl::StringPiece empty;
18 
19     EXPECT_NULL(empty.data());
20 
21     EXPECT_EQ(0u, empty.length());
22     EXPECT_EQ(0u, empty.size());
23     EXPECT_TRUE(empty.empty());
24 
25     EXPECT_NULL(empty.begin());
26     EXPECT_NULL(empty.end());
27     EXPECT_NULL(empty.cbegin());
28     EXPECT_NULL(empty.cend());
29 
30     END_TEST;
31 }
32 
non_empty_string_test()33 bool non_empty_string_test() {
34     BEGIN_TEST;
35 
36     const char data[] = "abc";
37 
38     fbl::StringPiece str1(data);
39 
40     EXPECT_EQ(data, str1.data());
41 
42     EXPECT_EQ(3u, str1.length());
43     EXPECT_EQ(3u, str1.size());
44     EXPECT_FALSE(str1.empty());
45 
46     EXPECT_EQ(data, str1.begin());
47     EXPECT_EQ(data + 3u, str1.end());
48     EXPECT_EQ(data, str1.cbegin());
49     EXPECT_EQ(data + 3u, str1.cend());
50 
51     EXPECT_EQ('b', str1[1u]);
52 
53     fbl::StringPiece str2(data + 1u, 2u);
54 
55     EXPECT_EQ(data + 1u, str2.data());
56 
57     EXPECT_EQ(2u, str2.length());
58     EXPECT_EQ(2u, str2.size());
59     EXPECT_FALSE(str2.empty());
60 
61     EXPECT_EQ(data + 1u, str2.begin());
62     EXPECT_EQ(data + 3u, str2.end());
63     EXPECT_EQ(data + 1u, str2.cbegin());
64     EXPECT_EQ(data + 3u, str2.cend());
65 
66     EXPECT_EQ('c', str2[1u]);
67 
68     END_TEST;
69 }
70 
copy_move_and_assignment_test()71 bool copy_move_and_assignment_test() {
72     BEGIN_TEST;
73 
74     const char data[] = "abc";
75 
76     {
77         fbl::StringPiece abc(data);
78         fbl::StringPiece str(abc);
79         EXPECT_EQ(data, str.data());
80         EXPECT_EQ(3u, str.length());
81     }
82 
83     {
84         fbl::StringPiece abc(data);
85         fbl::StringPiece str(std::move(abc));
86         EXPECT_EQ(data, str.data());
87         EXPECT_EQ(3u, str.length());
88     }
89 
90     {
91         fbl::StringPiece abc(data);
92         fbl::StringPiece str;
93         str = abc;
94         EXPECT_EQ(data, str.data());
95         EXPECT_EQ(3u, str.length());
96     }
97 
98     {
99         fbl::StringPiece abc(data);
100         fbl::StringPiece str;
101         str = std::move(abc);
102         EXPECT_EQ(data, str.data());
103         EXPECT_EQ(3u, str.length());
104     }
105 
106     {
107         fbl::StringPiece str;
108         str = data;
109         EXPECT_EQ(data, str.data());
110         EXPECT_EQ(3u, str.length());
111 
112         str = nullptr;
113         EXPECT_NULL(str.data());
114         EXPECT_EQ(0u, str.length());
115     }
116 
117     END_TEST;
118 }
119 
set_clear_test()120 bool set_clear_test() {
121     BEGIN_TEST;
122 
123     const char data[] = "abc";
124 
125     fbl::StringPiece str;
126     EXPECT_NULL(str.data());
127     EXPECT_EQ(0u, str.length());
128 
129     str.set(data);
130     EXPECT_EQ(data, str.data());
131     EXPECT_EQ(3u, str.length());
132 
133     str.set(nullptr);
134     EXPECT_NULL(str.data());
135     EXPECT_EQ(0u, str.length());
136 
137     str.set(data, 2);
138     EXPECT_EQ(data, str.data());
139     EXPECT_EQ(2u, str.length());
140 
141     str.clear();
142     EXPECT_NULL(str.data());
143     EXPECT_EQ(0u, str.length());
144 
145     END_TEST;
146 }
147 
compare_test()148 bool compare_test() {
149     BEGIN_TEST;
150 
151     const char data[] = "abc";
152     fbl::StringPiece empty;
153     fbl::StringPiece a(data, 1);
154     fbl::StringPiece ab(data, 2);
155     fbl::StringPiece b(data + 1, 1);
156     fbl::StringPiece bc(data + 1, 2);
157 
158     EXPECT_EQ(0, empty.compare(empty));
159     EXPECT_EQ(-1, empty.compare(a));
160     EXPECT_EQ(1, a.compare(empty));
161 
162     EXPECT_EQ(0, a.compare(a));
163     EXPECT_EQ(0, ab.compare(ab));
164     EXPECT_EQ(-1, a.compare(ab));
165     EXPECT_EQ(1, ab.compare(a));
166     EXPECT_EQ(-1, ab.compare(bc));
167     EXPECT_EQ(1, bc.compare(ab));
168 
169     EXPECT_TRUE(empty == empty);
170     EXPECT_TRUE(empty <= empty);
171     EXPECT_TRUE(empty >= empty);
172     EXPECT_FALSE(empty != empty);
173     EXPECT_FALSE(empty < empty);
174     EXPECT_FALSE(empty > empty);
175     EXPECT_TRUE(empty < a);
176     EXPECT_TRUE(a > empty);
177 
178     EXPECT_TRUE(a == a);
179     EXPECT_TRUE(ab == ab);
180     EXPECT_TRUE(a != ab);
181     EXPECT_TRUE(a != b);
182     EXPECT_TRUE(ab != a);
183 
184     EXPECT_FALSE(a < a);
185     EXPECT_FALSE(a > a);
186     EXPECT_TRUE(a >= a);
187     EXPECT_TRUE(a <= a);
188 
189     EXPECT_TRUE(a < ab);
190     EXPECT_FALSE(a > ab);
191     EXPECT_FALSE(a >= ab);
192     EXPECT_TRUE(a <= ab);
193 
194     EXPECT_FALSE(ab < a);
195     EXPECT_TRUE(ab > a);
196     EXPECT_TRUE(ab >= a);
197     EXPECT_FALSE(ab <= a);
198 
199     EXPECT_TRUE(a < b);
200     EXPECT_FALSE(a > b);
201     EXPECT_FALSE(a >= b);
202     EXPECT_TRUE(a <= b);
203 
204     EXPECT_FALSE(b < a);
205     EXPECT_TRUE(b > a);
206     EXPECT_TRUE(b >= a);
207     EXPECT_FALSE(b <= a);
208 
209     EXPECT_TRUE(a < bc);
210     EXPECT_FALSE(a > bc);
211     EXPECT_FALSE(a >= bc);
212     EXPECT_TRUE(a <= bc);
213 
214     EXPECT_FALSE(bc < a);
215     EXPECT_TRUE(bc > a);
216     EXPECT_TRUE(bc >= a);
217     EXPECT_FALSE(bc <= a);
218 
219     END_TEST;
220 }
221 
222 constexpr char kFakeStringData[] = "hello";
223 constexpr size_t kFakeStringLength = fbl::count_of(kFakeStringData);
224 
225 struct SimpleFakeString {
data__anon240007050111::SimpleFakeString226     const char* data() const { return kFakeStringData; }
length__anon240007050111::SimpleFakeString227     size_t length() const { return kFakeStringLength; }
228 };
229 
230 struct OverloadedFakeString {
data__anon240007050111::OverloadedFakeString231     const char* data() const { return kFakeStringData; }
length__anon240007050111::OverloadedFakeString232     size_t length() const { return kFakeStringLength; }
233 
234     // These are decoys to verify that the conversion operator only considers
235     // the const overloads of these members.
236     void data();
237     void length();
238 };
239 
240 struct EmptyString {
data__anon240007050111::EmptyString241     const char* data() const { return nullptr; }
length__anon240007050111::EmptyString242     size_t length() const { return 0u; }
243 };
244 
conversion_from_string_like_object()245 bool conversion_from_string_like_object() {
246     BEGIN_TEST;
247 
248     {
249         SimpleFakeString str;
250         fbl::StringPiece p(str);
251         EXPECT_EQ(kFakeStringData, p.data());
252         EXPECT_EQ(kFakeStringLength, p.length());
253     }
254 
255     {
256         OverloadedFakeString str;
257         fbl::StringPiece p(str);
258         EXPECT_EQ(kFakeStringData, p.data());
259         EXPECT_EQ(kFakeStringLength, p.length());
260     }
261 
262     {
263         EmptyString str;
264         fbl::StringPiece p(str);
265         EXPECT_NULL(p.data());
266         EXPECT_EQ(0u, p.length());
267     }
268 
269     END_TEST;
270 }
271 
assignment_from_string_like_object()272 bool assignment_from_string_like_object() {
273     BEGIN_TEST;
274 
275     {
276         SimpleFakeString str;
277         fbl::StringPiece p;
278         p = str;
279         EXPECT_EQ(kFakeStringData, p.data());
280         EXPECT_EQ(kFakeStringLength, p.length());
281     }
282 
283     {
284         OverloadedFakeString str;
285         fbl::StringPiece p;
286         p = str;
287         EXPECT_EQ(kFakeStringData, p.data());
288         EXPECT_EQ(kFakeStringLength, p.length());
289     }
290 
291     {
292         EmptyString str;
293         fbl::StringPiece p("abc");
294         p = str;
295         EXPECT_NULL(p.data());
296         EXPECT_EQ(0u, p.length());
297     }
298 
299     END_TEST;
300 }
301 
302 } // namespace
303 
304 BEGIN_TEST_CASE(string_piece_tests)
305 RUN_TEST(empty_string_test)
306 RUN_TEST(non_empty_string_test)
307 RUN_TEST(copy_move_and_assignment_test)
308 RUN_TEST(set_clear_test)
309 RUN_TEST(compare_test)
310 RUN_TEST(conversion_from_string_like_object)
311 RUN_TEST(assignment_from_string_like_object)
312 END_TEST_CASE(string_piece_tests)
313