1// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "core/fxcrt/widestring.h"
6
7#include <algorithm>
8#include <vector>
9
10#include "core/fxcrt/fx_string.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace fxcrt {
14
15TEST(WideString, ElementAccess) {
16  const WideString abc(L"abc");
17  EXPECT_EQ(L'a', abc[0]);
18  EXPECT_EQ(L'b', abc[1]);
19  EXPECT_EQ(L'c', abc[2]);
20#ifndef NDEBUG
21  EXPECT_DEATH({ abc[4]; }, ".*");
22#endif
23
24  WideString mutable_abc = abc;
25  EXPECT_EQ(abc.c_str(), mutable_abc.c_str());
26  EXPECT_EQ(L'a', mutable_abc[0]);
27  EXPECT_EQ(L'b', mutable_abc[1]);
28  EXPECT_EQ(L'c', mutable_abc[2]);
29  EXPECT_EQ(abc.c_str(), mutable_abc.c_str());
30  EXPECT_EQ(L"abc", abc);
31
32  const wchar_t* c_str = abc.c_str();
33  mutable_abc.SetAt(0, L'd');
34  EXPECT_EQ(c_str, abc.c_str());
35  EXPECT_NE(c_str, mutable_abc.c_str());
36  EXPECT_EQ(L"abc", abc);
37  EXPECT_EQ(L"dbc", mutable_abc);
38
39  mutable_abc.SetAt(1, L'e');
40  EXPECT_EQ(L"abc", abc);
41  EXPECT_EQ(L"dec", mutable_abc);
42
43  mutable_abc.SetAt(2, L'f');
44  EXPECT_EQ(L"abc", abc);
45  EXPECT_EQ(L"def", mutable_abc);
46#ifndef NDEBUG
47  EXPECT_DEATH({ mutable_abc.SetAt(3, L'g'); }, ".*");
48  EXPECT_EQ(L"abc", abc);
49#endif
50}
51
52TEST(WideString, OperatorLT) {
53  WideString empty;
54  WideString a(L"a");
55  WideString abc(L"\x0110qq");  // Comes before despite endianness.
56  WideString def(L"\x1001qq");  // Comes after despite endianness.
57  WideStringView v_empty;
58  WideStringView v_a(L"a");
59  WideStringView v_abc(L"\x0110qq");
60  WideStringView v_def(L"\x1001qq");
61  const wchar_t* const c_null = nullptr;
62  const wchar_t* const c_empty = L"";
63  const wchar_t* const c_a = L"a";
64  const wchar_t* const c_abc = L"\x0110qq";
65  const wchar_t* const c_def = L"\x1001qq";
66
67  EXPECT_FALSE(empty < empty);
68  EXPECT_FALSE(a < a);
69  EXPECT_FALSE(abc < abc);
70  EXPECT_FALSE(def < def);
71  EXPECT_FALSE(c_null < empty);
72  EXPECT_FALSE(c_empty < empty);
73  EXPECT_FALSE(c_a < a);
74  EXPECT_FALSE(c_abc < abc);
75  EXPECT_FALSE(c_def < def);
76  EXPECT_FALSE(empty < c_null);
77  EXPECT_FALSE(empty < c_empty);
78  EXPECT_FALSE(a < c_a);
79  EXPECT_FALSE(abc < c_abc);
80  EXPECT_FALSE(def < c_def);
81  EXPECT_FALSE(empty < v_empty);
82  EXPECT_FALSE(a < v_a);
83  EXPECT_FALSE(abc < v_abc);
84  EXPECT_FALSE(def < v_def);
85
86  EXPECT_TRUE(empty < a);
87  EXPECT_FALSE(a < empty);
88  EXPECT_TRUE(c_null < a);
89  EXPECT_TRUE(c_empty < a);
90  EXPECT_FALSE(c_a < empty);
91  EXPECT_TRUE(empty < c_a);
92  EXPECT_FALSE(a < c_null);
93  EXPECT_FALSE(a < c_empty);
94  EXPECT_TRUE(empty < v_a);
95  EXPECT_FALSE(a < v_empty);
96
97  EXPECT_TRUE(empty < abc);
98  EXPECT_FALSE(abc < empty);
99  EXPECT_TRUE(c_null < abc);
100  EXPECT_TRUE(c_empty < abc);
101  EXPECT_FALSE(c_abc < empty);
102  EXPECT_TRUE(empty < c_abc);
103  EXPECT_FALSE(abc < c_null);
104  EXPECT_FALSE(abc < c_empty);
105  EXPECT_TRUE(empty < v_abc);
106  EXPECT_FALSE(abc < v_empty);
107
108  EXPECT_TRUE(empty < def);
109  EXPECT_FALSE(def < empty);
110  EXPECT_TRUE(c_null < def);
111  EXPECT_TRUE(c_empty < def);
112  EXPECT_FALSE(c_def < empty);
113  EXPECT_TRUE(empty < c_def);
114  EXPECT_FALSE(def < c_null);
115  EXPECT_FALSE(def < c_empty);
116  EXPECT_TRUE(empty < v_def);
117  EXPECT_FALSE(def < v_empty);
118
119  EXPECT_TRUE(a < abc);
120  EXPECT_FALSE(abc < a);
121  EXPECT_TRUE(c_a < abc);
122  EXPECT_FALSE(c_abc < a);
123  EXPECT_TRUE(a < c_abc);
124  EXPECT_FALSE(abc < c_a);
125  EXPECT_TRUE(a < v_abc);
126  EXPECT_FALSE(abc < v_a);
127
128  EXPECT_TRUE(a < def);
129  EXPECT_FALSE(def < a);
130  EXPECT_TRUE(c_a < def);
131  EXPECT_FALSE(c_def < a);
132  EXPECT_TRUE(a < c_def);
133  EXPECT_FALSE(def < c_a);
134  EXPECT_TRUE(a < v_def);
135  EXPECT_FALSE(def < v_a);
136
137  EXPECT_TRUE(abc < def);
138  EXPECT_FALSE(def < abc);
139  EXPECT_TRUE(c_abc < def);
140  EXPECT_FALSE(c_def < abc);
141  EXPECT_TRUE(abc < c_def);
142  EXPECT_FALSE(def < c_abc);
143  EXPECT_TRUE(abc < v_def);
144  EXPECT_FALSE(def < v_abc);
145}
146
147TEST(WideString, OperatorEQ) {
148  WideString null_string;
149  EXPECT_TRUE(null_string == null_string);
150
151  WideString empty_string(L"");
152  EXPECT_TRUE(empty_string == empty_string);
153  EXPECT_TRUE(empty_string == null_string);
154  EXPECT_TRUE(null_string == empty_string);
155
156  WideString deleted_string(L"hello");
157  deleted_string.Delete(0, 5);
158  EXPECT_TRUE(deleted_string == deleted_string);
159  EXPECT_TRUE(deleted_string == null_string);
160  EXPECT_TRUE(deleted_string == empty_string);
161  EXPECT_TRUE(null_string == deleted_string);
162  EXPECT_TRUE(null_string == empty_string);
163
164  WideString wide_string(L"hello");
165  EXPECT_TRUE(wide_string == wide_string);
166  EXPECT_FALSE(wide_string == null_string);
167  EXPECT_FALSE(wide_string == empty_string);
168  EXPECT_FALSE(wide_string == deleted_string);
169  EXPECT_FALSE(null_string == wide_string);
170  EXPECT_FALSE(empty_string == wide_string);
171  EXPECT_FALSE(deleted_string == wide_string);
172
173  WideString wide_string_same1(L"hello");
174  EXPECT_TRUE(wide_string == wide_string_same1);
175  EXPECT_TRUE(wide_string_same1 == wide_string);
176
177  WideString wide_string_same2(wide_string);
178  EXPECT_TRUE(wide_string == wide_string_same2);
179  EXPECT_TRUE(wide_string_same2 == wide_string);
180
181  WideString wide_string1(L"he");
182  WideString wide_string2(L"hellp");
183  WideString wide_string3(L"hellod");
184  EXPECT_FALSE(wide_string == wide_string1);
185  EXPECT_FALSE(wide_string == wide_string2);
186  EXPECT_FALSE(wide_string == wide_string3);
187  EXPECT_FALSE(wide_string1 == wide_string);
188  EXPECT_FALSE(wide_string2 == wide_string);
189  EXPECT_FALSE(wide_string3 == wide_string);
190
191  WideStringView null_string_c;
192  WideStringView empty_string_c(L"");
193  EXPECT_TRUE(null_string == null_string_c);
194  EXPECT_TRUE(null_string == empty_string_c);
195  EXPECT_TRUE(empty_string == null_string_c);
196  EXPECT_TRUE(empty_string == empty_string_c);
197  EXPECT_TRUE(deleted_string == null_string_c);
198  EXPECT_TRUE(deleted_string == empty_string_c);
199  EXPECT_TRUE(null_string_c == null_string);
200  EXPECT_TRUE(empty_string_c == null_string);
201  EXPECT_TRUE(null_string_c == empty_string);
202  EXPECT_TRUE(empty_string_c == empty_string);
203  EXPECT_TRUE(null_string_c == deleted_string);
204  EXPECT_TRUE(empty_string_c == deleted_string);
205
206  WideStringView wide_string_c_same1(L"hello");
207  EXPECT_TRUE(wide_string == wide_string_c_same1);
208  EXPECT_TRUE(wide_string_c_same1 == wide_string);
209
210  WideStringView wide_string_c1(L"he");
211  WideStringView wide_string_c2(L"hellp");
212  WideStringView wide_string_c3(L"hellod");
213  EXPECT_FALSE(wide_string == wide_string_c1);
214  EXPECT_FALSE(wide_string == wide_string_c2);
215  EXPECT_FALSE(wide_string == wide_string_c3);
216  EXPECT_FALSE(wide_string_c1 == wide_string);
217  EXPECT_FALSE(wide_string_c2 == wide_string);
218  EXPECT_FALSE(wide_string_c3 == wide_string);
219
220  const wchar_t* const c_null_string = nullptr;
221  const wchar_t* const c_empty_string = L"";
222  EXPECT_TRUE(null_string == c_null_string);
223  EXPECT_TRUE(null_string == c_empty_string);
224  EXPECT_TRUE(empty_string == c_null_string);
225  EXPECT_TRUE(empty_string == c_empty_string);
226  EXPECT_TRUE(deleted_string == c_null_string);
227  EXPECT_TRUE(deleted_string == c_empty_string);
228  EXPECT_TRUE(c_null_string == null_string);
229  EXPECT_TRUE(c_empty_string == null_string);
230  EXPECT_TRUE(c_null_string == empty_string);
231  EXPECT_TRUE(c_empty_string == empty_string);
232  EXPECT_TRUE(c_null_string == deleted_string);
233  EXPECT_TRUE(c_empty_string == deleted_string);
234
235  const wchar_t* const c_string_same1 = L"hello";
236  EXPECT_TRUE(wide_string == c_string_same1);
237  EXPECT_TRUE(c_string_same1 == wide_string);
238
239  const wchar_t* const c_string1 = L"he";
240  const wchar_t* const c_string2 = L"hellp";
241  const wchar_t* const c_string3 = L"hellod";
242  EXPECT_FALSE(wide_string == c_string1);
243  EXPECT_FALSE(wide_string == c_string2);
244  EXPECT_FALSE(wide_string == c_string3);
245  EXPECT_FALSE(c_string1 == wide_string);
246  EXPECT_FALSE(c_string2 == wide_string);
247  EXPECT_FALSE(c_string3 == wide_string);
248}
249
250TEST(WideString, OperatorNE) {
251  WideString null_string;
252  EXPECT_FALSE(null_string != null_string);
253
254  WideString empty_string(L"");
255  EXPECT_FALSE(empty_string != empty_string);
256  EXPECT_FALSE(empty_string != null_string);
257  EXPECT_FALSE(null_string != empty_string);
258
259  WideString deleted_string(L"hello");
260  deleted_string.Delete(0, 5);
261  EXPECT_FALSE(deleted_string != deleted_string);
262  EXPECT_FALSE(deleted_string != null_string);
263  EXPECT_FALSE(deleted_string != empty_string);
264  EXPECT_FALSE(null_string != deleted_string);
265  EXPECT_FALSE(null_string != empty_string);
266
267  WideString wide_string(L"hello");
268  EXPECT_FALSE(wide_string != wide_string);
269  EXPECT_TRUE(wide_string != null_string);
270  EXPECT_TRUE(wide_string != empty_string);
271  EXPECT_TRUE(wide_string != deleted_string);
272  EXPECT_TRUE(null_string != wide_string);
273  EXPECT_TRUE(empty_string != wide_string);
274  EXPECT_TRUE(deleted_string != wide_string);
275
276  WideString wide_string_same1(L"hello");
277  EXPECT_FALSE(wide_string != wide_string_same1);
278  EXPECT_FALSE(wide_string_same1 != wide_string);
279
280  WideString wide_string_same2(wide_string);
281  EXPECT_FALSE(wide_string != wide_string_same2);
282  EXPECT_FALSE(wide_string_same2 != wide_string);
283
284  WideString wide_string1(L"he");
285  WideString wide_string2(L"hellp");
286  WideString wide_string3(L"hellod");
287  EXPECT_TRUE(wide_string != wide_string1);
288  EXPECT_TRUE(wide_string != wide_string2);
289  EXPECT_TRUE(wide_string != wide_string3);
290  EXPECT_TRUE(wide_string1 != wide_string);
291  EXPECT_TRUE(wide_string2 != wide_string);
292  EXPECT_TRUE(wide_string3 != wide_string);
293
294  WideStringView null_string_c;
295  WideStringView empty_string_c(L"");
296  EXPECT_FALSE(null_string != null_string_c);
297  EXPECT_FALSE(null_string != empty_string_c);
298  EXPECT_FALSE(empty_string != null_string_c);
299  EXPECT_FALSE(empty_string != empty_string_c);
300  EXPECT_FALSE(deleted_string != null_string_c);
301  EXPECT_FALSE(deleted_string != empty_string_c);
302  EXPECT_FALSE(null_string_c != null_string);
303  EXPECT_FALSE(empty_string_c != null_string);
304  EXPECT_FALSE(null_string_c != empty_string);
305  EXPECT_FALSE(empty_string_c != empty_string);
306
307  WideStringView wide_string_c_same1(L"hello");
308  EXPECT_FALSE(wide_string != wide_string_c_same1);
309  EXPECT_FALSE(wide_string_c_same1 != wide_string);
310
311  WideStringView wide_string_c1(L"he");
312  WideStringView wide_string_c2(L"hellp");
313  WideStringView wide_string_c3(L"hellod");
314  EXPECT_TRUE(wide_string != wide_string_c1);
315  EXPECT_TRUE(wide_string != wide_string_c2);
316  EXPECT_TRUE(wide_string != wide_string_c3);
317  EXPECT_TRUE(wide_string_c1 != wide_string);
318  EXPECT_TRUE(wide_string_c2 != wide_string);
319  EXPECT_TRUE(wide_string_c3 != wide_string);
320
321  const wchar_t* const c_null_string = nullptr;
322  const wchar_t* const c_empty_string = L"";
323  EXPECT_FALSE(null_string != c_null_string);
324  EXPECT_FALSE(null_string != c_empty_string);
325  EXPECT_FALSE(empty_string != c_null_string);
326  EXPECT_FALSE(empty_string != c_empty_string);
327  EXPECT_FALSE(deleted_string != c_null_string);
328  EXPECT_FALSE(deleted_string != c_empty_string);
329  EXPECT_FALSE(c_null_string != null_string);
330  EXPECT_FALSE(c_empty_string != null_string);
331  EXPECT_FALSE(c_null_string != empty_string);
332  EXPECT_FALSE(c_empty_string != empty_string);
333  EXPECT_FALSE(c_null_string != deleted_string);
334  EXPECT_FALSE(c_empty_string != deleted_string);
335
336  const wchar_t* const c_string_same1 = L"hello";
337  EXPECT_FALSE(wide_string != c_string_same1);
338  EXPECT_FALSE(c_string_same1 != wide_string);
339
340  const wchar_t* const c_string1 = L"he";
341  const wchar_t* const c_string2 = L"hellp";
342  const wchar_t* const c_string3 = L"hellod";
343  EXPECT_TRUE(wide_string != c_string1);
344  EXPECT_TRUE(wide_string != c_string2);
345  EXPECT_TRUE(wide_string != c_string3);
346  EXPECT_TRUE(c_string1 != wide_string);
347  EXPECT_TRUE(c_string2 != wide_string);
348  EXPECT_TRUE(c_string3 != wide_string);
349}
350
351TEST(WideString, ConcatInPlace) {
352  WideString fred;
353  fred.Concat(L"FRED", 4);
354  EXPECT_EQ(L"FRED", fred);
355
356  fred.Concat(L"DY", 2);
357  EXPECT_EQ(L"FREDDY", fred);
358
359  fred.Delete(3, 3);
360  EXPECT_EQ(L"FRE", fred);
361
362  fred.Concat(L"D", 1);
363  EXPECT_EQ(L"FRED", fred);
364
365  WideString copy = fred;
366  fred.Concat(L"DY", 2);
367  EXPECT_EQ(L"FREDDY", fred);
368  EXPECT_EQ(L"FRED", copy);
369}
370
371TEST(WideString, Remove) {
372  WideString freed(L"FREED");
373  freed.Remove(L'E');
374  EXPECT_EQ(L"FRD", freed);
375  freed.Remove(L'F');
376  EXPECT_EQ(L"RD", freed);
377  freed.Remove(L'D');
378  EXPECT_EQ(L"R", freed);
379  freed.Remove(L'X');
380  EXPECT_EQ(L"R", freed);
381  freed.Remove(L'R');
382  EXPECT_EQ(L"", freed);
383
384  WideString empty;
385  empty.Remove(L'X');
386  EXPECT_EQ(L"", empty);
387}
388
389TEST(WideString, RemoveCopies) {
390  WideString freed(L"FREED");
391  const wchar_t* old_buffer = freed.c_str();
392
393  // No change with single reference - no copy.
394  freed.Remove(L'Q');
395  EXPECT_EQ(L"FREED", freed);
396  EXPECT_EQ(old_buffer, freed.c_str());
397
398  // Change with single reference - no copy.
399  freed.Remove(L'E');
400  EXPECT_EQ(L"FRD", freed);
401  EXPECT_EQ(old_buffer, freed.c_str());
402
403  // No change with multiple references - no copy.
404  WideString shared(freed);
405  freed.Remove(L'Q');
406  EXPECT_EQ(L"FRD", freed);
407  EXPECT_EQ(old_buffer, freed.c_str());
408  EXPECT_EQ(old_buffer, shared.c_str());
409
410  // Change with multiple references -- must copy.
411  freed.Remove(L'D');
412  EXPECT_EQ(L"FR", freed);
413  EXPECT_NE(old_buffer, freed.c_str());
414  EXPECT_EQ(L"FRD", shared);
415  EXPECT_EQ(old_buffer, shared.c_str());
416}
417
418TEST(WideString, Replace) {
419  WideString fred(L"FRED");
420  fred.Replace(L"FR", L"BL");
421  EXPECT_EQ(L"BLED", fred);
422  fred.Replace(L"D", L"DDY");
423  EXPECT_EQ(L"BLEDDY", fred);
424  fred.Replace(L"LEDD", L"");
425  EXPECT_EQ(L"BY", fred);
426  fred.Replace(L"X", L"CLAMS");
427  EXPECT_EQ(L"BY", fred);
428  fred.Replace(L"BY", L"HI");
429  EXPECT_EQ(L"HI", fred);
430  fred.Replace(L"", L"CLAMS");
431  EXPECT_EQ(L"HI", fred);
432  fred.Replace(L"HI", L"");
433  EXPECT_EQ(L"", fred);
434}
435
436TEST(WideString, Insert) {
437  WideString fred(L"FRED");
438  EXPECT_EQ(5u, fred.Insert(0, 'S'));
439  EXPECT_EQ(L"SFRED", fred);
440  EXPECT_EQ(6u, fred.Insert(1, 'T'));
441  EXPECT_EQ(L"STFRED", fred);
442  EXPECT_EQ(7u, fred.Insert(4, 'U'));
443  EXPECT_EQ(L"STFRUED", fred);
444  EXPECT_EQ(8u, fred.Insert(7, 'V'));
445  EXPECT_EQ(L"STFRUEDV", fred);
446  EXPECT_EQ(8u, fred.Insert(12, 'P'));
447  EXPECT_EQ(L"STFRUEDV", fred);
448  {
449    WideString empty;
450    EXPECT_EQ(1u, empty.Insert(0, 'X'));
451    EXPECT_EQ(L"X", empty);
452  }
453  {
454    WideString empty;
455    EXPECT_EQ(0u, empty.Insert(5, 'X'));
456    EXPECT_NE(L"X", empty);
457  }
458}
459
460TEST(WideString, InsertAtFrontAndInsertAtBack) {
461  {
462    WideString empty;
463    EXPECT_EQ(1u, empty.InsertAtFront('D'));
464    EXPECT_EQ(L"D", empty);
465    EXPECT_EQ(2u, empty.InsertAtFront('E'));
466    EXPECT_EQ(L"ED", empty);
467    EXPECT_EQ(3u, empty.InsertAtFront('R'));
468    EXPECT_EQ(L"RED", empty);
469    EXPECT_EQ(4u, empty.InsertAtFront('F'));
470    EXPECT_EQ(L"FRED", empty);
471  }
472  {
473    WideString empty;
474    EXPECT_EQ(1u, empty.InsertAtBack('F'));
475    EXPECT_EQ(L"F", empty);
476    EXPECT_EQ(2u, empty.InsertAtBack('R'));
477    EXPECT_EQ(L"FR", empty);
478    EXPECT_EQ(3u, empty.InsertAtBack('E'));
479    EXPECT_EQ(L"FRE", empty);
480    EXPECT_EQ(4u, empty.InsertAtBack('D'));
481    EXPECT_EQ(L"FRED", empty);
482  }
483  {
484    WideString empty;
485    EXPECT_EQ(1u, empty.InsertAtBack('E'));
486    EXPECT_EQ(L"E", empty);
487    EXPECT_EQ(2u, empty.InsertAtFront('R'));
488    EXPECT_EQ(L"RE", empty);
489    EXPECT_EQ(3u, empty.InsertAtBack('D'));
490    EXPECT_EQ(L"RED", empty);
491    EXPECT_EQ(4u, empty.InsertAtFront('F'));
492    EXPECT_EQ(L"FRED", empty);
493  }
494}
495
496TEST(WideString, Delete) {
497  WideString fred(L"FRED");
498  EXPECT_EQ(4u, fred.Delete(0, 0));
499  EXPECT_EQ(L"FRED", fred);
500  EXPECT_EQ(2u, fred.Delete(0, 2));
501  EXPECT_EQ(L"ED", fred);
502  EXPECT_EQ(1u, fred.Delete(1));
503  EXPECT_EQ(L"E", fred);
504  EXPECT_EQ(0u, fred.Delete(0));
505  EXPECT_EQ(L"", fred);
506  EXPECT_EQ(0u, fred.Delete(0));
507  EXPECT_EQ(L"", fred);
508
509  WideString empty;
510  EXPECT_EQ(0u, empty.Delete(0));
511  EXPECT_EQ(L"", empty);
512  EXPECT_EQ(0u, empty.Delete(1));
513  EXPECT_EQ(L"", empty);
514}
515
516TEST(WideString, Mid) {
517  WideString fred(L"FRED");
518  EXPECT_EQ(L"", fred.Mid(0, 0));
519  EXPECT_EQ(L"", fred.Mid(3, 0));
520  EXPECT_EQ(L"FRED", fred.Mid(0, 4));
521  EXPECT_EQ(L"RED", fred.Mid(1, 3));
522  EXPECT_EQ(L"ED", fred.Mid(2, 2));
523  EXPECT_EQ(L"D", fred.Mid(3, 1));
524  EXPECT_EQ(L"F", fred.Mid(0, 1));
525  EXPECT_EQ(L"R", fred.Mid(1, 1));
526  EXPECT_EQ(L"E", fred.Mid(2, 1));
527  EXPECT_EQ(L"D", fred.Mid(3, 1));
528  EXPECT_EQ(L"FR", fred.Mid(0, 2));
529  EXPECT_EQ(L"FRED", fred.Mid(0, 4));
530  EXPECT_EQ(L"", fred.Mid(0, 10));
531
532  EXPECT_EQ(L"", fred.Mid(1, 4));
533  EXPECT_EQ(L"", fred.Mid(4, 1));
534
535  WideString empty;
536  EXPECT_EQ(L"", empty.Mid(0, 0));
537}
538
539TEST(WideString, Left) {
540  WideString fred(L"FRED");
541  EXPECT_EQ(L"", fred.Left(0));
542  EXPECT_EQ(L"F", fred.Left(1));
543  EXPECT_EQ(L"FR", fred.Left(2));
544  EXPECT_EQ(L"FRE", fred.Left(3));
545  EXPECT_EQ(L"FRED", fred.Left(4));
546
547  EXPECT_EQ(L"", fred.Left(5));
548
549  WideString empty;
550  EXPECT_EQ(L"", empty.Left(0));
551  EXPECT_EQ(L"", empty.Left(1));
552}
553
554TEST(WideString, Right) {
555  WideString fred(L"FRED");
556  EXPECT_EQ(L"", fred.Right(0));
557  EXPECT_EQ(L"D", fred.Right(1));
558  EXPECT_EQ(L"ED", fred.Right(2));
559  EXPECT_EQ(L"RED", fred.Right(3));
560  EXPECT_EQ(L"FRED", fred.Right(4));
561
562  EXPECT_EQ(L"", fred.Right(5));
563
564  WideString empty;
565  EXPECT_EQ(L"", empty.Right(0));
566  EXPECT_EQ(L"", empty.Right(1));
567}
568
569TEST(WideString, Find) {
570  WideString null_string;
571  EXPECT_FALSE(null_string.Find(L'a').has_value());
572  EXPECT_FALSE(null_string.Find(L'\0').has_value());
573
574  WideString empty_string(L"");
575  EXPECT_FALSE(empty_string.Find(L'a').has_value());
576  EXPECT_FALSE(empty_string.Find(L'\0').has_value());
577
578  Optional<size_t> result;
579  WideString single_string(L"a");
580  result = single_string.Find(L'a');
581  ASSERT_TRUE(result.has_value());
582  EXPECT_EQ(0u, result.value());
583  EXPECT_FALSE(single_string.Find(L'b').has_value());
584  EXPECT_FALSE(single_string.Find(L'\0').has_value());
585
586  WideString longer_string(L"abccc");
587  result = longer_string.Find(L'a');
588  ASSERT_TRUE(result.has_value());
589  EXPECT_EQ(0u, result.value());
590  result = longer_string.Find(L'c');
591  ASSERT_TRUE(result.has_value());
592  EXPECT_EQ(2u, result.value());
593  result = longer_string.Find(L'c', 3);
594  ASSERT_TRUE(result.has_value());
595  EXPECT_EQ(3u, result.value());
596  EXPECT_FALSE(longer_string.Find(L'\0').has_value());
597
598  result = longer_string.Find(L"ab");
599  ASSERT_TRUE(result.has_value());
600  EXPECT_EQ(0u, result.value());
601  result = longer_string.Find(L"ccc");
602  ASSERT_TRUE(result.has_value());
603  EXPECT_EQ(2u, result.value());
604  result = longer_string.Find(L"cc", 3);
605  ASSERT_TRUE(result.has_value());
606  EXPECT_EQ(3u, result.value());
607  EXPECT_FALSE(longer_string.Find(L"d").has_value());
608
609  WideString hibyte_string(
610      L"ab\xff8c"
611      L"def");
612  result = hibyte_string.Find(L'\xff8c');
613  ASSERT_TRUE(result.has_value());
614  EXPECT_EQ(2u, result.value());
615}
616
617TEST(WideString, UpperLower) {
618  WideString fred(L"F-Re.42D");
619  fred.MakeLower();
620  EXPECT_EQ(L"f-re.42d", fred);
621  fred.MakeUpper();
622  EXPECT_EQ(L"F-RE.42D", fred);
623
624  WideString empty;
625  empty.MakeLower();
626  EXPECT_EQ(L"", empty);
627  empty.MakeUpper();
628  EXPECT_EQ(L"", empty);
629}
630
631TEST(WideString, Trim) {
632  WideString fred(L"  FRED  ");
633  fred.Trim();
634  EXPECT_EQ(L"FRED", fred);
635  fred.Trim(L'E');
636  EXPECT_EQ(L"FRED", fred);
637  fred.Trim(L'F');
638  EXPECT_EQ(L"RED", fred);
639  fred.Trim(L"ERP");
640  EXPECT_EQ(L"D", fred);
641
642  WideString blank(L"   ");
643  blank.Trim(L"ERP");
644  EXPECT_EQ(L"   ", blank);
645  blank.Trim(L'E');
646  EXPECT_EQ(L"   ", blank);
647  blank.Trim();
648  EXPECT_EQ(L"", blank);
649
650  WideString empty;
651  empty.Trim(L"ERP");
652  EXPECT_EQ(L"", empty);
653  empty.Trim(L'E');
654  EXPECT_EQ(L"", empty);
655  empty.Trim();
656  EXPECT_EQ(L"", empty);
657
658  WideString abc(L"  ABCCBA  ");
659  abc.Trim(L"A");
660  EXPECT_EQ(L"  ABCCBA  ", abc);
661  abc.Trim(L" A");
662  EXPECT_EQ(L"BCCB", abc);
663}
664
665TEST(WideString, TrimLeft) {
666  WideString fred(L"  FRED  ");
667  fred.TrimLeft();
668  EXPECT_EQ(L"FRED  ", fred);
669  fred.TrimLeft(L'E');
670  EXPECT_EQ(L"FRED  ", fred);
671  fred.TrimLeft(L'F');
672  EXPECT_EQ(L"RED  ", fred);
673  fred.TrimLeft(L"ERP");
674  EXPECT_EQ(L"D  ", fred);
675
676  WideString blank(L"   ");
677  blank.TrimLeft(L"ERP");
678  EXPECT_EQ(L"   ", blank);
679  blank.TrimLeft(L'E');
680  EXPECT_EQ(L"   ", blank);
681  blank.TrimLeft();
682  EXPECT_EQ(L"", blank);
683
684  WideString empty;
685  empty.TrimLeft(L"ERP");
686  EXPECT_EQ(L"", empty);
687  empty.TrimLeft(L'E');
688  EXPECT_EQ(L"", empty);
689  empty.TrimLeft();
690  EXPECT_EQ(L"", empty);
691}
692
693TEST(WideString, TrimLeftCopies) {
694  {
695    // With a single reference, no copy takes place.
696    WideString fred(L"  FRED  ");
697    const wchar_t* old_buffer = fred.c_str();
698    fred.TrimLeft();
699    EXPECT_EQ(L"FRED  ", fred);
700    EXPECT_EQ(old_buffer, fred.c_str());
701  }
702  {
703    // With multiple references, we must copy.
704    WideString fred(L"  FRED  ");
705    WideString other_fred = fred;
706    const wchar_t* old_buffer = fred.c_str();
707    fred.TrimLeft();
708    EXPECT_EQ(L"FRED  ", fred);
709    EXPECT_EQ(L"  FRED  ", other_fred);
710    EXPECT_NE(old_buffer, fred.c_str());
711  }
712  {
713    // With multiple references, but no modifications, no copy.
714    WideString fred(L"FRED");
715    WideString other_fred = fred;
716    const wchar_t* old_buffer = fred.c_str();
717    fred.TrimLeft();
718    EXPECT_EQ(L"FRED", fred);
719    EXPECT_EQ(L"FRED", other_fred);
720    EXPECT_EQ(old_buffer, fred.c_str());
721  }
722}
723
724TEST(WideString, TrimRight) {
725  WideString fred(L"  FRED  ");
726  fred.TrimRight();
727  EXPECT_EQ(L"  FRED", fred);
728  fred.TrimRight(L'E');
729  EXPECT_EQ(L"  FRED", fred);
730  fred.TrimRight(L'D');
731  EXPECT_EQ(L"  FRE", fred);
732  fred.TrimRight(L"ERP");
733  EXPECT_EQ(L"  F", fred);
734
735  WideString blank(L"   ");
736  blank.TrimRight(L"ERP");
737  EXPECT_EQ(L"   ", blank);
738  blank.TrimRight(L'E');
739  EXPECT_EQ(L"   ", blank);
740  blank.TrimRight();
741  EXPECT_EQ(L"", blank);
742
743  WideString empty;
744  empty.TrimRight(L"ERP");
745  EXPECT_EQ(L"", empty);
746  empty.TrimRight(L'E');
747  EXPECT_EQ(L"", empty);
748  empty.TrimRight();
749  EXPECT_EQ(L"", empty);
750}
751
752TEST(WideString, TrimRightCopies) {
753  {
754    // With a single reference, no copy takes place.
755    WideString fred(L"  FRED  ");
756    const wchar_t* old_buffer = fred.c_str();
757    fred.TrimRight();
758    EXPECT_EQ(L"  FRED", fred);
759    EXPECT_EQ(old_buffer, fred.c_str());
760  }
761  {
762    // With multiple references, we must copy.
763    WideString fred(L"  FRED  ");
764    WideString other_fred = fred;
765    const wchar_t* old_buffer = fred.c_str();
766    fred.TrimRight();
767    EXPECT_EQ(L"  FRED", fred);
768    EXPECT_EQ(L"  FRED  ", other_fred);
769    EXPECT_NE(old_buffer, fred.c_str());
770  }
771  {
772    // With multiple references, but no modifications, no copy.
773    WideString fred(L"FRED");
774    WideString other_fred = fred;
775    const wchar_t* old_buffer = fred.c_str();
776    fred.TrimRight();
777    EXPECT_EQ(L"FRED", fred);
778    EXPECT_EQ(L"FRED", other_fred);
779    EXPECT_EQ(old_buffer, fred.c_str());
780  }
781}
782
783TEST(WideString, Reserve) {
784  {
785    WideString str;
786    str.Reserve(6);
787    const wchar_t* old_buffer = str.c_str();
788    str += L"ABCDEF";
789    EXPECT_EQ(old_buffer, str.c_str());
790    str += L"Blah Blah Blah Blah Blah Blah";
791    EXPECT_NE(old_buffer, str.c_str());
792  }
793  {
794    WideString str(L"A");
795    str.Reserve(6);
796    const wchar_t* old_buffer = str.c_str();
797    str += L"BCDEF";
798    EXPECT_EQ(old_buffer, str.c_str());
799    str += L"Blah Blah Blah Blah Blah Blah";
800    EXPECT_NE(old_buffer, str.c_str());
801  }
802}
803
804TEST(WideString, GetBuffer) {
805  {
806    WideString str;
807    wchar_t* buffer = str.GetBuffer(12);
808    wcscpy(buffer, L"clams");
809    str.ReleaseBuffer(str.GetStringLength());
810    EXPECT_EQ(L"clams", str);
811  }
812  {
813    WideString str(L"cl");
814    wchar_t* buffer = str.GetBuffer(12);
815    wcscpy(buffer + 2, L"ams");
816    str.ReleaseBuffer(str.GetStringLength());
817    EXPECT_EQ(L"clams", str);
818  }
819}
820
821TEST(WideString, ReleaseBuffer) {
822  {
823    WideString str;
824    str.Reserve(12);
825    str += L"clams";
826    const wchar_t* old_buffer = str.c_str();
827    str.ReleaseBuffer(4);
828    EXPECT_EQ(old_buffer, str.c_str());
829    EXPECT_EQ(L"clam", str);
830  }
831  {
832    WideString str(L"c");
833    str.Reserve(12);
834    str += L"lams";
835    const wchar_t* old_buffer = str.c_str();
836    str.ReleaseBuffer(4);
837    EXPECT_EQ(old_buffer, str.c_str());
838    EXPECT_EQ(L"clam", str);
839  }
840  {
841    WideString str;
842    str.Reserve(200);
843    str += L"clams";
844    const wchar_t* old_buffer = str.c_str();
845    str.ReleaseBuffer(4);
846    EXPECT_NE(old_buffer, str.c_str());
847    EXPECT_EQ(L"clam", str);
848  }
849  {
850    WideString str(L"c");
851    str.Reserve(200);
852    str += L"lams";
853    const wchar_t* old_buffer = str.c_str();
854    str.ReleaseBuffer(4);
855    EXPECT_NE(old_buffer, str.c_str());
856    EXPECT_EQ(L"clam", str);
857  }
858}
859
860TEST(WideString, EmptyReverseIterator) {
861  WideString empty;
862  auto iter = empty.rbegin();
863  EXPECT_TRUE(iter == empty.rend());
864  EXPECT_FALSE(iter != empty.rend());
865  EXPECT_FALSE(iter < empty.rend());
866}
867
868TEST(WideString, OneCharReverseIterator) {
869  WideString one_str(L"a");
870  auto iter = one_str.rbegin();
871  EXPECT_FALSE(iter == one_str.rend());
872  EXPECT_TRUE(iter != one_str.rend());
873  EXPECT_TRUE(iter < one_str.rend());
874
875  char ch = *iter++;
876  EXPECT_EQ('a', ch);
877  EXPECT_TRUE(iter == one_str.rend());
878  EXPECT_FALSE(iter != one_str.rend());
879  EXPECT_FALSE(iter < one_str.rend());
880}
881
882TEST(WideString, MultiCharReverseIterator) {
883  WideString multi_str(L"abcd");
884  auto iter = multi_str.rbegin();
885  EXPECT_FALSE(iter == multi_str.rend());
886
887  char ch = *iter++;
888  EXPECT_EQ('d', ch);
889  EXPECT_EQ('c', *iter);
890  EXPECT_FALSE(iter == multi_str.rend());
891
892  ch = *(++iter);
893  EXPECT_EQ('b', ch);
894  EXPECT_EQ('b', *iter);
895  EXPECT_FALSE(iter == multi_str.rend());
896
897  ch = *iter++;
898  EXPECT_EQ('b', ch);
899  EXPECT_EQ('a', *iter);
900  EXPECT_FALSE(iter == multi_str.rend());
901
902  ch = *iter++;
903  EXPECT_EQ('a', ch);
904  EXPECT_TRUE(iter == multi_str.rend());
905
906  ch = *(--iter);
907  EXPECT_EQ('a', ch);
908  EXPECT_EQ('a', *iter);
909  EXPECT_FALSE(iter == multi_str.rend());
910
911  ch = *iter--;
912  EXPECT_EQ('a', ch);
913  EXPECT_EQ('b', *iter);
914  EXPECT_FALSE(iter == multi_str.rend());
915
916  ch = *iter--;
917  EXPECT_EQ('b', ch);
918  EXPECT_EQ('c', *iter);
919  EXPECT_FALSE(iter == multi_str.rend());
920
921  ch = *(--iter);
922  EXPECT_EQ('d', ch);
923  EXPECT_EQ('d', *iter);
924  EXPECT_TRUE(iter == multi_str.rbegin());
925}
926
927TEST(WideString, UTF16LE_Encode) {
928  struct UTF16LEEncodeCase {
929    WideString ws;
930    ByteString bs;
931  } const utf16le_encode_cases[] = {
932      {L"", ByteString("\0\0", 2)},
933      {L"abc", ByteString("a\0b\0c\0\0\0", 8)},
934      {L"abcdef", ByteString("a\0b\0c\0d\0e\0f\0\0\0", 14)},
935      {L"abc\0def", ByteString("a\0b\0c\0\0\0", 8)},
936      {L"\xaabb\xccdd", ByteString("\xbb\xaa\xdd\xcc\0\0", 6)},
937      {L"\x3132\x6162", ByteString("\x32\x31\x62\x61\0\0", 6)},
938  };
939
940  for (size_t i = 0; i < FX_ArraySize(utf16le_encode_cases); ++i) {
941    EXPECT_EQ(utf16le_encode_cases[i].bs,
942              utf16le_encode_cases[i].ws.UTF16LE_Encode())
943        << " for case number " << i;
944  }
945}
946
947TEST(WideStringView, FromVector) {
948  std::vector<WideStringView::UnsignedType> null_vec;
949  WideStringView null_string(null_vec);
950  EXPECT_EQ(0u, null_string.GetLength());
951
952  std::vector<WideStringView::UnsignedType> lower_a_vec(
953      10, static_cast<WideStringView::UnsignedType>(L'a'));
954  WideStringView lower_a_string(lower_a_vec);
955  EXPECT_EQ(10u, lower_a_string.GetLength());
956  EXPECT_EQ(L"aaaaaaaaaa", lower_a_string);
957
958  std::vector<WideStringView::UnsignedType> cleared_vec;
959  cleared_vec.push_back(42);
960  cleared_vec.pop_back();
961  WideStringView cleared_string(cleared_vec);
962  EXPECT_EQ(0u, cleared_string.GetLength());
963  EXPECT_EQ(nullptr, cleared_string.raw_str());
964}
965
966TEST(WideStringView, ElementAccess) {
967  WideStringView abc(L"abc");
968  EXPECT_EQ(L'a', static_cast<wchar_t>(abc[0]));
969  EXPECT_EQ(L'b', static_cast<wchar_t>(abc[1]));
970  EXPECT_EQ(L'c', static_cast<wchar_t>(abc[2]));
971#ifndef NDEBUG
972  EXPECT_DEATH({ abc[4]; }, ".*");
973#endif
974}
975
976TEST(WideStringView, OperatorLT) {
977  WideStringView empty;
978  WideStringView a(L"a");
979  WideStringView abc(L"\x0110qq");  // Comes InsertAtFront despite endianness.
980  WideStringView def(L"\x1001qq");  // Comes InsertAtBack despite endianness.
981  const wchar_t* const c_null = nullptr;
982  const wchar_t* const c_empty = L"";
983  const wchar_t* const c_a = L"a";
984  const wchar_t* const c_abc = L"\x0110qq";
985  const wchar_t* const c_def = L"\x1001qq";
986
987  EXPECT_FALSE(empty < empty);
988  EXPECT_FALSE(a < a);
989  EXPECT_FALSE(abc < abc);
990  EXPECT_FALSE(def < def);
991  EXPECT_FALSE(c_null < empty);
992  EXPECT_FALSE(c_empty < empty);
993  EXPECT_FALSE(c_a < a);
994  EXPECT_FALSE(c_abc < abc);
995  EXPECT_FALSE(c_def < def);
996  EXPECT_FALSE(empty < c_null);
997  EXPECT_FALSE(empty < c_empty);
998  EXPECT_FALSE(a < c_a);
999  EXPECT_FALSE(abc < c_abc);
1000  EXPECT_FALSE(def < c_def);
1001
1002  EXPECT_TRUE(empty < a);
1003  EXPECT_FALSE(a < empty);
1004  EXPECT_TRUE(empty < c_a);
1005  EXPECT_FALSE(a < c_null);
1006  EXPECT_FALSE(a < c_empty);
1007
1008  EXPECT_TRUE(empty < abc);
1009  EXPECT_FALSE(abc < empty);
1010  EXPECT_TRUE(empty < c_abc);
1011  EXPECT_FALSE(abc < c_null);
1012  EXPECT_FALSE(abc < c_empty);
1013
1014  EXPECT_TRUE(empty < def);
1015  EXPECT_FALSE(def < empty);
1016  EXPECT_TRUE(empty < c_def);
1017  EXPECT_FALSE(def < c_null);
1018  EXPECT_FALSE(def < c_empty);
1019
1020  EXPECT_TRUE(a < abc);
1021  EXPECT_FALSE(abc < a);
1022  EXPECT_TRUE(a < c_abc);
1023  EXPECT_FALSE(abc < c_a);
1024
1025  EXPECT_TRUE(a < def);
1026  EXPECT_FALSE(def < a);
1027  EXPECT_TRUE(a < c_def);
1028  EXPECT_FALSE(def < c_a);
1029
1030  EXPECT_TRUE(abc < def);
1031  EXPECT_FALSE(def < abc);
1032  EXPECT_TRUE(abc < c_def);
1033  EXPECT_FALSE(def < c_abc);
1034}
1035
1036TEST(WideStringView, OperatorEQ) {
1037  WideStringView wide_string_c(L"hello");
1038  EXPECT_TRUE(wide_string_c == wide_string_c);
1039
1040  WideStringView wide_string_c_same1(L"hello");
1041  EXPECT_TRUE(wide_string_c == wide_string_c_same1);
1042  EXPECT_TRUE(wide_string_c_same1 == wide_string_c);
1043
1044  WideStringView wide_string_c_same2(wide_string_c);
1045  EXPECT_TRUE(wide_string_c == wide_string_c_same2);
1046  EXPECT_TRUE(wide_string_c_same2 == wide_string_c);
1047
1048  WideStringView wide_string_c1(L"he");
1049  WideStringView wide_string_c2(L"hellp");
1050  WideStringView wide_string_c3(L"hellod");
1051  EXPECT_FALSE(wide_string_c == wide_string_c1);
1052  EXPECT_FALSE(wide_string_c == wide_string_c2);
1053  EXPECT_FALSE(wide_string_c == wide_string_c3);
1054  EXPECT_FALSE(wide_string_c1 == wide_string_c);
1055  EXPECT_FALSE(wide_string_c2 == wide_string_c);
1056  EXPECT_FALSE(wide_string_c3 == wide_string_c);
1057
1058  WideString wide_string_same1(L"hello");
1059  EXPECT_TRUE(wide_string_c == wide_string_same1);
1060  EXPECT_TRUE(wide_string_same1 == wide_string_c);
1061
1062  WideString wide_string1(L"he");
1063  WideString wide_string2(L"hellp");
1064  WideString wide_string3(L"hellod");
1065  EXPECT_FALSE(wide_string_c == wide_string1);
1066  EXPECT_FALSE(wide_string_c == wide_string2);
1067  EXPECT_FALSE(wide_string_c == wide_string3);
1068  EXPECT_FALSE(wide_string1 == wide_string_c);
1069  EXPECT_FALSE(wide_string2 == wide_string_c);
1070  EXPECT_FALSE(wide_string3 == wide_string_c);
1071
1072  const wchar_t* const c_string_same1 = L"hello";
1073  EXPECT_TRUE(wide_string_c == c_string_same1);
1074  EXPECT_TRUE(c_string_same1 == wide_string_c);
1075
1076  const wchar_t* const c_string1 = L"he";
1077  const wchar_t* const c_string2 = L"hellp";
1078  const wchar_t* const c_string3 = L"hellod";
1079  EXPECT_FALSE(wide_string_c == c_string1);
1080  EXPECT_FALSE(wide_string_c == c_string2);
1081  EXPECT_FALSE(wide_string_c == c_string3);
1082
1083  EXPECT_FALSE(c_string1 == wide_string_c);
1084  EXPECT_FALSE(c_string2 == wide_string_c);
1085  EXPECT_FALSE(c_string3 == wide_string_c);
1086}
1087
1088TEST(WideStringView, OperatorNE) {
1089  WideStringView wide_string_c(L"hello");
1090  EXPECT_FALSE(wide_string_c != wide_string_c);
1091
1092  WideStringView wide_string_c_same1(L"hello");
1093  EXPECT_FALSE(wide_string_c != wide_string_c_same1);
1094  EXPECT_FALSE(wide_string_c_same1 != wide_string_c);
1095
1096  WideStringView wide_string_c_same2(wide_string_c);
1097  EXPECT_FALSE(wide_string_c != wide_string_c_same2);
1098  EXPECT_FALSE(wide_string_c_same2 != wide_string_c);
1099
1100  WideStringView wide_string_c1(L"he");
1101  WideStringView wide_string_c2(L"hellp");
1102  WideStringView wide_string_c3(L"hellod");
1103  EXPECT_TRUE(wide_string_c != wide_string_c1);
1104  EXPECT_TRUE(wide_string_c != wide_string_c2);
1105  EXPECT_TRUE(wide_string_c != wide_string_c3);
1106  EXPECT_TRUE(wide_string_c1 != wide_string_c);
1107  EXPECT_TRUE(wide_string_c2 != wide_string_c);
1108  EXPECT_TRUE(wide_string_c3 != wide_string_c);
1109
1110  WideString wide_string_same1(L"hello");
1111  EXPECT_FALSE(wide_string_c != wide_string_same1);
1112  EXPECT_FALSE(wide_string_same1 != wide_string_c);
1113
1114  WideString wide_string1(L"he");
1115  WideString wide_string2(L"hellp");
1116  WideString wide_string3(L"hellod");
1117  EXPECT_TRUE(wide_string_c != wide_string1);
1118  EXPECT_TRUE(wide_string_c != wide_string2);
1119  EXPECT_TRUE(wide_string_c != wide_string3);
1120  EXPECT_TRUE(wide_string1 != wide_string_c);
1121  EXPECT_TRUE(wide_string2 != wide_string_c);
1122  EXPECT_TRUE(wide_string3 != wide_string_c);
1123
1124  const wchar_t* const c_string_same1 = L"hello";
1125  EXPECT_FALSE(wide_string_c != c_string_same1);
1126  EXPECT_FALSE(c_string_same1 != wide_string_c);
1127
1128  const wchar_t* const c_string1 = L"he";
1129  const wchar_t* const c_string2 = L"hellp";
1130  const wchar_t* const c_string3 = L"hellod";
1131  EXPECT_TRUE(wide_string_c != c_string1);
1132  EXPECT_TRUE(wide_string_c != c_string2);
1133  EXPECT_TRUE(wide_string_c != c_string3);
1134
1135  EXPECT_TRUE(c_string1 != wide_string_c);
1136  EXPECT_TRUE(c_string2 != wide_string_c);
1137  EXPECT_TRUE(c_string3 != wide_string_c);
1138}
1139
1140TEST(WideStringView, Find) {
1141  WideStringView null_string;
1142  EXPECT_FALSE(null_string.Find(L'a').has_value());
1143  EXPECT_FALSE(null_string.Find(L'\0').has_value());
1144
1145  WideStringView empty_string(L"");
1146  EXPECT_FALSE(empty_string.Find(L'a').has_value());
1147  EXPECT_FALSE(empty_string.Find(L'\0').has_value());
1148
1149  Optional<size_t> result;
1150  WideStringView single_string(L"a");
1151  result = single_string.Find(L'a');
1152  ASSERT_TRUE(result.has_value());
1153  EXPECT_EQ(0u, result.value());
1154  EXPECT_FALSE(single_string.Find(L'b').has_value());
1155  EXPECT_FALSE(single_string.Find(L'\0').has_value());
1156
1157  WideStringView longer_string(L"abccc");
1158  result = longer_string.Find(L'a');
1159  ASSERT_TRUE(result.has_value());
1160  EXPECT_EQ(0u, result.value());
1161  result = longer_string.Find(L'c');
1162  ASSERT_TRUE(result.has_value());
1163  EXPECT_EQ(2u, result.value());
1164  EXPECT_FALSE(longer_string.Find(L'd').has_value());
1165  EXPECT_FALSE(longer_string.Find(L'\0').has_value());
1166
1167  WideStringView hibyte_string(
1168      L"ab\xFF8c"
1169      L"def");
1170  result = hibyte_string.Find(L'\xFF8c');
1171  ASSERT_TRUE(result.has_value());
1172  EXPECT_EQ(2u, result.value());
1173}
1174
1175TEST(WideStringView, NullIterator) {
1176  WideStringView null_str;
1177  int32_t sum = 0;
1178  bool any_present = false;
1179  for (const auto& c : null_str) {
1180    sum += c;  // Avoid unused arg warnings.
1181    any_present = true;
1182  }
1183  EXPECT_FALSE(any_present);
1184  EXPECT_EQ(0, sum);
1185}
1186
1187TEST(WideStringView, EmptyIterator) {
1188  WideStringView empty_str(L"");
1189  int32_t sum = 0;
1190  bool any_present = false;
1191  for (const auto& c : empty_str) {
1192    any_present = true;
1193    sum += c;  // Avoid unused arg warnings.
1194  }
1195  EXPECT_FALSE(any_present);
1196  EXPECT_EQ(0, sum);
1197}
1198
1199TEST(WideStringView, OneCharIterator) {
1200  WideStringView one_str(L"a");
1201  int32_t sum = 0;
1202  bool any_present = false;
1203  for (const auto& c : one_str) {
1204    any_present = true;
1205    sum += c;  // Avoid unused arg warnings.
1206  }
1207  EXPECT_TRUE(any_present);
1208  EXPECT_EQ(static_cast<int32_t>(L'a'), sum);
1209}
1210
1211TEST(WideStringView, MultiCharIterator) {
1212  WideStringView one_str(L"abc");
1213  int32_t sum = 0;
1214  bool any_present = false;
1215  for (const auto& c : one_str) {
1216    any_present = true;
1217    sum += c;  // Avoid unused arg warnings.
1218  }
1219  EXPECT_TRUE(any_present);
1220  EXPECT_EQ(static_cast<int32_t>(L'a' + L'b' + L'c'), sum);
1221}
1222
1223TEST(WideStringView, EmptyReverseIterator) {
1224  WideStringView empty;
1225  auto iter = empty.rbegin();
1226  EXPECT_TRUE(iter == empty.rend());
1227  EXPECT_FALSE(iter != empty.rend());
1228  EXPECT_FALSE(iter < empty.rend());
1229}
1230
1231TEST(WideStringView, OneCharReverseIterator) {
1232  WideStringView one_str(L"a");
1233  auto iter = one_str.rbegin();
1234  EXPECT_FALSE(iter == one_str.rend());
1235  EXPECT_TRUE(iter != one_str.rend());
1236  EXPECT_TRUE(iter < one_str.rend());
1237
1238  char ch = *iter++;
1239  EXPECT_EQ('a', ch);
1240  EXPECT_TRUE(iter == one_str.rend());
1241  EXPECT_FALSE(iter != one_str.rend());
1242  EXPECT_FALSE(iter < one_str.rend());
1243}
1244
1245TEST(WideStringView, MultiCharReverseIterator) {
1246  WideStringView multi_str(L"abcd");
1247  auto iter = multi_str.rbegin();
1248  EXPECT_FALSE(iter == multi_str.rend());
1249
1250  char ch = *iter++;
1251  EXPECT_EQ('d', ch);
1252  EXPECT_EQ('c', *iter);
1253  EXPECT_FALSE(iter == multi_str.rend());
1254
1255  ch = *(++iter);
1256  EXPECT_EQ('b', ch);
1257  EXPECT_EQ('b', *iter);
1258  EXPECT_FALSE(iter == multi_str.rend());
1259
1260  ch = *iter++;
1261  EXPECT_EQ('b', ch);
1262  EXPECT_EQ('a', *iter);
1263  EXPECT_FALSE(iter == multi_str.rend());
1264
1265  ch = *iter++;
1266  EXPECT_EQ('a', ch);
1267  EXPECT_TRUE(iter == multi_str.rend());
1268
1269  ch = *(--iter);
1270  EXPECT_EQ('a', ch);
1271  EXPECT_EQ('a', *iter);
1272  EXPECT_FALSE(iter == multi_str.rend());
1273
1274  ch = *iter--;
1275  EXPECT_EQ('a', ch);
1276  EXPECT_EQ('b', *iter);
1277  EXPECT_FALSE(iter == multi_str.rend());
1278
1279  ch = *iter--;
1280  EXPECT_EQ('b', ch);
1281  EXPECT_EQ('c', *iter);
1282  EXPECT_FALSE(iter == multi_str.rend());
1283
1284  ch = *(--iter);
1285  EXPECT_EQ('d', ch);
1286  EXPECT_EQ('d', *iter);
1287  EXPECT_TRUE(iter == multi_str.rbegin());
1288}
1289
1290TEST(WideStringView, AnyAllNoneOf) {
1291  WideStringView str(L"aaaaaaaaaaaaaaaaab");
1292  EXPECT_FALSE(std::all_of(str.begin(), str.end(),
1293                           [](const wchar_t& c) { return c == L'a'; }));
1294
1295  EXPECT_FALSE(std::none_of(str.begin(), str.end(),
1296                            [](const wchar_t& c) { return c == L'a'; }));
1297
1298  EXPECT_TRUE(std::any_of(str.begin(), str.end(),
1299                          [](const wchar_t& c) { return c == L'a'; }));
1300
1301  EXPECT_TRUE(pdfium::ContainsValue(str, L'a'));
1302  EXPECT_TRUE(pdfium::ContainsValue(str, L'b'));
1303  EXPECT_FALSE(pdfium::ContainsValue(str, L'z'));
1304}
1305
1306TEST(WideStringView, TrimmedRight) {
1307  WideStringView fred(L"FRED");
1308  EXPECT_EQ(L"FRED", fred.TrimmedRight(L'E'));
1309  EXPECT_EQ(L"FRE", fred.TrimmedRight(L'D'));
1310  WideStringView fredd(L"FREDD");
1311  EXPECT_EQ(L"FRE", fred.TrimmedRight(L'D'));
1312}
1313
1314TEST(WideString, FormatWidth) {
1315  EXPECT_EQ(L"    1", WideString::Format(L"%5d", 1));
1316  EXPECT_EQ(L"1", WideString::Format(L"%d", 1));
1317  EXPECT_EQ(L"    1", WideString::Format(L"%*d", 5, 1));
1318  EXPECT_EQ(L"1", WideString::Format(L"%-1d", 1));
1319  EXPECT_EQ(L"1", WideString::Format(L"%0d", 1));
1320  EXPECT_EQ(L"", WideString::Format(L"%1048576d", 1));
1321}
1322
1323TEST(WideString, FormatPrecision) {
1324  EXPECT_EQ(L"1.12", WideString::Format(L"%.2f", 1.12345));
1325  EXPECT_EQ(L"1.123", WideString::Format(L"%.*f", 3, 1.12345));
1326  EXPECT_EQ(L"1.123450", WideString::Format(L"%f", 1.12345));
1327  EXPECT_EQ(L"1.123450", WideString::Format(L"%-1f", 1.12345));
1328  EXPECT_EQ(L"1.123450", WideString::Format(L"%0f", 1.12345));
1329  EXPECT_EQ(L"", WideString::Format(L"%.1048576f", 1.2));
1330}
1331
1332TEST(WideString, FormatOutOfRangeChar) {
1333  EXPECT_NE(L"", WideString::Format(L"unsupported char '%c'", 0x00FF00FF));
1334}
1335
1336TEST(WideString, Empty) {
1337  WideString empty_str;
1338  EXPECT_TRUE(empty_str.IsEmpty());
1339  EXPECT_EQ(0u, empty_str.GetLength());
1340  const wchar_t* cstr = empty_str.c_str();
1341  EXPECT_EQ(0u, wcslen(cstr));
1342}
1343
1344TEST(CFX_WidString, InitializerList) {
1345  WideString many_str({L"clams", L" and ", L"oysters"});
1346  EXPECT_EQ(L"clams and oysters", many_str);
1347  many_str = {L"fish", L" and ", L"chips", L" and ", L"soda"};
1348  EXPECT_EQ(L"fish and chips and soda", many_str);
1349}
1350
1351TEST(WideString, NullIterator) {
1352  WideString null_str;
1353  int32_t sum = 0;
1354  bool any_present = false;
1355  for (const auto& c : null_str) {
1356    sum += c;  // Avoid unused arg warnings.
1357    any_present = true;
1358  }
1359  EXPECT_FALSE(any_present);
1360  EXPECT_EQ(0, sum);
1361}
1362
1363TEST(WideString, EmptyIterator) {
1364  WideString empty_str(L"");
1365  int32_t sum = 0;
1366  bool any_present = false;
1367  for (const auto& c : empty_str) {
1368    any_present = true;
1369    sum += c;  // Avoid unused arg warnings.
1370  }
1371  EXPECT_FALSE(any_present);
1372  EXPECT_EQ(0, sum);
1373}
1374
1375TEST(WideString, OneCharIterator) {
1376  WideString one_str(L"a");
1377  int32_t sum = 0;
1378  bool any_present = false;
1379  for (const auto& c : one_str) {
1380    any_present = true;
1381    sum += c;  // Avoid unused arg warnings.
1382  }
1383  EXPECT_TRUE(any_present);
1384  EXPECT_EQ(static_cast<int32_t>(L'a'), sum);
1385}
1386
1387TEST(WideString, MultiCharIterator) {
1388  WideString one_str(L"abc");
1389  int32_t sum = 0;
1390  bool any_present = false;
1391  for (const auto& c : one_str) {
1392    any_present = true;
1393    sum += c;  // Avoid unused arg warnings.
1394  }
1395  EXPECT_TRUE(any_present);
1396  EXPECT_EQ(static_cast<int32_t>(L'a' + L'b' + L'c'), sum);
1397}
1398
1399TEST(WideString, AnyAllNoneOf) {
1400  WideString str(L"aaaaaaaaaaaaaaaaab");
1401  EXPECT_FALSE(std::all_of(str.begin(), str.end(),
1402                           [](const wchar_t& c) { return c == L'a'; }));
1403
1404  EXPECT_FALSE(std::none_of(str.begin(), str.end(),
1405                            [](const wchar_t& c) { return c == L'a'; }));
1406
1407  EXPECT_TRUE(std::any_of(str.begin(), str.end(),
1408                          [](const wchar_t& c) { return c == L'a'; }));
1409
1410  EXPECT_TRUE(pdfium::ContainsValue(str, L'a'));
1411  EXPECT_TRUE(pdfium::ContainsValue(str, L'b'));
1412  EXPECT_FALSE(pdfium::ContainsValue(str, L'z'));
1413}
1414
1415TEST(WideString, OStreamOverload) {
1416  std::ostringstream stream;
1417
1418  // Basic case, empty string
1419  WideString str;
1420  stream << str;
1421  EXPECT_EQ("", stream.str());
1422
1423  // Basic case, wide character
1424  str = L"\u20AC";
1425  stream << str;
1426  EXPECT_EQ("\u20AC", stream.str());
1427
1428  // Basic case, non-empty string
1429  str = L"def";
1430  stream.str("");
1431  stream << "abc" << str << "ghi";
1432  EXPECT_EQ("abcdefghi", stream.str());
1433
1434  // Changing the WideString does not change the stream it was written to.
1435  str = L"123";
1436  EXPECT_EQ("abcdefghi", stream.str());
1437
1438  // Writing it again to the stream will use the latest value.
1439  stream.str("");
1440  stream << "abc" << str << "ghi";
1441  EXPECT_EQ("abc123ghi", stream.str());
1442
1443  wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
1444
1445  // Writing a WideString with nulls and no specified length treats it as
1446  // a C-style null-terminated string.
1447  str = WideString(stringWithNulls);
1448  EXPECT_EQ(2u, str.GetLength());
1449  stream.str("");
1450  stream << str;
1451  EXPECT_EQ(2u, stream.tellp());
1452
1453  // Writing a WideString with nulls but specifying its length treats it as
1454  // a C++-style string.
1455  str = WideString(stringWithNulls, 4);
1456  EXPECT_EQ(4u, str.GetLength());
1457  stream.str("");
1458  stream << str;
1459  EXPECT_EQ(4u, stream.tellp());
1460
1461  // << operators can be chained.
1462  WideString str1(L"abc");
1463  WideString str2(L"def");
1464  stream.str("");
1465  stream << str1 << str2;
1466  EXPECT_EQ("abcdef", stream.str());
1467}
1468
1469TEST(WideString, WideOStreamOverload) {
1470  std::wostringstream stream;
1471
1472  // Basic case, empty string
1473  WideString str;
1474  stream << str;
1475  EXPECT_EQ(L"", stream.str());
1476
1477  // Basic case, wide character
1478  str = L"\u20AC";
1479  stream << str;
1480  EXPECT_EQ(L"\u20AC", stream.str());
1481
1482  // Basic case, non-empty string
1483  str = L"def";
1484  stream.str(L"");
1485  stream << L"abc" << str << L"ghi";
1486  EXPECT_EQ(L"abcdefghi", stream.str());
1487
1488  // Changing the WideString does not change the stream it was written to.
1489  str = L"123";
1490  EXPECT_EQ(L"abcdefghi", stream.str());
1491
1492  // Writing it again to the stream will use the latest value.
1493  stream.str(L"");
1494  stream << L"abc" << str << L"ghi";
1495  EXPECT_EQ(L"abc123ghi", stream.str());
1496
1497  wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
1498
1499  // Writing a WideString with nulls and no specified length treats it as
1500  // a C-style null-terminated string.
1501  str = WideString(stringWithNulls);
1502  EXPECT_EQ(2u, str.GetLength());
1503  stream.str(L"");
1504  stream << str;
1505  EXPECT_EQ(2u, stream.tellp());
1506
1507  // Writing a WideString with nulls but specifying its length treats it as
1508  // a C++-style string.
1509  str = WideString(stringWithNulls, 4);
1510  EXPECT_EQ(4u, str.GetLength());
1511  stream.str(L"");
1512  stream << str;
1513  EXPECT_EQ(4u, stream.tellp());
1514
1515  // << operators can be chained.
1516  WideString str1(L"abc");
1517  WideString str2(L"def");
1518  stream.str(L"");
1519  stream << str1 << str2;
1520  EXPECT_EQ(L"abcdef", stream.str());
1521}
1522
1523TEST(WideStringView, OStreamOverload) {
1524  // Basic case, empty string
1525  {
1526    std::ostringstream stream;
1527    WideStringView str;
1528    stream << str;
1529    EXPECT_EQ("", stream.str());
1530  }
1531
1532  // Basic case, non-empty string
1533  {
1534    std::ostringstream stream;
1535    WideStringView str(L"def");
1536    stream << "abc" << str << "ghi";
1537    EXPECT_EQ("abcdefghi", stream.str());
1538  }
1539
1540  // Basic case, wide character
1541  {
1542    std::ostringstream stream;
1543    WideStringView str(L"\u20AC");
1544    stream << str;
1545    EXPECT_EQ("\u20AC", stream.str());
1546  }
1547
1548  // Changing the WideStringView does not change the stream it was written to.
1549  {
1550    std::ostringstream stream;
1551    WideStringView str(L"abc");
1552    stream << str;
1553    str = L"123";
1554    EXPECT_EQ("abc", stream.str());
1555  }
1556
1557  // Writing it again to the stream will use the latest value.
1558  {
1559    std::ostringstream stream;
1560    WideStringView str(L"abc");
1561    stream << str;
1562    stream.str("");
1563    str = L"123";
1564    stream << str;
1565    EXPECT_EQ("123", stream.str());
1566  }
1567
1568  // Writing a WideStringView with nulls and no specified length treats it as
1569  // a C-style null-terminated string.
1570  {
1571    wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
1572    std::ostringstream stream;
1573    WideStringView str(stringWithNulls);
1574    EXPECT_EQ(2u, str.GetLength());
1575    stream << str;
1576    EXPECT_EQ(2u, stream.tellp());
1577    str = L"";
1578  }
1579
1580  // Writing a WideStringView with nulls but specifying its length treats it as
1581  // a C++-style string.
1582  {
1583    wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
1584    std::ostringstream stream;
1585    WideStringView str(stringWithNulls, 4);
1586    EXPECT_EQ(4u, str.GetLength());
1587    stream << str;
1588    EXPECT_EQ(4u, stream.tellp());
1589    str = L"";
1590  }
1591
1592  // << operators can be chained.
1593  {
1594    std::ostringstream stream;
1595    WideStringView str1(L"abc");
1596    WideStringView str2(L"def");
1597    stream << str1 << str2;
1598    EXPECT_EQ("abcdef", stream.str());
1599  }
1600}
1601
1602TEST(WideStringView, WideOStreamOverload) {
1603  // Basic case, empty string
1604  {
1605    std::wostringstream stream;
1606    WideStringView str;
1607    stream << str;
1608    EXPECT_EQ(L"", stream.str());
1609  }
1610
1611  // Basic case, non-empty string
1612  {
1613    std::wostringstream stream;
1614    WideStringView str(L"def");
1615    stream << "abc" << str << "ghi";
1616    EXPECT_EQ(L"abcdefghi", stream.str());
1617  }
1618
1619  // Basic case, wide character
1620  {
1621    std::wostringstream stream;
1622    WideStringView str(L"\u20AC");
1623    stream << str;
1624    EXPECT_EQ(L"\u20AC", stream.str());
1625  }
1626
1627  // Changing the WideStringView does not change the stream it was written to.
1628  {
1629    std::wostringstream stream;
1630    WideStringView str(L"abc");
1631    stream << str;
1632    str = L"123";
1633    EXPECT_EQ(L"abc", stream.str());
1634  }
1635
1636  // Writing it again to the stream will use the latest value.
1637  {
1638    std::wostringstream stream;
1639    WideStringView str(L"abc");
1640    stream << str;
1641    stream.str(L"");
1642    str = L"123";
1643    stream << str;
1644    EXPECT_EQ(L"123", stream.str());
1645  }
1646
1647  // Writing a WideStringView with nulls and no specified length treats it as
1648  // a C-style null-terminated string.
1649  {
1650    wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
1651    std::wostringstream stream;
1652    WideStringView str(stringWithNulls);
1653    EXPECT_EQ(2u, str.GetLength());
1654    stream << str;
1655    EXPECT_EQ(2u, stream.tellp());
1656  }
1657
1658  // Writing a WideStringView with nulls but specifying its length treats it as
1659  // a C++-style string.
1660  {
1661    wchar_t stringWithNulls[]{'x', 'y', '\0', 'z'};
1662    std::wostringstream stream;
1663    WideStringView str(stringWithNulls, 4);
1664    EXPECT_EQ(4u, str.GetLength());
1665    stream << str;
1666    EXPECT_EQ(4u, stream.tellp());
1667  }
1668
1669  // << operators can be chained.
1670  {
1671    std::wostringstream stream;
1672    WideStringView str1(L"abc");
1673    WideStringView str2(L"def");
1674    stream << str1 << str2;
1675    EXPECT_EQ(L"abcdef", stream.str());
1676  }
1677}
1678
1679}  // namespace fxcrt
1680