1 | /* |
2 | * Copyright (C) 2014 Apple Inc. All rights reserved. |
3 | * |
4 | * Redistribution and use in source and binary forms, with or without |
5 | * modification, are permitted provided that the following conditions |
6 | * are met: |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * |
13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
23 | * THE POSSIBILITY OF SUCH DAMAGE. |
24 | */ |
25 | |
26 | #include "config.h" |
27 | |
28 | #include <wtf/text/StringBuilder.h> |
29 | #include <wtf/text/StringView.h> |
30 | |
31 | namespace TestWebKitAPI { |
32 | |
33 | StringView stringViewFromLiteral(const char* characters) |
34 | { |
35 | return StringView(reinterpret_cast<const LChar*>(characters), strlen(characters)); |
36 | } |
37 | |
38 | StringView stringViewFromUTF8(String &ref, const char* characters) |
39 | { |
40 | ref = String::fromUTF8(characters); |
41 | return ref; |
42 | } |
43 | |
44 | TEST(WTF, StringViewEmptyVsNull) |
45 | { |
46 | StringView nullView; |
47 | EXPECT_TRUE(nullView.isNull()); |
48 | EXPECT_TRUE(nullView.isEmpty()); |
49 | |
50 | // Test in a boolean context to test operator bool(). |
51 | if (nullView) |
52 | FAIL(); |
53 | else |
54 | SUCCEED(); |
55 | |
56 | if (!nullView) |
57 | SUCCEED(); |
58 | else |
59 | FAIL(); |
60 | |
61 | StringView emptyView = StringView::empty(); |
62 | EXPECT_FALSE(emptyView.isNull()); |
63 | EXPECT_TRUE(emptyView.isEmpty()); |
64 | |
65 | // Test in a boolean context to test operator bool(). |
66 | if (emptyView) |
67 | SUCCEED(); |
68 | else |
69 | FAIL(); |
70 | |
71 | if (!emptyView) |
72 | FAIL(); |
73 | else |
74 | SUCCEED(); |
75 | |
76 | StringView viewWithCharacters(String("hello" )); |
77 | EXPECT_FALSE(viewWithCharacters.isNull()); |
78 | EXPECT_FALSE(viewWithCharacters.isEmpty()); |
79 | |
80 | // Test in a boolean context to test operator bool(). |
81 | if (viewWithCharacters) |
82 | SUCCEED(); |
83 | else |
84 | FAIL(); |
85 | |
86 | if (!viewWithCharacters) |
87 | FAIL(); |
88 | else |
89 | SUCCEED(); |
90 | } |
91 | |
92 | bool compareLoopIterations(StringView::GraphemeClusters graphemeClusters, std::vector<StringView> expected) |
93 | { |
94 | std::vector<StringView> actual; |
95 | for (auto graphemeCluster : graphemeClusters) |
96 | actual.push_back(graphemeCluster); |
97 | return actual == expected; |
98 | } |
99 | |
100 | bool compareLoopIterations(StringView::CodePoints codePoints, std::vector<UChar32> expected) |
101 | { |
102 | std::vector<UChar32> actual; |
103 | for (auto codePoint : codePoints) |
104 | actual.push_back(codePoint); |
105 | return actual == expected; |
106 | } |
107 | |
108 | static bool compareLoopIterations(StringView::CodeUnits codeUnits, std::vector<UChar> expected) |
109 | { |
110 | std::vector<UChar> actual; |
111 | for (auto codeUnit : codeUnits) |
112 | actual.push_back(codeUnit); |
113 | return actual == expected; |
114 | } |
115 | |
116 | static void build(StringBuilder& builder, std::vector<UChar> input) |
117 | { |
118 | builder.clear(); |
119 | for (auto codeUnit : input) |
120 | builder.append(codeUnit); |
121 | } |
122 | |
123 | TEST(WTF, StringViewIterators) |
124 | { |
125 | EXPECT_TRUE(compareLoopIterations(StringView().codePoints(), { })); |
126 | EXPECT_TRUE(compareLoopIterations(StringView().codeUnits(), { })); |
127 | EXPECT_TRUE(compareLoopIterations(StringView().graphemeClusters(), { })); |
128 | |
129 | EXPECT_TRUE(compareLoopIterations(StringView::empty().codePoints(), { })); |
130 | EXPECT_TRUE(compareLoopIterations(StringView::empty().codeUnits(), { })); |
131 | EXPECT_TRUE(compareLoopIterations(StringView::empty().graphemeClusters(), { })); |
132 | |
133 | String helo("helo" ); |
134 | StringView heloView(helo); |
135 | |
136 | auto codePoints = heloView.codePoints(); |
137 | auto codePointsIterator = codePoints.begin(); |
138 | EXPECT_EQ(*codePointsIterator, 'h'); |
139 | EXPECT_EQ(*codePointsIterator, 'h'); |
140 | ++codePointsIterator; |
141 | ++codePointsIterator; |
142 | EXPECT_EQ(*codePointsIterator, 'l'); |
143 | auto savedIterator = codePointsIterator; |
144 | codePointsIterator = codePoints.begin(); |
145 | EXPECT_EQ(*codePointsIterator, 'h'); |
146 | codePointsIterator = savedIterator; |
147 | EXPECT_EQ(*codePointsIterator, 'l'); |
148 | String webkit("webkit" ); |
149 | auto webkitCodePoints = StringView(webkit).codePoints(); |
150 | codePointsIterator = webkitCodePoints.begin(); |
151 | ++codePointsIterator; |
152 | ++codePointsIterator; |
153 | EXPECT_EQ(*codePointsIterator, 'b'); |
154 | while (codePointsIterator != webkitCodePoints.end()) |
155 | ++codePointsIterator; |
156 | |
157 | EXPECT_TRUE(compareLoopIterations(heloView.codePoints(), {'h', 'e', 'l', 'o'})); |
158 | EXPECT_TRUE(compareLoopIterations(heloView.codeUnits(), {'h', 'e', 'l', 'o'})); |
159 | EXPECT_TRUE(compareLoopIterations(heloView.graphemeClusters(), { |
160 | StringView(heloView.characters8(), 1), |
161 | StringView(heloView.characters8() + 1, 1), |
162 | StringView(heloView.characters8() + 2, 1), |
163 | StringView(heloView.characters8() + 3, 1)})); |
164 | |
165 | StringBuilder b; |
166 | build(b, {0xD800, 0xDD55}); // Surrogates for unicode code point U+10155 |
167 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x10155})); |
168 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800, 0xDD55})); |
169 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), {StringView(b.toString())})); |
170 | |
171 | build(b, {0xD800}); // Leading surrogate only |
172 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xD800})); |
173 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800})); |
174 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), {StringView(b.toString())})); |
175 | |
176 | build(b, {0xD800, 0xD801}); // Two leading surrogates |
177 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xD800, 0xD801})); |
178 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800, 0xD801})); |
179 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), {StringView(b.characters16(), 1), StringView(b.characters16() + 1, 1)})); |
180 | |
181 | build(b, {0xDD55}); // Trailing surrogate only |
182 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xDD55})); |
183 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xDD55})); |
184 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), {StringView(b.toString())})); |
185 | |
186 | build(b, {0xD800, 'h'}); // Leading surrogate followed by non-surrogate |
187 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0xD800, 'h'})); |
188 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0xD800, 'h'})); |
189 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), {StringView(b.characters16(), 1), StringView(b.characters16() + 1, 1)})); |
190 | |
191 | build(b, {0x0306}); // "COMBINING BREVE" |
192 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x0306})); |
193 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0x0306})); |
194 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), {StringView(b.toString())})); |
195 | |
196 | build(b, {0x0306, 0xD800, 0xDD55, 'h', 'e', 'l', 'o'}); // Mix of single code unit and multi code unit code points |
197 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x0306, 0x10155, 'h', 'e', 'l', 'o'})); |
198 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0x0306, 0xD800, 0xDD55, 'h', 'e', 'l', 'o'})); |
199 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), { |
200 | StringView(b.characters16(), 1), |
201 | StringView(b.characters16() + 1, 2), |
202 | StringView(b.characters16() + 3, 1), |
203 | StringView(b.characters16() + 4, 1), |
204 | StringView(b.characters16() + 5, 1), |
205 | StringView(b.characters16() + 6, 1)})); |
206 | |
207 | build(b, {'e', 0x0301}); // "COMBINING ACUTE" |
208 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {'e', 0x0301})); |
209 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {'e', 0x0301})); |
210 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), {StringView(b.toString())})); |
211 | |
212 | build(b, {'e', 0x0301, 0x0306, 'a'}); // "COMBINING ACUTE" "COMBINING BREVE" |
213 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {'e', 0x0301, 0x0306, 'a'})); |
214 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {'e', 0x0301, 0x0306, 'a'})); |
215 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), { |
216 | StringView(b.characters16(), 3), |
217 | StringView(b.characters16() + 3, 1), |
218 | })); |
219 | |
220 | build(b, {0x1112, 0x116f, 0x11b6, 0x1107, 0x1161, 0x11B8}); // Korean combining Jamo |
221 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codePoints(), {0x1112, 0x116f, 0x11b6, 0x1107, 0x1161, 0x11B8})); |
222 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).codeUnits(), {0x1112, 0x116f, 0x11b6, 0x1107, 0x1161, 0x11B8})); |
223 | EXPECT_TRUE(compareLoopIterations(StringView(b.toString()).graphemeClusters(), { |
224 | StringView(b.characters16(), 3), |
225 | StringView(b.characters16() + 3, 3)})); |
226 | } |
227 | |
228 | static Vector<String> vectorFromSplitResult(const StringView::SplitResult& substrings) |
229 | { |
230 | Vector<String> result; |
231 | for (StringView substring : substrings) |
232 | result.append(substring.toString()); |
233 | return result; |
234 | } |
235 | |
236 | TEST(WTF, StringViewSplitEmptyAndNullStrings) |
237 | { |
238 | StringView a = emptyString(); |
239 | auto splitResult = a.split('b'); |
240 | EXPECT_TRUE(splitResult.begin() == splitResult.end()); |
241 | |
242 | a = { String { } }; |
243 | splitResult = a.split('b'); |
244 | EXPECT_TRUE(splitResult.begin() == splitResult.end()); |
245 | |
246 | a = { }; |
247 | splitResult = a.split('b'); |
248 | EXPECT_TRUE(splitResult.begin() == splitResult.end()); |
249 | } |
250 | |
251 | TEST(WTF, StringViewSplitBasic) |
252 | { |
253 | String referenceHolder; |
254 | StringView a = stringViewFromUTF8(referenceHolder, "This is a sentence." ); |
255 | |
256 | // Simple |
257 | Vector<String> actual = vectorFromSplitResult(a.split('T')); |
258 | Vector<String> expected({ "his is a sentence." }); |
259 | ASSERT_EQ(expected.size(), actual.size()); |
260 | for (size_t i = 0; i < actual.size(); ++i) |
261 | EXPECT_STREQ(expected[i].utf8().data(), actual[i].utf8().data()) << "Vectors differ at index " << i; |
262 | |
263 | actual = vectorFromSplitResult(a.split('.')); |
264 | expected = { "This is a sentence" }; |
265 | ASSERT_EQ(expected.size(), actual.size()); |
266 | for (size_t i = 0; i < actual.size(); ++i) |
267 | EXPECT_STREQ(expected[i].utf8().data(), actual[i].utf8().data()) << "Vectors differ at index " << i; |
268 | |
269 | actual = vectorFromSplitResult(a.split('a')); |
270 | expected = { "This is " , " sentence." }; |
271 | ASSERT_EQ(expected.size(), actual.size()); |
272 | for (size_t i = 0; i < actual.size(); ++i) |
273 | EXPECT_STREQ(expected[i].utf8().data(), actual[i].utf8().data()) << "Vectors differ at index " << i; |
274 | |
275 | actual = vectorFromSplitResult(a.split(' ')); |
276 | expected = { "This" , "is" , "a" , "sentence." }; |
277 | ASSERT_EQ(expected.size(), actual.size()); |
278 | for (size_t i = 0; i < actual.size(); ++i) |
279 | EXPECT_STREQ(expected[i].utf8().data(), actual[i].utf8().data()) << "Vectors differ at index " << i; |
280 | |
281 | // Non-existent separator |
282 | actual = vectorFromSplitResult(a.split('z')); |
283 | expected = { "This is a sentence." }; |
284 | ASSERT_EQ(expected.size(), actual.size()); |
285 | for (size_t i = 0; i < actual.size(); ++i) |
286 | EXPECT_STREQ(expected[i].utf8().data(), actual[i].utf8().data()) << "Vectors differ at index " << i; |
287 | } |
288 | |
289 | TEST(WTF, StringViewSplitWithConsecutiveSeparators) |
290 | { |
291 | String referenceHolder; |
292 | StringView a = stringViewFromUTF8(referenceHolder, " This is a sentence. " ); |
293 | |
294 | Vector<String> actual = vectorFromSplitResult(a.split(' ')); |
295 | Vector<String> expected({ "This" , "is" , "a" , "sentence." }); |
296 | ASSERT_EQ(expected.size(), actual.size()); |
297 | for (size_t i = 0; i < actual.size(); ++i) |
298 | EXPECT_STREQ(expected[i].utf8().data(), actual[i].utf8().data()) << "Vectors differ at index " << i; |
299 | |
300 | actual = vectorFromSplitResult(a.splitAllowingEmptyEntries(' ')); |
301 | expected = { "" , "This" , "" , "" , "" , "" , "is" , "" , "a" , "" , "" , "" , "" , "" , "" , "sentence." , "" }; |
302 | ASSERT_EQ(expected.size(), actual.size()); |
303 | for (size_t i = 0; i < actual.size(); ++i) |
304 | EXPECT_STREQ(expected[i].utf8().data(), actual[i].utf8().data()) << "Vectors differ at index " << i; |
305 | } |
306 | |
307 | TEST(WTF, StringViewEqualBasic) |
308 | { |
309 | String referenceHolder; |
310 | StringView a = stringViewFromUTF8(referenceHolder, "Hello World!" ); |
311 | EXPECT_TRUE(a == "Hello World!" ); |
312 | EXPECT_FALSE(a == "Hello World" ); |
313 | EXPECT_FALSE(a == "Hello World!!" ); |
314 | |
315 | auto test = "Hell\0" ; |
316 | a = StringView { (const LChar*)test, 5 }; |
317 | EXPECT_FALSE(a == "Hell\0" ); |
318 | EXPECT_FALSE(a == "Hell" ); |
319 | |
320 | StringView test3 = "Hello" ; |
321 | EXPECT_TRUE(test3 == "Hello\0" ); |
322 | EXPECT_TRUE(test3 == "Hello" ); |
323 | } |
324 | |
325 | TEST(WTF, StringViewEqualIgnoringASCIICaseBasic) |
326 | { |
327 | RefPtr<StringImpl> a = StringImpl::createFromLiteral("aBcDeFG" ); |
328 | RefPtr<StringImpl> b = StringImpl::createFromLiteral("ABCDEFG" ); |
329 | RefPtr<StringImpl> c = StringImpl::createFromLiteral("abcdefg" ); |
330 | const char d[] = "aBcDeFG" ; |
331 | RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>("" )); |
332 | RefPtr<StringImpl> shorter = StringImpl::createFromLiteral("abcdef" ); |
333 | RefPtr<StringImpl> different = StringImpl::createFromLiteral("abcrefg" ); |
334 | |
335 | StringView stringViewA(*a.get()); |
336 | StringView stringViewB(*b.get()); |
337 | StringView stringViewC(*c.get()); |
338 | StringView emptyStringView(*empty.get()); |
339 | StringView shorterStringView(*shorter.get()); |
340 | StringView differentStringView(*different.get()); |
341 | |
342 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewB)); |
343 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewC)); |
344 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewC)); |
345 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, d)); |
346 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, d)); |
347 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewC, d)); |
348 | |
349 | // Identity. |
350 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewA)); |
351 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewB)); |
352 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewC, stringViewC)); |
353 | |
354 | // Transitivity. |
355 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewB)); |
356 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewC)); |
357 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewC)); |
358 | |
359 | // Negative cases. |
360 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, emptyStringView)); |
361 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, emptyStringView)); |
362 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewC, emptyStringView)); |
363 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, shorterStringView)); |
364 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, shorterStringView)); |
365 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewC, shorterStringView)); |
366 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, differentStringView)); |
367 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, differentStringView)); |
368 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewC, differentStringView)); |
369 | ASSERT_FALSE(equalIgnoringASCIICase(emptyStringView, d)); |
370 | ASSERT_FALSE(equalIgnoringASCIICase(shorterStringView, d)); |
371 | ASSERT_FALSE(equalIgnoringASCIICase(differentStringView, d)); |
372 | } |
373 | |
374 | TEST(WTF, StringViewEqualIgnoringASCIICaseWithEmpty) |
375 | { |
376 | RefPtr<StringImpl> a = StringImpl::create(reinterpret_cast<const LChar*>("" )); |
377 | RefPtr<StringImpl> b = StringImpl::create(reinterpret_cast<const LChar*>("" )); |
378 | StringView stringViewA(*a.get()); |
379 | StringView stringViewB(*b.get()); |
380 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewB)); |
381 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewA)); |
382 | } |
383 | |
384 | TEST(WTF, StringViewEqualIgnoringASCIICaseWithLatin1Characters) |
385 | { |
386 | RefPtr<StringImpl> a = StringImpl::create(reinterpret_cast<const LChar*>("aBcéeFG" )); |
387 | RefPtr<StringImpl> b = StringImpl::create(reinterpret_cast<const LChar*>("ABCÉEFG" )); |
388 | RefPtr<StringImpl> c = StringImpl::create(reinterpret_cast<const LChar*>("ABCéEFG" )); |
389 | RefPtr<StringImpl> d = StringImpl::create(reinterpret_cast<const LChar*>("abcéefg" )); |
390 | const char e[] = "aBcéeFG" ; |
391 | StringView stringViewA(*a.get()); |
392 | StringView stringViewB(*b.get()); |
393 | StringView stringViewC(*c.get()); |
394 | StringView stringViewD(*d.get()); |
395 | |
396 | // Identity. |
397 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewA)); |
398 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewB, stringViewB)); |
399 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewC, stringViewC)); |
400 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewD, stringViewD)); |
401 | |
402 | // All combination. |
403 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, stringViewB)); |
404 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewC)); |
405 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewA, stringViewD)); |
406 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, stringViewC)); |
407 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, stringViewD)); |
408 | ASSERT_TRUE(equalIgnoringASCIICase(stringViewC, stringViewD)); |
409 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewA, e)); |
410 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewB, e)); |
411 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewC, e)); |
412 | ASSERT_FALSE(equalIgnoringASCIICase(stringViewD, e)); |
413 | } |
414 | |
415 | TEST(WTF, StringViewFindIgnoringASCIICaseBasic) |
416 | { |
417 | String referenceAHolder; |
418 | StringView referenceA = stringViewFromUTF8(referenceAHolder, "aBcéeFG" ); |
419 | String referenceBHolder; |
420 | StringView referenceB = stringViewFromUTF8(referenceBHolder, "ABCÉEFG" ); |
421 | |
422 | // Search the exact string. |
423 | EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(referenceA)); |
424 | EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(referenceB)); |
425 | |
426 | // A and B are distinct by the non-ascii character é/É. |
427 | EXPECT_EQ(static_cast<size_t>(notFound), referenceA.findIgnoringASCIICase(referenceB)); |
428 | EXPECT_EQ(static_cast<size_t>(notFound), referenceB.findIgnoringASCIICase(referenceA)); |
429 | |
430 | String tempStringHolder; |
431 | // Find the prefix. |
432 | EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(stringViewFromLiteral("a" ))); |
433 | EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "abcé" ))); |
434 | EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(stringViewFromLiteral("A" ))); |
435 | EXPECT_EQ(static_cast<size_t>(0), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCé" ))); |
436 | EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(stringViewFromLiteral("a" ))); |
437 | EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "abcÉ" ))); |
438 | EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(stringViewFromLiteral("A" ))); |
439 | EXPECT_EQ(static_cast<size_t>(0), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ" ))); |
440 | |
441 | // Not a prefix. |
442 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromLiteral("x" ))); |
443 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "accé" ))); |
444 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "abcÉ" ))); |
445 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromLiteral("X" ))); |
446 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABDé" ))); |
447 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ" ))); |
448 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromLiteral("y" ))); |
449 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "accÉ" ))); |
450 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "abcé" ))); |
451 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromLiteral("Y" ))); |
452 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABdÉ" ))); |
453 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCé" ))); |
454 | |
455 | // Find the infix. |
456 | EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cée" ))); |
457 | EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ée" ))); |
458 | EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cé" ))); |
459 | EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "c" ))); |
460 | EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "é" ))); |
461 | EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Cée" ))); |
462 | EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éE" ))); |
463 | EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Cé" ))); |
464 | EXPECT_EQ(static_cast<size_t>(2), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "C" ))); |
465 | |
466 | EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cÉe" ))); |
467 | EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Ée" ))); |
468 | EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cÉ" ))); |
469 | EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "c" ))); |
470 | EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "É" ))); |
471 | EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "CÉe" ))); |
472 | EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ÉE" ))); |
473 | EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "CÉ" ))); |
474 | EXPECT_EQ(static_cast<size_t>(2), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "C" ))); |
475 | |
476 | // Not an infix. |
477 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "céd" ))); |
478 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Ée" ))); |
479 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "bé" ))); |
480 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "x" ))); |
481 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "É" ))); |
482 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "CÉe" ))); |
483 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éd" ))); |
484 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "CÉ" ))); |
485 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Y" ))); |
486 | |
487 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cée" ))); |
488 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Éc" ))); |
489 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "cé" ))); |
490 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "W" ))); |
491 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "é" ))); |
492 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "bÉe" ))); |
493 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éE" ))); |
494 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "BÉ" ))); |
495 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "z" ))); |
496 | |
497 | // Find the suffix. |
498 | EXPECT_EQ(static_cast<size_t>(6), referenceA.findIgnoringASCIICase(stringViewFromLiteral("g" ))); |
499 | EXPECT_EQ(static_cast<size_t>(4), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "efg" ))); |
500 | EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éefg" ))); |
501 | EXPECT_EQ(static_cast<size_t>(6), referenceA.findIgnoringASCIICase(stringViewFromLiteral("G" ))); |
502 | EXPECT_EQ(static_cast<size_t>(4), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "EFG" ))); |
503 | EXPECT_EQ(static_cast<size_t>(3), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éEFG" ))); |
504 | |
505 | EXPECT_EQ(static_cast<size_t>(6), referenceB.findIgnoringASCIICase(stringViewFromLiteral("g" ))); |
506 | EXPECT_EQ(static_cast<size_t>(4), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "efg" ))); |
507 | EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Éefg" ))); |
508 | EXPECT_EQ(static_cast<size_t>(6), referenceB.findIgnoringASCIICase(stringViewFromLiteral("G" ))); |
509 | EXPECT_EQ(static_cast<size_t>(4), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "EFG" ))); |
510 | EXPECT_EQ(static_cast<size_t>(3), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ÉEFG" ))); |
511 | |
512 | // Not a suffix. |
513 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromLiteral("X" ))); |
514 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "edg" ))); |
515 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "Éefg" ))); |
516 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromLiteral("w" ))); |
517 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "dFG" ))); |
518 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ÉEFG" ))); |
519 | |
520 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromLiteral("Z" ))); |
521 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ffg" ))); |
522 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éefg" ))); |
523 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromLiteral("r" ))); |
524 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "EgG" ))); |
525 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "éEFG" ))); |
526 | } |
527 | |
528 | TEST(WTF, StringViewFindIgnoringASCIICaseWithValidOffset) |
529 | { |
530 | String referenceHolder; |
531 | StringView reference = stringViewFromUTF8(referenceHolder, "ABCÉEFGaBcéeFG" ); |
532 | String tempStringHolder; |
533 | |
534 | EXPECT_EQ(static_cast<size_t>(0), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABC" ), 0)); |
535 | EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABC" ), 1)); |
536 | EXPECT_EQ(static_cast<size_t>(0), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ" ), 0)); |
537 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ" ), 1)); |
538 | EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCé" ), 0)); |
539 | EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCé" ), 1)); |
540 | } |
541 | |
542 | TEST(WTF, StringViewFindIgnoringASCIICaseWithInvalidOffset) |
543 | { |
544 | String referenceHolder; |
545 | StringView reference = stringViewFromUTF8(referenceHolder, "ABCÉEFGaBcéeFG" ); |
546 | String tempStringHolder; |
547 | |
548 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABC" ), 15)); |
549 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABC" ), 16)); |
550 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ" ), 17)); |
551 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ" ), 42)); |
552 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(stringViewFromUTF8(tempStringHolder, "ABCÉ" ), std::numeric_limits<unsigned>::max())); |
553 | } |
554 | |
555 | TEST(WTF, StringViewFindIgnoringASCIICaseOnEmpty) |
556 | { |
557 | String referenceHolder; |
558 | StringView reference = stringViewFromUTF8(referenceHolder, "ABCÉEFG" ); |
559 | StringView empty = stringViewFromLiteral("" ); |
560 | EXPECT_EQ(static_cast<size_t>(0), reference.findIgnoringASCIICase(empty)); |
561 | EXPECT_EQ(static_cast<size_t>(0), reference.findIgnoringASCIICase(empty, 0)); |
562 | EXPECT_EQ(static_cast<size_t>(3), reference.findIgnoringASCIICase(empty, 3)); |
563 | EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(empty, 7)); |
564 | EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(empty, 8)); |
565 | EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(empty, 42)); |
566 | EXPECT_EQ(static_cast<size_t>(7), reference.findIgnoringASCIICase(empty, std::numeric_limits<unsigned>::max())); |
567 | } |
568 | |
569 | TEST(WTF, StringViewFindIgnoringASCIICaseWithPatternLongerThanReference) |
570 | { |
571 | String referenceHolder; |
572 | StringView reference = stringViewFromUTF8(referenceHolder, "ABCÉEFG" ); |
573 | String patternHolder; |
574 | StringView pattern = stringViewFromUTF8(patternHolder, "ABCÉEFGA" ); |
575 | |
576 | EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference.findIgnoringASCIICase(pattern)); |
577 | EXPECT_EQ(static_cast<size_t>(0), pattern.findIgnoringASCIICase(reference)); |
578 | } |
579 | |
580 | TEST(WTF, StringViewStartsWithBasic) |
581 | { |
582 | StringView reference = stringViewFromLiteral("abcdefg" ); |
583 | String referenceUTF8Ref; |
584 | StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "à îûèô" ); |
585 | |
586 | StringView oneLetterPrefix = stringViewFromLiteral("a" ); |
587 | StringView shortPrefix = stringViewFromLiteral("abc" ); |
588 | StringView longPrefix = stringViewFromLiteral("abcdef" ); |
589 | StringView upperCasePrefix = stringViewFromLiteral("ABC" ); |
590 | StringView empty = stringViewFromLiteral("" ); |
591 | StringView notPrefix = stringViewFromLiteral("bc" ); |
592 | |
593 | String oneLetterPrefixUTF8Ref; |
594 | StringView oneLetterPrefixUTF8 = stringViewFromUTF8(oneLetterPrefixUTF8Ref, "Ã " ); |
595 | String shortPrefixUTF8Ref; |
596 | StringView shortPrefixUTF8 = stringViewFromUTF8(shortPrefixUTF8Ref, "à î" ); |
597 | String longPrefixUTF8Ref; |
598 | StringView longPrefixUTF8 = stringViewFromUTF8(longPrefixUTF8Ref, "à îûè" ); |
599 | String upperCasePrefixUTF8Ref; |
600 | StringView upperCasePrefixUTF8 = stringViewFromUTF8(upperCasePrefixUTF8Ref, "ÀÎ" ); |
601 | String notPrefixUTF8Ref; |
602 | StringView notPrefixUTF8 = stringViewFromUTF8(notPrefixUTF8Ref, "îû" ); |
603 | |
604 | EXPECT_TRUE(reference.startsWith(reference)); |
605 | EXPECT_TRUE(reference.startsWith(oneLetterPrefix)); |
606 | EXPECT_TRUE(reference.startsWith(shortPrefix)); |
607 | EXPECT_TRUE(reference.startsWith(longPrefix)); |
608 | EXPECT_TRUE(reference.startsWith(empty)); |
609 | |
610 | EXPECT_TRUE(referenceUTF8.startsWith(referenceUTF8)); |
611 | EXPECT_TRUE(referenceUTF8.startsWith(oneLetterPrefixUTF8)); |
612 | EXPECT_TRUE(referenceUTF8.startsWith(shortPrefixUTF8)); |
613 | EXPECT_TRUE(referenceUTF8.startsWith(longPrefixUTF8)); |
614 | EXPECT_TRUE(referenceUTF8.startsWith(empty)); |
615 | |
616 | EXPECT_FALSE(reference.startsWith(notPrefix)); |
617 | EXPECT_FALSE(reference.startsWith(upperCasePrefix)); |
618 | EXPECT_FALSE(reference.startsWith(notPrefixUTF8)); |
619 | EXPECT_FALSE(reference.startsWith(upperCasePrefixUTF8)); |
620 | EXPECT_FALSE(referenceUTF8.startsWith(notPrefix)); |
621 | EXPECT_FALSE(referenceUTF8.startsWith(upperCasePrefix)); |
622 | EXPECT_FALSE(referenceUTF8.startsWith(notPrefixUTF8)); |
623 | EXPECT_FALSE(referenceUTF8.startsWith(upperCasePrefixUTF8)); |
624 | } |
625 | |
626 | TEST(WTF, StringViewStartsWithEmpty) |
627 | { |
628 | StringView a = stringViewFromLiteral("" ); |
629 | String refB; |
630 | StringView b = stringViewFromUTF8(refB, "" ); |
631 | |
632 | EXPECT_TRUE(a.startsWith(a)); |
633 | EXPECT_TRUE(a.startsWith(b)); |
634 | EXPECT_TRUE(b.startsWith(a)); |
635 | EXPECT_TRUE(b.startsWith(b)); |
636 | } |
637 | |
638 | TEST(WTF, StringViewStartsWithIgnoringASCIICaseBasic) |
639 | { |
640 | StringView reference = stringViewFromLiteral("abcdefg" ); |
641 | |
642 | String referenceUTF8Ref; |
643 | StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "à îûèô" ); |
644 | |
645 | StringView oneLetterPrefix = stringViewFromLiteral("a" ); |
646 | StringView shortPrefix = stringViewFromLiteral("abc" ); |
647 | StringView longPrefix = stringViewFromLiteral("abcdef" ); |
648 | StringView upperCasePrefix = stringViewFromLiteral("ABC" ); |
649 | StringView mixedCasePrefix = stringViewFromLiteral("aBcDe" ); |
650 | StringView empty = stringViewFromLiteral("" ); |
651 | StringView notPrefix = stringViewFromLiteral("bc" ); |
652 | |
653 | String oneLetterPrefixUTF8Ref; |
654 | StringView oneLetterPrefixUTF8 = stringViewFromUTF8(oneLetterPrefixUTF8Ref, "Ã " ); |
655 | String shortPrefixUTF8Ref; |
656 | StringView shortPrefixUTF8 = stringViewFromUTF8(shortPrefixUTF8Ref, "à î" ); |
657 | String longPrefixUTF8Ref; |
658 | StringView longPrefixUTF8 = stringViewFromUTF8(longPrefixUTF8Ref, "à îûè" ); |
659 | String upperCasePrefixUTF8Ref; |
660 | StringView upperCasePrefixUTF8 = stringViewFromUTF8(upperCasePrefixUTF8Ref, "ÀÎ" ); |
661 | String notPrefixUTF8Ref; |
662 | StringView notPrefixUTF8 = stringViewFromUTF8(notPrefixUTF8Ref, "îû" ); |
663 | |
664 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(reference)); |
665 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(oneLetterPrefix)); |
666 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(shortPrefix)); |
667 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(longPrefix)); |
668 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(empty)); |
669 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(upperCasePrefix)); |
670 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(mixedCasePrefix)); |
671 | |
672 | EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(referenceUTF8)); |
673 | EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(oneLetterPrefixUTF8)); |
674 | EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(shortPrefixUTF8)); |
675 | EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(longPrefixUTF8)); |
676 | EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(empty)); |
677 | |
678 | EXPECT_FALSE(reference.startsWithIgnoringASCIICase(notPrefix)); |
679 | EXPECT_FALSE(reference.startsWithIgnoringASCIICase(notPrefixUTF8)); |
680 | EXPECT_FALSE(reference.startsWithIgnoringASCIICase(upperCasePrefixUTF8)); |
681 | EXPECT_FALSE(referenceUTF8.startsWithIgnoringASCIICase(notPrefix)); |
682 | EXPECT_FALSE(referenceUTF8.startsWithIgnoringASCIICase(notPrefixUTF8)); |
683 | EXPECT_FALSE(referenceUTF8.startsWithIgnoringASCIICase(upperCasePrefix)); |
684 | EXPECT_FALSE(referenceUTF8.startsWithIgnoringASCIICase(upperCasePrefixUTF8)); |
685 | } |
686 | |
687 | |
688 | TEST(WTF, StringViewStartsWithIgnoringASCIICaseEmpty) |
689 | { |
690 | StringView a = stringViewFromLiteral("" ); |
691 | String refB; |
692 | StringView b = stringViewFromUTF8(refB, "" ); |
693 | |
694 | EXPECT_TRUE(a.startsWithIgnoringASCIICase(a)); |
695 | EXPECT_TRUE(a.startsWithIgnoringASCIICase(b)); |
696 | EXPECT_TRUE(b.startsWithIgnoringASCIICase(a)); |
697 | EXPECT_TRUE(b.startsWithIgnoringASCIICase(b)); |
698 | } |
699 | |
700 | TEST(WTF, StringViewStartsWithIgnoringASCIICaseWithLatin1Characters) |
701 | { |
702 | StringView reference = stringViewFromLiteral("aBcéeFG" ); |
703 | String referenceUTF8Ref; |
704 | StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "aBcéeFG" ); |
705 | |
706 | StringView a = stringViewFromLiteral("aBcéeF" ); |
707 | StringView b = stringViewFromLiteral("ABCéEF" ); |
708 | StringView c = stringViewFromLiteral("abcéef" ); |
709 | StringView d = stringViewFromLiteral("Abcéef" ); |
710 | |
711 | String refE; |
712 | StringView e = stringViewFromUTF8(refE, "aBcéeF" ); |
713 | String refF; |
714 | StringView f = stringViewFromUTF8(refF, "ABCéEF" ); |
715 | String refG; |
716 | StringView g = stringViewFromUTF8(refG, "abcéef" ); |
717 | String refH; |
718 | StringView h = stringViewFromUTF8(refH, "Abcéef" ); |
719 | |
720 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(a)); |
721 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(b)); |
722 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(c)); |
723 | EXPECT_TRUE(reference.startsWithIgnoringASCIICase(d)); |
724 | |
725 | EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(e)); |
726 | EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(f)); |
727 | EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(g)); |
728 | EXPECT_TRUE(referenceUTF8.startsWithIgnoringASCIICase(h)); |
729 | |
730 | EXPECT_FALSE(reference.endsWithIgnoringASCIICase(referenceUTF8)); |
731 | EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(reference)); |
732 | } |
733 | |
734 | TEST(WTF, StringViewEndsWithBasic) |
735 | { |
736 | StringView reference = stringViewFromLiteral("abcdefg" ); |
737 | String referenceUTF8Ref; |
738 | StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "à îûèô" ); |
739 | |
740 | StringView oneLetterSuffix = stringViewFromLiteral("g" ); |
741 | StringView shortSuffix = stringViewFromLiteral("efg" ); |
742 | StringView longSuffix = stringViewFromLiteral("cdefg" ); |
743 | StringView upperCaseSuffix = stringViewFromLiteral("EFG" ); |
744 | StringView empty = stringViewFromLiteral("" ); |
745 | StringView notSuffix = stringViewFromLiteral("bc" ); |
746 | |
747 | String oneLetterSuffixUTF8Ref; |
748 | StringView oneLetterSuffixUTF8 = stringViewFromUTF8(oneLetterSuffixUTF8Ref, "ô" ); |
749 | String shortSuffixUTF8Ref; |
750 | StringView shortSuffixUTF8 = stringViewFromUTF8(shortSuffixUTF8Ref, "èô" ); |
751 | String longSuffixUTF8Ref; |
752 | StringView longSuffixUTF8 = stringViewFromUTF8(longSuffixUTF8Ref, "îûèô" ); |
753 | String upperCaseSuffixUTF8Ref; |
754 | StringView upperCaseSuffixUTF8 = stringViewFromUTF8(upperCaseSuffixUTF8Ref, "ÈÔ" ); |
755 | String notSuffixUTF8Ref; |
756 | StringView notSuffixUTF8 = stringViewFromUTF8(notSuffixUTF8Ref, "îû" ); |
757 | |
758 | EXPECT_TRUE(reference.endsWith(reference)); |
759 | EXPECT_TRUE(reference.endsWith(oneLetterSuffix)); |
760 | EXPECT_TRUE(reference.endsWith(shortSuffix)); |
761 | EXPECT_TRUE(reference.endsWith(longSuffix)); |
762 | EXPECT_TRUE(reference.endsWith(empty)); |
763 | |
764 | EXPECT_TRUE(referenceUTF8.endsWith(referenceUTF8)); |
765 | EXPECT_TRUE(referenceUTF8.endsWith(oneLetterSuffixUTF8)); |
766 | EXPECT_TRUE(referenceUTF8.endsWith(shortSuffixUTF8)); |
767 | EXPECT_TRUE(referenceUTF8.endsWith(longSuffixUTF8)); |
768 | EXPECT_TRUE(referenceUTF8.endsWith(empty)); |
769 | |
770 | EXPECT_FALSE(reference.endsWith(notSuffix)); |
771 | EXPECT_FALSE(reference.endsWith(upperCaseSuffix)); |
772 | EXPECT_FALSE(reference.endsWith(notSuffixUTF8)); |
773 | EXPECT_FALSE(reference.endsWith(upperCaseSuffixUTF8)); |
774 | EXPECT_FALSE(referenceUTF8.endsWith(notSuffix)); |
775 | EXPECT_FALSE(referenceUTF8.endsWith(upperCaseSuffix)); |
776 | EXPECT_FALSE(referenceUTF8.endsWith(notSuffixUTF8)); |
777 | EXPECT_FALSE(referenceUTF8.endsWith(upperCaseSuffixUTF8)); |
778 | } |
779 | |
780 | TEST(WTF, StringViewEndsWithEmpty) |
781 | { |
782 | StringView a = stringViewFromLiteral("" ); |
783 | String refB; |
784 | StringView b = stringViewFromUTF8(refB, "" ); |
785 | |
786 | EXPECT_TRUE(a.endsWith(a)); |
787 | EXPECT_TRUE(a.endsWith(b)); |
788 | EXPECT_TRUE(b.endsWith(a)); |
789 | EXPECT_TRUE(b.endsWith(b)); |
790 | } |
791 | |
792 | TEST(WTF, StringViewEndsWithIgnoringASCIICaseBasic) |
793 | { |
794 | StringView reference = stringViewFromLiteral("abcdefg" ); |
795 | String referenceUTF8Ref; |
796 | StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "à îûèô" ); |
797 | |
798 | StringView oneLetterSuffix = stringViewFromLiteral("g" ); |
799 | StringView shortSuffix = stringViewFromLiteral("efg" ); |
800 | StringView longSuffix = stringViewFromLiteral("bcdefg" ); |
801 | StringView upperCaseSuffix = stringViewFromLiteral("EFG" ); |
802 | StringView mixedCaseSuffix = stringViewFromLiteral("bCdeFg" ); |
803 | StringView empty = stringViewFromLiteral("" ); |
804 | StringView notSuffix = stringViewFromLiteral("bc" ); |
805 | |
806 | String oneLetterSuffixUTF8Ref; |
807 | StringView oneLetterSuffixUTF8 = stringViewFromUTF8(oneLetterSuffixUTF8Ref, "ô" ); |
808 | String shortSuffixUTF8Ref; |
809 | StringView shortSuffixUTF8 = stringViewFromUTF8(shortSuffixUTF8Ref, "èô" ); |
810 | String longSuffixUTF8Ref; |
811 | StringView longSuffixUTF8 = stringViewFromUTF8(longSuffixUTF8Ref, "îûèô" ); |
812 | String upperCaseSuffixUTF8Ref; |
813 | StringView upperCaseSuffixUTF8 = stringViewFromUTF8(upperCaseSuffixUTF8Ref, "ÈÔ" ); |
814 | String notSuffixUTF8Ref; |
815 | StringView notSuffixUTF8 = stringViewFromUTF8(notSuffixUTF8Ref, "îû" ); |
816 | |
817 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(reference)); |
818 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(oneLetterSuffix)); |
819 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(shortSuffix)); |
820 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(longSuffix)); |
821 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(empty)); |
822 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(upperCaseSuffix)); |
823 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(mixedCaseSuffix)); |
824 | |
825 | EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(referenceUTF8)); |
826 | EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(oneLetterSuffixUTF8)); |
827 | EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(shortSuffixUTF8)); |
828 | EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(longSuffixUTF8)); |
829 | EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(empty)); |
830 | |
831 | EXPECT_FALSE(reference.endsWithIgnoringASCIICase(notSuffix)); |
832 | EXPECT_FALSE(reference.endsWithIgnoringASCIICase(notSuffixUTF8)); |
833 | EXPECT_FALSE(reference.endsWithIgnoringASCIICase(upperCaseSuffixUTF8)); |
834 | EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(notSuffix)); |
835 | EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(notSuffixUTF8)); |
836 | EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(upperCaseSuffix)); |
837 | EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(upperCaseSuffixUTF8)); |
838 | } |
839 | |
840 | TEST(WTF, StringViewEndsWithIgnoringASCIICaseEmpty) |
841 | { |
842 | StringView a = stringViewFromLiteral("" ); |
843 | String refB; |
844 | StringView b = stringViewFromUTF8(refB, "" ); |
845 | |
846 | EXPECT_TRUE(a.endsWithIgnoringASCIICase(a)); |
847 | EXPECT_TRUE(a.endsWithIgnoringASCIICase(b)); |
848 | EXPECT_TRUE(b.endsWithIgnoringASCIICase(a)); |
849 | EXPECT_TRUE(b.endsWithIgnoringASCIICase(b)); |
850 | } |
851 | |
852 | TEST(WTF, StringViewEndsWithIgnoringASCIICaseWithLatin1Characters) |
853 | { |
854 | StringView reference = stringViewFromLiteral("aBcéeFG" ); |
855 | String referenceUTF8Ref; |
856 | StringView referenceUTF8 = stringViewFromUTF8(referenceUTF8Ref, "aBcéeFG" ); |
857 | |
858 | StringView a = stringViewFromLiteral("BcéeFG" ); |
859 | StringView b = stringViewFromLiteral("BCéEFG" ); |
860 | StringView c = stringViewFromLiteral("bcéefG" ); |
861 | StringView d = stringViewFromLiteral("bcéefg" ); |
862 | |
863 | String refE; |
864 | StringView e = stringViewFromUTF8(refE, "bcéefG" ); |
865 | String refF; |
866 | StringView f = stringViewFromUTF8(refF, "BCéEFG" ); |
867 | String refG; |
868 | StringView g = stringViewFromUTF8(refG, "bcéefG" ); |
869 | String refH; |
870 | StringView h = stringViewFromUTF8(refH, "bcéefg" ); |
871 | |
872 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(a)); |
873 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(b)); |
874 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(c)); |
875 | EXPECT_TRUE(reference.endsWithIgnoringASCIICase(d)); |
876 | |
877 | EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(e)); |
878 | EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(f)); |
879 | EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(g)); |
880 | EXPECT_TRUE(referenceUTF8.endsWithIgnoringASCIICase(h)); |
881 | |
882 | EXPECT_FALSE(reference.endsWithIgnoringASCIICase(referenceUTF8)); |
883 | EXPECT_FALSE(referenceUTF8.endsWithIgnoringASCIICase(reference)); |
884 | } |
885 | |
886 | TEST(WTF, StringView8Bit) |
887 | { |
888 | StringView nullView; |
889 | EXPECT_TRUE(StringView().is8Bit()); |
890 | EXPECT_TRUE(StringView::empty().is8Bit()); |
891 | |
892 | LChar* lcharPtr = nullptr; |
893 | UChar* ucharPtr = nullptr; |
894 | EXPECT_TRUE(StringView(lcharPtr, 0).is8Bit()); |
895 | EXPECT_FALSE(StringView(ucharPtr, 0).is8Bit()); |
896 | |
897 | EXPECT_TRUE(StringView(String(lcharPtr, 0)).is8Bit()); |
898 | EXPECT_TRUE(StringView(String(ucharPtr, 0)).is8Bit()); |
899 | |
900 | EXPECT_TRUE(StringView(String().impl()).is8Bit()); |
901 | EXPECT_TRUE(StringView(emptyString().impl()).is8Bit()); |
902 | } |
903 | |
904 | TEST(WTF, StringViewRightBasic) |
905 | { |
906 | auto reference = stringViewFromLiteral("Cappuccino" ); |
907 | EXPECT_TRUE(reference.right(0) == stringViewFromLiteral("" )); |
908 | EXPECT_TRUE(reference.right(1) == stringViewFromLiteral("o" )); |
909 | EXPECT_TRUE(reference.right(2) == stringViewFromLiteral("no" )); |
910 | EXPECT_TRUE(reference.right(3) == stringViewFromLiteral("ino" )); |
911 | EXPECT_TRUE(reference.right(4) == stringViewFromLiteral("cino" )); |
912 | EXPECT_TRUE(reference.right(5) == stringViewFromLiteral("ccino" )); |
913 | EXPECT_TRUE(reference.right(6) == stringViewFromLiteral("uccino" )); |
914 | EXPECT_TRUE(reference.right(7) == stringViewFromLiteral("puccino" )); |
915 | EXPECT_TRUE(reference.right(8) == stringViewFromLiteral("ppuccino" )); |
916 | EXPECT_TRUE(reference.right(9) == stringViewFromLiteral("appuccino" )); |
917 | EXPECT_TRUE(reference.right(10) == stringViewFromLiteral("Cappuccino" )); |
918 | } |
919 | |
920 | TEST(WTF, StringViewLeftBasic) |
921 | { |
922 | auto reference = stringViewFromLiteral("Cappuccino" ); |
923 | EXPECT_TRUE(reference.left(0) == stringViewFromLiteral("" )); |
924 | EXPECT_TRUE(reference.left(1) == stringViewFromLiteral("C" )); |
925 | EXPECT_TRUE(reference.left(2) == stringViewFromLiteral("Ca" )); |
926 | EXPECT_TRUE(reference.left(3) == stringViewFromLiteral("Cap" )); |
927 | EXPECT_TRUE(reference.left(4) == stringViewFromLiteral("Capp" )); |
928 | EXPECT_TRUE(reference.left(5) == stringViewFromLiteral("Cappu" )); |
929 | EXPECT_TRUE(reference.left(6) == stringViewFromLiteral("Cappuc" )); |
930 | EXPECT_TRUE(reference.left(7) == stringViewFromLiteral("Cappucc" )); |
931 | EXPECT_TRUE(reference.left(8) == stringViewFromLiteral("Cappucci" )); |
932 | EXPECT_TRUE(reference.left(9) == stringViewFromLiteral("Cappuccin" )); |
933 | EXPECT_TRUE(reference.left(10) == stringViewFromLiteral("Cappuccino" )); |
934 | } |
935 | |
936 | TEST(WTF, StringViewReverseFindBasic) |
937 | { |
938 | auto reference = stringViewFromLiteral("Cappuccino" ); |
939 | EXPECT_EQ(reference.reverseFind('o'), 9U); |
940 | EXPECT_EQ(reference.reverseFind('n'), 8U); |
941 | EXPECT_EQ(reference.reverseFind('c'), 6U); |
942 | EXPECT_EQ(reference.reverseFind('p'), 3U); |
943 | EXPECT_EQ(reference.reverseFind('k'), notFound); |
944 | |
945 | EXPECT_EQ(reference.reverseFind('o', 8), notFound); |
946 | EXPECT_EQ(reference.reverseFind('c', 8), 6U); |
947 | EXPECT_EQ(reference.reverseFind('c', 6), 6U); |
948 | EXPECT_EQ(reference.reverseFind('c', 5), 5U); |
949 | EXPECT_EQ(reference.reverseFind('c', 4), notFound); |
950 | } |
951 | |
952 | TEST(WTF, StringViewStripLeadingAndTrailingMatchedCharacters) |
953 | { |
954 | auto isA = [] (UChar c) { |
955 | return c == 'A'; |
956 | }; |
957 | |
958 | EXPECT_TRUE(stringViewFromLiteral("AAABBBAAA" ).stripLeadingAndTrailingMatchedCharacters(isA) == stringViewFromLiteral("BBB" )); |
959 | EXPECT_TRUE(stringViewFromLiteral("AAABBBCCC" ).stripLeadingAndTrailingMatchedCharacters(isA) == stringViewFromLiteral("BBBCCC" )); |
960 | EXPECT_TRUE(stringViewFromLiteral("CCCBBBAAA" ).stripLeadingAndTrailingMatchedCharacters(isA) == stringViewFromLiteral("CCCBBB" )); |
961 | EXPECT_TRUE(stringViewFromLiteral("CCCBBBCCC" ).stripLeadingAndTrailingMatchedCharacters(isA) == stringViewFromLiteral("CCCBBBCCC" )); |
962 | EXPECT_TRUE(stringViewFromLiteral("AAAAAACCC" ).stripLeadingAndTrailingMatchedCharacters(isA) == stringViewFromLiteral("CCC" )); |
963 | EXPECT_TRUE(stringViewFromLiteral("BBBAAAAAA" ).stripLeadingAndTrailingMatchedCharacters(isA) == stringViewFromLiteral("BBB" )); |
964 | EXPECT_TRUE(stringViewFromLiteral("CCCAAABBB" ).stripLeadingAndTrailingMatchedCharacters(isA) == stringViewFromLiteral("CCCAAABBB" )); |
965 | EXPECT_TRUE(stringViewFromLiteral("AAAAAAAAA" ).stripLeadingAndTrailingMatchedCharacters(isA) == StringView::empty()); |
966 | |
967 | StringView emptyView = StringView::empty(); |
968 | EXPECT_TRUE(emptyView.stripLeadingAndTrailingMatchedCharacters(isA) == emptyView); |
969 | |
970 | StringView nullView; |
971 | EXPECT_TRUE(nullView.stripLeadingAndTrailingMatchedCharacters(isA) == nullView); |
972 | } |
973 | |
974 | } // namespace TestWebKitAPI |
975 | |