blob: 2fbe45e924bfba0d1ead12fa058a22b52119de7d [file] [log] [blame]
[email protected]dbb97ba2013-09-09 22:15:251// Copyright (c) 2012 The Chromium 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// Unit tests for eliding and formatting utility functions.
6
7#include "ui/gfx/text_elider.h"
8
mgiuca034e9302015-04-22 02:44:539#include <vector>
10
[email protected]dbb97ba2013-09-09 22:15:2511#include "base/files/file_path.h"
12#include "base/i18n/rtl.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/strings/string_util.h"
15#include "base/strings/utf_string_conversions.h"
16#include "testing/gtest/include/gtest/gtest.h"
17#include "ui/gfx/font.h"
[email protected]8ad3c5a2013-10-10 09:57:1918#include "ui/gfx/font_list.h"
rsorokin370fe4b2014-11-11 15:14:0719#include "ui/gfx/font_render_params.h"
[email protected]8ad3c5a2013-10-10 09:57:1920#include "ui/gfx/text_utils.h"
[email protected]dbb97ba2013-09-09 22:15:2521
[email protected]dd2cc802013-12-25 20:09:3622using base::ASCIIToUTF16;
23using base::UTF16ToUTF8;
[email protected]f729d7a2013-12-26 07:07:5624using base::UTF16ToWide;
[email protected]dd2cc802013-12-25 20:09:3625using base::UTF8ToUTF16;
26using base::WideToUTF16;
27
[email protected]dbb97ba2013-09-09 22:15:2528namespace gfx {
29
30namespace {
31
32struct Testcase {
33 const std::string input;
34 const std::string output;
35};
36
37struct FileTestcase {
38 const base::FilePath::StringType input;
39 const std::string output;
40};
41
42struct UTF16Testcase {
[email protected]2aadf212013-12-18 20:03:4443 const base::string16 input;
44 const base::string16 output;
[email protected]dbb97ba2013-09-09 22:15:2545};
46
47struct TestData {
48 const std::string a;
49 const std::string b;
50 const int compare_result;
51};
52
[email protected]dbb97ba2013-09-09 22:15:2553} // namespace
54
olivierrobin697bbda2015-12-07 14:53:4855// TODO(crbug.com/546240): This test fails on iOS because iOS version of
56// GetStringWidthF that calls [NSString sizeWithFont] returns the rounded string
57// width.
58// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:3359#if defined(OS_IOS) || defined(OS_ANDROID)
[email protected]dbb97ba2013-09-09 22:15:2560#define MAYBE_ElideEmail DISABLED_ElideEmail
61#else
62#define MAYBE_ElideEmail ElideEmail
63#endif
64TEST(TextEliderTest, MAYBE_ElideEmail) {
65 const std::string kEllipsisStr(kEllipsis);
66
67 // Test emails and their expected elided forms (from which the available
68 // widths will be derived).
69 // For elided forms in which both the username and domain must be elided:
70 // the result (how many characters are left on each side) can be font
71 // dependent. To avoid this, the username is prefixed with the characters
72 // expected to remain in the domain.
73 Testcase testcases[] = {
74 {"[email protected]", "[email protected]"},
75 {"[email protected]", kEllipsisStr},
76 {"[email protected]", "ga@c" + kEllipsisStr + "a"},
77 {"[email protected]", "s" + kEllipsisStr + "@s" + kEllipsisStr},
78 {"[email protected]", "s" + kEllipsisStr + "@small.com"},
79 {"[email protected]", "[email protected]"},
80 {"[email protected]",
81 "short@long" + kEllipsisStr + ".com"},
82 {"[email protected]",
83 "la" + kEllipsisStr + "@l" + kEllipsisStr + "a"},
84 {"[email protected]", "long" + kEllipsisStr + "@gmail.com"},
85 {"[email protected]", "e" + kEllipsisStr + "@justfits.com"},
86 {"[email protected]",
87 "thatom" + kEllipsisStr + "@tha" + kEllipsisStr + "om"},
88 {"[email protected]",
89 "namefits@butthedo" + kEllipsisStr + "snt.com"},
90 {"[email protected]", kEllipsisStr},
91 {"nospaceforusername@l", kEllipsisStr},
92 {"[email protected]", "l" + kEllipsisStr + "@l" + kEllipsisStr},
93 {"[email protected]", "l@lllll" + kEllipsisStr + ".com"},
94 {"messed\"up@whyanat\"[email protected]",
95 "messed\"up@whyanat\"[email protected]"},
96 {"messed\"up@whyanat\"[email protected]",
97 "messed\"up@why" + kEllipsisStr + "@notgoogley.com"},
98 {"noca_messed\"up@whyanat\"[email protected]",
99 "noca" + kEllipsisStr + "@no" + kEllipsisStr + "ca"},
100 {"at\"@@@@@@@@@...@@.@.@.@@@\"@madness.com",
101 "at\"@@@@@@@@@...@@.@." + kEllipsisStr + "@madness.com"},
102 // Special case: "m..." takes more than half of the available width; thus
103 // the domain must elide to "l..." and not "l...l" as it must allow enough
104 // space for the minimal username elision although its half of the
105 // available width would normally allow it to elide to "l...l".
106 {"mmmmm@llllllllll", "m" + kEllipsisStr + "@l" + kEllipsisStr},
107 };
108
[email protected]8ad3c5a2013-10-10 09:57:19109 const FontList font_list;
[email protected]dbb97ba2013-09-09 22:15:25110 for (size_t i = 0; i < arraysize(testcases); ++i) {
[email protected]2aadf212013-12-18 20:03:44111 const base::string16 expected_output = UTF8ToUTF16(testcases[i].output);
[email protected]dbb97ba2013-09-09 22:15:25112 EXPECT_EQ(expected_output,
[email protected]f3ce6212014-06-05 22:42:08113 ElideText(UTF8ToUTF16(testcases[i].input), font_list,
114 GetStringWidthF(expected_output, font_list),
115 ELIDE_EMAIL));
[email protected]dbb97ba2013-09-09 22:15:25116 }
117}
118
olivierrobin697bbda2015-12-07 14:53:48119// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33120#if defined(OS_ANDROID)
121#define MAYBE_ElideEmailMoreSpace DISABLED_ElideEmailMoreSpace
122#else
123#define MAYBE_ElideEmailMoreSpace ElideEmailMoreSpace
124#endif
125TEST(TextEliderTest, MAYBE_ElideEmailMoreSpace) {
[email protected]dbb97ba2013-09-09 22:15:25126 const int test_width_factors[] = {
127 100,
128 10000,
129 1000000,
130 };
131 const std::string test_emails[] = {
132 "a@c",
133 "[email protected]",
134 "[email protected]",
135 "[email protected]",
136 };
137
[email protected]2859ff352013-11-08 15:58:49138 const FontList font_list;
[email protected]dbb97ba2013-09-09 22:15:25139 for (size_t i = 0; i < arraysize(test_width_factors); ++i) {
[email protected]2859ff352013-11-08 15:58:49140 const int test_width =
141 font_list.GetExpectedTextWidth(test_width_factors[i]);
[email protected]dbb97ba2013-09-09 22:15:25142 for (size_t j = 0; j < arraysize(test_emails); ++j) {
143 // Extra space is available: the email should not be elided.
[email protected]2aadf212013-12-18 20:03:44144 const base::string16 test_email = UTF8ToUTF16(test_emails[j]);
[email protected]f3ce6212014-06-05 22:42:08145 EXPECT_EQ(test_email,
146 ElideText(test_email, font_list, test_width, ELIDE_EMAIL));
[email protected]dbb97ba2013-09-09 22:15:25147 }
148 }
149}
150
olivierrobin697bbda2015-12-07 14:53:48151// TODO(crbug.com/546240): This test fails on iOS because iOS version of
152// GetStringWidthF that calls [NSString sizeWithFont] returns the rounded string
153// width.
154// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33155#if defined(OS_IOS) || defined(OS_ANDROID)
[email protected]dbb97ba2013-09-09 22:15:25156#define MAYBE_TestFilenameEliding DISABLED_TestFilenameEliding
157#else
158#define MAYBE_TestFilenameEliding TestFilenameEliding
159#endif
160TEST(TextEliderTest, MAYBE_TestFilenameEliding) {
161 const std::string kEllipsisStr(kEllipsis);
162 const base::FilePath::StringType kPathSeparator =
163 base::FilePath::StringType().append(1, base::FilePath::kSeparators[0]);
164
165 FileTestcase testcases[] = {
166 {FILE_PATH_LITERAL(""), ""},
167 {FILE_PATH_LITERAL("."), "."},
168 {FILE_PATH_LITERAL("filename.exe"), "filename.exe"},
169 {FILE_PATH_LITERAL(".longext"), ".longext"},
170 {FILE_PATH_LITERAL("pie"), "pie"},
171 {FILE_PATH_LITERAL("c:") + kPathSeparator + FILE_PATH_LITERAL("path") +
172 kPathSeparator + FILE_PATH_LITERAL("filename.pie"),
173 "filename.pie"},
174 {FILE_PATH_LITERAL("c:") + kPathSeparator + FILE_PATH_LITERAL("path") +
175 kPathSeparator + FILE_PATH_LITERAL("longfilename.pie"),
176 "long" + kEllipsisStr + ".pie"},
177 {FILE_PATH_LITERAL("http://path.com/filename.pie"), "filename.pie"},
178 {FILE_PATH_LITERAL("http://path.com/longfilename.pie"),
179 "long" + kEllipsisStr + ".pie"},
180 {FILE_PATH_LITERAL("piesmashingtacularpants"), "pie" + kEllipsisStr},
181 {FILE_PATH_LITERAL(".piesmashingtacularpants"), ".pie" + kEllipsisStr},
182 {FILE_PATH_LITERAL("cheese."), "cheese."},
183 {FILE_PATH_LITERAL("file name.longext"),
184 "file" + kEllipsisStr + ".longext"},
185 {FILE_PATH_LITERAL("fil ename.longext"),
186 "fil " + kEllipsisStr + ".longext"},
187 {FILE_PATH_LITERAL("filename.longext"),
188 "file" + kEllipsisStr + ".longext"},
189 {FILE_PATH_LITERAL("filename.middleext.longext"),
190 "filename.mid" + kEllipsisStr + ".longext"},
191 {FILE_PATH_LITERAL("filename.superduperextremelylongext"),
192 "filename.sup" + kEllipsisStr + "emelylongext"},
193 {FILE_PATH_LITERAL("filenamereallylongtext.superduperextremelylongext"),
194 "filenamereall" + kEllipsisStr + "emelylongext"},
195 {FILE_PATH_LITERAL("file.name.really.long.text.superduperextremelylongext"),
196 "file.name.re" + kEllipsisStr + "emelylongext"}
197 };
198
[email protected]8ad3c5a2013-10-10 09:57:19199 static const FontList font_list;
[email protected]dbb97ba2013-09-09 22:15:25200 for (size_t i = 0; i < arraysize(testcases); ++i) {
201 base::FilePath filepath(testcases[i].input);
[email protected]2aadf212013-12-18 20:03:44202 base::string16 expected = UTF8ToUTF16(testcases[i].output);
[email protected]dbb97ba2013-09-09 22:15:25203 expected = base::i18n::GetDisplayStringInLTRDirectionality(expected);
[email protected]8ad3c5a2013-10-10 09:57:19204 EXPECT_EQ(expected, ElideFilename(filepath, font_list,
205 GetStringWidthF(UTF8ToUTF16(testcases[i].output), font_list)));
[email protected]dbb97ba2013-09-09 22:15:25206 }
207}
208
olivierrobin697bbda2015-12-07 14:53:48209// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33210#if defined(OS_ANDROID)
211#define MAYBE_ElideTextTruncate DISABLED_ElideTextTruncate
212#else
213#define MAYBE_ElideTextTruncate ElideTextTruncate
214#endif
215TEST(TextEliderTest, MAYBE_ElideTextTruncate) {
[email protected]8ad3c5a2013-10-10 09:57:19216 const FontList font_list;
217 const float kTestWidth = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25218 struct TestData {
219 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19220 float width;
[email protected]dbb97ba2013-09-09 22:15:25221 const char* output;
222 } cases[] = {
223 { "", 0, "" },
224 { "Test", 0, "" },
225 { "", kTestWidth, "" },
226 { "Tes", kTestWidth, "Tes" },
227 { "Test", kTestWidth, "Test" },
228 { "Tests", kTestWidth, "Test" },
229 };
230
viettrungluua5ca99b2014-10-16 16:28:48231 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44232 base::string16 result = ElideText(UTF8ToUTF16(cases[i].input), font_list,
[email protected]f3ce6212014-06-05 22:42:08233 cases[i].width, TRUNCATE);
[email protected]dbb97ba2013-09-09 22:15:25234 EXPECT_EQ(cases[i].output, UTF16ToUTF8(result));
235 }
236}
237
olivierrobin697bbda2015-12-07 14:53:48238// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33239#if defined(OS_ANDROID)
240#define MAYBE_ElideTextEllipsis DISABLED_ElideTextEllipsis
241#else
242#define MAYBE_ElideTextEllipsis ElideTextEllipsis
243#endif
244TEST(TextEliderTest, MAYBE_ElideTextEllipsis) {
[email protected]8ad3c5a2013-10-10 09:57:19245 const FontList font_list;
246 const float kTestWidth = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25247 const char* kEllipsis = "\xE2\x80\xA6";
[email protected]8ad3c5a2013-10-10 09:57:19248 const float kEllipsisWidth =
249 GetStringWidthF(UTF8ToUTF16(kEllipsis), font_list);
[email protected]dbb97ba2013-09-09 22:15:25250 struct TestData {
251 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19252 float width;
[email protected]dbb97ba2013-09-09 22:15:25253 const char* output;
254 } cases[] = {
255 { "", 0, "" },
256 { "Test", 0, "" },
257 { "Test", kEllipsisWidth, kEllipsis },
258 { "", kTestWidth, "" },
259 { "Tes", kTestWidth, "Tes" },
260 { "Test", kTestWidth, "Test" },
261 };
262
viettrungluua5ca99b2014-10-16 16:28:48263 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44264 base::string16 result = ElideText(UTF8ToUTF16(cases[i].input), font_list,
[email protected]f3ce6212014-06-05 22:42:08265 cases[i].width, ELIDE_TAIL);
[email protected]dbb97ba2013-09-09 22:15:25266 EXPECT_EQ(cases[i].output, UTF16ToUTF8(result));
267 }
268}
269
olivierrobin697bbda2015-12-07 14:53:48270// TODO(crbug.com/338784): Enable this on android.
[email protected]9d3e32b32014-02-04 16:01:47271#if defined(OS_ANDROID)
272#define MAYBE_ElideTextEllipsisFront DISABLED_ElideTextEllipsisFront
273#else
274#define MAYBE_ElideTextEllipsisFront ElideTextEllipsisFront
275#endif
276TEST(TextEliderTest, MAYBE_ElideTextEllipsisFront) {
277 const FontList font_list;
278 const float kTestWidth = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
279 const std::string kEllipsisStr(kEllipsis);
280 const float kEllipsisWidth =
281 GetStringWidthF(UTF8ToUTF16(kEllipsis), font_list);
282 const float kEllipsis23Width =
283 GetStringWidthF(UTF8ToUTF16(kEllipsisStr + "23"), font_list);
284 struct TestData {
285 const char* input;
286 float width;
287 const base::string16 output;
288 } cases[] = {
289 { "", 0, base::string16() },
290 { "Test", 0, base::string16() },
291 { "Test", kEllipsisWidth, UTF8ToUTF16(kEllipsisStr) },
292 { "", kTestWidth, base::string16() },
293 { "Tes", kTestWidth, ASCIIToUTF16("Tes") },
294 { "Test", kTestWidth, ASCIIToUTF16("Test") },
295 { "Test123", kEllipsis23Width, UTF8ToUTF16(kEllipsisStr + "23") },
296 };
297
viettrungluua5ca99b2014-10-16 16:28:48298 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]9d3e32b32014-02-04 16:01:47299 base::string16 result = ElideText(UTF8ToUTF16(cases[i].input), font_list,
[email protected]f3ce6212014-06-05 22:42:08300 cases[i].width, ELIDE_HEAD);
[email protected]9d3e32b32014-02-04 16:01:47301 EXPECT_EQ(cases[i].output, result);
302 }
303}
304
[email protected]dbb97ba2013-09-09 22:15:25305// Checks that all occurrences of |first_char| are followed by |second_char| and
mgiuca034e9302015-04-22 02:44:53306// all occurrences of |second_char| are preceded by |first_char| in |text|. Can
307// be used to test surrogate pairs or two-character combining sequences.
308static void CheckCodeUnitPairs(const base::string16& text,
309 base::char16 first_char,
310 base::char16 second_char) {
[email protected]8d936142014-07-10 21:40:37311 for (size_t index = 0; index < text.length(); ++index) {
312 EXPECT_NE(second_char, text[index]);
313 if (text[index] == first_char) {
314 ASSERT_LT(++index, text.length());
315 EXPECT_EQ(second_char, text[index]);
316 }
[email protected]dbb97ba2013-09-09 22:15:25317 }
318}
319
mgiuca034e9302015-04-22 02:44:53320// Test that both both UTF-16 surrogate pairs and combining character sequences
321// do not get split by ElideText.
olivierrobin697bbda2015-12-07 14:53:48322// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33323#if defined(OS_ANDROID)
mgiuca034e9302015-04-22 02:44:53324#define MAYBE_ElideTextAtomicSequences DISABLED_ElideTextAtomicSequences
[email protected]ebc9b662014-01-30 03:37:33325#else
mgiuca034e9302015-04-22 02:44:53326#define MAYBE_ElideTextAtomicSequences ElideTextAtomicSequences
[email protected]ebc9b662014-01-30 03:37:33327#endif
mgiuca034e9302015-04-22 02:44:53328TEST(TextEliderTest, MAYBE_ElideTextAtomicSequences) {
[email protected]8ad3c5a2013-10-10 09:57:19329 const FontList font_list;
mgiuca034e9302015-04-22 02:44:53330 // The below is 'MUSICAL SYMBOL G CLEF' (U+1D11E), which is represented in
331 // UTF-16 as two code units forming a surrogate pair: 0xD834 0xDD1E.
332 const base::char16 kSurrogate[] = {0xD834, 0xDD1E, 0};
333 // The below is a Devanagari two-character combining sequence U+0921 U+093F.
334 // The sequence forms a single display character and should not be separated.
335 const base::char16 kCombiningSequence[] = {0x921, 0x93F, 0};
336 std::vector<base::string16> pairs;
337 pairs.push_back(kSurrogate);
338 pairs.push_back(kCombiningSequence);
[email protected]dbb97ba2013-09-09 22:15:25339
mgiuca034e9302015-04-22 02:44:53340 for (const base::string16& pair : pairs) {
341 base::char16 first_char = pair[0];
342 base::char16 second_char = pair[1];
343 base::string16 test_string = pair + UTF8ToUTF16("x") + pair;
344 SCOPED_TRACE(test_string);
345 const float test_string_width = GetStringWidthF(test_string, font_list);
346 base::string16 result;
[email protected]dbb97ba2013-09-09 22:15:25347
mgiuca034e9302015-04-22 02:44:53348 // Elide |text_string| to all possible widths and check that no instance of
349 // |pair| was split in two.
350 for (float width = 0; width <= test_string_width; width++) {
351 result = ElideText(test_string, font_list, width, TRUNCATE);
352 CheckCodeUnitPairs(result, first_char, second_char);
[email protected]dbb97ba2013-09-09 22:15:25353
mgiuca034e9302015-04-22 02:44:53354 result = ElideText(test_string, font_list, width, ELIDE_TAIL);
355 CheckCodeUnitPairs(result, first_char, second_char);
[email protected]9d3e32b32014-02-04 16:01:47356
mgiuca034e9302015-04-22 02:44:53357 result = ElideText(test_string, font_list, width, ELIDE_MIDDLE);
358 CheckCodeUnitPairs(result, first_char, second_char);
359
360 result = ElideText(test_string, font_list, width, ELIDE_HEAD);
361 CheckCodeUnitPairs(result, first_char, second_char);
362 }
[email protected]dbb97ba2013-09-09 22:15:25363 }
364}
365
olivierrobin697bbda2015-12-07 14:53:48366// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33367#if defined(OS_ANDROID)
368#define MAYBE_ElideTextLongStrings DISABLED_ElideTextLongStrings
369#else
370#define MAYBE_ElideTextLongStrings ElideTextLongStrings
371#endif
372TEST(TextEliderTest, MAYBE_ElideTextLongStrings) {
[email protected]2aadf212013-12-18 20:03:44373 const base::string16 kEllipsisStr = UTF8ToUTF16(kEllipsis);
374 base::string16 data_scheme(UTF8ToUTF16("data:text/plain,"));
[email protected]dbb97ba2013-09-09 22:15:25375 size_t data_scheme_length = data_scheme.length();
376
[email protected]2aadf212013-12-18 20:03:44377 base::string16 ten_a(10, 'a');
378 base::string16 hundred_a(100, 'a');
379 base::string16 thousand_a(1000, 'a');
380 base::string16 ten_thousand_a(10000, 'a');
381 base::string16 hundred_thousand_a(100000, 'a');
382 base::string16 million_a(1000000, 'a');
[email protected]dbb97ba2013-09-09 22:15:25383
[email protected]9d3e32b32014-02-04 16:01:47384 // TODO(gbillock): Improve these tests by adding more string diversity and
385 // doing string compares instead of length compares. See bug 338836.
386
[email protected]dbb97ba2013-09-09 22:15:25387 size_t number_of_as = 156;
[email protected]2aadf212013-12-18 20:03:44388 base::string16 long_string_end(
389 data_scheme + base::string16(number_of_as, 'a') + kEllipsisStr);
[email protected]dbb97ba2013-09-09 22:15:25390 UTF16Testcase testcases_end[] = {
[email protected]9d3e32b32014-02-04 16:01:47391 { data_scheme + ten_a, data_scheme + ten_a },
392 { data_scheme + hundred_a, data_scheme + hundred_a },
393 { data_scheme + thousand_a, long_string_end },
394 { data_scheme + ten_thousand_a, long_string_end },
395 { data_scheme + hundred_thousand_a, long_string_end },
396 { data_scheme + million_a, long_string_end },
[email protected]dbb97ba2013-09-09 22:15:25397 };
398
[email protected]8ad3c5a2013-10-10 09:57:19399 const FontList font_list;
400 float ellipsis_width = GetStringWidthF(kEllipsisStr, font_list);
[email protected]dbb97ba2013-09-09 22:15:25401 for (size_t i = 0; i < arraysize(testcases_end); ++i) {
402 // Compare sizes rather than actual contents because if the test fails,
403 // output is rather long.
404 EXPECT_EQ(testcases_end[i].output.size(),
[email protected]f3ce6212014-06-05 22:42:08405 ElideText(testcases_end[i].input, font_list,
406 GetStringWidthF(testcases_end[i].output, font_list),
407 ELIDE_TAIL).size());
[email protected]dbb97ba2013-09-09 22:15:25408 EXPECT_EQ(kEllipsisStr,
[email protected]8ad3c5a2013-10-10 09:57:19409 ElideText(testcases_end[i].input, font_list, ellipsis_width,
[email protected]f3ce6212014-06-05 22:42:08410 ELIDE_TAIL));
[email protected]dbb97ba2013-09-09 22:15:25411 }
412
413 size_t number_of_trailing_as = (data_scheme_length + number_of_as) / 2;
[email protected]2aadf212013-12-18 20:03:44414 base::string16 long_string_middle(data_scheme +
415 base::string16(number_of_as - number_of_trailing_as, 'a') + kEllipsisStr +
416 base::string16(number_of_trailing_as, 'a'));
[email protected]dbb97ba2013-09-09 22:15:25417 UTF16Testcase testcases_middle[] = {
[email protected]9d3e32b32014-02-04 16:01:47418 { data_scheme + ten_a, data_scheme + ten_a },
419 { data_scheme + hundred_a, data_scheme + hundred_a },
420 { data_scheme + thousand_a, long_string_middle },
421 { data_scheme + ten_thousand_a, long_string_middle },
422 { data_scheme + hundred_thousand_a, long_string_middle },
423 { data_scheme + million_a, long_string_middle },
[email protected]dbb97ba2013-09-09 22:15:25424 };
425
426 for (size_t i = 0; i < arraysize(testcases_middle); ++i) {
427 // Compare sizes rather than actual contents because if the test fails,
428 // output is rather long.
429 EXPECT_EQ(testcases_middle[i].output.size(),
[email protected]f3ce6212014-06-05 22:42:08430 ElideText(testcases_middle[i].input, font_list,
431 GetStringWidthF(testcases_middle[i].output, font_list),
432 ELIDE_MIDDLE).size());
[email protected]dbb97ba2013-09-09 22:15:25433 EXPECT_EQ(kEllipsisStr,
[email protected]8ad3c5a2013-10-10 09:57:19434 ElideText(testcases_middle[i].input, font_list, ellipsis_width,
[email protected]f3ce6212014-06-05 22:42:08435 ELIDE_MIDDLE));
[email protected]9d3e32b32014-02-04 16:01:47436 }
437
438 base::string16 long_string_beginning(
439 kEllipsisStr + base::string16(number_of_as, 'a'));
440 UTF16Testcase testcases_beginning[] = {
441 { data_scheme + ten_a, data_scheme + ten_a },
442 { data_scheme + hundred_a, data_scheme + hundred_a },
443 { data_scheme + thousand_a, long_string_beginning },
444 { data_scheme + ten_thousand_a, long_string_beginning },
445 { data_scheme + hundred_thousand_a, long_string_beginning },
446 { data_scheme + million_a, long_string_beginning },
447 };
448 for (size_t i = 0; i < arraysize(testcases_beginning); ++i) {
449 EXPECT_EQ(testcases_beginning[i].output.size(),
450 ElideText(
451 testcases_beginning[i].input, font_list,
452 GetStringWidthF(testcases_beginning[i].output, font_list),
[email protected]f3ce6212014-06-05 22:42:08453 ELIDE_HEAD).size());
[email protected]9d3e32b32014-02-04 16:01:47454 EXPECT_EQ(kEllipsisStr,
455 ElideText(testcases_beginning[i].input, font_list, ellipsis_width,
[email protected]f3ce6212014-06-05 22:42:08456 ELIDE_HEAD));
[email protected]dbb97ba2013-09-09 22:15:25457 }
458}
459
mgiuca034e9302015-04-22 02:44:53460// Detailed tests for StringSlicer. These are faster and test more of the edge
461// cases than the above tests which are more end-to-end.
462
463TEST(TextEliderTest, StringSlicerBasicTest) {
464 // Must store strings in variables (StringSlicer retains a reference to them).
465 base::string16 text(UTF8ToUTF16("Hello, world!"));
466 base::string16 ellipsis(kEllipsisUTF16);
467 StringSlicer slicer(text, ellipsis, false, false);
468
469 EXPECT_EQ(UTF8ToUTF16(""), slicer.CutString(0, false));
470 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
471
472 EXPECT_EQ(UTF8ToUTF16("Hell"), slicer.CutString(4, false));
473 EXPECT_EQ(UTF8ToUTF16("Hell") + kEllipsisUTF16, slicer.CutString(4, true));
474
475 EXPECT_EQ(text, slicer.CutString(text.length(), false));
476 EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(text.length(), true));
477
478 StringSlicer slicer_begin(text, ellipsis, false, true);
479 EXPECT_EQ(UTF8ToUTF16("rld!"), slicer_begin.CutString(4, false));
480 EXPECT_EQ(kEllipsisUTF16 + UTF8ToUTF16("rld!"),
481 slicer_begin.CutString(4, true));
482
483 StringSlicer slicer_mid(text, ellipsis, true, false);
484 EXPECT_EQ(UTF8ToUTF16("Held!"), slicer_mid.CutString(5, false));
485 EXPECT_EQ(UTF8ToUTF16("Hel") + kEllipsisUTF16 + UTF8ToUTF16("d!"),
486 slicer_mid.CutString(5, true));
487}
488
489TEST(TextEliderTest, StringSlicerSurrogate) {
490 // The below is 'MUSICAL SYMBOL G CLEF' (U+1D11E), which is represented in
491 // UTF-16 as two code units forming a surrogate pair: 0xD834 0xDD1E.
492 const base::char16 kSurrogate[] = {0xD834, 0xDD1E, 0};
493 base::string16 text(UTF8ToUTF16("abc") + kSurrogate + UTF8ToUTF16("xyz"));
494 base::string16 ellipsis(kEllipsisUTF16);
495 StringSlicer slicer(text, ellipsis, false, false);
496
497 // Cut surrogate on the right. Should round left and exclude the surrogate.
498 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
499 EXPECT_EQ(UTF8ToUTF16("abc") + kEllipsisUTF16, slicer.CutString(4, true));
500 EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(text.length(), true));
501
502 // Cut surrogate on the left. Should round left and include the surrogate.
503 StringSlicer slicer_begin(text, ellipsis, false, true);
504 EXPECT_EQ(base::string16(kEllipsisUTF16) + kSurrogate + UTF8ToUTF16("xyz"),
505 slicer_begin.CutString(4, true));
506
507 // Cut surrogate in the middle. Should round right and exclude the surrogate.
508 base::string16 short_text(UTF8ToUTF16("abc") + kSurrogate);
509 StringSlicer slicer_mid(short_text, ellipsis, true, false);
510 EXPECT_EQ(UTF8ToUTF16("a") + kEllipsisUTF16, slicer_mid.CutString(2, true));
511
512 // String that starts with a dangling trailing surrogate.
513 base::char16 dangling_trailing_chars[] = {kSurrogate[1], 0};
514 base::string16 dangling_trailing_text(dangling_trailing_chars);
515 StringSlicer slicer_dangling_trailing(dangling_trailing_text, ellipsis, false,
516 false);
517 EXPECT_EQ(base::string16(kEllipsisUTF16),
518 slicer_dangling_trailing.CutString(0, true));
519 EXPECT_EQ(dangling_trailing_text + kEllipsisUTF16,
520 slicer_dangling_trailing.CutString(1, true));
521}
522
523TEST(TextEliderTest, StringSlicerCombining) {
524 // The following string contains three combining character sequences (one for
525 // each category of combining mark):
526 // LATIN SMALL LETTER E + COMBINING ACUTE ACCENT + COMBINING CEDILLA
527 // LATIN SMALL LETTER X + COMBINING ENCLOSING KEYCAP
528 // DEVANAGARI LETTER DDA + DEVANAGARI VOWEL SIGN I
529 const base::char16 kText[] = {
530 'e', 0x301, 0x327, ' ', 'x', 0x20E3, ' ', 0x921, 0x93F, 0};
531 base::string16 text(kText);
532 base::string16 ellipsis(kEllipsisUTF16);
533 StringSlicer slicer(text, ellipsis, false, false);
534
535 // Attempt to cut the string for all lengths. When a combining sequence is
536 // cut, it should always round left and exclude the combining sequence.
537 // First sequence:
538 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
539 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(1, true));
540 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(2, true));
541 EXPECT_EQ(text.substr(0, 3) + kEllipsisUTF16, slicer.CutString(3, true));
542 // Second sequence:
543 EXPECT_EQ(text.substr(0, 4) + kEllipsisUTF16, slicer.CutString(4, true));
544 EXPECT_EQ(text.substr(0, 4) + kEllipsisUTF16, slicer.CutString(5, true));
545 EXPECT_EQ(text.substr(0, 6) + kEllipsisUTF16, slicer.CutString(6, true));
546 // Third sequence:
547 EXPECT_EQ(text.substr(0, 7) + kEllipsisUTF16, slicer.CutString(7, true));
548 EXPECT_EQ(text.substr(0, 7) + kEllipsisUTF16, slicer.CutString(8, true));
549 EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(9, true));
550
551 // Cut string in the middle, splitting the second sequence in half. Should
552 // round both left and right, excluding the second sequence.
553 StringSlicer slicer_mid(text, ellipsis, true, false);
554 EXPECT_EQ(text.substr(0, 4) + kEllipsisUTF16 + text.substr(6),
555 slicer_mid.CutString(9, true));
556
557 // String that starts with a dangling combining mark.
558 base::char16 dangling_mark_chars[] = {text[1], 0};
559 base::string16 dangling_mark_text(dangling_mark_chars);
560 StringSlicer slicer_dangling_mark(dangling_mark_text, ellipsis, false, false);
561 EXPECT_EQ(base::string16(kEllipsisUTF16),
562 slicer_dangling_mark.CutString(0, true));
563 EXPECT_EQ(dangling_mark_text + kEllipsisUTF16,
564 slicer_dangling_mark.CutString(1, true));
565}
566
567TEST(TextEliderTest, StringSlicerCombiningSurrogate) {
568 // The ultimate test: combining sequences comprised of surrogate pairs.
569 // The following string contains a single combining character sequence:
570 // MUSICAL SYMBOL G CLEF (U+1D11E) + MUSICAL SYMBOL COMBINING FLAG-1 (U+1D16E)
571 // Represented as four UTF-16 code units.
572 const base::char16 kText[] = {0xD834, 0xDD1E, 0xD834, 0xDD6E, 0};
573 base::string16 text(kText);
574 base::string16 ellipsis(kEllipsisUTF16);
575 StringSlicer slicer(text, ellipsis, false, false);
576
577 // Attempt to cut the string for all lengths. Should always round left and
578 // exclude the combining sequence.
579 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
580 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(1, true));
581 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(2, true));
582 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(3, true));
583 EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(4, true));
584
585 // Cut string in the middle. Should exclude the sequence.
586 StringSlicer slicer_mid(text, ellipsis, true, false);
587 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer_mid.CutString(4, true));
588}
589
[email protected]dbb97ba2013-09-09 22:15:25590TEST(TextEliderTest, ElideString) {
591 struct TestData {
592 const char* input;
593 int max_len;
594 bool result;
595 const char* output;
596 } cases[] = {
597 { "Hello", 0, true, "" },
598 { "", 0, false, "" },
599 { "Hello, my name is Tom", 1, true, "H" },
600 { "Hello, my name is Tom", 2, true, "He" },
601 { "Hello, my name is Tom", 3, true, "H.m" },
602 { "Hello, my name is Tom", 4, true, "H..m" },
603 { "Hello, my name is Tom", 5, true, "H...m" },
604 { "Hello, my name is Tom", 6, true, "He...m" },
605 { "Hello, my name is Tom", 7, true, "He...om" },
606 { "Hello, my name is Tom", 10, true, "Hell...Tom" },
607 { "Hello, my name is Tom", 100, false, "Hello, my name is Tom" }
608 };
viettrungluua5ca99b2014-10-16 16:28:48609 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44610 base::string16 output;
[email protected]dbb97ba2013-09-09 22:15:25611 EXPECT_EQ(cases[i].result,
612 ElideString(UTF8ToUTF16(cases[i].input),
613 cases[i].max_len, &output));
614 EXPECT_EQ(cases[i].output, UTF16ToUTF8(output));
615 }
616}
617
olivierrobin697bbda2015-12-07 14:53:48618// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33619#if defined(OS_ANDROID)
620#define MAYBE_ElideRectangleText DISABLED_ElideRectangleText
621#else
622#define MAYBE_ElideRectangleText ElideRectangleText
623#endif
624TEST(TextEliderTest, MAYBE_ElideRectangleText) {
[email protected]8ad3c5a2013-10-10 09:57:19625 const FontList font_list;
626 const int line_height = font_list.GetHeight();
627 const float test_width = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25628
629 struct TestData {
630 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19631 float available_pixel_width;
[email protected]dbb97ba2013-09-09 22:15:25632 int available_pixel_height;
633 bool truncated_y;
634 const char* output;
635 } cases[] = {
636 { "", 0, 0, false, NULL },
637 { "", 1, 1, false, NULL },
638 { "Test", test_width, 0, true, NULL },
639 { "Test", test_width, 1, false, "Test" },
640 { "Test", test_width, line_height, false, "Test" },
641 { "Test Test", test_width, line_height, true, "Test" },
642 { "Test Test", test_width, line_height + 1, false, "Test|Test" },
643 { "Test Test", test_width, line_height * 2, false, "Test|Test" },
644 { "Test Test", test_width, line_height * 3, false, "Test|Test" },
645 { "Test Test", test_width * 2, line_height * 2, false, "Test|Test" },
646 { "Test Test", test_width * 3, line_height, false, "Test Test" },
647 { "Test\nTest", test_width * 3, line_height * 2, false, "Test|Test" },
648 { "Te\nst Te", test_width, line_height * 3, false, "Te|st|Te" },
649 { "\nTest", test_width, line_height * 2, false, "|Test" },
650 { "\nTest", test_width, line_height, true, "" },
651 { "\n\nTest", test_width, line_height * 3, false, "||Test" },
652 { "\n\nTest", test_width, line_height * 2, true, "|" },
653 { "Test\n", 2 * test_width, line_height * 5, false, "Test|" },
654 { "Test\n\n", 2 * test_width, line_height * 5, false, "Test||" },
655 { "Test\n\n\n", 2 * test_width, line_height * 5, false, "Test|||" },
656 { "Test\nTest\n\n", 2 * test_width, line_height * 5, false, "Test|Test||" },
657 { "Test\n\nTest\n", 2 * test_width, line_height * 5, false, "Test||Test|" },
658 { "Test\n\n\nTest", 2 * test_width, line_height * 5, false, "Test|||Test" },
659 { "Te ", test_width, line_height, false, "Te" },
660 { "Te Te Test", test_width, 3 * line_height, false, "Te|Te|Test" },
661 };
662
viettrungluua5ca99b2014-10-16 16:28:48663 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44664 std::vector<base::string16> lines;
[email protected]dbb97ba2013-09-09 22:15:25665 EXPECT_EQ(cases[i].truncated_y ? INSUFFICIENT_SPACE_VERTICAL : 0,
666 ElideRectangleText(UTF8ToUTF16(cases[i].input),
[email protected]8ad3c5a2013-10-10 09:57:19667 font_list,
[email protected]dbb97ba2013-09-09 22:15:25668 cases[i].available_pixel_width,
669 cases[i].available_pixel_height,
670 TRUNCATE_LONG_WORDS,
671 &lines));
672 if (cases[i].output) {
brettwd94a22142015-07-15 05:19:26673 const std::string result =
674 UTF16ToUTF8(base::JoinString(lines, ASCIIToUTF16("|")));
[email protected]dbb97ba2013-09-09 22:15:25675 EXPECT_EQ(cases[i].output, result) << "Case " << i << " failed!";
676 } else {
677 EXPECT_TRUE(lines.empty()) << "Case " << i << " failed!";
678 }
679 }
680}
681
olivierrobin697bbda2015-12-07 14:53:48682// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33683#if defined(OS_ANDROID)
684#define MAYBE_ElideRectangleTextPunctuation \
685 DISABLED_ElideRectangleTextPunctuation
686#else
687#define MAYBE_ElideRectangleTextPunctuation ElideRectangleTextPunctuation
688#endif
689TEST(TextEliderTest, MAYBE_ElideRectangleTextPunctuation) {
[email protected]8ad3c5a2013-10-10 09:57:19690 const FontList font_list;
691 const int line_height = font_list.GetHeight();
692 const float test_width = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
693 const float test_t_width = GetStringWidthF(ASCIIToUTF16("Test T"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25694
695 struct TestData {
696 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19697 float available_pixel_width;
[email protected]dbb97ba2013-09-09 22:15:25698 int available_pixel_height;
699 bool wrap_words;
700 bool truncated_x;
701 const char* output;
702 } cases[] = {
703 { "Test T.", test_t_width, line_height * 2, false, false, "Test|T." },
704 { "Test T ?", test_t_width, line_height * 2, false, false, "Test|T ?" },
705 { "Test. Test", test_width, line_height * 3, false, true, "Test|Test" },
706 { "Test. Test", test_width, line_height * 3, true, false, "Test|.|Test" },
707 };
708
viettrungluua5ca99b2014-10-16 16:28:48709 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44710 std::vector<base::string16> lines;
[email protected]dbb97ba2013-09-09 22:15:25711 const WordWrapBehavior wrap_behavior =
712 (cases[i].wrap_words ? WRAP_LONG_WORDS : TRUNCATE_LONG_WORDS);
713 EXPECT_EQ(cases[i].truncated_x ? INSUFFICIENT_SPACE_HORIZONTAL : 0,
714 ElideRectangleText(UTF8ToUTF16(cases[i].input),
[email protected]8ad3c5a2013-10-10 09:57:19715 font_list,
[email protected]dbb97ba2013-09-09 22:15:25716 cases[i].available_pixel_width,
717 cases[i].available_pixel_height,
718 wrap_behavior,
719 &lines));
720 if (cases[i].output) {
brettwd94a22142015-07-15 05:19:26721 const std::string result =
722 UTF16ToUTF8(base::JoinString(lines, base::ASCIIToUTF16("|")));
[email protected]dbb97ba2013-09-09 22:15:25723 EXPECT_EQ(cases[i].output, result) << "Case " << i << " failed!";
724 } else {
725 EXPECT_TRUE(lines.empty()) << "Case " << i << " failed!";
726 }
727 }
728}
729
olivierrobin697bbda2015-12-07 14:53:48730// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33731#if defined(OS_ANDROID)
732#define MAYBE_ElideRectangleTextLongWords DISABLED_ElideRectangleTextLongWords
733#else
734#define MAYBE_ElideRectangleTextLongWords ElideRectangleTextLongWords
735#endif
736TEST(TextEliderTest, MAYBE_ElideRectangleTextLongWords) {
[email protected]8ad3c5a2013-10-10 09:57:19737 const FontList font_list;
[email protected]dbb97ba2013-09-09 22:15:25738 const int kAvailableHeight = 1000;
[email protected]2aadf212013-12-18 20:03:44739 const base::string16 kElidedTesting =
740 UTF8ToUTF16(std::string("Tes") + kEllipsis);
[email protected]8ad3c5a2013-10-10 09:57:19741 const float elided_width = GetStringWidthF(kElidedTesting, font_list);
742 const float test_width = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25743
744 struct TestData {
745 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19746 float available_pixel_width;
[email protected]dbb97ba2013-09-09 22:15:25747 WordWrapBehavior wrap_behavior;
748 bool truncated_x;
749 const char* output;
750 } cases[] = {
751 { "Testing", test_width, IGNORE_LONG_WORDS, false, "Testing" },
752 { "X Testing", test_width, IGNORE_LONG_WORDS, false, "X|Testing" },
753 { "Test Testing", test_width, IGNORE_LONG_WORDS, false, "Test|Testing" },
754 { "Test\nTesting", test_width, IGNORE_LONG_WORDS, false, "Test|Testing" },
755 { "Test Tests ", test_width, IGNORE_LONG_WORDS, false, "Test|Tests" },
756 { "Test Tests T", test_width, IGNORE_LONG_WORDS, false, "Test|Tests|T" },
757
758 { "Testing", elided_width, ELIDE_LONG_WORDS, true, "Tes..." },
759 { "X Testing", elided_width, ELIDE_LONG_WORDS, true, "X|Tes..." },
760 { "Test Testing", elided_width, ELIDE_LONG_WORDS, true, "Test|Tes..." },
761 { "Test\nTesting", elided_width, ELIDE_LONG_WORDS, true, "Test|Tes..." },
762
763 { "Testing", test_width, TRUNCATE_LONG_WORDS, true, "Test" },
764 { "X Testing", test_width, TRUNCATE_LONG_WORDS, true, "X|Test" },
765 { "Test Testing", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test" },
766 { "Test\nTesting", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test" },
767 { "Test Tests ", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test" },
768 { "Test Tests T", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test|T" },
769
770 { "Testing", test_width, WRAP_LONG_WORDS, false, "Test|ing" },
771 { "X Testing", test_width, WRAP_LONG_WORDS, false, "X|Test|ing" },
772 { "Test Testing", test_width, WRAP_LONG_WORDS, false, "Test|Test|ing" },
773 { "Test\nTesting", test_width, WRAP_LONG_WORDS, false, "Test|Test|ing" },
774 { "Test Tests ", test_width, WRAP_LONG_WORDS, false, "Test|Test|s" },
775 { "Test Tests T", test_width, WRAP_LONG_WORDS, false, "Test|Test|s T" },
776 { "TestTestTest", test_width, WRAP_LONG_WORDS, false, "Test|Test|Test" },
777 { "TestTestTestT", test_width, WRAP_LONG_WORDS, false, "Test|Test|Test|T" },
778 };
779
viettrungluua5ca99b2014-10-16 16:28:48780 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44781 std::vector<base::string16> lines;
[email protected]dbb97ba2013-09-09 22:15:25782 EXPECT_EQ(cases[i].truncated_x ? INSUFFICIENT_SPACE_HORIZONTAL : 0,
783 ElideRectangleText(UTF8ToUTF16(cases[i].input),
[email protected]8ad3c5a2013-10-10 09:57:19784 font_list,
[email protected]dbb97ba2013-09-09 22:15:25785 cases[i].available_pixel_width,
786 kAvailableHeight,
787 cases[i].wrap_behavior,
788 &lines));
789 std::string expected_output(cases[i].output);
brettwe6dae462015-06-24 20:54:45790 base::ReplaceSubstringsAfterOffset(&expected_output, 0, "...", kEllipsis);
brettwd94a22142015-07-15 05:19:26791 const std::string result =
792 UTF16ToUTF8(base::JoinString(lines, base::ASCIIToUTF16("|")));
[email protected]dbb97ba2013-09-09 22:15:25793 EXPECT_EQ(expected_output, result) << "Case " << i << " failed!";
794 }
795}
796
[email protected]c3087982013-09-20 17:46:53797// This test is to make sure that the width of each wrapped line does not
798// exceed the available width. On some platform like Mac, this test used to
799// fail because the truncated integer width is returned for the string
800// and the accumulation of the truncated values causes the elide function
801// to wrap incorrectly.
olivierrobin697bbda2015-12-07 14:53:48802// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33803#if defined(OS_ANDROID)
804#define MAYBE_ElideRectangleTextCheckLineWidth \
805 DISABLED_ElideRectangleTextCheckLineWidth
806#else
807#define MAYBE_ElideRectangleTextCheckLineWidth ElideRectangleTextCheckLineWidth
808#endif
809TEST(TextEliderTest, MAYBE_ElideRectangleTextCheckLineWidth) {
[email protected]8ad3c5a2013-10-10 09:57:19810 FontList font_list;
811#if defined(OS_MACOSX) && !defined(OS_IOS)
812 // Use a specific font to expose the line width exceeding problem.
813 font_list = FontList(Font("LucidaGrande", 12));
814#endif
815 const float kAvailableWidth = 235;
[email protected]c3087982013-09-20 17:46:53816 const int kAvailableHeight = 1000;
817 const char text[] = "that Russian place we used to go to after fencing";
[email protected]2aadf212013-12-18 20:03:44818 std::vector<base::string16> lines;
[email protected]c3087982013-09-20 17:46:53819 EXPECT_EQ(0, ElideRectangleText(UTF8ToUTF16(text),
[email protected]8ad3c5a2013-10-10 09:57:19820 font_list,
[email protected]c3087982013-09-20 17:46:53821 kAvailableWidth,
822 kAvailableHeight,
823 WRAP_LONG_WORDS,
824 &lines));
825 ASSERT_EQ(2u, lines.size());
[email protected]8ad3c5a2013-10-10 09:57:19826 EXPECT_LE(GetStringWidthF(lines[0], font_list), kAvailableWidth);
827 EXPECT_LE(GetStringWidthF(lines[1], font_list), kAvailableWidth);
[email protected]c3087982013-09-20 17:46:53828}
829
rsorokin370fe4b2014-11-11 15:14:07830#ifdef OS_CHROMEOS
831// This test was created specifically to test a message from crbug.com/415213.
832// It tests that width of concatenation of words equals sum of widths of the
833// words.
834TEST(TextEliderTest, ElideRectangleTextCheckConcatWidthEqualsSumOfWidths) {
835 FontList font_list;
836 font_list = FontList("Noto Sans UI,ui-sans, 12px");
837 SetFontRenderParamsDeviceScaleFactor(1.25f);
838#define WIDTH(x) GetStringWidthF(UTF8ToUTF16(x), font_list)
839 EXPECT_EQ(WIDTH("The administrator for this account has"),
840 WIDTH("The ") + WIDTH("administrator ") + WIDTH("for ") +
841 WIDTH("this ") + WIDTH("account ") + WIDTH("has"));
842#undef WIDTH
843 SetFontRenderParamsDeviceScaleFactor(1.0f);
844}
845#endif // OS_CHROMEOS
846
olivierrobin697bbda2015-12-07 14:53:48847// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:24848#if defined(OS_ANDROID)
849#define MAYBE_ElideRectangleString DISABLED_ElideRectangleString
850#else
851#define MAYBE_ElideRectangleString ElideRectangleString
852#endif
853TEST(TextEliderTest, MAYBE_ElideRectangleString) {
[email protected]dbb97ba2013-09-09 22:15:25854 struct TestData {
855 const char* input;
856 int max_rows;
857 int max_cols;
858 bool result;
859 const char* output;
860 } cases[] = {
861 { "", 0, 0, false, "" },
862 { "", 1, 1, false, "" },
863 { "Hi, my name is\nTom", 0, 0, true, "..." },
864 { "Hi, my name is\nTom", 1, 0, true, "\n..." },
865 { "Hi, my name is\nTom", 0, 1, true, "..." },
866 { "Hi, my name is\nTom", 1, 1, true, "H\n..." },
867 { "Hi, my name is\nTom", 2, 1, true, "H\ni\n..." },
868 { "Hi, my name is\nTom", 3, 1, true, "H\ni\n,\n..." },
869 { "Hi, my name is\nTom", 4, 1, true, "H\ni\n,\n \n..." },
870 { "Hi, my name is\nTom", 5, 1, true, "H\ni\n,\n \nm\n..." },
871 { "Hi, my name is\nTom", 0, 2, true, "..." },
872 { "Hi, my name is\nTom", 1, 2, true, "Hi\n..." },
873 { "Hi, my name is\nTom", 2, 2, true, "Hi\n, \n..." },
874 { "Hi, my name is\nTom", 3, 2, true, "Hi\n, \nmy\n..." },
875 { "Hi, my name is\nTom", 4, 2, true, "Hi\n, \nmy\n n\n..." },
876 { "Hi, my name is\nTom", 5, 2, true, "Hi\n, \nmy\n n\nam\n..." },
877 { "Hi, my name is\nTom", 0, 3, true, "..." },
878 { "Hi, my name is\nTom", 1, 3, true, "Hi,\n..." },
879 { "Hi, my name is\nTom", 2, 3, true, "Hi,\n my\n..." },
880 { "Hi, my name is\nTom", 3, 3, true, "Hi,\n my\n na\n..." },
881 { "Hi, my name is\nTom", 4, 3, true, "Hi,\n my\n na\nme \n..." },
882 { "Hi, my name is\nTom", 5, 3, true, "Hi,\n my\n na\nme \nis\n..." },
883 { "Hi, my name is\nTom", 1, 4, true, "Hi, \n..." },
884 { "Hi, my name is\nTom", 2, 4, true, "Hi, \nmy n\n..." },
885 { "Hi, my name is\nTom", 3, 4, true, "Hi, \nmy n\name \n..." },
886 { "Hi, my name is\nTom", 4, 4, true, "Hi, \nmy n\name \nis\n..." },
887 { "Hi, my name is\nTom", 5, 4, false, "Hi, \nmy n\name \nis\nTom" },
888 { "Hi, my name is\nTom", 1, 5, true, "Hi, \n..." },
889 { "Hi, my name is\nTom", 2, 5, true, "Hi, \nmy na\n..." },
890 { "Hi, my name is\nTom", 3, 5, true, "Hi, \nmy na\nme \n..." },
891 { "Hi, my name is\nTom", 4, 5, true, "Hi, \nmy na\nme \nis\n..." },
892 { "Hi, my name is\nTom", 5, 5, false, "Hi, \nmy na\nme \nis\nTom" },
893 { "Hi, my name is\nTom", 1, 6, true, "Hi, \n..." },
894 { "Hi, my name is\nTom", 2, 6, true, "Hi, \nmy \n..." },
895 { "Hi, my name is\nTom", 3, 6, true, "Hi, \nmy \nname \n..." },
896 { "Hi, my name is\nTom", 4, 6, true, "Hi, \nmy \nname \nis\n..." },
897 { "Hi, my name is\nTom", 5, 6, false, "Hi, \nmy \nname \nis\nTom" },
898 { "Hi, my name is\nTom", 1, 7, true, "Hi, \n..." },
899 { "Hi, my name is\nTom", 2, 7, true, "Hi, \nmy \n..." },
900 { "Hi, my name is\nTom", 3, 7, true, "Hi, \nmy \nname \n..." },
901 { "Hi, my name is\nTom", 4, 7, true, "Hi, \nmy \nname \nis\n..." },
902 { "Hi, my name is\nTom", 5, 7, false, "Hi, \nmy \nname \nis\nTom" },
903 { "Hi, my name is\nTom", 1, 8, true, "Hi, my \n..." },
904 { "Hi, my name is\nTom", 2, 8, true, "Hi, my \nname \n..." },
905 { "Hi, my name is\nTom", 3, 8, true, "Hi, my \nname \nis\n..." },
906 { "Hi, my name is\nTom", 4, 8, false, "Hi, my \nname \nis\nTom" },
907 { "Hi, my name is\nTom", 1, 9, true, "Hi, my \n..." },
908 { "Hi, my name is\nTom", 2, 9, true, "Hi, my \nname is\n..." },
909 { "Hi, my name is\nTom", 3, 9, false, "Hi, my \nname is\nTom" },
910 { "Hi, my name is\nTom", 1, 10, true, "Hi, my \n..." },
911 { "Hi, my name is\nTom", 2, 10, true, "Hi, my \nname is\n..." },
912 { "Hi, my name is\nTom", 3, 10, false, "Hi, my \nname is\nTom" },
913 { "Hi, my name is\nTom", 1, 11, true, "Hi, my \n..." },
914 { "Hi, my name is\nTom", 2, 11, true, "Hi, my \nname is\n..." },
915 { "Hi, my name is\nTom", 3, 11, false, "Hi, my \nname is\nTom" },
916 { "Hi, my name is\nTom", 1, 12, true, "Hi, my \n..." },
917 { "Hi, my name is\nTom", 2, 12, true, "Hi, my \nname is\n..." },
918 { "Hi, my name is\nTom", 3, 12, false, "Hi, my \nname is\nTom" },
919 { "Hi, my name is\nTom", 1, 13, true, "Hi, my name \n..." },
920 { "Hi, my name is\nTom", 2, 13, true, "Hi, my name \nis\n..." },
921 { "Hi, my name is\nTom", 3, 13, false, "Hi, my name \nis\nTom" },
922 { "Hi, my name is\nTom", 1, 20, true, "Hi, my name is\n..." },
923 { "Hi, my name is\nTom", 2, 20, false, "Hi, my name is\nTom" },
924 { "Hi, my name is Tom", 1, 40, false, "Hi, my name is Tom" },
925 };
[email protected]2aadf212013-12-18 20:03:44926 base::string16 output;
viettrungluua5ca99b2014-10-16 16:28:48927 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]dbb97ba2013-09-09 22:15:25928 EXPECT_EQ(cases[i].result,
929 ElideRectangleString(UTF8ToUTF16(cases[i].input),
930 cases[i].max_rows, cases[i].max_cols,
931 true, &output));
932 EXPECT_EQ(cases[i].output, UTF16ToUTF8(output));
933 }
934}
935
olivierrobin697bbda2015-12-07 14:53:48936// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:24937#if defined(OS_ANDROID)
938#define MAYBE_ElideRectangleStringNotStrict \
939 DISABLED_ElideRectangleStringNotStrict
940#else
941#define MAYBE_ElideRectangleStringNotStrict ElideRectangleStringNotStrict
942#endif
943TEST(TextEliderTest, MAYBE_ElideRectangleStringNotStrict) {
[email protected]dbb97ba2013-09-09 22:15:25944 struct TestData {
945 const char* input;
946 int max_rows;
947 int max_cols;
948 bool result;
949 const char* output;
950 } cases[] = {
951 { "", 0, 0, false, "" },
952 { "", 1, 1, false, "" },
953 { "Hi, my name_is\nDick", 0, 0, true, "..." },
954 { "Hi, my name_is\nDick", 1, 0, true, "\n..." },
955 { "Hi, my name_is\nDick", 0, 1, true, "..." },
956 { "Hi, my name_is\nDick", 1, 1, true, "H\n..." },
957 { "Hi, my name_is\nDick", 2, 1, true, "H\ni\n..." },
958 { "Hi, my name_is\nDick", 3, 1, true, "H\ni\n,\n..." },
959 { "Hi, my name_is\nDick", 4, 1, true, "H\ni\n,\n \n..." },
960 { "Hi, my name_is\nDick", 5, 1, true, "H\ni\n,\n \nm\n..." },
961 { "Hi, my name_is\nDick", 0, 2, true, "..." },
962 { "Hi, my name_is\nDick", 1, 2, true, "Hi\n..." },
963 { "Hi, my name_is\nDick", 2, 2, true, "Hi\n, \n..." },
964 { "Hi, my name_is\nDick", 3, 2, true, "Hi\n, \nmy\n..." },
965 { "Hi, my name_is\nDick", 4, 2, true, "Hi\n, \nmy\n n\n..." },
966 { "Hi, my name_is\nDick", 5, 2, true, "Hi\n, \nmy\n n\nam\n..." },
967 { "Hi, my name_is\nDick", 0, 3, true, "..." },
968 { "Hi, my name_is\nDick", 1, 3, true, "Hi,\n..." },
969 { "Hi, my name_is\nDick", 2, 3, true, "Hi,\n my\n..." },
970 { "Hi, my name_is\nDick", 3, 3, true, "Hi,\n my\n na\n..." },
971 { "Hi, my name_is\nDick", 4, 3, true, "Hi,\n my\n na\nme_\n..." },
972 { "Hi, my name_is\nDick", 5, 3, true, "Hi,\n my\n na\nme_\nis\n..." },
973 { "Hi, my name_is\nDick", 1, 4, true, "Hi, ..." },
974 { "Hi, my name_is\nDick", 2, 4, true, "Hi, my n\n..." },
975 { "Hi, my name_is\nDick", 3, 4, true, "Hi, my n\name_\n..." },
976 { "Hi, my name_is\nDick", 4, 4, true, "Hi, my n\name_\nis\n..." },
977 { "Hi, my name_is\nDick", 5, 4, false, "Hi, my n\name_\nis\nDick" },
978 { "Hi, my name_is\nDick", 1, 5, true, "Hi, ..." },
979 { "Hi, my name_is\nDick", 2, 5, true, "Hi, my na\n..." },
980 { "Hi, my name_is\nDick", 3, 5, true, "Hi, my na\nme_is\n..." },
981 { "Hi, my name_is\nDick", 4, 5, true, "Hi, my na\nme_is\n\n..." },
982 { "Hi, my name_is\nDick", 5, 5, false, "Hi, my na\nme_is\n\nDick" },
983 { "Hi, my name_is\nDick", 1, 6, true, "Hi, ..." },
984 { "Hi, my name_is\nDick", 2, 6, true, "Hi, my nam\n..." },
985 { "Hi, my name_is\nDick", 3, 6, true, "Hi, my nam\ne_is\n..." },
986 { "Hi, my name_is\nDick", 4, 6, false, "Hi, my nam\ne_is\nDick" },
987 { "Hi, my name_is\nDick", 5, 6, false, "Hi, my nam\ne_is\nDick" },
988 { "Hi, my name_is\nDick", 1, 7, true, "Hi, ..." },
989 { "Hi, my name_is\nDick", 2, 7, true, "Hi, my name\n..." },
990 { "Hi, my name_is\nDick", 3, 7, true, "Hi, my name\n_is\n..." },
991 { "Hi, my name_is\nDick", 4, 7, false, "Hi, my name\n_is\nDick" },
992 { "Hi, my name_is\nDick", 5, 7, false, "Hi, my name\n_is\nDick" },
993 { "Hi, my name_is\nDick", 1, 8, true, "Hi, my n\n..." },
994 { "Hi, my name_is\nDick", 2, 8, true, "Hi, my n\name_is\n..." },
995 { "Hi, my name_is\nDick", 3, 8, false, "Hi, my n\name_is\nDick" },
996 { "Hi, my name_is\nDick", 1, 9, true, "Hi, my ..." },
997 { "Hi, my name_is\nDick", 2, 9, true, "Hi, my name_is\n..." },
998 { "Hi, my name_is\nDick", 3, 9, false, "Hi, my name_is\nDick" },
999 { "Hi, my name_is\nDick", 1, 10, true, "Hi, my ..." },
1000 { "Hi, my name_is\nDick", 2, 10, true, "Hi, my name_is\n..." },
1001 { "Hi, my name_is\nDick", 3, 10, false, "Hi, my name_is\nDick" },
1002 { "Hi, my name_is\nDick", 1, 11, true, "Hi, my ..." },
1003 { "Hi, my name_is\nDick", 2, 11, true, "Hi, my name_is\n..." },
1004 { "Hi, my name_is\nDick", 3, 11, false, "Hi, my name_is\nDick" },
1005 { "Hi, my name_is\nDick", 1, 12, true, "Hi, my ..." },
1006 { "Hi, my name_is\nDick", 2, 12, true, "Hi, my name_is\n..." },
1007 { "Hi, my name_is\nDick", 3, 12, false, "Hi, my name_is\nDick" },
1008 { "Hi, my name_is\nDick", 1, 13, true, "Hi, my ..." },
1009 { "Hi, my name_is\nDick", 2, 13, true, "Hi, my name_is\n..." },
1010 { "Hi, my name_is\nDick", 3, 13, false, "Hi, my name_is\nDick" },
1011 { "Hi, my name_is\nDick", 1, 20, true, "Hi, my name_is\n..." },
1012 { "Hi, my name_is\nDick", 2, 20, false, "Hi, my name_is\nDick" },
1013 { "Hi, my name_is Dick", 1, 40, false, "Hi, my name_is Dick" },
1014 };
[email protected]2aadf212013-12-18 20:03:441015 base::string16 output;
viettrungluua5ca99b2014-10-16 16:28:481016 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]dbb97ba2013-09-09 22:15:251017 EXPECT_EQ(cases[i].result,
1018 ElideRectangleString(UTF8ToUTF16(cases[i].input),
1019 cases[i].max_rows, cases[i].max_cols,
1020 false, &output));
1021 EXPECT_EQ(cases[i].output, UTF16ToUTF8(output));
1022 }
1023}
1024
olivierrobin697bbda2015-12-07 14:53:481025// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:241026#if defined(OS_ANDROID)
1027#define MAYBE_ElideRectangleWide16 DISABLED_ElideRectangleWide16
1028#else
1029#define MAYBE_ElideRectangleWide16 ElideRectangleWide16
1030#endif
1031TEST(TextEliderTest, MAYBE_ElideRectangleWide16) {
[email protected]dbb97ba2013-09-09 22:15:251032 // Two greek words separated by space.
[email protected]2aadf212013-12-18 20:03:441033 const base::string16 str(WideToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251034 L"\x03a0\x03b1\x03b3\x03ba\x03cc\x03c3\x03bc\x03b9"
1035 L"\x03bf\x03c2\x0020\x0399\x03c3\x03c4\x03cc\x03c2"));
[email protected]2aadf212013-12-18 20:03:441036 const base::string16 out1(WideToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251037 L"\x03a0\x03b1\x03b3\x03ba\n"
1038 L"\x03cc\x03c3\x03bc\x03b9\n"
1039 L"..."));
[email protected]2aadf212013-12-18 20:03:441040 const base::string16 out2(WideToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251041 L"\x03a0\x03b1\x03b3\x03ba\x03cc\x03c3\x03bc\x03b9\x03bf\x03c2\x0020\n"
1042 L"\x0399\x03c3\x03c4\x03cc\x03c2"));
[email protected]2aadf212013-12-18 20:03:441043 base::string16 output;
[email protected]dbb97ba2013-09-09 22:15:251044 EXPECT_TRUE(ElideRectangleString(str, 2, 4, true, &output));
1045 EXPECT_EQ(out1, output);
1046 EXPECT_FALSE(ElideRectangleString(str, 2, 12, true, &output));
1047 EXPECT_EQ(out2, output);
1048}
1049
olivierrobin697bbda2015-12-07 14:53:481050// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:241051#if defined(OS_ANDROID)
1052#define MAYBE_ElideRectangleWide32 DISABLED_ElideRectangleWide32
1053#else
1054#define MAYBE_ElideRectangleWide32 ElideRectangleWide32
1055#endif
1056TEST(TextEliderTest, MAYBE_ElideRectangleWide32) {
[email protected]dbb97ba2013-09-09 22:15:251057 // Four U+1D49C MATHEMATICAL SCRIPT CAPITAL A followed by space "aaaaa".
[email protected]2aadf212013-12-18 20:03:441058 const base::string16 str(UTF8ToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251059 "\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C"
1060 " aaaaa"));
[email protected]2aadf212013-12-18 20:03:441061 const base::string16 out(UTF8ToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251062 "\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\n"
1063 "\xF0\x9D\x92\x9C \naaa\n..."));
[email protected]2aadf212013-12-18 20:03:441064 base::string16 output;
[email protected]dbb97ba2013-09-09 22:15:251065 EXPECT_TRUE(ElideRectangleString(str, 3, 3, true, &output));
1066 EXPECT_EQ(out, output);
1067}
1068
olivierrobin697bbda2015-12-07 14:53:481069// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:241070#if defined(OS_ANDROID)
1071#define MAYBE_TruncateString DISABLED_TruncateString
1072#else
1073#define MAYBE_TruncateString TruncateString
1074#endif
1075TEST(TextEliderTest, MAYBE_TruncateString) {
pkastingfc336922015-09-23 05:59:311076 base::string16 str = ASCIIToUTF16("fooooey bxxxar baz ");
[email protected]dbb97ba2013-09-09 22:15:251077
pkastingfc336922015-09-23 05:59:311078 // Test breaking at character 0.
1079 EXPECT_EQ(base::string16(), TruncateString(str, 0, WORD_BREAK));
1080 EXPECT_EQ(base::string16(), TruncateString(str, 0, CHARACTER_BREAK));
[email protected]41c0d7c12014-07-23 15:52:581081
pkastingfc336922015-09-23 05:59:311082 // Test breaking at character 1.
1083 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str, 1, WORD_BREAK)));
1084 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str, 1, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251085
pkastingfc336922015-09-23 05:59:311086 // Test breaking in the middle of the first word.
1087 EXPECT_EQ(L"f\x2026", UTF16ToWide(TruncateString(str, 2, WORD_BREAK)));
1088 EXPECT_EQ(L"f\x2026", UTF16ToWide(TruncateString(str, 2, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251089
pkastingfc336922015-09-23 05:59:311090 // Test breaking in between words.
1091 EXPECT_EQ(L"fooooey\x2026", UTF16ToWide(TruncateString(str, 9, WORD_BREAK)));
1092 EXPECT_EQ(L"fooooey\x2026",
1093 UTF16ToWide(TruncateString(str, 9, CHARACTER_BREAK)));
[email protected]41c0d7c12014-07-23 15:52:581094
pkastingfc336922015-09-23 05:59:311095 // Test breaking at the start of a later word.
1096 EXPECT_EQ(L"fooooey\x2026", UTF16ToWide(TruncateString(str, 11, WORD_BREAK)));
1097 EXPECT_EQ(L"fooooey\x2026",
1098 UTF16ToWide(TruncateString(str, 11, CHARACTER_BREAK)));
[email protected]41c0d7c12014-07-23 15:52:581099
pkastingfc336922015-09-23 05:59:311100 // Test breaking in the middle of a word.
1101 EXPECT_EQ(L"fooooey\x2026", UTF16ToWide(TruncateString(str, 12, WORD_BREAK)));
1102 EXPECT_EQ(L"fooooey\x2026",
1103 UTF16ToWide(TruncateString(str, 12, CHARACTER_BREAK)));
1104 EXPECT_EQ(L"fooooey\x2026", UTF16ToWide(TruncateString(str, 14, WORD_BREAK)));
1105 EXPECT_EQ(L"fooooey bx\x2026",
1106 UTF16ToWide(TruncateString(str, 14, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251107
pkastingfc336922015-09-23 05:59:311108 // Test breaking in whitespace at the end of the string.
1109 EXPECT_EQ(L"fooooey bxxxar baz\x2026",
1110 UTF16ToWide(TruncateString(str, 22, WORD_BREAK)));
1111 EXPECT_EQ(L"fooooey bxxxar baz\x2026",
1112 UTF16ToWide(TruncateString(str, 22, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251113
pkastingfc336922015-09-23 05:59:311114 // Test breaking at the end of the string.
1115 EXPECT_EQ(str, TruncateString(str, str.length(), WORD_BREAK));
1116 EXPECT_EQ(str, TruncateString(str, str.length(), CHARACTER_BREAK));
[email protected]dbb97ba2013-09-09 22:15:251117
pkastingfc336922015-09-23 05:59:311118 // Test breaking past the end of the string.
1119 EXPECT_EQ(str, TruncateString(str, str.length() + 10, WORD_BREAK));
1120 EXPECT_EQ(str, TruncateString(str, str.length() + 10, CHARACTER_BREAK));
[email protected]dbb97ba2013-09-09 22:15:251121
[email protected]41c0d7c12014-07-23 15:52:581122
pkastingfc336922015-09-23 05:59:311123 // Tests of strings with leading whitespace:
1124 base::string16 str2 = ASCIIToUTF16(" foo");
[email protected]41c0d7c12014-07-23 15:52:581125
pkastingfc336922015-09-23 05:59:311126 // Test breaking in leading whitespace.
1127 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 2, WORD_BREAK)));
1128 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 2, CHARACTER_BREAK)));
1129
1130 // Test breaking at the beginning of the first word, with leading whitespace.
1131 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 3, WORD_BREAK)));
1132 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 3, CHARACTER_BREAK)));
1133
1134 // Test breaking in the middle of the first word, with leading whitespace.
1135 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 4, WORD_BREAK)));
1136 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 4, CHARACTER_BREAK)));
1137 EXPECT_EQ(L" f\x2026", UTF16ToWide(TruncateString(str2, 5, WORD_BREAK)));
1138 EXPECT_EQ(L" f\x2026",
1139 UTF16ToWide(TruncateString(str2, 5, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251140}
1141
1142} // namespace gfx