blob: ae6fac49fa5c8ea00d1daad58967edbc78c9bf4d [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
avic89eb8d42015-12-23 08:08:189#include <stddef.h>
10
danakj25c52c32016-04-12 21:51:0811#include <memory>
mgiuca034e9302015-04-22 02:44:5312#include <vector>
13
[email protected]dbb97ba2013-09-09 22:15:2514#include "base/files/file_path.h"
15#include "base/i18n/rtl.h"
avic89eb8d42015-12-23 08:08:1816#include "base/macros.h"
kulshince612eb2016-06-29 18:46:5117#include "base/run_loop.h"
[email protected]dbb97ba2013-09-09 22:15:2518#include "base/strings/string_util.h"
19#include "base/strings/utf_string_conversions.h"
avic89eb8d42015-12-23 08:08:1820#include "build/build_config.h"
[email protected]dbb97ba2013-09-09 22:15:2521#include "testing/gtest/include/gtest/gtest.h"
22#include "ui/gfx/font.h"
[email protected]8ad3c5a2013-10-10 09:57:1923#include "ui/gfx/font_list.h"
rsorokin370fe4b2014-11-11 15:14:0724#include "ui/gfx/font_render_params.h"
[email protected]8ad3c5a2013-10-10 09:57:1925#include "ui/gfx/text_utils.h"
[email protected]dbb97ba2013-09-09 22:15:2526
[email protected]dd2cc802013-12-25 20:09:3627using base::ASCIIToUTF16;
28using base::UTF16ToUTF8;
[email protected]f729d7a2013-12-26 07:07:5629using base::UTF16ToWide;
[email protected]dd2cc802013-12-25 20:09:3630using base::UTF8ToUTF16;
31using base::WideToUTF16;
32
[email protected]dbb97ba2013-09-09 22:15:2533namespace gfx {
34
35namespace {
36
37struct Testcase {
38 const std::string input;
39 const std::string output;
40};
41
42struct FileTestcase {
43 const base::FilePath::StringType input;
44 const std::string output;
45};
46
47struct UTF16Testcase {
[email protected]2aadf212013-12-18 20:03:4448 const base::string16 input;
49 const base::string16 output;
[email protected]dbb97ba2013-09-09 22:15:2550};
51
52struct TestData {
53 const std::string a;
54 const std::string b;
55 const int compare_result;
56};
57
[email protected]dbb97ba2013-09-09 22:15:2558} // namespace
59
olivierrobin697bbda2015-12-07 14:53:4860// TODO(crbug.com/546240): This test fails on iOS because iOS version of
61// GetStringWidthF that calls [NSString sizeWithFont] returns the rounded string
62// width.
63// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:3364#if defined(OS_IOS) || defined(OS_ANDROID)
[email protected]dbb97ba2013-09-09 22:15:2565#define MAYBE_ElideEmail DISABLED_ElideEmail
66#else
67#define MAYBE_ElideEmail ElideEmail
68#endif
69TEST(TextEliderTest, MAYBE_ElideEmail) {
70 const std::string kEllipsisStr(kEllipsis);
71
72 // Test emails and their expected elided forms (from which the available
73 // widths will be derived).
74 // For elided forms in which both the username and domain must be elided:
75 // the result (how many characters are left on each side) can be font
76 // dependent. To avoid this, the username is prefixed with the characters
77 // expected to remain in the domain.
78 Testcase testcases[] = {
79 {"[email protected]", "[email protected]"},
80 {"[email protected]", kEllipsisStr},
81 {"[email protected]", "ga@c" + kEllipsisStr + "a"},
82 {"[email protected]", "s" + kEllipsisStr + "@s" + kEllipsisStr},
83 {"[email protected]", "s" + kEllipsisStr + "@small.com"},
84 {"[email protected]", "[email protected]"},
85 {"[email protected]",
86 "short@long" + kEllipsisStr + ".com"},
87 {"[email protected]",
88 "la" + kEllipsisStr + "@l" + kEllipsisStr + "a"},
89 {"[email protected]", "long" + kEllipsisStr + "@gmail.com"},
90 {"[email protected]", "e" + kEllipsisStr + "@justfits.com"},
91 {"[email protected]",
92 "thatom" + kEllipsisStr + "@tha" + kEllipsisStr + "om"},
93 {"[email protected]",
94 "namefits@butthedo" + kEllipsisStr + "snt.com"},
95 {"[email protected]", kEllipsisStr},
96 {"nospaceforusername@l", kEllipsisStr},
97 {"[email protected]", "l" + kEllipsisStr + "@l" + kEllipsisStr},
98 {"[email protected]", "l@lllll" + kEllipsisStr + ".com"},
99 {"messed\"up@whyanat\"[email protected]",
100 "messed\"up@whyanat\"[email protected]"},
101 {"messed\"up@whyanat\"[email protected]",
102 "messed\"up@why" + kEllipsisStr + "@notgoogley.com"},
103 {"noca_messed\"up@whyanat\"[email protected]",
104 "noca" + kEllipsisStr + "@no" + kEllipsisStr + "ca"},
105 {"at\"@@@@@@@@@...@@.@.@.@@@\"@madness.com",
106 "at\"@@@@@@@@@...@@.@." + kEllipsisStr + "@madness.com"},
107 // Special case: "m..." takes more than half of the available width; thus
108 // the domain must elide to "l..." and not "l...l" as it must allow enough
109 // space for the minimal username elision although its half of the
110 // available width would normally allow it to elide to "l...l".
111 {"mmmmm@llllllllll", "m" + kEllipsisStr + "@l" + kEllipsisStr},
112 };
113
[email protected]8ad3c5a2013-10-10 09:57:19114 const FontList font_list;
[email protected]dbb97ba2013-09-09 22:15:25115 for (size_t i = 0; i < arraysize(testcases); ++i) {
[email protected]2aadf212013-12-18 20:03:44116 const base::string16 expected_output = UTF8ToUTF16(testcases[i].output);
[email protected]dbb97ba2013-09-09 22:15:25117 EXPECT_EQ(expected_output,
[email protected]f3ce6212014-06-05 22:42:08118 ElideText(UTF8ToUTF16(testcases[i].input), font_list,
119 GetStringWidthF(expected_output, font_list),
120 ELIDE_EMAIL));
[email protected]dbb97ba2013-09-09 22:15:25121 }
122}
123
olivierrobin697bbda2015-12-07 14:53:48124// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33125#if defined(OS_ANDROID)
126#define MAYBE_ElideEmailMoreSpace DISABLED_ElideEmailMoreSpace
127#else
128#define MAYBE_ElideEmailMoreSpace ElideEmailMoreSpace
129#endif
130TEST(TextEliderTest, MAYBE_ElideEmailMoreSpace) {
[email protected]dbb97ba2013-09-09 22:15:25131 const int test_width_factors[] = {
132 100,
133 10000,
134 1000000,
135 };
136 const std::string test_emails[] = {
137 "a@c",
138 "[email protected]",
139 "[email protected]",
140 "[email protected]",
141 };
142
[email protected]2859ff352013-11-08 15:58:49143 const FontList font_list;
[email protected]dbb97ba2013-09-09 22:15:25144 for (size_t i = 0; i < arraysize(test_width_factors); ++i) {
[email protected]2859ff352013-11-08 15:58:49145 const int test_width =
146 font_list.GetExpectedTextWidth(test_width_factors[i]);
[email protected]dbb97ba2013-09-09 22:15:25147 for (size_t j = 0; j < arraysize(test_emails); ++j) {
148 // Extra space is available: the email should not be elided.
[email protected]2aadf212013-12-18 20:03:44149 const base::string16 test_email = UTF8ToUTF16(test_emails[j]);
[email protected]f3ce6212014-06-05 22:42:08150 EXPECT_EQ(test_email,
151 ElideText(test_email, font_list, test_width, ELIDE_EMAIL));
[email protected]dbb97ba2013-09-09 22:15:25152 }
153 }
154}
155
olivierrobin697bbda2015-12-07 14:53:48156// TODO(crbug.com/546240): This test fails on iOS because iOS version of
157// GetStringWidthF that calls [NSString sizeWithFont] returns the rounded string
158// width.
159// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33160#if defined(OS_IOS) || defined(OS_ANDROID)
[email protected]dbb97ba2013-09-09 22:15:25161#define MAYBE_TestFilenameEliding DISABLED_TestFilenameEliding
162#else
163#define MAYBE_TestFilenameEliding TestFilenameEliding
164#endif
165TEST(TextEliderTest, MAYBE_TestFilenameEliding) {
166 const std::string kEllipsisStr(kEllipsis);
167 const base::FilePath::StringType kPathSeparator =
168 base::FilePath::StringType().append(1, base::FilePath::kSeparators[0]);
169
170 FileTestcase testcases[] = {
171 {FILE_PATH_LITERAL(""), ""},
172 {FILE_PATH_LITERAL("."), "."},
173 {FILE_PATH_LITERAL("filename.exe"), "filename.exe"},
174 {FILE_PATH_LITERAL(".longext"), ".longext"},
175 {FILE_PATH_LITERAL("pie"), "pie"},
176 {FILE_PATH_LITERAL("c:") + kPathSeparator + FILE_PATH_LITERAL("path") +
177 kPathSeparator + FILE_PATH_LITERAL("filename.pie"),
178 "filename.pie"},
179 {FILE_PATH_LITERAL("c:") + kPathSeparator + FILE_PATH_LITERAL("path") +
180 kPathSeparator + FILE_PATH_LITERAL("longfilename.pie"),
181 "long" + kEllipsisStr + ".pie"},
182 {FILE_PATH_LITERAL("http://path.com/filename.pie"), "filename.pie"},
183 {FILE_PATH_LITERAL("http://path.com/longfilename.pie"),
184 "long" + kEllipsisStr + ".pie"},
185 {FILE_PATH_LITERAL("piesmashingtacularpants"), "pie" + kEllipsisStr},
186 {FILE_PATH_LITERAL(".piesmashingtacularpants"), ".pie" + kEllipsisStr},
187 {FILE_PATH_LITERAL("cheese."), "cheese."},
188 {FILE_PATH_LITERAL("file name.longext"),
189 "file" + kEllipsisStr + ".longext"},
190 {FILE_PATH_LITERAL("fil ename.longext"),
191 "fil " + kEllipsisStr + ".longext"},
192 {FILE_PATH_LITERAL("filename.longext"),
193 "file" + kEllipsisStr + ".longext"},
194 {FILE_PATH_LITERAL("filename.middleext.longext"),
195 "filename.mid" + kEllipsisStr + ".longext"},
196 {FILE_PATH_LITERAL("filename.superduperextremelylongext"),
197 "filename.sup" + kEllipsisStr + "emelylongext"},
198 {FILE_PATH_LITERAL("filenamereallylongtext.superduperextremelylongext"),
199 "filenamereall" + kEllipsisStr + "emelylongext"},
200 {FILE_PATH_LITERAL("file.name.really.long.text.superduperextremelylongext"),
201 "file.name.re" + kEllipsisStr + "emelylongext"}
202 };
203
[email protected]8ad3c5a2013-10-10 09:57:19204 static const FontList font_list;
[email protected]dbb97ba2013-09-09 22:15:25205 for (size_t i = 0; i < arraysize(testcases); ++i) {
206 base::FilePath filepath(testcases[i].input);
[email protected]2aadf212013-12-18 20:03:44207 base::string16 expected = UTF8ToUTF16(testcases[i].output);
[email protected]dbb97ba2013-09-09 22:15:25208 expected = base::i18n::GetDisplayStringInLTRDirectionality(expected);
[email protected]8ad3c5a2013-10-10 09:57:19209 EXPECT_EQ(expected, ElideFilename(filepath, font_list,
210 GetStringWidthF(UTF8ToUTF16(testcases[i].output), font_list)));
[email protected]dbb97ba2013-09-09 22:15:25211 }
212}
213
olivierrobin697bbda2015-12-07 14:53:48214// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33215#if defined(OS_ANDROID)
216#define MAYBE_ElideTextTruncate DISABLED_ElideTextTruncate
217#else
218#define MAYBE_ElideTextTruncate ElideTextTruncate
219#endif
220TEST(TextEliderTest, MAYBE_ElideTextTruncate) {
[email protected]8ad3c5a2013-10-10 09:57:19221 const FontList font_list;
222 const float kTestWidth = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25223 struct TestData {
224 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19225 float width;
[email protected]dbb97ba2013-09-09 22:15:25226 const char* output;
227 } cases[] = {
228 { "", 0, "" },
229 { "Test", 0, "" },
230 { "", kTestWidth, "" },
231 { "Tes", kTestWidth, "Tes" },
232 { "Test", kTestWidth, "Test" },
233 { "Tests", kTestWidth, "Test" },
234 };
235
viettrungluua5ca99b2014-10-16 16:28:48236 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44237 base::string16 result = ElideText(UTF8ToUTF16(cases[i].input), font_list,
[email protected]f3ce6212014-06-05 22:42:08238 cases[i].width, TRUNCATE);
[email protected]dbb97ba2013-09-09 22:15:25239 EXPECT_EQ(cases[i].output, UTF16ToUTF8(result));
240 }
241}
242
olivierrobin697bbda2015-12-07 14:53:48243// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33244#if defined(OS_ANDROID)
245#define MAYBE_ElideTextEllipsis DISABLED_ElideTextEllipsis
246#else
247#define MAYBE_ElideTextEllipsis ElideTextEllipsis
248#endif
249TEST(TextEliderTest, MAYBE_ElideTextEllipsis) {
[email protected]8ad3c5a2013-10-10 09:57:19250 const FontList font_list;
251 const float kTestWidth = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25252 const char* kEllipsis = "\xE2\x80\xA6";
[email protected]8ad3c5a2013-10-10 09:57:19253 const float kEllipsisWidth =
254 GetStringWidthF(UTF8ToUTF16(kEllipsis), font_list);
[email protected]dbb97ba2013-09-09 22:15:25255 struct TestData {
256 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19257 float width;
[email protected]dbb97ba2013-09-09 22:15:25258 const char* output;
259 } cases[] = {
260 { "", 0, "" },
261 { "Test", 0, "" },
262 { "Test", kEllipsisWidth, kEllipsis },
263 { "", kTestWidth, "" },
264 { "Tes", kTestWidth, "Tes" },
265 { "Test", kTestWidth, "Test" },
266 };
267
viettrungluua5ca99b2014-10-16 16:28:48268 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44269 base::string16 result = ElideText(UTF8ToUTF16(cases[i].input), font_list,
[email protected]f3ce6212014-06-05 22:42:08270 cases[i].width, ELIDE_TAIL);
[email protected]dbb97ba2013-09-09 22:15:25271 EXPECT_EQ(cases[i].output, UTF16ToUTF8(result));
272 }
273}
274
olivierrobin697bbda2015-12-07 14:53:48275// TODO(crbug.com/338784): Enable this on android.
[email protected]9d3e32b32014-02-04 16:01:47276#if defined(OS_ANDROID)
277#define MAYBE_ElideTextEllipsisFront DISABLED_ElideTextEllipsisFront
278#else
279#define MAYBE_ElideTextEllipsisFront ElideTextEllipsisFront
280#endif
281TEST(TextEliderTest, MAYBE_ElideTextEllipsisFront) {
282 const FontList font_list;
283 const float kTestWidth = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
284 const std::string kEllipsisStr(kEllipsis);
285 const float kEllipsisWidth =
286 GetStringWidthF(UTF8ToUTF16(kEllipsis), font_list);
287 const float kEllipsis23Width =
288 GetStringWidthF(UTF8ToUTF16(kEllipsisStr + "23"), font_list);
289 struct TestData {
290 const char* input;
291 float width;
292 const base::string16 output;
293 } cases[] = {
294 { "", 0, base::string16() },
295 { "Test", 0, base::string16() },
296 { "Test", kEllipsisWidth, UTF8ToUTF16(kEllipsisStr) },
297 { "", kTestWidth, base::string16() },
298 { "Tes", kTestWidth, ASCIIToUTF16("Tes") },
299 { "Test", kTestWidth, ASCIIToUTF16("Test") },
300 { "Test123", kEllipsis23Width, UTF8ToUTF16(kEllipsisStr + "23") },
301 };
302
viettrungluua5ca99b2014-10-16 16:28:48303 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]9d3e32b32014-02-04 16:01:47304 base::string16 result = ElideText(UTF8ToUTF16(cases[i].input), font_list,
[email protected]f3ce6212014-06-05 22:42:08305 cases[i].width, ELIDE_HEAD);
[email protected]9d3e32b32014-02-04 16:01:47306 EXPECT_EQ(cases[i].output, result);
307 }
308}
309
[email protected]dbb97ba2013-09-09 22:15:25310// Checks that all occurrences of |first_char| are followed by |second_char| and
mgiuca034e9302015-04-22 02:44:53311// all occurrences of |second_char| are preceded by |first_char| in |text|. Can
312// be used to test surrogate pairs or two-character combining sequences.
313static void CheckCodeUnitPairs(const base::string16& text,
314 base::char16 first_char,
315 base::char16 second_char) {
[email protected]8d936142014-07-10 21:40:37316 for (size_t index = 0; index < text.length(); ++index) {
317 EXPECT_NE(second_char, text[index]);
318 if (text[index] == first_char) {
319 ASSERT_LT(++index, text.length());
320 EXPECT_EQ(second_char, text[index]);
321 }
[email protected]dbb97ba2013-09-09 22:15:25322 }
323}
324
mgiuca034e9302015-04-22 02:44:53325// Test that both both UTF-16 surrogate pairs and combining character sequences
326// do not get split by ElideText.
olivierrobin697bbda2015-12-07 14:53:48327// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33328#if defined(OS_ANDROID)
mgiuca034e9302015-04-22 02:44:53329#define MAYBE_ElideTextAtomicSequences DISABLED_ElideTextAtomicSequences
[email protected]ebc9b662014-01-30 03:37:33330#else
mgiuca034e9302015-04-22 02:44:53331#define MAYBE_ElideTextAtomicSequences ElideTextAtomicSequences
[email protected]ebc9b662014-01-30 03:37:33332#endif
mgiuca034e9302015-04-22 02:44:53333TEST(TextEliderTest, MAYBE_ElideTextAtomicSequences) {
kulshince612eb2016-06-29 18:46:51334#if defined(OS_WIN)
335 // Needed to bypass DCHECK in GetFallbackFont.
336 base::MessageLoopForUI message_loop;
337#endif
[email protected]8ad3c5a2013-10-10 09:57:19338 const FontList font_list;
mgiuca034e9302015-04-22 02:44:53339 // The below is 'MUSICAL SYMBOL G CLEF' (U+1D11E), which is represented in
340 // UTF-16 as two code units forming a surrogate pair: 0xD834 0xDD1E.
341 const base::char16 kSurrogate[] = {0xD834, 0xDD1E, 0};
342 // The below is a Devanagari two-character combining sequence U+0921 U+093F.
343 // The sequence forms a single display character and should not be separated.
344 const base::char16 kCombiningSequence[] = {0x921, 0x93F, 0};
345 std::vector<base::string16> pairs;
346 pairs.push_back(kSurrogate);
347 pairs.push_back(kCombiningSequence);
[email protected]dbb97ba2013-09-09 22:15:25348
mgiuca034e9302015-04-22 02:44:53349 for (const base::string16& pair : pairs) {
350 base::char16 first_char = pair[0];
351 base::char16 second_char = pair[1];
352 base::string16 test_string = pair + UTF8ToUTF16("x") + pair;
353 SCOPED_TRACE(test_string);
354 const float test_string_width = GetStringWidthF(test_string, font_list);
355 base::string16 result;
[email protected]dbb97ba2013-09-09 22:15:25356
mgiuca034e9302015-04-22 02:44:53357 // Elide |text_string| to all possible widths and check that no instance of
358 // |pair| was split in two.
359 for (float width = 0; width <= test_string_width; width++) {
360 result = ElideText(test_string, font_list, width, TRUNCATE);
361 CheckCodeUnitPairs(result, first_char, second_char);
[email protected]dbb97ba2013-09-09 22:15:25362
mgiuca034e9302015-04-22 02:44:53363 result = ElideText(test_string, font_list, width, ELIDE_TAIL);
364 CheckCodeUnitPairs(result, first_char, second_char);
[email protected]9d3e32b32014-02-04 16:01:47365
mgiuca034e9302015-04-22 02:44:53366 result = ElideText(test_string, font_list, width, ELIDE_MIDDLE);
367 CheckCodeUnitPairs(result, first_char, second_char);
368
369 result = ElideText(test_string, font_list, width, ELIDE_HEAD);
370 CheckCodeUnitPairs(result, first_char, second_char);
371 }
[email protected]dbb97ba2013-09-09 22:15:25372 }
373}
374
olivierrobin697bbda2015-12-07 14:53:48375// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33376#if defined(OS_ANDROID)
377#define MAYBE_ElideTextLongStrings DISABLED_ElideTextLongStrings
378#else
379#define MAYBE_ElideTextLongStrings ElideTextLongStrings
380#endif
381TEST(TextEliderTest, MAYBE_ElideTextLongStrings) {
[email protected]2aadf212013-12-18 20:03:44382 const base::string16 kEllipsisStr = UTF8ToUTF16(kEllipsis);
383 base::string16 data_scheme(UTF8ToUTF16("data:text/plain,"));
[email protected]dbb97ba2013-09-09 22:15:25384 size_t data_scheme_length = data_scheme.length();
385
[email protected]2aadf212013-12-18 20:03:44386 base::string16 ten_a(10, 'a');
387 base::string16 hundred_a(100, 'a');
388 base::string16 thousand_a(1000, 'a');
389 base::string16 ten_thousand_a(10000, 'a');
390 base::string16 hundred_thousand_a(100000, 'a');
391 base::string16 million_a(1000000, 'a');
[email protected]dbb97ba2013-09-09 22:15:25392
[email protected]9d3e32b32014-02-04 16:01:47393 // TODO(gbillock): Improve these tests by adding more string diversity and
394 // doing string compares instead of length compares. See bug 338836.
395
[email protected]dbb97ba2013-09-09 22:15:25396 size_t number_of_as = 156;
[email protected]2aadf212013-12-18 20:03:44397 base::string16 long_string_end(
398 data_scheme + base::string16(number_of_as, 'a') + kEllipsisStr);
[email protected]dbb97ba2013-09-09 22:15:25399 UTF16Testcase testcases_end[] = {
[email protected]9d3e32b32014-02-04 16:01:47400 { data_scheme + ten_a, data_scheme + ten_a },
401 { data_scheme + hundred_a, data_scheme + hundred_a },
402 { data_scheme + thousand_a, long_string_end },
403 { data_scheme + ten_thousand_a, long_string_end },
404 { data_scheme + hundred_thousand_a, long_string_end },
405 { data_scheme + million_a, long_string_end },
[email protected]dbb97ba2013-09-09 22:15:25406 };
407
[email protected]8ad3c5a2013-10-10 09:57:19408 const FontList font_list;
409 float ellipsis_width = GetStringWidthF(kEllipsisStr, font_list);
[email protected]dbb97ba2013-09-09 22:15:25410 for (size_t i = 0; i < arraysize(testcases_end); ++i) {
411 // Compare sizes rather than actual contents because if the test fails,
412 // output is rather long.
413 EXPECT_EQ(testcases_end[i].output.size(),
[email protected]f3ce6212014-06-05 22:42:08414 ElideText(testcases_end[i].input, font_list,
415 GetStringWidthF(testcases_end[i].output, font_list),
416 ELIDE_TAIL).size());
[email protected]dbb97ba2013-09-09 22:15:25417 EXPECT_EQ(kEllipsisStr,
[email protected]8ad3c5a2013-10-10 09:57:19418 ElideText(testcases_end[i].input, font_list, ellipsis_width,
[email protected]f3ce6212014-06-05 22:42:08419 ELIDE_TAIL));
[email protected]dbb97ba2013-09-09 22:15:25420 }
421
422 size_t number_of_trailing_as = (data_scheme_length + number_of_as) / 2;
[email protected]2aadf212013-12-18 20:03:44423 base::string16 long_string_middle(data_scheme +
424 base::string16(number_of_as - number_of_trailing_as, 'a') + kEllipsisStr +
425 base::string16(number_of_trailing_as, 'a'));
[email protected]dbb97ba2013-09-09 22:15:25426 UTF16Testcase testcases_middle[] = {
[email protected]9d3e32b32014-02-04 16:01:47427 { data_scheme + ten_a, data_scheme + ten_a },
428 { data_scheme + hundred_a, data_scheme + hundred_a },
429 { data_scheme + thousand_a, long_string_middle },
430 { data_scheme + ten_thousand_a, long_string_middle },
431 { data_scheme + hundred_thousand_a, long_string_middle },
432 { data_scheme + million_a, long_string_middle },
[email protected]dbb97ba2013-09-09 22:15:25433 };
434
435 for (size_t i = 0; i < arraysize(testcases_middle); ++i) {
436 // Compare sizes rather than actual contents because if the test fails,
437 // output is rather long.
438 EXPECT_EQ(testcases_middle[i].output.size(),
[email protected]f3ce6212014-06-05 22:42:08439 ElideText(testcases_middle[i].input, font_list,
440 GetStringWidthF(testcases_middle[i].output, font_list),
441 ELIDE_MIDDLE).size());
[email protected]dbb97ba2013-09-09 22:15:25442 EXPECT_EQ(kEllipsisStr,
[email protected]8ad3c5a2013-10-10 09:57:19443 ElideText(testcases_middle[i].input, font_list, ellipsis_width,
[email protected]f3ce6212014-06-05 22:42:08444 ELIDE_MIDDLE));
[email protected]9d3e32b32014-02-04 16:01:47445 }
446
447 base::string16 long_string_beginning(
448 kEllipsisStr + base::string16(number_of_as, 'a'));
449 UTF16Testcase testcases_beginning[] = {
450 { data_scheme + ten_a, data_scheme + ten_a },
451 { data_scheme + hundred_a, data_scheme + hundred_a },
452 { data_scheme + thousand_a, long_string_beginning },
453 { data_scheme + ten_thousand_a, long_string_beginning },
454 { data_scheme + hundred_thousand_a, long_string_beginning },
455 { data_scheme + million_a, long_string_beginning },
456 };
457 for (size_t i = 0; i < arraysize(testcases_beginning); ++i) {
458 EXPECT_EQ(testcases_beginning[i].output.size(),
459 ElideText(
460 testcases_beginning[i].input, font_list,
461 GetStringWidthF(testcases_beginning[i].output, font_list),
[email protected]f3ce6212014-06-05 22:42:08462 ELIDE_HEAD).size());
[email protected]9d3e32b32014-02-04 16:01:47463 EXPECT_EQ(kEllipsisStr,
464 ElideText(testcases_beginning[i].input, font_list, ellipsis_width,
[email protected]f3ce6212014-06-05 22:42:08465 ELIDE_HEAD));
[email protected]dbb97ba2013-09-09 22:15:25466 }
467}
468
mgiuca034e9302015-04-22 02:44:53469// Detailed tests for StringSlicer. These are faster and test more of the edge
470// cases than the above tests which are more end-to-end.
471
472TEST(TextEliderTest, StringSlicerBasicTest) {
473 // Must store strings in variables (StringSlicer retains a reference to them).
474 base::string16 text(UTF8ToUTF16("Hello, world!"));
475 base::string16 ellipsis(kEllipsisUTF16);
476 StringSlicer slicer(text, ellipsis, false, false);
477
478 EXPECT_EQ(UTF8ToUTF16(""), slicer.CutString(0, false));
479 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
480
481 EXPECT_EQ(UTF8ToUTF16("Hell"), slicer.CutString(4, false));
482 EXPECT_EQ(UTF8ToUTF16("Hell") + kEllipsisUTF16, slicer.CutString(4, true));
483
484 EXPECT_EQ(text, slicer.CutString(text.length(), false));
485 EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(text.length(), true));
486
487 StringSlicer slicer_begin(text, ellipsis, false, true);
488 EXPECT_EQ(UTF8ToUTF16("rld!"), slicer_begin.CutString(4, false));
489 EXPECT_EQ(kEllipsisUTF16 + UTF8ToUTF16("rld!"),
490 slicer_begin.CutString(4, true));
491
492 StringSlicer slicer_mid(text, ellipsis, true, false);
493 EXPECT_EQ(UTF8ToUTF16("Held!"), slicer_mid.CutString(5, false));
494 EXPECT_EQ(UTF8ToUTF16("Hel") + kEllipsisUTF16 + UTF8ToUTF16("d!"),
495 slicer_mid.CutString(5, true));
496}
497
498TEST(TextEliderTest, StringSlicerSurrogate) {
499 // The below is 'MUSICAL SYMBOL G CLEF' (U+1D11E), which is represented in
500 // UTF-16 as two code units forming a surrogate pair: 0xD834 0xDD1E.
501 const base::char16 kSurrogate[] = {0xD834, 0xDD1E, 0};
502 base::string16 text(UTF8ToUTF16("abc") + kSurrogate + UTF8ToUTF16("xyz"));
503 base::string16 ellipsis(kEllipsisUTF16);
504 StringSlicer slicer(text, ellipsis, false, false);
505
506 // Cut surrogate on the right. Should round left and exclude the surrogate.
507 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
508 EXPECT_EQ(UTF8ToUTF16("abc") + kEllipsisUTF16, slicer.CutString(4, true));
509 EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(text.length(), true));
510
511 // Cut surrogate on the left. Should round left and include the surrogate.
512 StringSlicer slicer_begin(text, ellipsis, false, true);
513 EXPECT_EQ(base::string16(kEllipsisUTF16) + kSurrogate + UTF8ToUTF16("xyz"),
514 slicer_begin.CutString(4, true));
515
516 // Cut surrogate in the middle. Should round right and exclude the surrogate.
517 base::string16 short_text(UTF8ToUTF16("abc") + kSurrogate);
518 StringSlicer slicer_mid(short_text, ellipsis, true, false);
519 EXPECT_EQ(UTF8ToUTF16("a") + kEllipsisUTF16, slicer_mid.CutString(2, true));
520
521 // String that starts with a dangling trailing surrogate.
522 base::char16 dangling_trailing_chars[] = {kSurrogate[1], 0};
523 base::string16 dangling_trailing_text(dangling_trailing_chars);
524 StringSlicer slicer_dangling_trailing(dangling_trailing_text, ellipsis, false,
525 false);
526 EXPECT_EQ(base::string16(kEllipsisUTF16),
527 slicer_dangling_trailing.CutString(0, true));
528 EXPECT_EQ(dangling_trailing_text + kEllipsisUTF16,
529 slicer_dangling_trailing.CutString(1, true));
530}
531
532TEST(TextEliderTest, StringSlicerCombining) {
533 // The following string contains three combining character sequences (one for
534 // each category of combining mark):
535 // LATIN SMALL LETTER E + COMBINING ACUTE ACCENT + COMBINING CEDILLA
536 // LATIN SMALL LETTER X + COMBINING ENCLOSING KEYCAP
537 // DEVANAGARI LETTER DDA + DEVANAGARI VOWEL SIGN I
538 const base::char16 kText[] = {
539 'e', 0x301, 0x327, ' ', 'x', 0x20E3, ' ', 0x921, 0x93F, 0};
540 base::string16 text(kText);
541 base::string16 ellipsis(kEllipsisUTF16);
542 StringSlicer slicer(text, ellipsis, false, false);
543
544 // Attempt to cut the string for all lengths. When a combining sequence is
545 // cut, it should always round left and exclude the combining sequence.
546 // First sequence:
547 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
548 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(1, true));
549 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(2, true));
550 EXPECT_EQ(text.substr(0, 3) + kEllipsisUTF16, slicer.CutString(3, true));
551 // Second sequence:
552 EXPECT_EQ(text.substr(0, 4) + kEllipsisUTF16, slicer.CutString(4, true));
553 EXPECT_EQ(text.substr(0, 4) + kEllipsisUTF16, slicer.CutString(5, true));
554 EXPECT_EQ(text.substr(0, 6) + kEllipsisUTF16, slicer.CutString(6, true));
555 // Third sequence:
556 EXPECT_EQ(text.substr(0, 7) + kEllipsisUTF16, slicer.CutString(7, true));
557 EXPECT_EQ(text.substr(0, 7) + kEllipsisUTF16, slicer.CutString(8, true));
558 EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(9, true));
559
560 // Cut string in the middle, splitting the second sequence in half. Should
561 // round both left and right, excluding the second sequence.
562 StringSlicer slicer_mid(text, ellipsis, true, false);
563 EXPECT_EQ(text.substr(0, 4) + kEllipsisUTF16 + text.substr(6),
564 slicer_mid.CutString(9, true));
565
566 // String that starts with a dangling combining mark.
567 base::char16 dangling_mark_chars[] = {text[1], 0};
568 base::string16 dangling_mark_text(dangling_mark_chars);
569 StringSlicer slicer_dangling_mark(dangling_mark_text, ellipsis, false, false);
570 EXPECT_EQ(base::string16(kEllipsisUTF16),
571 slicer_dangling_mark.CutString(0, true));
572 EXPECT_EQ(dangling_mark_text + kEllipsisUTF16,
573 slicer_dangling_mark.CutString(1, true));
574}
575
576TEST(TextEliderTest, StringSlicerCombiningSurrogate) {
577 // The ultimate test: combining sequences comprised of surrogate pairs.
578 // The following string contains a single combining character sequence:
579 // MUSICAL SYMBOL G CLEF (U+1D11E) + MUSICAL SYMBOL COMBINING FLAG-1 (U+1D16E)
580 // Represented as four UTF-16 code units.
581 const base::char16 kText[] = {0xD834, 0xDD1E, 0xD834, 0xDD6E, 0};
582 base::string16 text(kText);
583 base::string16 ellipsis(kEllipsisUTF16);
584 StringSlicer slicer(text, ellipsis, false, false);
585
586 // Attempt to cut the string for all lengths. Should always round left and
587 // exclude the combining sequence.
588 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(0, true));
589 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(1, true));
590 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(2, true));
591 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer.CutString(3, true));
592 EXPECT_EQ(text + kEllipsisUTF16, slicer.CutString(4, true));
593
594 // Cut string in the middle. Should exclude the sequence.
595 StringSlicer slicer_mid(text, ellipsis, true, false);
596 EXPECT_EQ(base::string16(kEllipsisUTF16), slicer_mid.CutString(4, true));
597}
598
[email protected]dbb97ba2013-09-09 22:15:25599TEST(TextEliderTest, ElideString) {
600 struct TestData {
601 const char* input;
thestigbbf93ac2016-02-02 00:24:49602 size_t max_len;
[email protected]dbb97ba2013-09-09 22:15:25603 bool result;
604 const char* output;
605 } cases[] = {
606 { "Hello", 0, true, "" },
607 { "", 0, false, "" },
608 { "Hello, my name is Tom", 1, true, "H" },
609 { "Hello, my name is Tom", 2, true, "He" },
610 { "Hello, my name is Tom", 3, true, "H.m" },
611 { "Hello, my name is Tom", 4, true, "H..m" },
612 { "Hello, my name is Tom", 5, true, "H...m" },
613 { "Hello, my name is Tom", 6, true, "He...m" },
614 { "Hello, my name is Tom", 7, true, "He...om" },
615 { "Hello, my name is Tom", 10, true, "Hell...Tom" },
616 { "Hello, my name is Tom", 100, false, "Hello, my name is Tom" }
617 };
viettrungluua5ca99b2014-10-16 16:28:48618 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44619 base::string16 output;
[email protected]dbb97ba2013-09-09 22:15:25620 EXPECT_EQ(cases[i].result,
621 ElideString(UTF8ToUTF16(cases[i].input),
622 cases[i].max_len, &output));
623 EXPECT_EQ(cases[i].output, UTF16ToUTF8(output));
624 }
625}
626
olivierrobin697bbda2015-12-07 14:53:48627// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33628#if defined(OS_ANDROID)
629#define MAYBE_ElideRectangleText DISABLED_ElideRectangleText
630#else
631#define MAYBE_ElideRectangleText ElideRectangleText
632#endif
633TEST(TextEliderTest, MAYBE_ElideRectangleText) {
[email protected]8ad3c5a2013-10-10 09:57:19634 const FontList font_list;
635 const int line_height = font_list.GetHeight();
636 const float test_width = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25637
638 struct TestData {
639 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19640 float available_pixel_width;
[email protected]dbb97ba2013-09-09 22:15:25641 int available_pixel_height;
642 bool truncated_y;
643 const char* output;
644 } cases[] = {
645 { "", 0, 0, false, NULL },
646 { "", 1, 1, false, NULL },
647 { "Test", test_width, 0, true, NULL },
648 { "Test", test_width, 1, false, "Test" },
649 { "Test", test_width, line_height, false, "Test" },
650 { "Test Test", test_width, line_height, true, "Test" },
651 { "Test Test", test_width, line_height + 1, false, "Test|Test" },
652 { "Test Test", test_width, line_height * 2, false, "Test|Test" },
653 { "Test Test", test_width, line_height * 3, false, "Test|Test" },
654 { "Test Test", test_width * 2, line_height * 2, false, "Test|Test" },
655 { "Test Test", test_width * 3, line_height, false, "Test Test" },
656 { "Test\nTest", test_width * 3, line_height * 2, false, "Test|Test" },
657 { "Te\nst Te", test_width, line_height * 3, false, "Te|st|Te" },
658 { "\nTest", test_width, line_height * 2, false, "|Test" },
659 { "\nTest", test_width, line_height, true, "" },
660 { "\n\nTest", test_width, line_height * 3, false, "||Test" },
661 { "\n\nTest", test_width, line_height * 2, true, "|" },
662 { "Test\n", 2 * test_width, line_height * 5, false, "Test|" },
663 { "Test\n\n", 2 * test_width, line_height * 5, false, "Test||" },
664 { "Test\n\n\n", 2 * test_width, line_height * 5, false, "Test|||" },
665 { "Test\nTest\n\n", 2 * test_width, line_height * 5, false, "Test|Test||" },
666 { "Test\n\nTest\n", 2 * test_width, line_height * 5, false, "Test||Test|" },
667 { "Test\n\n\nTest", 2 * test_width, line_height * 5, false, "Test|||Test" },
668 { "Te ", test_width, line_height, false, "Te" },
669 { "Te Te Test", test_width, 3 * line_height, false, "Te|Te|Test" },
670 };
671
viettrungluua5ca99b2014-10-16 16:28:48672 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44673 std::vector<base::string16> lines;
[email protected]dbb97ba2013-09-09 22:15:25674 EXPECT_EQ(cases[i].truncated_y ? INSUFFICIENT_SPACE_VERTICAL : 0,
675 ElideRectangleText(UTF8ToUTF16(cases[i].input),
[email protected]8ad3c5a2013-10-10 09:57:19676 font_list,
[email protected]dbb97ba2013-09-09 22:15:25677 cases[i].available_pixel_width,
678 cases[i].available_pixel_height,
679 TRUNCATE_LONG_WORDS,
680 &lines));
681 if (cases[i].output) {
brettwd94a22142015-07-15 05:19:26682 const std::string result =
683 UTF16ToUTF8(base::JoinString(lines, ASCIIToUTF16("|")));
[email protected]dbb97ba2013-09-09 22:15:25684 EXPECT_EQ(cases[i].output, result) << "Case " << i << " failed!";
685 } else {
686 EXPECT_TRUE(lines.empty()) << "Case " << i << " failed!";
687 }
688 }
689}
690
olivierrobin697bbda2015-12-07 14:53:48691// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33692#if defined(OS_ANDROID)
693#define MAYBE_ElideRectangleTextPunctuation \
694 DISABLED_ElideRectangleTextPunctuation
695#else
696#define MAYBE_ElideRectangleTextPunctuation ElideRectangleTextPunctuation
697#endif
698TEST(TextEliderTest, MAYBE_ElideRectangleTextPunctuation) {
[email protected]8ad3c5a2013-10-10 09:57:19699 const FontList font_list;
700 const int line_height = font_list.GetHeight();
701 const float test_width = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
702 const float test_t_width = GetStringWidthF(ASCIIToUTF16("Test T"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25703
704 struct TestData {
705 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19706 float available_pixel_width;
[email protected]dbb97ba2013-09-09 22:15:25707 int available_pixel_height;
708 bool wrap_words;
709 bool truncated_x;
710 const char* output;
711 } cases[] = {
712 { "Test T.", test_t_width, line_height * 2, false, false, "Test|T." },
713 { "Test T ?", test_t_width, line_height * 2, false, false, "Test|T ?" },
714 { "Test. Test", test_width, line_height * 3, false, true, "Test|Test" },
715 { "Test. Test", test_width, line_height * 3, true, false, "Test|.|Test" },
716 };
717
viettrungluua5ca99b2014-10-16 16:28:48718 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44719 std::vector<base::string16> lines;
[email protected]dbb97ba2013-09-09 22:15:25720 const WordWrapBehavior wrap_behavior =
721 (cases[i].wrap_words ? WRAP_LONG_WORDS : TRUNCATE_LONG_WORDS);
722 EXPECT_EQ(cases[i].truncated_x ? INSUFFICIENT_SPACE_HORIZONTAL : 0,
723 ElideRectangleText(UTF8ToUTF16(cases[i].input),
[email protected]8ad3c5a2013-10-10 09:57:19724 font_list,
[email protected]dbb97ba2013-09-09 22:15:25725 cases[i].available_pixel_width,
726 cases[i].available_pixel_height,
727 wrap_behavior,
728 &lines));
729 if (cases[i].output) {
brettwd94a22142015-07-15 05:19:26730 const std::string result =
731 UTF16ToUTF8(base::JoinString(lines, base::ASCIIToUTF16("|")));
[email protected]dbb97ba2013-09-09 22:15:25732 EXPECT_EQ(cases[i].output, result) << "Case " << i << " failed!";
733 } else {
734 EXPECT_TRUE(lines.empty()) << "Case " << i << " failed!";
735 }
736 }
737}
738
olivierrobin697bbda2015-12-07 14:53:48739// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33740#if defined(OS_ANDROID)
741#define MAYBE_ElideRectangleTextLongWords DISABLED_ElideRectangleTextLongWords
742#else
743#define MAYBE_ElideRectangleTextLongWords ElideRectangleTextLongWords
744#endif
745TEST(TextEliderTest, MAYBE_ElideRectangleTextLongWords) {
[email protected]8ad3c5a2013-10-10 09:57:19746 const FontList font_list;
[email protected]dbb97ba2013-09-09 22:15:25747 const int kAvailableHeight = 1000;
[email protected]2aadf212013-12-18 20:03:44748 const base::string16 kElidedTesting =
749 UTF8ToUTF16(std::string("Tes") + kEllipsis);
[email protected]8ad3c5a2013-10-10 09:57:19750 const float elided_width = GetStringWidthF(kElidedTesting, font_list);
751 const float test_width = GetStringWidthF(ASCIIToUTF16("Test"), font_list);
[email protected]dbb97ba2013-09-09 22:15:25752
753 struct TestData {
754 const char* input;
[email protected]8ad3c5a2013-10-10 09:57:19755 float available_pixel_width;
[email protected]dbb97ba2013-09-09 22:15:25756 WordWrapBehavior wrap_behavior;
757 bool truncated_x;
758 const char* output;
759 } cases[] = {
760 { "Testing", test_width, IGNORE_LONG_WORDS, false, "Testing" },
761 { "X Testing", test_width, IGNORE_LONG_WORDS, false, "X|Testing" },
762 { "Test Testing", test_width, IGNORE_LONG_WORDS, false, "Test|Testing" },
763 { "Test\nTesting", test_width, IGNORE_LONG_WORDS, false, "Test|Testing" },
764 { "Test Tests ", test_width, IGNORE_LONG_WORDS, false, "Test|Tests" },
765 { "Test Tests T", test_width, IGNORE_LONG_WORDS, false, "Test|Tests|T" },
766
767 { "Testing", elided_width, ELIDE_LONG_WORDS, true, "Tes..." },
768 { "X Testing", elided_width, ELIDE_LONG_WORDS, true, "X|Tes..." },
769 { "Test Testing", elided_width, ELIDE_LONG_WORDS, true, "Test|Tes..." },
770 { "Test\nTesting", elided_width, ELIDE_LONG_WORDS, true, "Test|Tes..." },
771
772 { "Testing", test_width, TRUNCATE_LONG_WORDS, true, "Test" },
773 { "X Testing", test_width, TRUNCATE_LONG_WORDS, true, "X|Test" },
774 { "Test Testing", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test" },
775 { "Test\nTesting", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test" },
776 { "Test Tests ", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test" },
777 { "Test Tests T", test_width, TRUNCATE_LONG_WORDS, true, "Test|Test|T" },
778
779 { "Testing", test_width, WRAP_LONG_WORDS, false, "Test|ing" },
780 { "X Testing", test_width, WRAP_LONG_WORDS, false, "X|Test|ing" },
781 { "Test Testing", test_width, WRAP_LONG_WORDS, false, "Test|Test|ing" },
782 { "Test\nTesting", test_width, WRAP_LONG_WORDS, false, "Test|Test|ing" },
783 { "Test Tests ", test_width, WRAP_LONG_WORDS, false, "Test|Test|s" },
784 { "Test Tests T", test_width, WRAP_LONG_WORDS, false, "Test|Test|s T" },
785 { "TestTestTest", test_width, WRAP_LONG_WORDS, false, "Test|Test|Test" },
786 { "TestTestTestT", test_width, WRAP_LONG_WORDS, false, "Test|Test|Test|T" },
787 };
788
viettrungluua5ca99b2014-10-16 16:28:48789 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]2aadf212013-12-18 20:03:44790 std::vector<base::string16> lines;
[email protected]dbb97ba2013-09-09 22:15:25791 EXPECT_EQ(cases[i].truncated_x ? INSUFFICIENT_SPACE_HORIZONTAL : 0,
792 ElideRectangleText(UTF8ToUTF16(cases[i].input),
[email protected]8ad3c5a2013-10-10 09:57:19793 font_list,
[email protected]dbb97ba2013-09-09 22:15:25794 cases[i].available_pixel_width,
795 kAvailableHeight,
796 cases[i].wrap_behavior,
797 &lines));
798 std::string expected_output(cases[i].output);
brettwe6dae462015-06-24 20:54:45799 base::ReplaceSubstringsAfterOffset(&expected_output, 0, "...", kEllipsis);
brettwd94a22142015-07-15 05:19:26800 const std::string result =
801 UTF16ToUTF8(base::JoinString(lines, base::ASCIIToUTF16("|")));
[email protected]dbb97ba2013-09-09 22:15:25802 EXPECT_EQ(expected_output, result) << "Case " << i << " failed!";
803 }
804}
805
[email protected]c3087982013-09-20 17:46:53806// This test is to make sure that the width of each wrapped line does not
807// exceed the available width. On some platform like Mac, this test used to
808// fail because the truncated integer width is returned for the string
809// and the accumulation of the truncated values causes the elide function
810// to wrap incorrectly.
olivierrobin697bbda2015-12-07 14:53:48811// TODO(crbug.com/338784): Enable this on android.
[email protected]ebc9b662014-01-30 03:37:33812#if defined(OS_ANDROID)
813#define MAYBE_ElideRectangleTextCheckLineWidth \
814 DISABLED_ElideRectangleTextCheckLineWidth
815#else
816#define MAYBE_ElideRectangleTextCheckLineWidth ElideRectangleTextCheckLineWidth
817#endif
818TEST(TextEliderTest, MAYBE_ElideRectangleTextCheckLineWidth) {
[email protected]8ad3c5a2013-10-10 09:57:19819 FontList font_list;
820#if defined(OS_MACOSX) && !defined(OS_IOS)
821 // Use a specific font to expose the line width exceeding problem.
822 font_list = FontList(Font("LucidaGrande", 12));
823#endif
824 const float kAvailableWidth = 235;
[email protected]c3087982013-09-20 17:46:53825 const int kAvailableHeight = 1000;
826 const char text[] = "that Russian place we used to go to after fencing";
[email protected]2aadf212013-12-18 20:03:44827 std::vector<base::string16> lines;
[email protected]c3087982013-09-20 17:46:53828 EXPECT_EQ(0, ElideRectangleText(UTF8ToUTF16(text),
[email protected]8ad3c5a2013-10-10 09:57:19829 font_list,
[email protected]c3087982013-09-20 17:46:53830 kAvailableWidth,
831 kAvailableHeight,
832 WRAP_LONG_WORDS,
833 &lines));
834 ASSERT_EQ(2u, lines.size());
[email protected]8ad3c5a2013-10-10 09:57:19835 EXPECT_LE(GetStringWidthF(lines[0], font_list), kAvailableWidth);
836 EXPECT_LE(GetStringWidthF(lines[1], font_list), kAvailableWidth);
[email protected]c3087982013-09-20 17:46:53837}
838
thestigbbf93ac2016-02-02 00:24:49839#if defined(OS_CHROMEOS)
rsorokin370fe4b2014-11-11 15:14:07840// This test was created specifically to test a message from crbug.com/415213.
841// It tests that width of concatenation of words equals sum of widths of the
842// words.
843TEST(TextEliderTest, ElideRectangleTextCheckConcatWidthEqualsSumOfWidths) {
844 FontList font_list;
845 font_list = FontList("Noto Sans UI,ui-sans, 12px");
846 SetFontRenderParamsDeviceScaleFactor(1.25f);
847#define WIDTH(x) GetStringWidthF(UTF8ToUTF16(x), font_list)
848 EXPECT_EQ(WIDTH("The administrator for this account has"),
849 WIDTH("The ") + WIDTH("administrator ") + WIDTH("for ") +
850 WIDTH("this ") + WIDTH("account ") + WIDTH("has"));
851#undef WIDTH
852 SetFontRenderParamsDeviceScaleFactor(1.0f);
853}
thestigbbf93ac2016-02-02 00:24:49854#endif // defined(OS_CHROMEOS)
rsorokin370fe4b2014-11-11 15:14:07855
olivierrobin697bbda2015-12-07 14:53:48856// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:24857#if defined(OS_ANDROID)
858#define MAYBE_ElideRectangleString DISABLED_ElideRectangleString
859#else
860#define MAYBE_ElideRectangleString ElideRectangleString
861#endif
862TEST(TextEliderTest, MAYBE_ElideRectangleString) {
[email protected]dbb97ba2013-09-09 22:15:25863 struct TestData {
864 const char* input;
865 int max_rows;
866 int max_cols;
867 bool result;
868 const char* output;
869 } cases[] = {
870 { "", 0, 0, false, "" },
871 { "", 1, 1, false, "" },
872 { "Hi, my name is\nTom", 0, 0, true, "..." },
873 { "Hi, my name is\nTom", 1, 0, true, "\n..." },
874 { "Hi, my name is\nTom", 0, 1, true, "..." },
875 { "Hi, my name is\nTom", 1, 1, true, "H\n..." },
876 { "Hi, my name is\nTom", 2, 1, true, "H\ni\n..." },
877 { "Hi, my name is\nTom", 3, 1, true, "H\ni\n,\n..." },
878 { "Hi, my name is\nTom", 4, 1, true, "H\ni\n,\n \n..." },
879 { "Hi, my name is\nTom", 5, 1, true, "H\ni\n,\n \nm\n..." },
880 { "Hi, my name is\nTom", 0, 2, true, "..." },
881 { "Hi, my name is\nTom", 1, 2, true, "Hi\n..." },
882 { "Hi, my name is\nTom", 2, 2, true, "Hi\n, \n..." },
883 { "Hi, my name is\nTom", 3, 2, true, "Hi\n, \nmy\n..." },
884 { "Hi, my name is\nTom", 4, 2, true, "Hi\n, \nmy\n n\n..." },
885 { "Hi, my name is\nTom", 5, 2, true, "Hi\n, \nmy\n n\nam\n..." },
886 { "Hi, my name is\nTom", 0, 3, true, "..." },
887 { "Hi, my name is\nTom", 1, 3, true, "Hi,\n..." },
888 { "Hi, my name is\nTom", 2, 3, true, "Hi,\n my\n..." },
889 { "Hi, my name is\nTom", 3, 3, true, "Hi,\n my\n na\n..." },
890 { "Hi, my name is\nTom", 4, 3, true, "Hi,\n my\n na\nme \n..." },
891 { "Hi, my name is\nTom", 5, 3, true, "Hi,\n my\n na\nme \nis\n..." },
892 { "Hi, my name is\nTom", 1, 4, true, "Hi, \n..." },
893 { "Hi, my name is\nTom", 2, 4, true, "Hi, \nmy n\n..." },
894 { "Hi, my name is\nTom", 3, 4, true, "Hi, \nmy n\name \n..." },
895 { "Hi, my name is\nTom", 4, 4, true, "Hi, \nmy n\name \nis\n..." },
896 { "Hi, my name is\nTom", 5, 4, false, "Hi, \nmy n\name \nis\nTom" },
897 { "Hi, my name is\nTom", 1, 5, true, "Hi, \n..." },
898 { "Hi, my name is\nTom", 2, 5, true, "Hi, \nmy na\n..." },
899 { "Hi, my name is\nTom", 3, 5, true, "Hi, \nmy na\nme \n..." },
900 { "Hi, my name is\nTom", 4, 5, true, "Hi, \nmy na\nme \nis\n..." },
901 { "Hi, my name is\nTom", 5, 5, false, "Hi, \nmy na\nme \nis\nTom" },
902 { "Hi, my name is\nTom", 1, 6, true, "Hi, \n..." },
903 { "Hi, my name is\nTom", 2, 6, true, "Hi, \nmy \n..." },
904 { "Hi, my name is\nTom", 3, 6, true, "Hi, \nmy \nname \n..." },
905 { "Hi, my name is\nTom", 4, 6, true, "Hi, \nmy \nname \nis\n..." },
906 { "Hi, my name is\nTom", 5, 6, false, "Hi, \nmy \nname \nis\nTom" },
907 { "Hi, my name is\nTom", 1, 7, true, "Hi, \n..." },
908 { "Hi, my name is\nTom", 2, 7, true, "Hi, \nmy \n..." },
909 { "Hi, my name is\nTom", 3, 7, true, "Hi, \nmy \nname \n..." },
910 { "Hi, my name is\nTom", 4, 7, true, "Hi, \nmy \nname \nis\n..." },
911 { "Hi, my name is\nTom", 5, 7, false, "Hi, \nmy \nname \nis\nTom" },
912 { "Hi, my name is\nTom", 1, 8, true, "Hi, my \n..." },
913 { "Hi, my name is\nTom", 2, 8, true, "Hi, my \nname \n..." },
914 { "Hi, my name is\nTom", 3, 8, true, "Hi, my \nname \nis\n..." },
915 { "Hi, my name is\nTom", 4, 8, false, "Hi, my \nname \nis\nTom" },
916 { "Hi, my name is\nTom", 1, 9, true, "Hi, my \n..." },
917 { "Hi, my name is\nTom", 2, 9, true, "Hi, my \nname is\n..." },
918 { "Hi, my name is\nTom", 3, 9, false, "Hi, my \nname is\nTom" },
919 { "Hi, my name is\nTom", 1, 10, true, "Hi, my \n..." },
920 { "Hi, my name is\nTom", 2, 10, true, "Hi, my \nname is\n..." },
921 { "Hi, my name is\nTom", 3, 10, false, "Hi, my \nname is\nTom" },
922 { "Hi, my name is\nTom", 1, 11, true, "Hi, my \n..." },
923 { "Hi, my name is\nTom", 2, 11, true, "Hi, my \nname is\n..." },
924 { "Hi, my name is\nTom", 3, 11, false, "Hi, my \nname is\nTom" },
925 { "Hi, my name is\nTom", 1, 12, true, "Hi, my \n..." },
926 { "Hi, my name is\nTom", 2, 12, true, "Hi, my \nname is\n..." },
927 { "Hi, my name is\nTom", 3, 12, false, "Hi, my \nname is\nTom" },
928 { "Hi, my name is\nTom", 1, 13, true, "Hi, my name \n..." },
929 { "Hi, my name is\nTom", 2, 13, true, "Hi, my name \nis\n..." },
930 { "Hi, my name is\nTom", 3, 13, false, "Hi, my name \nis\nTom" },
931 { "Hi, my name is\nTom", 1, 20, true, "Hi, my name is\n..." },
932 { "Hi, my name is\nTom", 2, 20, false, "Hi, my name is\nTom" },
933 { "Hi, my name is Tom", 1, 40, false, "Hi, my name is Tom" },
934 };
[email protected]2aadf212013-12-18 20:03:44935 base::string16 output;
viettrungluua5ca99b2014-10-16 16:28:48936 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]dbb97ba2013-09-09 22:15:25937 EXPECT_EQ(cases[i].result,
938 ElideRectangleString(UTF8ToUTF16(cases[i].input),
939 cases[i].max_rows, cases[i].max_cols,
940 true, &output));
941 EXPECT_EQ(cases[i].output, UTF16ToUTF8(output));
942 }
943}
944
olivierrobin697bbda2015-12-07 14:53:48945// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:24946#if defined(OS_ANDROID)
947#define MAYBE_ElideRectangleStringNotStrict \
948 DISABLED_ElideRectangleStringNotStrict
949#else
950#define MAYBE_ElideRectangleStringNotStrict ElideRectangleStringNotStrict
951#endif
952TEST(TextEliderTest, MAYBE_ElideRectangleStringNotStrict) {
[email protected]dbb97ba2013-09-09 22:15:25953 struct TestData {
954 const char* input;
955 int max_rows;
956 int max_cols;
957 bool result;
958 const char* output;
959 } cases[] = {
960 { "", 0, 0, false, "" },
961 { "", 1, 1, false, "" },
962 { "Hi, my name_is\nDick", 0, 0, true, "..." },
963 { "Hi, my name_is\nDick", 1, 0, true, "\n..." },
964 { "Hi, my name_is\nDick", 0, 1, true, "..." },
965 { "Hi, my name_is\nDick", 1, 1, true, "H\n..." },
966 { "Hi, my name_is\nDick", 2, 1, true, "H\ni\n..." },
967 { "Hi, my name_is\nDick", 3, 1, true, "H\ni\n,\n..." },
968 { "Hi, my name_is\nDick", 4, 1, true, "H\ni\n,\n \n..." },
969 { "Hi, my name_is\nDick", 5, 1, true, "H\ni\n,\n \nm\n..." },
970 { "Hi, my name_is\nDick", 0, 2, true, "..." },
971 { "Hi, my name_is\nDick", 1, 2, true, "Hi\n..." },
972 { "Hi, my name_is\nDick", 2, 2, true, "Hi\n, \n..." },
973 { "Hi, my name_is\nDick", 3, 2, true, "Hi\n, \nmy\n..." },
974 { "Hi, my name_is\nDick", 4, 2, true, "Hi\n, \nmy\n n\n..." },
975 { "Hi, my name_is\nDick", 5, 2, true, "Hi\n, \nmy\n n\nam\n..." },
976 { "Hi, my name_is\nDick", 0, 3, true, "..." },
977 { "Hi, my name_is\nDick", 1, 3, true, "Hi,\n..." },
978 { "Hi, my name_is\nDick", 2, 3, true, "Hi,\n my\n..." },
979 { "Hi, my name_is\nDick", 3, 3, true, "Hi,\n my\n na\n..." },
980 { "Hi, my name_is\nDick", 4, 3, true, "Hi,\n my\n na\nme_\n..." },
981 { "Hi, my name_is\nDick", 5, 3, true, "Hi,\n my\n na\nme_\nis\n..." },
982 { "Hi, my name_is\nDick", 1, 4, true, "Hi, ..." },
983 { "Hi, my name_is\nDick", 2, 4, true, "Hi, my n\n..." },
984 { "Hi, my name_is\nDick", 3, 4, true, "Hi, my n\name_\n..." },
985 { "Hi, my name_is\nDick", 4, 4, true, "Hi, my n\name_\nis\n..." },
986 { "Hi, my name_is\nDick", 5, 4, false, "Hi, my n\name_\nis\nDick" },
987 { "Hi, my name_is\nDick", 1, 5, true, "Hi, ..." },
988 { "Hi, my name_is\nDick", 2, 5, true, "Hi, my na\n..." },
989 { "Hi, my name_is\nDick", 3, 5, true, "Hi, my na\nme_is\n..." },
990 { "Hi, my name_is\nDick", 4, 5, true, "Hi, my na\nme_is\n\n..." },
991 { "Hi, my name_is\nDick", 5, 5, false, "Hi, my na\nme_is\n\nDick" },
992 { "Hi, my name_is\nDick", 1, 6, true, "Hi, ..." },
993 { "Hi, my name_is\nDick", 2, 6, true, "Hi, my nam\n..." },
994 { "Hi, my name_is\nDick", 3, 6, true, "Hi, my nam\ne_is\n..." },
995 { "Hi, my name_is\nDick", 4, 6, false, "Hi, my nam\ne_is\nDick" },
996 { "Hi, my name_is\nDick", 5, 6, false, "Hi, my nam\ne_is\nDick" },
997 { "Hi, my name_is\nDick", 1, 7, true, "Hi, ..." },
998 { "Hi, my name_is\nDick", 2, 7, true, "Hi, my name\n..." },
999 { "Hi, my name_is\nDick", 3, 7, true, "Hi, my name\n_is\n..." },
1000 { "Hi, my name_is\nDick", 4, 7, false, "Hi, my name\n_is\nDick" },
1001 { "Hi, my name_is\nDick", 5, 7, false, "Hi, my name\n_is\nDick" },
1002 { "Hi, my name_is\nDick", 1, 8, true, "Hi, my n\n..." },
1003 { "Hi, my name_is\nDick", 2, 8, true, "Hi, my n\name_is\n..." },
1004 { "Hi, my name_is\nDick", 3, 8, false, "Hi, my n\name_is\nDick" },
1005 { "Hi, my name_is\nDick", 1, 9, true, "Hi, my ..." },
1006 { "Hi, my name_is\nDick", 2, 9, true, "Hi, my name_is\n..." },
1007 { "Hi, my name_is\nDick", 3, 9, false, "Hi, my name_is\nDick" },
1008 { "Hi, my name_is\nDick", 1, 10, true, "Hi, my ..." },
1009 { "Hi, my name_is\nDick", 2, 10, true, "Hi, my name_is\n..." },
1010 { "Hi, my name_is\nDick", 3, 10, false, "Hi, my name_is\nDick" },
1011 { "Hi, my name_is\nDick", 1, 11, true, "Hi, my ..." },
1012 { "Hi, my name_is\nDick", 2, 11, true, "Hi, my name_is\n..." },
1013 { "Hi, my name_is\nDick", 3, 11, false, "Hi, my name_is\nDick" },
1014 { "Hi, my name_is\nDick", 1, 12, true, "Hi, my ..." },
1015 { "Hi, my name_is\nDick", 2, 12, true, "Hi, my name_is\n..." },
1016 { "Hi, my name_is\nDick", 3, 12, false, "Hi, my name_is\nDick" },
1017 { "Hi, my name_is\nDick", 1, 13, true, "Hi, my ..." },
1018 { "Hi, my name_is\nDick", 2, 13, true, "Hi, my name_is\n..." },
1019 { "Hi, my name_is\nDick", 3, 13, false, "Hi, my name_is\nDick" },
1020 { "Hi, my name_is\nDick", 1, 20, true, "Hi, my name_is\n..." },
1021 { "Hi, my name_is\nDick", 2, 20, false, "Hi, my name_is\nDick" },
1022 { "Hi, my name_is Dick", 1, 40, false, "Hi, my name_is Dick" },
1023 };
[email protected]2aadf212013-12-18 20:03:441024 base::string16 output;
viettrungluua5ca99b2014-10-16 16:28:481025 for (size_t i = 0; i < arraysize(cases); ++i) {
[email protected]dbb97ba2013-09-09 22:15:251026 EXPECT_EQ(cases[i].result,
1027 ElideRectangleString(UTF8ToUTF16(cases[i].input),
1028 cases[i].max_rows, cases[i].max_cols,
1029 false, &output));
1030 EXPECT_EQ(cases[i].output, UTF16ToUTF8(output));
1031 }
1032}
1033
olivierrobin697bbda2015-12-07 14:53:481034// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:241035#if defined(OS_ANDROID)
1036#define MAYBE_ElideRectangleWide16 DISABLED_ElideRectangleWide16
1037#else
1038#define MAYBE_ElideRectangleWide16 ElideRectangleWide16
1039#endif
1040TEST(TextEliderTest, MAYBE_ElideRectangleWide16) {
[email protected]dbb97ba2013-09-09 22:15:251041 // Two greek words separated by space.
[email protected]2aadf212013-12-18 20:03:441042 const base::string16 str(WideToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251043 L"\x03a0\x03b1\x03b3\x03ba\x03cc\x03c3\x03bc\x03b9"
1044 L"\x03bf\x03c2\x0020\x0399\x03c3\x03c4\x03cc\x03c2"));
[email protected]2aadf212013-12-18 20:03:441045 const base::string16 out1(WideToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251046 L"\x03a0\x03b1\x03b3\x03ba\n"
1047 L"\x03cc\x03c3\x03bc\x03b9\n"
1048 L"..."));
[email protected]2aadf212013-12-18 20:03:441049 const base::string16 out2(WideToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251050 L"\x03a0\x03b1\x03b3\x03ba\x03cc\x03c3\x03bc\x03b9\x03bf\x03c2\x0020\n"
1051 L"\x0399\x03c3\x03c4\x03cc\x03c2"));
[email protected]2aadf212013-12-18 20:03:441052 base::string16 output;
[email protected]dbb97ba2013-09-09 22:15:251053 EXPECT_TRUE(ElideRectangleString(str, 2, 4, true, &output));
1054 EXPECT_EQ(out1, output);
1055 EXPECT_FALSE(ElideRectangleString(str, 2, 12, true, &output));
1056 EXPECT_EQ(out2, output);
1057}
1058
olivierrobin697bbda2015-12-07 14:53:481059// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:241060#if defined(OS_ANDROID)
1061#define MAYBE_ElideRectangleWide32 DISABLED_ElideRectangleWide32
1062#else
1063#define MAYBE_ElideRectangleWide32 ElideRectangleWide32
1064#endif
1065TEST(TextEliderTest, MAYBE_ElideRectangleWide32) {
[email protected]dbb97ba2013-09-09 22:15:251066 // Four U+1D49C MATHEMATICAL SCRIPT CAPITAL A followed by space "aaaaa".
[email protected]2aadf212013-12-18 20:03:441067 const base::string16 str(UTF8ToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251068 "\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C"
1069 " aaaaa"));
[email protected]2aadf212013-12-18 20:03:441070 const base::string16 out(UTF8ToUTF16(
[email protected]dbb97ba2013-09-09 22:15:251071 "\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\xF0\x9D\x92\x9C\n"
1072 "\xF0\x9D\x92\x9C \naaa\n..."));
[email protected]2aadf212013-12-18 20:03:441073 base::string16 output;
[email protected]dbb97ba2013-09-09 22:15:251074 EXPECT_TRUE(ElideRectangleString(str, 3, 3, true, &output));
1075 EXPECT_EQ(out, output);
1076}
1077
olivierrobin697bbda2015-12-07 14:53:481078// TODO(crbug.com/338784): Enable this on android.
pkotwicz85fd1d92015-05-20 16:36:241079#if defined(OS_ANDROID)
1080#define MAYBE_TruncateString DISABLED_TruncateString
1081#else
1082#define MAYBE_TruncateString TruncateString
1083#endif
1084TEST(TextEliderTest, MAYBE_TruncateString) {
pkastingfc336922015-09-23 05:59:311085 base::string16 str = ASCIIToUTF16("fooooey bxxxar baz ");
[email protected]dbb97ba2013-09-09 22:15:251086
pkastingfc336922015-09-23 05:59:311087 // Test breaking at character 0.
1088 EXPECT_EQ(base::string16(), TruncateString(str, 0, WORD_BREAK));
1089 EXPECT_EQ(base::string16(), TruncateString(str, 0, CHARACTER_BREAK));
[email protected]41c0d7c12014-07-23 15:52:581090
pkastingfc336922015-09-23 05:59:311091 // Test breaking at character 1.
1092 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str, 1, WORD_BREAK)));
1093 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str, 1, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251094
pkastingfc336922015-09-23 05:59:311095 // Test breaking in the middle of the first word.
1096 EXPECT_EQ(L"f\x2026", UTF16ToWide(TruncateString(str, 2, WORD_BREAK)));
1097 EXPECT_EQ(L"f\x2026", UTF16ToWide(TruncateString(str, 2, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251098
pkastingfc336922015-09-23 05:59:311099 // Test breaking in between words.
1100 EXPECT_EQ(L"fooooey\x2026", UTF16ToWide(TruncateString(str, 9, WORD_BREAK)));
1101 EXPECT_EQ(L"fooooey\x2026",
1102 UTF16ToWide(TruncateString(str, 9, CHARACTER_BREAK)));
[email protected]41c0d7c12014-07-23 15:52:581103
pkastingfc336922015-09-23 05:59:311104 // Test breaking at the start of a later word.
1105 EXPECT_EQ(L"fooooey\x2026", UTF16ToWide(TruncateString(str, 11, WORD_BREAK)));
1106 EXPECT_EQ(L"fooooey\x2026",
1107 UTF16ToWide(TruncateString(str, 11, CHARACTER_BREAK)));
[email protected]41c0d7c12014-07-23 15:52:581108
pkastingfc336922015-09-23 05:59:311109 // Test breaking in the middle of a word.
1110 EXPECT_EQ(L"fooooey\x2026", UTF16ToWide(TruncateString(str, 12, WORD_BREAK)));
1111 EXPECT_EQ(L"fooooey\x2026",
1112 UTF16ToWide(TruncateString(str, 12, CHARACTER_BREAK)));
1113 EXPECT_EQ(L"fooooey\x2026", UTF16ToWide(TruncateString(str, 14, WORD_BREAK)));
1114 EXPECT_EQ(L"fooooey bx\x2026",
1115 UTF16ToWide(TruncateString(str, 14, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251116
pkastingfc336922015-09-23 05:59:311117 // Test breaking in whitespace at the end of the string.
1118 EXPECT_EQ(L"fooooey bxxxar baz\x2026",
1119 UTF16ToWide(TruncateString(str, 22, WORD_BREAK)));
1120 EXPECT_EQ(L"fooooey bxxxar baz\x2026",
1121 UTF16ToWide(TruncateString(str, 22, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251122
pkastingfc336922015-09-23 05:59:311123 // Test breaking at the end of the string.
1124 EXPECT_EQ(str, TruncateString(str, str.length(), WORD_BREAK));
1125 EXPECT_EQ(str, TruncateString(str, str.length(), CHARACTER_BREAK));
[email protected]dbb97ba2013-09-09 22:15:251126
pkastingfc336922015-09-23 05:59:311127 // Test breaking past the end of the string.
1128 EXPECT_EQ(str, TruncateString(str, str.length() + 10, WORD_BREAK));
1129 EXPECT_EQ(str, TruncateString(str, str.length() + 10, CHARACTER_BREAK));
[email protected]dbb97ba2013-09-09 22:15:251130
[email protected]41c0d7c12014-07-23 15:52:581131
pkastingfc336922015-09-23 05:59:311132 // Tests of strings with leading whitespace:
1133 base::string16 str2 = ASCIIToUTF16(" foo");
[email protected]41c0d7c12014-07-23 15:52:581134
pkastingfc336922015-09-23 05:59:311135 // Test breaking in leading whitespace.
1136 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 2, WORD_BREAK)));
1137 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 2, CHARACTER_BREAK)));
1138
1139 // Test breaking at the beginning of the first word, with leading whitespace.
1140 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 3, WORD_BREAK)));
1141 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 3, CHARACTER_BREAK)));
1142
1143 // Test breaking in the middle of the first word, with leading whitespace.
1144 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 4, WORD_BREAK)));
1145 EXPECT_EQ(L"\x2026", UTF16ToWide(TruncateString(str2, 4, CHARACTER_BREAK)));
1146 EXPECT_EQ(L" f\x2026", UTF16ToWide(TruncateString(str2, 5, WORD_BREAK)));
1147 EXPECT_EQ(L" f\x2026",
1148 UTF16ToWide(TruncateString(str2, 5, CHARACTER_BREAK)));
[email protected]dbb97ba2013-09-09 22:15:251149}
1150
1151} // namespace gfx