8cd6c09cfb5c24f79a623876543af3791398226f
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WTF / StringImpl.cpp
1 /*
2  * Copyright (C) 2012, 2016 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/SymbolImpl.h>
29 #include <wtf/text/WTFString.h>
30
31 namespace TestWebKitAPI {
32
33 TEST(WTF, StringImplCreationFromLiteral)
34 {
35     // Constructor using the template to determine the size.
36     RefPtr<StringImpl> stringWithTemplate = StringImpl::createFromLiteral("Template Literal");
37     ASSERT_EQ(strlen("Template Literal"), stringWithTemplate->length());
38     ASSERT_TRUE(equal(stringWithTemplate.get(), "Template Literal"));
39     ASSERT_TRUE(stringWithTemplate->is8Bit());
40
41     // Constructor taking the size explicitely.
42     const char* programmaticStringData = "Explicit Size Literal";
43     RefPtr<StringImpl> programmaticString = StringImpl::createFromLiteral(programmaticStringData, strlen(programmaticStringData));
44     ASSERT_EQ(strlen(programmaticStringData), programmaticString->length());
45     ASSERT_TRUE(equal(programmaticString.get(), programmaticStringData));
46     ASSERT_EQ(programmaticStringData, reinterpret_cast<const char*>(programmaticString->characters8()));
47     ASSERT_TRUE(programmaticString->is8Bit());
48
49     // Constructor without explicit size.
50     const char* stringWithoutLengthLiteral = "No Size Literal";
51     RefPtr<StringImpl> programmaticStringNoLength = StringImpl::createFromLiteral(stringWithoutLengthLiteral);
52     ASSERT_EQ(strlen(stringWithoutLengthLiteral), programmaticStringNoLength->length());
53     ASSERT_TRUE(equal(programmaticStringNoLength.get(), stringWithoutLengthLiteral));
54     ASSERT_EQ(stringWithoutLengthLiteral, reinterpret_cast<const char*>(programmaticStringNoLength->characters8()));
55     ASSERT_TRUE(programmaticStringNoLength->is8Bit());
56 }
57
58 TEST(WTF, StringImplReplaceWithLiteral)
59 {
60     RefPtr<StringImpl> testStringImpl = StringImpl::createFromLiteral("1224");
61     ASSERT_TRUE(testStringImpl->is8Bit());
62
63     // Cases for 8Bit source.
64     testStringImpl = testStringImpl->replace('2', "", 0);
65     ASSERT_TRUE(equal(testStringImpl.get(), "14"));
66
67     testStringImpl = StringImpl::createFromLiteral("1224");
68     ASSERT_TRUE(testStringImpl->is8Bit());
69
70     testStringImpl = testStringImpl->replace('3', "NotFound", 8);
71     ASSERT_TRUE(equal(testStringImpl.get(), "1224"));
72
73     testStringImpl = testStringImpl->replace('2', "3", 1);
74     ASSERT_TRUE(equal(testStringImpl.get(), "1334"));
75
76     testStringImpl = StringImpl::createFromLiteral("1224");
77     ASSERT_TRUE(testStringImpl->is8Bit());
78     testStringImpl = testStringImpl->replace('2', "555", 3);
79     ASSERT_TRUE(equal(testStringImpl.get(), "15555554"));
80
81     // Cases for 16Bit source.
82     String testString = String::fromUTF8("résumé");
83     ASSERT_FALSE(testString.impl()->is8Bit());
84
85     testStringImpl = testString.impl()->replace('2', "NotFound", 8);
86     ASSERT_TRUE(equal(testStringImpl.get(), String::fromUTF8("résumé").impl()));
87
88     testStringImpl = testString.impl()->replace(UChar(0x00E9 /*U+00E9 is 'é'*/), "e", 1);
89     ASSERT_TRUE(equal(testStringImpl.get(), "resume"));
90
91     testString = String::fromUTF8("résumé");
92     ASSERT_FALSE(testString.impl()->is8Bit());
93     testStringImpl = testString.impl()->replace(UChar(0x00E9 /*U+00E9 is 'é'*/), "", 0);
94     ASSERT_TRUE(equal(testStringImpl.get(), "rsum"));
95
96     testString = String::fromUTF8("résumé");
97     ASSERT_FALSE(testString.impl()->is8Bit());
98     testStringImpl = testString.impl()->replace(UChar(0x00E9 /*U+00E9 is 'é'*/), "555", 3);
99     ASSERT_TRUE(equal(testStringImpl.get(), "r555sum555"));
100 }
101
102 TEST(WTF, StringImplEqualIgnoringASCIICaseBasic)
103 {
104     RefPtr<StringImpl> a = StringImpl::createFromLiteral("aBcDeFG");
105     RefPtr<StringImpl> b = StringImpl::createFromLiteral("ABCDEFG");
106     RefPtr<StringImpl> c = StringImpl::createFromLiteral("abcdefg");
107     const char d[] = "aBcDeFG";
108     RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
109     RefPtr<StringImpl> shorter = StringImpl::createFromLiteral("abcdef");
110     RefPtr<StringImpl> different = StringImpl::createFromLiteral("abcrefg");
111
112     // Identity.
113     ASSERT_TRUE(equalIgnoringASCIICase(a.get(), a.get()));
114     ASSERT_TRUE(equalIgnoringASCIICase(b.get(), b.get()));
115     ASSERT_TRUE(equalIgnoringASCIICase(c.get(), c.get()));
116     ASSERT_TRUE(equalIgnoringASCIICase(a.get(), d));
117     ASSERT_TRUE(equalIgnoringASCIICase(b.get(), d));
118     ASSERT_TRUE(equalIgnoringASCIICase(c.get(), d));
119
120     // Transitivity.
121     ASSERT_TRUE(equalIgnoringASCIICase(a.get(), b.get()));
122     ASSERT_TRUE(equalIgnoringASCIICase(b.get(), c.get()));
123     ASSERT_TRUE(equalIgnoringASCIICase(a.get(), c.get()));
124
125     // Negative cases.
126     ASSERT_FALSE(equalIgnoringASCIICase(a.get(), empty.get()));
127     ASSERT_FALSE(equalIgnoringASCIICase(b.get(), empty.get()));
128     ASSERT_FALSE(equalIgnoringASCIICase(c.get(), empty.get()));
129     ASSERT_FALSE(equalIgnoringASCIICase(a.get(), shorter.get()));
130     ASSERT_FALSE(equalIgnoringASCIICase(b.get(), shorter.get()));
131     ASSERT_FALSE(equalIgnoringASCIICase(c.get(), shorter.get()));
132     ASSERT_FALSE(equalIgnoringASCIICase(a.get(), different.get()));
133     ASSERT_FALSE(equalIgnoringASCIICase(b.get(), different.get()));
134     ASSERT_FALSE(equalIgnoringASCIICase(c.get(), different.get()));
135     ASSERT_FALSE(equalIgnoringASCIICase(empty.get(), d));
136     ASSERT_FALSE(equalIgnoringASCIICase(shorter.get(), d));
137     ASSERT_FALSE(equalIgnoringASCIICase(different.get(), d));
138 }
139
140 TEST(WTF, StringImplEqualIgnoringASCIICaseWithNull)
141 {
142     RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG");
143     StringImpl* nullStringImpl = nullptr;
144     ASSERT_FALSE(equalIgnoringASCIICase(nullStringImpl, reference.get()));
145     ASSERT_FALSE(equalIgnoringASCIICase(reference.get(), nullStringImpl));
146     ASSERT_TRUE(equalIgnoringASCIICase(nullStringImpl, nullStringImpl));
147 }
148
149 TEST(WTF, StringImplEqualIgnoringASCIICaseWithEmpty)
150 {
151     RefPtr<StringImpl> a = StringImpl::create(reinterpret_cast<const LChar*>(""));
152     RefPtr<StringImpl> b = StringImpl::create(reinterpret_cast<const LChar*>(""));
153     ASSERT_TRUE(equalIgnoringASCIICase(a.get(), b.get()));
154     ASSERT_TRUE(equalIgnoringASCIICase(b.get(), a.get()));
155 }
156
157 static RefPtr<StringImpl> stringFromUTF8(const char* characters)
158 {
159     return String::fromUTF8(characters).impl();
160 }
161
162 TEST(WTF, StringImplEqualIgnoringASCIICaseWithLatin1Characters)
163 {
164     RefPtr<StringImpl> a = stringFromUTF8("aBcéeFG");
165     RefPtr<StringImpl> b = stringFromUTF8("ABCÉEFG");
166     RefPtr<StringImpl> c = stringFromUTF8("ABCéEFG");
167     RefPtr<StringImpl> d = stringFromUTF8("abcéefg");
168     const char e[] = "aBcéeFG";
169
170     // Identity.
171     ASSERT_TRUE(equalIgnoringASCIICase(a.get(), a.get()));
172     ASSERT_TRUE(equalIgnoringASCIICase(b.get(), b.get()));
173     ASSERT_TRUE(equalIgnoringASCIICase(c.get(), c.get()));
174     ASSERT_TRUE(equalIgnoringASCIICase(d.get(), d.get()));
175
176     // All combination.
177     ASSERT_FALSE(equalIgnoringASCIICase(a.get(), b.get()));
178     ASSERT_TRUE(equalIgnoringASCIICase(a.get(), c.get()));
179     ASSERT_TRUE(equalIgnoringASCIICase(a.get(), d.get()));
180     ASSERT_FALSE(equalIgnoringASCIICase(b.get(), c.get()));
181     ASSERT_FALSE(equalIgnoringASCIICase(b.get(), d.get()));
182     ASSERT_TRUE(equalIgnoringASCIICase(c.get(), d.get()));
183     ASSERT_FALSE(equalIgnoringASCIICase(a.get(), e));
184     ASSERT_FALSE(equalIgnoringASCIICase(b.get(), e));
185     ASSERT_FALSE(equalIgnoringASCIICase(c.get(), e));
186     ASSERT_FALSE(equalIgnoringASCIICase(d.get(), e));
187 }
188
189 TEST(WTF, StringImplFindIgnoringASCIICaseBasic)
190 {
191     RefPtr<StringImpl> referenceA = stringFromUTF8("aBcéeFG");
192     RefPtr<StringImpl> referenceB = stringFromUTF8("ABCÉEFG");
193
194     // Search the exact string.
195     EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(referenceA.get()));
196     EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(referenceB.get()));
197
198     // A and B are distinct by the non-ascii character é/É.
199     EXPECT_EQ(static_cast<size_t>(notFound), referenceA->findIgnoringASCIICase(referenceB.get()));
200     EXPECT_EQ(static_cast<size_t>(notFound), referenceB->findIgnoringASCIICase(referenceA.get()));
201
202     // Find the prefix.
203     EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("a").get()));
204     EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(stringFromUTF8("abcé").get()));
205     EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("A").get()));
206     EXPECT_EQ(static_cast<size_t>(0), referenceA->findIgnoringASCIICase(stringFromUTF8("ABCé").get()));
207     EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("a").get()));
208     EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(stringFromUTF8("abcÉ").get()));
209     EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("A").get()));
210     EXPECT_EQ(static_cast<size_t>(0), referenceB->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get()));
211
212     // Not a prefix.
213     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("x").get()));
214     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("accé").get()));
215     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("abcÉ").get()));
216     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("X").get()));
217     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("ABDé").get()));
218     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get()));
219     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("y").get()));
220     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("accÉ").get()));
221     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("abcé").get()));
222     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("Y").get()));
223     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("ABdÉ").get()));
224     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("ABCé").get()));
225
226     // Find the infix.
227     EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("cée").get()));
228     EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("ée").get()));
229     EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("cé").get()));
230     EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("c").get()));
231     EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("é").get()));
232     EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("Cée").get()));
233     EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("éE").get()));
234     EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("Cé").get()));
235     EXPECT_EQ(static_cast<size_t>(2), referenceA->findIgnoringASCIICase(stringFromUTF8("C").get()));
236
237     EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("cÉe").get()));
238     EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("Ée").get()));
239     EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("cÉ").get()));
240     EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("c").get()));
241     EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("É").get()));
242     EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("CÉe").get()));
243     EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("ÉE").get()));
244     EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("CÉ").get()));
245     EXPECT_EQ(static_cast<size_t>(2), referenceB->findIgnoringASCIICase(stringFromUTF8("C").get()));
246
247     // Not an infix.
248     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("céd").get()));
249     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("Ée").get()));
250     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("bé").get()));
251     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("x").get()));
252     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("É").get()));
253     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("CÉe").get()));
254     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("éd").get()));
255     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("CÉ").get()));
256     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("Y").get()));
257
258     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("cée").get()));
259     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("Éc").get()));
260     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("cé").get()));
261     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("W").get()));
262     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("é").get()));
263     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("bÉe").get()));
264     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("éE").get()));
265     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("BÉ").get()));
266     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("z").get()));
267
268     // Find the suffix.
269     EXPECT_EQ(static_cast<size_t>(6), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("g").get()));
270     EXPECT_EQ(static_cast<size_t>(4), referenceA->findIgnoringASCIICase(stringFromUTF8("efg").get()));
271     EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("éefg").get()));
272     EXPECT_EQ(static_cast<size_t>(6), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("G").get()));
273     EXPECT_EQ(static_cast<size_t>(4), referenceA->findIgnoringASCIICase(stringFromUTF8("EFG").get()));
274     EXPECT_EQ(static_cast<size_t>(3), referenceA->findIgnoringASCIICase(stringFromUTF8("éEFG").get()));
275
276     EXPECT_EQ(static_cast<size_t>(6), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("g").get()));
277     EXPECT_EQ(static_cast<size_t>(4), referenceB->findIgnoringASCIICase(stringFromUTF8("efg").get()));
278     EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("Éefg").get()));
279     EXPECT_EQ(static_cast<size_t>(6), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("G").get()));
280     EXPECT_EQ(static_cast<size_t>(4), referenceB->findIgnoringASCIICase(stringFromUTF8("EFG").get()));
281     EXPECT_EQ(static_cast<size_t>(3), referenceB->findIgnoringASCIICase(stringFromUTF8("ÉEFG").get()));
282
283     // Not a suffix.
284     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("X").get()));
285     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("edg").get()));
286     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("Éefg").get()));
287     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(StringImpl::createFromLiteral("w").get()));
288     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("dFG").get()));
289     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceA->findIgnoringASCIICase(stringFromUTF8("ÉEFG").get()));
290
291     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("Z").get()));
292     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("ffg").get()));
293     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("éefg").get()));
294     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(StringImpl::createFromLiteral("r").get()));
295     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("EgG").get()));
296     EXPECT_EQ(static_cast<size_t>(WTF::notFound), referenceB->findIgnoringASCIICase(stringFromUTF8("éEFG").get()));
297 }
298
299 TEST(WTF, StringImplFindIgnoringASCIICaseWithValidOffset)
300 {
301     RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFGaBcéeFG");
302     EXPECT_EQ(static_cast<size_t>(0), reference->findIgnoringASCIICase(stringFromUTF8("ABC").get(), 0));
303     EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(stringFromUTF8("ABC").get(), 1));
304     EXPECT_EQ(static_cast<size_t>(0), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), 0));
305     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), 1));
306     EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(stringFromUTF8("ABCé").get(), 0));
307     EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(stringFromUTF8("ABCé").get(), 1));
308 }
309
310 TEST(WTF, StringImplFindIgnoringASCIICaseWithInvalidOffset)
311 {
312     RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFGaBcéeFG");
313     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABC").get(), 15));
314     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABC").get(), 16));
315     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), 17));
316     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), 42));
317     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(stringFromUTF8("ABCÉ").get(), std::numeric_limits<unsigned>::max()));
318 }
319
320 TEST(WTF, StringImplFindIgnoringASCIICaseOnNull)
321 {
322     RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFG");
323     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr));
324     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 0));
325     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 3));
326     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 7));
327     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 8));
328     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, 42));
329     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(nullptr, std::numeric_limits<unsigned>::max()));
330 }
331
332 TEST(WTF, StringImplFindIgnoringASCIICaseOnEmpty)
333 {
334     RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFG");
335     RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
336     EXPECT_EQ(static_cast<size_t>(0), reference->findIgnoringASCIICase(empty.get()));
337     EXPECT_EQ(static_cast<size_t>(0), reference->findIgnoringASCIICase(empty.get(), 0));
338     EXPECT_EQ(static_cast<size_t>(3), reference->findIgnoringASCIICase(empty.get(), 3));
339     EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(empty.get(), 7));
340     EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(empty.get(), 8));
341     EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(empty.get(), 42));
342     EXPECT_EQ(static_cast<size_t>(7), reference->findIgnoringASCIICase(empty.get(), std::numeric_limits<unsigned>::max()));
343 }
344
345 TEST(WTF, StringImplFindIgnoringASCIICaseWithPatternLongerThanReference)
346 {
347     RefPtr<StringImpl> reference = stringFromUTF8("ABCÉEFG");
348     RefPtr<StringImpl> pattern = stringFromUTF8("XABCÉEFG");
349     EXPECT_EQ(static_cast<size_t>(WTF::notFound), reference->findIgnoringASCIICase(pattern.get()));
350     EXPECT_EQ(static_cast<size_t>(1), pattern->findIgnoringASCIICase(reference.get()));
351 }
352
353 TEST(WTF, StringImplStartsWithIgnoringASCIICaseBasic)
354 {
355     RefPtr<StringImpl> reference = stringFromUTF8("aBcéX");
356     RefPtr<StringImpl> referenceEquivalent = stringFromUTF8("AbCéx");
357
358     // Identity.
359     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(reference.get()));
360     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*reference.get()));
361     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(referenceEquivalent.get()));
362     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*referenceEquivalent.get()));
363     ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(reference.get()));
364     ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(*reference.get()));
365     ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(referenceEquivalent.get()));
366     ASSERT_TRUE(referenceEquivalent->startsWithIgnoringASCIICase(*referenceEquivalent.get()));
367
368     // Proper prefixes.
369     RefPtr<StringImpl> aLower = StringImpl::createFromLiteral("a");
370     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(aLower.get()));
371     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*aLower.get()));
372     RefPtr<StringImpl> aUpper = StringImpl::createFromLiteral("A");
373     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(aUpper.get()));
374     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*aUpper.get()));
375
376     RefPtr<StringImpl> abcLower = StringImpl::createFromLiteral("abc");
377     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcLower.get()));
378     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcLower.get()));
379     RefPtr<StringImpl> abcUpper = StringImpl::createFromLiteral("ABC");
380     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcUpper.get()));
381     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcUpper.get()));
382
383     RefPtr<StringImpl> abcAccentLower = stringFromUTF8("abcé");
384     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcAccentLower.get()));
385     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcAccentLower.get()));
386     RefPtr<StringImpl> abcAccentUpper = stringFromUTF8("ABCé");
387     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(abcAccentUpper.get()));
388     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*abcAccentUpper.get()));
389
390     // Negative cases.
391     RefPtr<StringImpl> differentFirstChar = stringFromUTF8("bBcéX");
392     RefPtr<StringImpl> differentFirstCharProperPrefix = stringFromUTF8("CBcé");
393     ASSERT_FALSE(reference->startsWithIgnoringASCIICase(differentFirstChar.get()));
394     ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*differentFirstChar.get()));
395     ASSERT_FALSE(reference->startsWithIgnoringASCIICase(differentFirstCharProperPrefix.get()));
396     ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*differentFirstCharProperPrefix.get()));
397
398     RefPtr<StringImpl> uppercaseAccent = stringFromUTF8("aBcÉX");
399     RefPtr<StringImpl> uppercaseAccentProperPrefix = stringFromUTF8("aBcÉX");
400     ASSERT_FALSE(reference->startsWithIgnoringASCIICase(uppercaseAccent.get()));
401     ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*uppercaseAccent.get()));
402     ASSERT_FALSE(reference->startsWithIgnoringASCIICase(uppercaseAccentProperPrefix.get()));
403     ASSERT_FALSE(reference->startsWithIgnoringASCIICase(*uppercaseAccentProperPrefix.get()));
404 }
405
406 TEST(WTF, StringImplStartsWithIgnoringASCIICaseWithNull)
407 {
408     RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG");
409     ASSERT_FALSE(reference->startsWithIgnoringASCIICase(nullptr));
410
411     RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
412     ASSERT_FALSE(empty->startsWithIgnoringASCIICase(nullptr));
413 }
414
415 TEST(WTF, StringImplStartsWithIgnoringASCIICaseWithEmpty)
416 {
417     RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG");
418     RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
419     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(empty.get()));
420     ASSERT_TRUE(reference->startsWithIgnoringASCIICase(*empty.get()));
421     ASSERT_TRUE(empty->startsWithIgnoringASCIICase(empty.get()));
422     ASSERT_TRUE(empty->startsWithIgnoringASCIICase(*empty.get()));
423     ASSERT_FALSE(empty->startsWithIgnoringASCIICase(reference.get()));
424     ASSERT_FALSE(empty->startsWithIgnoringASCIICase(*reference.get()));
425 }
426
427 TEST(WTF, StartsWithLettersIgnoringASCIICase)
428 {
429     String string("Test tEST");
430     ASSERT_TRUE(startsWithLettersIgnoringASCIICase(string, "test t"));
431     ASSERT_TRUE(startsWithLettersIgnoringASCIICase(string, "test te"));
432     ASSERT_TRUE(startsWithLettersIgnoringASCIICase(string, "test test"));
433     ASSERT_FALSE(startsWithLettersIgnoringASCIICase(string, "test tex"));
434
435     ASSERT_TRUE(startsWithLettersIgnoringASCIICase(string, ""));
436     ASSERT_TRUE(startsWithLettersIgnoringASCIICase(String(""), ""));
437
438     ASSERT_FALSE(startsWithLettersIgnoringASCIICase(String(), "t"));
439     ASSERT_FALSE(startsWithLettersIgnoringASCIICase(String(), ""));
440 }
441
442 TEST(WTF, StringImplEndsWithIgnoringASCIICaseBasic)
443 {
444     RefPtr<StringImpl> reference = stringFromUTF8("XÉCbA");
445     RefPtr<StringImpl> referenceEquivalent = stringFromUTF8("xÉcBa");
446
447     // Identity.
448     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(reference.get()));
449     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*reference.get()));
450     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(referenceEquivalent.get()));
451     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*referenceEquivalent.get()));
452     ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(reference.get()));
453     ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(*reference.get()));
454     ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(referenceEquivalent.get()));
455     ASSERT_TRUE(referenceEquivalent->endsWithIgnoringASCIICase(*referenceEquivalent.get()));
456
457     // Proper suffixes.
458     RefPtr<StringImpl> aLower = StringImpl::createFromLiteral("a");
459     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(aLower.get()));
460     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*aLower.get()));
461     RefPtr<StringImpl> aUpper = StringImpl::createFromLiteral("a");
462     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(aUpper.get()));
463     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*aUpper.get()));
464
465     RefPtr<StringImpl> abcLower = StringImpl::createFromLiteral("cba");
466     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcLower.get()));
467     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcLower.get()));
468     RefPtr<StringImpl> abcUpper = StringImpl::createFromLiteral("CBA");
469     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcUpper.get()));
470     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcUpper.get()));
471
472     RefPtr<StringImpl> abcAccentLower = stringFromUTF8("Écba");
473     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcAccentLower.get()));
474     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcAccentLower.get()));
475     RefPtr<StringImpl> abcAccentUpper = stringFromUTF8("ÉCBA");
476     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(abcAccentUpper.get()));
477     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*abcAccentUpper.get()));
478
479     // Negative cases.
480     RefPtr<StringImpl> differentLastChar = stringFromUTF8("XÉCbB");
481     RefPtr<StringImpl> differentLastCharProperSuffix = stringFromUTF8("ÉCbb");
482     ASSERT_FALSE(reference->endsWithIgnoringASCIICase(differentLastChar.get()));
483     ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*differentLastChar.get()));
484     ASSERT_FALSE(reference->endsWithIgnoringASCIICase(differentLastCharProperSuffix.get()));
485     ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*differentLastCharProperSuffix.get()));
486
487     RefPtr<StringImpl> lowercaseAccent = stringFromUTF8("aBcéX");
488     RefPtr<StringImpl> loweraseAccentProperSuffix = stringFromUTF8("aBcéX");
489     ASSERT_FALSE(reference->endsWithIgnoringASCIICase(lowercaseAccent.get()));
490     ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*lowercaseAccent.get()));
491     ASSERT_FALSE(reference->endsWithIgnoringASCIICase(loweraseAccentProperSuffix.get()));
492     ASSERT_FALSE(reference->endsWithIgnoringASCIICase(*loweraseAccentProperSuffix.get()));
493 }
494
495 TEST(WTF, StringImplEndsWithIgnoringASCIICaseWithNull)
496 {
497     RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG");
498     ASSERT_FALSE(reference->endsWithIgnoringASCIICase(nullptr));
499
500     RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
501     ASSERT_FALSE(empty->endsWithIgnoringASCIICase(nullptr));
502 }
503
504 TEST(WTF, StringImplEndsWithIgnoringASCIICaseWithEmpty)
505 {
506     RefPtr<StringImpl> reference = StringImpl::createFromLiteral("aBcDeFG");
507     RefPtr<StringImpl> empty = StringImpl::create(reinterpret_cast<const LChar*>(""));
508     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(empty.get()));
509     ASSERT_TRUE(reference->endsWithIgnoringASCIICase(*empty.get()));
510     ASSERT_TRUE(empty->endsWithIgnoringASCIICase(empty.get()));
511     ASSERT_TRUE(empty->endsWithIgnoringASCIICase(*empty.get()));
512     ASSERT_FALSE(empty->endsWithIgnoringASCIICase(reference.get()));
513     ASSERT_FALSE(empty->endsWithIgnoringASCIICase(*reference.get()));
514 }
515
516 TEST(WTF, StringImplCreateNullSymbol)
517 {
518     RefPtr<StringImpl> reference = StringImpl::createNullSymbol();
519     ASSERT_TRUE(reference->isSymbol());
520     ASSERT_TRUE(reference->isNullSymbol());
521     ASSERT_FALSE(reference->isAtomic());
522     ASSERT_EQ(0u, reference->length());
523     ASSERT_TRUE(equal(reference.get(), ""));
524 }
525
526 TEST(WTF, StringImplCreateSymbol)
527 {
528     RefPtr<StringImpl> original = stringFromUTF8("original");
529     RefPtr<StringImpl> reference = StringImpl::createSymbol(original);
530     ASSERT_TRUE(reference->isSymbol());
531     ASSERT_FALSE(reference->isNullSymbol());
532     ASSERT_FALSE(reference->isAtomic());
533     ASSERT_FALSE(original->isSymbol());
534     ASSERT_FALSE(original->isAtomic());
535     ASSERT_EQ(original->length(), reference->length());
536     ASSERT_TRUE(equal(reference.get(), "original"));
537
538     RefPtr<StringImpl> empty = stringFromUTF8("");
539     RefPtr<StringImpl> emptyReference = StringImpl::createSymbol(empty);
540     ASSERT_TRUE(emptyReference->isSymbol());
541     ASSERT_FALSE(emptyReference->isNullSymbol());
542     ASSERT_FALSE(emptyReference->isAtomic());
543     ASSERT_FALSE(empty->isSymbol());
544     ASSERT_FALSE(empty->isNullSymbol());
545     ASSERT_TRUE(empty->isAtomic());
546     ASSERT_EQ(empty->length(), emptyReference->length());
547     ASSERT_TRUE(equal(emptyReference.get(), ""));
548 }
549
550 TEST(WTF, StringImplSymbolToAtomicString)
551 {
552     RefPtr<StringImpl> original = stringFromUTF8("original");
553     RefPtr<StringImpl> reference = StringImpl::createSymbol(original);
554     ASSERT_TRUE(reference->isSymbol());
555     ASSERT_FALSE(reference->isAtomic());
556
557     RefPtr<StringImpl> atomic = AtomicStringImpl::add(reference.get());
558     ASSERT_TRUE(atomic->isAtomic());
559     ASSERT_FALSE(atomic->isSymbol());
560     ASSERT_TRUE(reference->isSymbol());
561     ASSERT_FALSE(reference->isAtomic());
562 }
563
564 TEST(WTF, StringImplNullSymbolToAtomicString)
565 {
566     RefPtr<StringImpl> reference = StringImpl::createNullSymbol();
567     ASSERT_TRUE(reference->isSymbol());
568     ASSERT_FALSE(reference->isAtomic());
569
570     RefPtr<StringImpl> atomic = AtomicStringImpl::add(reference.get());
571     ASSERT_TRUE(atomic->isAtomic());
572     ASSERT_FALSE(atomic->isSymbol());
573     ASSERT_TRUE(reference->isSymbol());
574     ASSERT_FALSE(reference->isAtomic());
575 }
576
577 } // namespace TestWebKitAPI