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