xref: /aosp_15_r20/external/cronet/base/i18n/string_search_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2011 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/i18n/string_search.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <string>
10*6777b538SAndroid Build Coastguard Worker #include <vector>
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker #include "base/i18n/rtl.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/strings/utf_string_conversions.h"
14*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
15*6777b538SAndroid Build Coastguard Worker #include "third_party/icu/source/i18n/unicode/usearch.h"
16*6777b538SAndroid Build Coastguard Worker 
17*6777b538SAndroid Build Coastguard Worker namespace base {
18*6777b538SAndroid Build Coastguard Worker namespace i18n {
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker #define EXPECT_MATCH_IGNORE_CASE(find_this, in_this, ex_start, ex_len)         \
21*6777b538SAndroid Build Coastguard Worker   {                                                                            \
22*6777b538SAndroid Build Coastguard Worker     size_t index = 0;                                                          \
23*6777b538SAndroid Build Coastguard Worker     size_t length = 0;                                                         \
24*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(StringSearchIgnoringCaseAndAccents(find_this, in_this, &index, \
25*6777b538SAndroid Build Coastguard Worker                                                    &length));                  \
26*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_start, index);                                                \
27*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_len, length);                                                 \
28*6777b538SAndroid Build Coastguard Worker     index = 0;                                                                 \
29*6777b538SAndroid Build Coastguard Worker     length = 0;                                                                \
30*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(                                                               \
31*6777b538SAndroid Build Coastguard Worker         StringSearch(find_this, in_this, &index, &length, false, true));       \
32*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_start, index);                                                \
33*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_len, length);                                                 \
34*6777b538SAndroid Build Coastguard Worker   }
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker #define EXPECT_MATCH_SENSITIVE(find_this, in_this, ex_start, ex_len)    \
37*6777b538SAndroid Build Coastguard Worker   {                                                                     \
38*6777b538SAndroid Build Coastguard Worker     size_t index = 0;                                                   \
39*6777b538SAndroid Build Coastguard Worker     size_t length = 0;                                                  \
40*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(                                                        \
41*6777b538SAndroid Build Coastguard Worker         StringSearch(find_this, in_this, &index, &length, true, true)); \
42*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_start, index);                                         \
43*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_len, length);                                          \
44*6777b538SAndroid Build Coastguard Worker   }
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker #define EXPECT_MATCH_IGNORE_CASE_BACKWARDS(find_this, in_this, ex_start,  \
47*6777b538SAndroid Build Coastguard Worker                                            ex_len)                        \
48*6777b538SAndroid Build Coastguard Worker   {                                                                       \
49*6777b538SAndroid Build Coastguard Worker     size_t index = 0;                                                     \
50*6777b538SAndroid Build Coastguard Worker     size_t length = 0;                                                    \
51*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(                                                          \
52*6777b538SAndroid Build Coastguard Worker         StringSearch(find_this, in_this, &index, &length, false, false)); \
53*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_start, index);                                           \
54*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_len, length);                                            \
55*6777b538SAndroid Build Coastguard Worker   }
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker #define EXPECT_MATCH_SENSITIVE_BACKWARDS(find_this, in_this, ex_start, ex_len) \
58*6777b538SAndroid Build Coastguard Worker   {                                                                            \
59*6777b538SAndroid Build Coastguard Worker     size_t index = 0;                                                          \
60*6777b538SAndroid Build Coastguard Worker     size_t length = 0;                                                         \
61*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(                                                               \
62*6777b538SAndroid Build Coastguard Worker         StringSearch(find_this, in_this, &index, &length, true, false));       \
63*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_start, index);                                                \
64*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(ex_len, length);                                                 \
65*6777b538SAndroid Build Coastguard Worker   }
66*6777b538SAndroid Build Coastguard Worker 
67*6777b538SAndroid Build Coastguard Worker #define EXPECT_MISS_IGNORE_CASE(find_this, in_this)                      \
68*6777b538SAndroid Build Coastguard Worker   {                                                                      \
69*6777b538SAndroid Build Coastguard Worker     size_t index = 0;                                                    \
70*6777b538SAndroid Build Coastguard Worker     size_t length = 0;                                                   \
71*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(StringSearchIgnoringCaseAndAccents(find_this, in_this,  \
72*6777b538SAndroid Build Coastguard Worker                                                     &index, &length));   \
73*6777b538SAndroid Build Coastguard Worker     index = 0;                                                           \
74*6777b538SAndroid Build Coastguard Worker     length = 0;                                                          \
75*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(                                                        \
76*6777b538SAndroid Build Coastguard Worker         StringSearch(find_this, in_this, &index, &length, false, true)); \
77*6777b538SAndroid Build Coastguard Worker   }
78*6777b538SAndroid Build Coastguard Worker 
79*6777b538SAndroid Build Coastguard Worker #define EXPECT_MISS_SENSITIVE(find_this, in_this)                       \
80*6777b538SAndroid Build Coastguard Worker   {                                                                     \
81*6777b538SAndroid Build Coastguard Worker     size_t index = 0;                                                   \
82*6777b538SAndroid Build Coastguard Worker     size_t length = 0;                                                  \
83*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(                                                       \
84*6777b538SAndroid Build Coastguard Worker         StringSearch(find_this, in_this, &index, &length, true, true)); \
85*6777b538SAndroid Build Coastguard Worker   }
86*6777b538SAndroid Build Coastguard Worker 
87*6777b538SAndroid Build Coastguard Worker #define EXPECT_MISS_IGNORE_CASE_BACKWARDS(find_this, in_this)             \
88*6777b538SAndroid Build Coastguard Worker   {                                                                       \
89*6777b538SAndroid Build Coastguard Worker     size_t index = 0;                                                     \
90*6777b538SAndroid Build Coastguard Worker     size_t length = 0;                                                    \
91*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(                                                         \
92*6777b538SAndroid Build Coastguard Worker         StringSearch(find_this, in_this, &index, &length, false, false)); \
93*6777b538SAndroid Build Coastguard Worker   }
94*6777b538SAndroid Build Coastguard Worker 
95*6777b538SAndroid Build Coastguard Worker #define EXPECT_MISS_SENSITIVE_BACKWARDS(find_this, in_this)              \
96*6777b538SAndroid Build Coastguard Worker   {                                                                      \
97*6777b538SAndroid Build Coastguard Worker     size_t index = 0;                                                    \
98*6777b538SAndroid Build Coastguard Worker     size_t length = 0;                                                   \
99*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(                                                        \
100*6777b538SAndroid Build Coastguard Worker         StringSearch(find_this, in_this, &index, &length, true, false)); \
101*6777b538SAndroid Build Coastguard Worker   }
102*6777b538SAndroid Build Coastguard Worker 
103*6777b538SAndroid Build Coastguard Worker // Note on setting default locale for testing: The current default locale on
104*6777b538SAndroid Build Coastguard Worker // the Mac trybot is en_US_POSIX, with which primary-level collation strength
105*6777b538SAndroid Build Coastguard Worker // string search is case-sensitive, when normally it should be
106*6777b538SAndroid Build Coastguard Worker // case-insensitive. In other locales (including en_US which English speakers
107*6777b538SAndroid Build Coastguard Worker // in the U.S. use), this search would be case-insensitive as expected.
108*6777b538SAndroid Build Coastguard Worker 
TEST(StringSearchTest,ASCII)109*6777b538SAndroid Build Coastguard Worker TEST(StringSearchTest, ASCII) {
110*6777b538SAndroid Build Coastguard Worker   std::string default_locale(uloc_getDefault());
111*6777b538SAndroid Build Coastguard Worker   bool locale_is_posix = (default_locale == "en_US_POSIX");
112*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
113*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale("en_US");
114*6777b538SAndroid Build Coastguard Worker 
115*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(u"hello", u"hello world", 0U, 5U);
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_IGNORE_CASE(u"h    e l l o", u"h   e l l o");
118*6777b538SAndroid Build Coastguard Worker 
119*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(u"aabaaa", u"aaabaabaaa", 4U, 6U);
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_IGNORE_CASE(u"searching within empty string", std::u16string());
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(std::u16string(), u"searching for empty string", 0U,
124*6777b538SAndroid Build Coastguard Worker                            0U);
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(u"case insensitivity", u"CaSe InSeNsItIvItY", 0U,
127*6777b538SAndroid Build Coastguard Worker                            18U);
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_SENSITIVE(u"aabaaa", u"aaabaabaaa", 4U, 6U);
130*6777b538SAndroid Build Coastguard Worker 
131*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(u"searching within empty string", std::u16string());
132*6777b538SAndroid Build Coastguard Worker 
133*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_SENSITIVE(std::u16string(), u"searching for empty string", 0U,
134*6777b538SAndroid Build Coastguard Worker                          0U);
135*6777b538SAndroid Build Coastguard Worker 
136*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(u"case insensitivity", u"CaSe InSeNsItIvItY");
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
139*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale(default_locale.data());
140*6777b538SAndroid Build Coastguard Worker }
141*6777b538SAndroid Build Coastguard Worker 
TEST(StringSearchTest,UnicodeLocaleIndependent)142*6777b538SAndroid Build Coastguard Worker TEST(StringSearchTest, UnicodeLocaleIndependent) {
143*6777b538SAndroid Build Coastguard Worker   // Base characters
144*6777b538SAndroid Build Coastguard Worker   const std::u16string e_base = u"e";
145*6777b538SAndroid Build Coastguard Worker   const std::u16string E_base = u"E";
146*6777b538SAndroid Build Coastguard Worker   const std::u16string a_base = u"a";
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker   // Composed characters
149*6777b538SAndroid Build Coastguard Worker   const std::u16string e_with_acute_accent = u"\u00e9";
150*6777b538SAndroid Build Coastguard Worker   const std::u16string E_with_acute_accent = u"\u00c9";
151*6777b538SAndroid Build Coastguard Worker   const std::u16string e_with_grave_accent = u"\u00e8";
152*6777b538SAndroid Build Coastguard Worker   const std::u16string E_with_grave_accent = u"\u00c8";
153*6777b538SAndroid Build Coastguard Worker   const std::u16string a_with_acute_accent = u"\u00e1";
154*6777b538SAndroid Build Coastguard Worker 
155*6777b538SAndroid Build Coastguard Worker   // Decomposed characters
156*6777b538SAndroid Build Coastguard Worker   const std::u16string e_with_acute_combining_mark = u"e\u0301";
157*6777b538SAndroid Build Coastguard Worker   const std::u16string E_with_acute_combining_mark = u"E\u0301";
158*6777b538SAndroid Build Coastguard Worker   const std::u16string e_with_grave_combining_mark = u"e\u0300";
159*6777b538SAndroid Build Coastguard Worker   const std::u16string E_with_grave_combining_mark = u"E\u0300";
160*6777b538SAndroid Build Coastguard Worker   const std::u16string a_with_acute_combining_mark = u"a\u0301";
161*6777b538SAndroid Build Coastguard Worker 
162*6777b538SAndroid Build Coastguard Worker   std::string default_locale(uloc_getDefault());
163*6777b538SAndroid Build Coastguard Worker   bool locale_is_posix = (default_locale == "en_US_POSIX");
164*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
165*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale("en_US");
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_base, e_with_acute_accent, 0U,
168*6777b538SAndroid Build Coastguard Worker                            e_with_acute_accent.size());
169*6777b538SAndroid Build Coastguard Worker 
170*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_with_acute_accent, e_base, 0U, e_base.size());
171*6777b538SAndroid Build Coastguard Worker 
172*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_base, e_with_acute_combining_mark, 0U,
173*6777b538SAndroid Build Coastguard Worker                            e_with_acute_combining_mark.size());
174*6777b538SAndroid Build Coastguard Worker 
175*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_with_acute_combining_mark, e_base, 0U,
176*6777b538SAndroid Build Coastguard Worker                            e_base.size());
177*6777b538SAndroid Build Coastguard Worker 
178*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_with_acute_combining_mark, e_with_acute_accent, 0U,
179*6777b538SAndroid Build Coastguard Worker                            e_with_acute_accent.size());
180*6777b538SAndroid Build Coastguard Worker 
181*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_with_acute_accent, e_with_acute_combining_mark, 0U,
182*6777b538SAndroid Build Coastguard Worker                            e_with_acute_combining_mark.size());
183*6777b538SAndroid Build Coastguard Worker 
184*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_with_acute_combining_mark,
185*6777b538SAndroid Build Coastguard Worker                            e_with_grave_combining_mark, 0U,
186*6777b538SAndroid Build Coastguard Worker                            e_with_grave_combining_mark.size());
187*6777b538SAndroid Build Coastguard Worker 
188*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_with_grave_combining_mark,
189*6777b538SAndroid Build Coastguard Worker                            e_with_acute_combining_mark, 0U,
190*6777b538SAndroid Build Coastguard Worker                            e_with_acute_combining_mark.size());
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_with_acute_combining_mark, e_with_grave_accent, 0U,
193*6777b538SAndroid Build Coastguard Worker                            e_with_grave_accent.size());
194*6777b538SAndroid Build Coastguard Worker 
195*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(e_with_grave_accent, e_with_acute_combining_mark, 0U,
196*6777b538SAndroid Build Coastguard Worker                            e_with_acute_combining_mark.size());
197*6777b538SAndroid Build Coastguard Worker 
198*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(E_with_acute_accent, e_with_acute_accent, 0U,
199*6777b538SAndroid Build Coastguard Worker                            e_with_acute_accent.size());
200*6777b538SAndroid Build Coastguard Worker 
201*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(E_with_grave_accent, e_with_acute_accent, 0U,
202*6777b538SAndroid Build Coastguard Worker                            e_with_acute_accent.size());
203*6777b538SAndroid Build Coastguard Worker 
204*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(E_with_acute_combining_mark, e_with_grave_accent, 0U,
205*6777b538SAndroid Build Coastguard Worker                            e_with_grave_accent.size());
206*6777b538SAndroid Build Coastguard Worker 
207*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(E_with_grave_combining_mark, e_with_acute_accent, 0U,
208*6777b538SAndroid Build Coastguard Worker                            e_with_acute_accent.size());
209*6777b538SAndroid Build Coastguard Worker 
210*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE(E_base, e_with_grave_accent, 0U,
211*6777b538SAndroid Build Coastguard Worker                            e_with_grave_accent.size());
212*6777b538SAndroid Build Coastguard Worker 
213*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_IGNORE_CASE(a_with_acute_accent, e_with_acute_accent);
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_IGNORE_CASE(a_with_acute_combining_mark,
216*6777b538SAndroid Build Coastguard Worker                           e_with_acute_combining_mark);
217*6777b538SAndroid Build Coastguard Worker 
218*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(e_base, e_with_acute_accent);
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(e_with_acute_accent, e_base);
221*6777b538SAndroid Build Coastguard Worker 
222*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(e_base, e_with_acute_combining_mark);
223*6777b538SAndroid Build Coastguard Worker 
224*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(e_with_acute_combining_mark, e_base);
225*6777b538SAndroid Build Coastguard Worker 
226*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_SENSITIVE(e_with_acute_combining_mark, e_with_acute_accent, 0U,
227*6777b538SAndroid Build Coastguard Worker                          1U);
228*6777b538SAndroid Build Coastguard Worker 
229*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_SENSITIVE(e_with_acute_accent, e_with_acute_combining_mark, 0U,
230*6777b538SAndroid Build Coastguard Worker                          2U);
231*6777b538SAndroid Build Coastguard Worker 
232*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(e_with_acute_combining_mark,
233*6777b538SAndroid Build Coastguard Worker                         e_with_grave_combining_mark);
234*6777b538SAndroid Build Coastguard Worker 
235*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(e_with_grave_combining_mark,
236*6777b538SAndroid Build Coastguard Worker                         e_with_acute_combining_mark);
237*6777b538SAndroid Build Coastguard Worker 
238*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(e_with_acute_combining_mark, e_with_grave_accent);
239*6777b538SAndroid Build Coastguard Worker 
240*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(e_with_grave_accent, e_with_acute_combining_mark);
241*6777b538SAndroid Build Coastguard Worker 
242*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(E_with_acute_accent, e_with_acute_accent);
243*6777b538SAndroid Build Coastguard Worker 
244*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(E_with_grave_accent, e_with_acute_accent);
245*6777b538SAndroid Build Coastguard Worker 
246*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(E_with_acute_combining_mark, e_with_grave_accent);
247*6777b538SAndroid Build Coastguard Worker 
248*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(E_with_grave_combining_mark, e_with_acute_accent);
249*6777b538SAndroid Build Coastguard Worker 
250*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(E_base, e_with_grave_accent);
251*6777b538SAndroid Build Coastguard Worker 
252*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(a_with_acute_accent, e_with_acute_accent);
253*6777b538SAndroid Build Coastguard Worker 
254*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE(a_with_acute_combining_mark,
255*6777b538SAndroid Build Coastguard Worker                         e_with_acute_combining_mark);
256*6777b538SAndroid Build Coastguard Worker 
257*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_SENSITIVE(a_with_acute_combining_mark,
258*6777b538SAndroid Build Coastguard Worker                          a_with_acute_combining_mark, 0U, 2U);
259*6777b538SAndroid Build Coastguard Worker 
260*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
261*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale(default_locale.data());
262*6777b538SAndroid Build Coastguard Worker }
263*6777b538SAndroid Build Coastguard Worker 
TEST(StringSearchTest,UnicodeLocaleDependent)264*6777b538SAndroid Build Coastguard Worker TEST(StringSearchTest, UnicodeLocaleDependent) {
265*6777b538SAndroid Build Coastguard Worker   // Base characters
266*6777b538SAndroid Build Coastguard Worker   const std::u16string a_base = u"a";
267*6777b538SAndroid Build Coastguard Worker 
268*6777b538SAndroid Build Coastguard Worker   // Composed characters
269*6777b538SAndroid Build Coastguard Worker   const std::u16string a_with_ring = u"\u00e5";
270*6777b538SAndroid Build Coastguard Worker 
271*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StringSearchIgnoringCaseAndAccents(a_base, a_with_ring, nullptr,
272*6777b538SAndroid Build Coastguard Worker                                                  nullptr));
273*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(StringSearch(a_base, a_with_ring, nullptr, nullptr, false, true));
274*6777b538SAndroid Build Coastguard Worker 
275*6777b538SAndroid Build Coastguard Worker   const char* default_locale = uloc_getDefault();
276*6777b538SAndroid Build Coastguard Worker   SetICUDefaultLocale("da");
277*6777b538SAndroid Build Coastguard Worker 
278*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(StringSearchIgnoringCaseAndAccents(a_base, a_with_ring, nullptr,
279*6777b538SAndroid Build Coastguard Worker                                                   nullptr));
280*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
281*6777b538SAndroid Build Coastguard Worker       StringSearch(a_base, a_with_ring, nullptr, nullptr, false, true));
282*6777b538SAndroid Build Coastguard Worker 
283*6777b538SAndroid Build Coastguard Worker   SetICUDefaultLocale(default_locale);
284*6777b538SAndroid Build Coastguard Worker }
285*6777b538SAndroid Build Coastguard Worker 
TEST(StringSearchTest,SearchBackwards)286*6777b538SAndroid Build Coastguard Worker TEST(StringSearchTest, SearchBackwards) {
287*6777b538SAndroid Build Coastguard Worker   std::string default_locale(uloc_getDefault());
288*6777b538SAndroid Build Coastguard Worker   bool locale_is_posix = (default_locale == "en_US_POSIX");
289*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
290*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale("en_US");
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_IGNORE_CASE_BACKWARDS(u"ab", u"ABAB", 2U, 2U);
293*6777b538SAndroid Build Coastguard Worker   EXPECT_MATCH_SENSITIVE_BACKWARDS(u"ab", u"abab", 2U, 2U);
294*6777b538SAndroid Build Coastguard Worker   EXPECT_MISS_SENSITIVE_BACKWARDS(u"ab", u"ABAB");
295*6777b538SAndroid Build Coastguard Worker 
296*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
297*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale(default_locale.data());
298*6777b538SAndroid Build Coastguard Worker }
299*6777b538SAndroid Build Coastguard Worker 
TEST(StringSearchTest,FixedPatternMultipleSearch)300*6777b538SAndroid Build Coastguard Worker TEST(StringSearchTest, FixedPatternMultipleSearch) {
301*6777b538SAndroid Build Coastguard Worker   std::string default_locale(uloc_getDefault());
302*6777b538SAndroid Build Coastguard Worker   bool locale_is_posix = (default_locale == "en_US_POSIX");
303*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
304*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale("en_US");
305*6777b538SAndroid Build Coastguard Worker 
306*6777b538SAndroid Build Coastguard Worker   size_t index = 0;
307*6777b538SAndroid Build Coastguard Worker   size_t length = 0;
308*6777b538SAndroid Build Coastguard Worker 
309*6777b538SAndroid Build Coastguard Worker   // Search "foo" over multiple texts.
310*6777b538SAndroid Build Coastguard Worker   FixedPatternStringSearch query1(u"foo", true);
311*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(query1.Search(u"12foo34", &index, &length, true));
312*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, index);
313*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3U, length);
314*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(query1.Search(u"bye", &index, &length, true));
315*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(query1.Search(u"FOO", &index, &length, true));
316*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(query1.Search(u"foobarfoo", &index, &length, true));
317*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, index);
318*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3U, length);
319*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(query1.Search(u"foobarfoo", &index, &length, false));
320*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(6U, index);
321*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(3U, length);
322*6777b538SAndroid Build Coastguard Worker 
323*6777b538SAndroid Build Coastguard Worker   // Search "hello" over multiple texts.
324*6777b538SAndroid Build Coastguard Worker   FixedPatternStringSearchIgnoringCaseAndAccents query2(u"hello");
325*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(query2.Search(u"12hello34", &index, &length));
326*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(2U, index);
327*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5U, length);
328*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(query2.Search(u"bye", &index, &length));
329*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(query2.Search(u"hELLo", &index, &length));
330*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0U, index);
331*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(5U, length);
332*6777b538SAndroid Build Coastguard Worker 
333*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
334*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale(default_locale.data());
335*6777b538SAndroid Build Coastguard Worker }
336*6777b538SAndroid Build Coastguard Worker 
TEST(StringSearchTest,RepeatingStringSearch)337*6777b538SAndroid Build Coastguard Worker TEST(StringSearchTest, RepeatingStringSearch) {
338*6777b538SAndroid Build Coastguard Worker   struct MatchResult {
339*6777b538SAndroid Build Coastguard Worker     int match_index;
340*6777b538SAndroid Build Coastguard Worker     int match_length;
341*6777b538SAndroid Build Coastguard Worker   };
342*6777b538SAndroid Build Coastguard Worker 
343*6777b538SAndroid Build Coastguard Worker   std::string default_locale(uloc_getDefault());
344*6777b538SAndroid Build Coastguard Worker   bool locale_is_posix = (default_locale == "en_US_POSIX");
345*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
346*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale("en_US");
347*6777b538SAndroid Build Coastguard Worker 
348*6777b538SAndroid Build Coastguard Worker   const char16_t kPattern[] = u"fox";
349*6777b538SAndroid Build Coastguard Worker   const char16_t kTarget[] = u"The quick brown fox jumped over the lazy Fox";
350*6777b538SAndroid Build Coastguard Worker 
351*6777b538SAndroid Build Coastguard Worker   // Case sensitive.
352*6777b538SAndroid Build Coastguard Worker   {
353*6777b538SAndroid Build Coastguard Worker     const MatchResult kExpectation[] = {{16, 3}};
354*6777b538SAndroid Build Coastguard Worker 
355*6777b538SAndroid Build Coastguard Worker     RepeatingStringSearch searcher(kPattern, kTarget, /*case_sensitive=*/true);
356*6777b538SAndroid Build Coastguard Worker     std::vector<MatchResult> results;
357*6777b538SAndroid Build Coastguard Worker     int match_index;
358*6777b538SAndroid Build Coastguard Worker     int match_length;
359*6777b538SAndroid Build Coastguard Worker     while (searcher.NextMatchResult(match_index, match_length)) {
360*6777b538SAndroid Build Coastguard Worker       results.push_back(
361*6777b538SAndroid Build Coastguard Worker           {.match_index = match_index, .match_length = match_length});
362*6777b538SAndroid Build Coastguard Worker     }
363*6777b538SAndroid Build Coastguard Worker 
364*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(std::size(kExpectation), results.size());
365*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < results.size(); ++i) {
366*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(results[i].match_index, kExpectation[i].match_index);
367*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(results[i].match_length, kExpectation[i].match_length);
368*6777b538SAndroid Build Coastguard Worker     }
369*6777b538SAndroid Build Coastguard Worker   }
370*6777b538SAndroid Build Coastguard Worker 
371*6777b538SAndroid Build Coastguard Worker   // Case insensitive.
372*6777b538SAndroid Build Coastguard Worker   {
373*6777b538SAndroid Build Coastguard Worker     const MatchResult kExpectation[] = {{16, 3}, {41, 3}};
374*6777b538SAndroid Build Coastguard Worker 
375*6777b538SAndroid Build Coastguard Worker     RepeatingStringSearch searcher(kPattern, kTarget, /*case_sensitive=*/false);
376*6777b538SAndroid Build Coastguard Worker     std::vector<MatchResult> results;
377*6777b538SAndroid Build Coastguard Worker     int match_index;
378*6777b538SAndroid Build Coastguard Worker     int match_length;
379*6777b538SAndroid Build Coastguard Worker     while (searcher.NextMatchResult(match_index, match_length)) {
380*6777b538SAndroid Build Coastguard Worker       results.push_back(
381*6777b538SAndroid Build Coastguard Worker           {.match_index = match_index, .match_length = match_length});
382*6777b538SAndroid Build Coastguard Worker     }
383*6777b538SAndroid Build Coastguard Worker 
384*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(std::size(kExpectation), results.size());
385*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < results.size(); ++i) {
386*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(results[i].match_index, kExpectation[i].match_index);
387*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(results[i].match_length, kExpectation[i].match_length);
388*6777b538SAndroid Build Coastguard Worker     }
389*6777b538SAndroid Build Coastguard Worker   }
390*6777b538SAndroid Build Coastguard Worker 
391*6777b538SAndroid Build Coastguard Worker   if (locale_is_posix)
392*6777b538SAndroid Build Coastguard Worker     SetICUDefaultLocale(default_locale.data());
393*6777b538SAndroid Build Coastguard Worker }
394*6777b538SAndroid Build Coastguard Worker 
395*6777b538SAndroid Build Coastguard Worker }  // namespace i18n
396*6777b538SAndroid Build Coastguard Worker }  // namespace base
397