Another take on menu's. This uses the hosting menu scroll view container as a menuba...
[chromium-blink-merge.git] / app / text_elider_unittest.cc
blob2dd76e290a0cf92381751c3a520a4790394c5db5
1 // Copyright (c) 2010 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.
5 #include "app/text_elider.h"
6 #include "base/file_path.h"
7 #include "base/i18n/rtl.h"
8 #include "base/scoped_ptr.h"
9 #include "base/string_util.h"
10 #include "base/utf_string_conversions.h"
11 #include "gfx/font.h"
12 #include "googleurl/src/gurl.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace {
17 const wchar_t kEllipsis[] = L"\x2026";
19 struct Testcase {
20 const std::string input;
21 const std::wstring output;
24 struct FileTestcase {
25 const FilePath::StringType input;
26 const std::wstring output;
29 struct WideTestcase {
30 const std::wstring input;
31 const std::wstring output;
34 struct TestData {
35 const std::string a;
36 const std::string b;
37 const int compare_result;
40 void RunTest(Testcase* testcases, size_t num_testcases) {
41 static const gfx::Font font;
42 for (size_t i = 0; i < num_testcases; ++i) {
43 const GURL url(testcases[i].input);
44 // Should we test with non-empty language list?
45 // That's kinda redundant with net_util_unittests.
46 EXPECT_EQ(testcases[i].output,
47 ElideUrl(url, font, font.GetStringWidth(testcases[i].output),
48 std::wstring()));
52 } // namespace
54 // Test eliding of commonplace URLs.
55 TEST(TextEliderTest, TestGeneralEliding) {
56 const std::wstring kEllipsisStr(kEllipsis);
57 Testcase testcases[] = {
58 {"http://www.google.com/intl/en/ads/",
59 L"www.google.com/intl/en/ads/"},
60 {"http://www.google.com/intl/en/ads/", L"www.google.com/intl/en/ads/"},
61 // TODO(port): make this test case work on mac.
62 #if !defined(OS_MACOSX)
63 {"http://www.google.com/intl/en/ads/",
64 L"google.com/intl/" + kEllipsisStr + L"/ads/"},
65 #endif
66 {"http://www.google.com/intl/en/ads/",
67 L"google.com/" + kEllipsisStr + L"/ads/"},
68 {"http://www.google.com/intl/en/ads/", L"google.com/" + kEllipsisStr},
69 {"http://www.google.com/intl/en/ads/", L"goog" + kEllipsisStr},
70 {"https://subdomain.foo.com/bar/filename.html",
71 L"subdomain.foo.com/bar/filename.html"},
72 {"https://subdomain.foo.com/bar/filename.html",
73 L"subdomain.foo.com/" + kEllipsisStr + L"/filename.html"},
74 {"http://subdomain.foo.com/bar/filename.html",
75 kEllipsisStr + L"foo.com/" + kEllipsisStr + L"/filename.html"},
76 {"http://www.google.com/intl/en/ads/?aLongQueryWhichIsNotRequired",
77 L"www.google.com/intl/en/ads/?aLongQ" + kEllipsisStr},
80 RunTest(testcases, arraysize(testcases));
83 // Test eliding of empty strings, URLs with ports, passwords, queries, etc.
84 TEST(TextEliderTest, TestMoreEliding) {
85 const std::wstring kEllipsisStr(kEllipsis);
86 Testcase testcases[] = {
87 {"http://www.google.com/foo?bar", L"www.google.com/foo?bar"},
88 {"http://xyz.google.com/foo?bar", L"xyz.google.com/foo?" + kEllipsisStr},
89 {"http://xyz.google.com/foo?bar", L"xyz.google.com/foo" + kEllipsisStr},
90 {"http://xyz.google.com/foo?bar", L"xyz.google.com/fo" + kEllipsisStr},
91 {"http://a.b.com/pathname/c?d", L"a.b.com/" + kEllipsisStr + L"/c?d"},
92 {"", L""},
93 {"http://foo.bar..example.com...hello/test/filename.html",
94 L"foo.bar..example.com...hello/" + kEllipsisStr + L"/filename.html"},
95 {"http://foo.bar../", L"foo.bar.."},
96 {"http://xn--1lq90i.cn/foo", L"\x5317\x4eac.cn/foo"},
97 {"http://me:mypass@secrethost.com:99/foo?bar#baz",
98 L"secrethost.com:99/foo?bar#baz"},
99 {"http://me:mypass@ss%xxfdsf.com/foo", L"ss%25xxfdsf.com/foo"},
100 {"mailto:elgoato@elgoato.com", L"mailto:elgoato@elgoato.com"},
101 {"javascript:click(0)", L"javascript:click(0)"},
102 {"https://chess.eecs.berkeley.edu:4430/login/arbitfilename",
103 L"chess.eecs.berkeley.edu:4430/login/arbitfilename"},
104 {"https://chess.eecs.berkeley.edu:4430/login/arbitfilename",
105 kEllipsisStr + L"berkeley.edu:4430/" + kEllipsisStr + L"/arbitfilename"},
107 // Unescaping.
108 {"http://www/%E4%BD%A0%E5%A5%BD?q=%E4%BD%A0%E5%A5%BD#\xe4\xbd\xa0",
109 L"www/\x4f60\x597d?q=\x4f60\x597d#\x4f60"},
111 // Invalid unescaping for path. The ref will always be valid UTF-8. We don't
112 // bother to do too many edge cases, since these are handled by the escaper
113 // unittest.
114 {"http://www/%E4%A0%E5%A5%BD?q=%E4%BD%A0%E5%A5%BD#\xe4\xbd\xa0",
115 L"www/%E4%A0%E5%A5%BD?q=\x4f60\x597d#\x4f60"},
118 RunTest(testcases, arraysize(testcases));
121 // Test eliding of file: URLs.
122 TEST(TextEliderTest, TestFileURLEliding) {
123 const std::wstring kEllipsisStr(kEllipsis);
124 Testcase testcases[] = {
125 {"file:///C:/path1/path2/path3/filename",
126 L"file:///C:/path1/path2/path3/filename"},
127 {"file:///C:/path1/path2/path3/filename",
128 L"C:/path1/path2/path3/filename"},
129 // GURL parses "file:///C:path" differently on windows than it does on posix.
130 #if defined(OS_WIN)
131 {"file:///C:path1/path2/path3/filename",
132 L"C:/path1/path2/" + kEllipsisStr + L"/filename"},
133 {"file:///C:path1/path2/path3/filename",
134 L"C:/path1/" + kEllipsisStr + L"/filename"},
135 {"file:///C:path1/path2/path3/filename",
136 L"C:/" + kEllipsisStr + L"/filename"},
137 #endif
138 {"file://filer/foo/bar/file", L"filer/foo/bar/file"},
139 {"file://filer/foo/bar/file", L"filer/foo/" + kEllipsisStr + L"/file"},
140 {"file://filer/foo/bar/file", L"filer/" + kEllipsisStr + L"/file"},
143 RunTest(testcases, arraysize(testcases));
146 TEST(TextEliderTest, TestFilenameEliding) {
147 const std::wstring kEllipsisStr(kEllipsis);
148 const FilePath::StringType kPathSeparator =
149 FilePath::StringType().append(1, FilePath::kSeparators[0]);
151 FileTestcase testcases[] = {
152 {FILE_PATH_LITERAL(""), L""},
153 {FILE_PATH_LITERAL("."), L"."},
154 {FILE_PATH_LITERAL("filename.exe"), L"filename.exe"},
155 {FILE_PATH_LITERAL(".longext"), L".longext"},
156 {FILE_PATH_LITERAL("pie"), L"pie"},
157 {FILE_PATH_LITERAL("c:") + kPathSeparator + FILE_PATH_LITERAL("path") +
158 kPathSeparator + FILE_PATH_LITERAL("filename.pie"),
159 L"filename.pie"},
160 {FILE_PATH_LITERAL("c:") + kPathSeparator + FILE_PATH_LITERAL("path") +
161 kPathSeparator + FILE_PATH_LITERAL("longfilename.pie"),
162 L"long" + kEllipsisStr + L".pie"},
163 {FILE_PATH_LITERAL("http://path.com/filename.pie"), L"filename.pie"},
164 {FILE_PATH_LITERAL("http://path.com/longfilename.pie"),
165 L"long" + kEllipsisStr + L".pie"},
166 {FILE_PATH_LITERAL("piesmashingtacularpants"), L"pie" + kEllipsisStr},
167 {FILE_PATH_LITERAL(".piesmashingtacularpants"), L".pie" + kEllipsisStr},
168 {FILE_PATH_LITERAL("cheese."), L"cheese."},
169 {FILE_PATH_LITERAL("file name.longext"),
170 L"file" + kEllipsisStr + L".longext"},
171 {FILE_PATH_LITERAL("fil ename.longext"),
172 L"fil " + kEllipsisStr + L".longext"},
173 {FILE_PATH_LITERAL("filename.longext"),
174 L"file" + kEllipsisStr + L".longext"},
175 {FILE_PATH_LITERAL("filename.middleext.longext"),
176 L"filename.mid" + kEllipsisStr + L".longext"}
179 static const gfx::Font font;
180 for (size_t i = 0; i < arraysize(testcases); ++i) {
181 FilePath filepath(testcases[i].input);
182 string16 expected = WideToUTF16(testcases[i].output);
183 expected = base::i18n::GetDisplayStringInLTRDirectionality(expected);
184 EXPECT_EQ(expected, WideToUTF16(ElideFilename(filepath,
185 font,
186 font.GetStringWidth(testcases[i].output))));
190 TEST(TextEliderTest, ElideTextLongStrings) {
191 const std::wstring kEllipsisStr(kEllipsis);
192 std::wstring data_scheme(L"data:text/plain,");
193 size_t data_scheme_length = data_scheme.length();
195 std::wstring ten_a(10, L'a');
196 std::wstring hundred_a(100, L'a');
197 std::wstring thousand_a(1000, L'a');
198 std::wstring ten_thousand_a(10000, L'a');
199 std::wstring hundred_thousand_a(100000, L'a');
200 std::wstring million_a(1000000, L'a');
202 size_t number_of_as = 156;
203 std::wstring long_string_end(
204 data_scheme + std::wstring(number_of_as, L'a') + kEllipsisStr);
205 WideTestcase testcases_end[] = {
206 {data_scheme + ten_a, data_scheme + ten_a},
207 {data_scheme + hundred_a, data_scheme + hundred_a},
208 {data_scheme + thousand_a, long_string_end},
209 {data_scheme + ten_thousand_a, long_string_end},
210 {data_scheme + hundred_thousand_a, long_string_end},
211 {data_scheme + million_a, long_string_end},
214 const gfx::Font font;
215 int ellipsis_width = font.GetStringWidth(kEllipsisStr);
216 for (size_t i = 0; i < arraysize(testcases_end); ++i) {
217 // Compare sizes rather than actual contents because if the test fails,
218 // output is rather long.
219 EXPECT_EQ(testcases_end[i].output.size(),
220 ElideText(testcases_end[i].input, font,
221 font.GetStringWidth(testcases_end[i].output),
222 false).size());
223 EXPECT_EQ(kEllipsisStr,
224 ElideText(testcases_end[i].input, font, ellipsis_width, false));
227 size_t number_of_trailing_as = (data_scheme_length + number_of_as) / 2;
228 std::wstring long_string_middle(data_scheme +
229 std::wstring(number_of_as - number_of_trailing_as, L'a') + kEllipsisStr +
230 std::wstring(number_of_trailing_as, L'a'));
231 WideTestcase testcases_middle[] = {
232 {data_scheme + ten_a, data_scheme + ten_a},
233 {data_scheme + hundred_a, data_scheme + hundred_a},
234 {data_scheme + thousand_a, long_string_middle},
235 {data_scheme + ten_thousand_a, long_string_middle},
236 {data_scheme + hundred_thousand_a, long_string_middle},
237 {data_scheme + million_a, long_string_middle},
240 for (size_t i = 0; i < arraysize(testcases_middle); ++i) {
241 // Compare sizes rather than actual contents because if the test fails,
242 // output is rather long.
243 EXPECT_EQ(testcases_middle[i].output.size(),
244 ElideText(testcases_middle[i].input, font,
245 font.GetStringWidth(testcases_middle[i].output),
246 false).size());
247 EXPECT_EQ(kEllipsisStr,
248 ElideText(testcases_middle[i].input, font, ellipsis_width,
249 false));
253 // Verifies display_url is set correctly.
254 TEST(TextEliderTest, SortedDisplayURL) {
255 gfx::SortedDisplayURL d_url(GURL("http://www.google.com"), std::wstring());
256 EXPECT_EQ("www.google.com", UTF16ToASCII(d_url.display_url()));
259 // Verifies DisplayURL::Compare works correctly.
260 TEST(TextEliderTest, SortedDisplayURLCompare) {
261 UErrorCode create_status = U_ZERO_ERROR;
262 scoped_ptr<icu::Collator> collator(
263 icu::Collator::createInstance(create_status));
264 if (!U_SUCCESS(create_status))
265 return;
267 TestData tests[] = {
268 // IDN comparison. Hosts equal, so compares on path.
269 { "http://xn--1lq90i.cn/a", "http://xn--1lq90i.cn/b", -1},
271 // Because the host and after host match, this compares the full url.
272 { "http://www.x/b", "http://x/b", -1 },
274 // Because the host and after host match, this compares the full url.
275 { "http://www.a:1/b", "http://a:1/b", 1 },
277 // The hosts match, so these end up comparing on the after host portion.
278 { "http://www.x:0/b", "http://x:1/b", -1 },
279 { "http://www.x/a", "http://x/b", -1 },
280 { "http://x/b", "http://www.x/a", 1 },
282 // Trivial Equality.
283 { "http://a/", "http://a/", 0 },
285 // Compares just hosts.
286 { "http://www.a/", "http://b/", -1 },
289 for (size_t i = 0; i < arraysize(tests); ++i) {
290 gfx::SortedDisplayURL url1(GURL(tests[i].a), std::wstring());
291 gfx::SortedDisplayURL url2(GURL(tests[i].b), std::wstring());
292 EXPECT_EQ(tests[i].compare_result, url1.Compare(url2, collator.get()));
293 EXPECT_EQ(-tests[i].compare_result, url2.Compare(url1, collator.get()));