- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / cocoa / omnibox / omnibox_popup_view_mac_unittest.mm
1 // 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 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.h"
6
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/sys_string_conversions.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h"
11 #import "chrome/browser/ui/cocoa/omnibox/omnibox_view_mac.h"
12 #include "chrome/test/base/testing_profile.h"
13 #include "ui/gfx/rect.h"
14 #include "ui/gfx/text_elider.h"
15
16 namespace {
17
18 const float kLargeWidth = 10000;
19
20 // Returns the length of the run starting at |location| for which
21 // |attributeName| remains the same.
22 NSUInteger RunLengthForAttribute(NSAttributedString* string,
23                                  NSUInteger location,
24                                  NSString* attributeName) {
25   const NSRange full_range = NSMakeRange(0, [string length]);
26   NSRange range;
27   [string attribute:attributeName
28             atIndex:location longestEffectiveRange:&range inRange:full_range];
29
30   // In order to signal when the run doesn't start exactly at location, return
31   // a weirdo length.  This causes the incorrect expectation to manifest at the
32   // calling location, which is more useful than an EXPECT_EQ() would be here.
33   if (range.location != location) {
34     return -1;
35   }
36
37   return range.length;
38 }
39
40 // Return true if the run starting at |location| has |color| for attribute
41 // NSForegroundColorAttributeName.
42 bool RunHasColor(NSAttributedString* string,
43                  NSUInteger location,
44                  NSColor* color) {
45   const NSRange full_range = NSMakeRange(0, [string length]);
46   NSRange range;
47   NSColor* run_color = [string attribute:NSForegroundColorAttributeName
48                                  atIndex:location
49                    longestEffectiveRange:&range
50                                  inRange:full_range];
51
52   // According to one "Ali Ozer", you can compare objects within the same color
53   // space using -isEqual:.  Converting color spaces seems too heavyweight for
54   // these tests.
55   // http://lists.apple.com/archives/cocoa-dev/2005/May/msg00186.html
56   return [run_color isEqual:color] ? true : false;
57 }
58
59 // Return true if the run starting at |location| has the font trait(s) in |mask|
60 // font in NSFontAttributeName.
61 bool RunHasFontTrait(NSAttributedString* string,
62                      NSUInteger location,
63                      NSFontTraitMask mask) {
64   const NSRange full_range = NSMakeRange(0, [string length]);
65   NSRange range;
66   NSFont* run_font = [string attribute:NSFontAttributeName
67                                atIndex:location
68                  longestEffectiveRange:&range
69                                inRange:full_range];
70   NSFontManager* fontManager = [NSFontManager sharedFontManager];
71   if (run_font && (mask == ([fontManager traitsOfFont:run_font] & mask))) {
72     return true;
73   }
74   return false;
75 }
76
77 // AutocompleteMatch doesn't really have the right constructor for our
78 // needs.  Fake one for us to use.
79 AutocompleteMatch MakeMatch(const string16& contents,
80                             const string16& description) {
81   AutocompleteMatch m(NULL, 1, true, AutocompleteMatchType::URL_WHAT_YOU_TYPED);
82   m.contents = contents;
83   m.description = description;
84   return m;
85 }
86
87 class MockOmniboxPopupViewMac : public OmniboxPopupViewMac {
88  public:
89   MockOmniboxPopupViewMac(OmniboxView* omnibox_view,
90                           OmniboxEditModel* edit_model,
91                           NSTextField* field)
92       : OmniboxPopupViewMac(omnibox_view, edit_model, field) {
93   }
94
95   void SetResultCount(size_t count) {
96     ACMatches matches;
97     for (size_t i = 0; i < count; ++i)
98       matches.push_back(AutocompleteMatch());
99     result_.Reset();
100     result_.AppendMatches(matches);
101   }
102
103  protected:
104   virtual const AutocompleteResult& GetResult() const OVERRIDE {
105     return result_;
106   }
107
108  private:
109   AutocompleteResult result_;
110 };
111
112 class OmniboxPopupViewMacTest : public CocoaProfileTest {
113  public:
114   OmniboxPopupViewMacTest() {
115     color_ = [NSColor blackColor];
116     dim_color_ = [NSColor darkGrayColor];
117     font_ = gfx::Font(
118         base::SysNSStringToUTF8([[NSFont userFontOfSize:12] fontName]), 12);
119   }
120
121  protected:
122   NSColor* color_;  // weak
123   NSColor* dim_color_;  // weak
124   gfx::Font font_;
125
126  private:
127   DISALLOW_COPY_AND_ASSIGN(OmniboxPopupViewMacTest);
128 };
129
130 // Simple inputs with no matches should result in styled output who's text
131 // matches the input string, with the passed-in color, and nothing bolded.
132 TEST_F(OmniboxPopupViewMacTest, DecorateMatchedStringNoMatch) {
133   NSString* const string = @"This is a test";
134   AutocompleteMatch::ACMatchClassifications classifications;
135
136   NSAttributedString* decorated =
137       OmniboxPopupViewMac::DecorateMatchedString(
138           base::SysNSStringToUTF16(string), classifications,
139           color_, dim_color_, font_);
140
141   // Result has same characters as the input.
142   EXPECT_EQ([decorated length], [string length]);
143   EXPECT_TRUE([[decorated string] isEqualToString:string]);
144
145   // Our passed-in color for the entire string.
146   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
147                                   NSForegroundColorAttributeName),
148             [string length]);
149   EXPECT_TRUE(RunHasColor(decorated, 0U, color_));
150
151   // An unbolded font for the entire string.
152   EXPECT_EQ(RunLengthForAttribute(decorated, 0U, NSFontAttributeName),
153             [string length]);
154   EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask));
155 }
156
157 // Identical to DecorateMatchedStringNoMatch, except test that URL style gets a
158 // different color than we passed in.
159 TEST_F(OmniboxPopupViewMacTest, DecorateMatchedStringURLNoMatch) {
160   NSString* const string = @"This is a test";
161   AutocompleteMatch::ACMatchClassifications classifications;
162
163   classifications.push_back(
164       ACMatchClassification(0, ACMatchClassification::URL));
165
166   NSAttributedString* decorated =
167       OmniboxPopupViewMac::DecorateMatchedString(
168           base::SysNSStringToUTF16(string), classifications,
169           color_, dim_color_, font_);
170
171   // Result has same characters as the input.
172   EXPECT_EQ([decorated length], [string length]);
173   EXPECT_TRUE([[decorated string] isEqualToString:string]);
174
175   // One color for the entire string, and it's not the one we passed in.
176   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
177                                   NSForegroundColorAttributeName),
178             [string length]);
179   EXPECT_FALSE(RunHasColor(decorated, 0U, color_));
180
181   // An unbolded font for the entire string.
182   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
183                                   NSFontAttributeName), [string length]);
184   EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask));
185 }
186
187 // Test that DIM works as expected.
188 TEST_F(OmniboxPopupViewMacTest, DecorateMatchedStringDimNoMatch) {
189   NSString* const string = @"This is a test";
190   // Dim "is".
191   const NSUInteger run_length_1 = 5, run_length_2 = 2, run_length_3 = 7;
192   // Make sure nobody messed up the inputs.
193   EXPECT_EQ(run_length_1 + run_length_2 + run_length_3, [string length]);
194
195   // Push each run onto classifications.
196   AutocompleteMatch::ACMatchClassifications classifications;
197   classifications.push_back(
198       ACMatchClassification(0, ACMatchClassification::NONE));
199   classifications.push_back(
200       ACMatchClassification(run_length_1, ACMatchClassification::DIM));
201   classifications.push_back(
202       ACMatchClassification(run_length_1 + run_length_2,
203                             ACMatchClassification::NONE));
204
205   NSAttributedString* decorated =
206       OmniboxPopupViewMac::DecorateMatchedString(
207           base::SysNSStringToUTF16(string), classifications,
208           color_, dim_color_, font_);
209
210   // Result has same characters as the input.
211   EXPECT_EQ([decorated length], [string length]);
212   EXPECT_TRUE([[decorated string] isEqualToString:string]);
213
214   // Should have three font runs, normal, dim, normal.
215   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
216                                   NSForegroundColorAttributeName),
217             run_length_1);
218   EXPECT_TRUE(RunHasColor(decorated, 0U, color_));
219
220   EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1,
221                                   NSForegroundColorAttributeName),
222             run_length_2);
223   EXPECT_TRUE(RunHasColor(decorated, run_length_1, dim_color_));
224
225   EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1 + run_length_2,
226                                   NSForegroundColorAttributeName),
227             run_length_3);
228   EXPECT_TRUE(RunHasColor(decorated, run_length_1 + run_length_2, color_));
229
230   // An unbolded font for the entire string.
231   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
232                                   NSFontAttributeName), [string length]);
233   EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask));
234 }
235
236 // Test that the matched run gets bold-faced, but keeps the same color.
237 TEST_F(OmniboxPopupViewMacTest, DecorateMatchedStringMatch) {
238   NSString* const string = @"This is a test";
239   // Match "is".
240   const NSUInteger run_length_1 = 5, run_length_2 = 2, run_length_3 = 7;
241   // Make sure nobody messed up the inputs.
242   EXPECT_EQ(run_length_1 + run_length_2 + run_length_3, [string length]);
243
244   // Push each run onto classifications.
245   AutocompleteMatch::ACMatchClassifications classifications;
246   classifications.push_back(
247       ACMatchClassification(0, ACMatchClassification::NONE));
248   classifications.push_back(
249       ACMatchClassification(run_length_1, ACMatchClassification::MATCH));
250   classifications.push_back(
251       ACMatchClassification(run_length_1 + run_length_2,
252                             ACMatchClassification::NONE));
253
254   NSAttributedString* decorated =
255       OmniboxPopupViewMac::DecorateMatchedString(
256           base::SysNSStringToUTF16(string), classifications,
257           color_, dim_color_, font_);
258
259   // Result has same characters as the input.
260   EXPECT_EQ([decorated length], [string length]);
261   EXPECT_TRUE([[decorated string] isEqualToString:string]);
262
263   // Our passed-in color for the entire string.
264   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
265                                   NSForegroundColorAttributeName),
266             [string length]);
267   EXPECT_TRUE(RunHasColor(decorated, 0U, color_));
268
269   // Should have three font runs, not bold, bold, then not bold again.
270   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
271                                   NSFontAttributeName), run_length_1);
272   EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask));
273
274   EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1,
275                                   NSFontAttributeName), run_length_2);
276   EXPECT_TRUE(RunHasFontTrait(decorated, run_length_1, NSBoldFontMask));
277
278   EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1 + run_length_2,
279                                   NSFontAttributeName), run_length_3);
280   EXPECT_FALSE(RunHasFontTrait(decorated, run_length_1 + run_length_2,
281                                NSBoldFontMask));
282 }
283
284 // Just like DecorateMatchedStringURLMatch, this time with URL style.
285 TEST_F(OmniboxPopupViewMacTest, DecorateMatchedStringURLMatch) {
286   NSString* const string = @"http://hello.world/";
287   // Match "hello".
288   const NSUInteger run_length_1 = 7, run_length_2 = 5, run_length_3 = 7;
289   // Make sure nobody messed up the inputs.
290   EXPECT_EQ(run_length_1 + run_length_2 + run_length_3, [string length]);
291
292   // Push each run onto classifications.
293   AutocompleteMatch::ACMatchClassifications classifications;
294   classifications.push_back(
295       ACMatchClassification(0, ACMatchClassification::URL));
296   const int kURLMatch = ACMatchClassification::URL|ACMatchClassification::MATCH;
297   classifications.push_back(ACMatchClassification(run_length_1, kURLMatch));
298   classifications.push_back(
299       ACMatchClassification(run_length_1 + run_length_2,
300                             ACMatchClassification::URL));
301
302   NSAttributedString* decorated =
303       OmniboxPopupViewMac::DecorateMatchedString(
304           base::SysNSStringToUTF16(string), classifications,
305           color_, dim_color_, font_);
306
307   // Result has same characters as the input.
308   EXPECT_EQ([decorated length], [string length]);
309   EXPECT_TRUE([[decorated string] isEqualToString:string]);
310
311   // One color for the entire string, and it's not the one we passed in.
312   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
313                                   NSForegroundColorAttributeName),
314             [string length]);
315   EXPECT_FALSE(RunHasColor(decorated, 0U, color_));
316
317   // Should have three font runs, not bold, bold, then not bold again.
318   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
319                                   NSFontAttributeName), run_length_1);
320   EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask));
321
322   EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1,
323                                   NSFontAttributeName), run_length_2);
324   EXPECT_TRUE(RunHasFontTrait(decorated, run_length_1, NSBoldFontMask));
325
326   EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1 + run_length_2,
327                                   NSFontAttributeName), run_length_3);
328   EXPECT_FALSE(RunHasFontTrait(decorated, run_length_1 + run_length_2,
329                                NSBoldFontMask));
330 }
331
332 // Check that matches with both contents and description come back
333 // with contents at the beginning, description at the end, and
334 // something separating them.  Not being specific about the separator
335 // on purpose, in case it changes.
336 TEST_F(OmniboxPopupViewMacTest, MatchText) {
337   NSString* const contents = @"contents";
338   NSString* const description = @"description";
339   AutocompleteMatch m = MakeMatch(base::SysNSStringToUTF16(contents),
340                                   base::SysNSStringToUTF16(description));
341
342   NSAttributedString* decorated =
343       OmniboxPopupViewMac::MatchText(m, font_, kLargeWidth);
344
345   // Result contains the characters of the input in the right places.
346   EXPECT_GT([decorated length], [contents length] + [description length]);
347   EXPECT_TRUE([[decorated string] hasPrefix:contents]);
348   EXPECT_TRUE([[decorated string] hasSuffix:description]);
349
350   // Check that the description is a different color from the
351   // contents.
352   const NSUInteger descriptionLocation =
353       [decorated length] - [description length];
354   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
355                                   NSForegroundColorAttributeName),
356             descriptionLocation);
357   EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation,
358                                   NSForegroundColorAttributeName),
359             [description length]);
360
361   // Same font all the way through, nothing bold.
362   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
363                                   NSFontAttributeName), [decorated length]);
364   EXPECT_FALSE(RunHasFontTrait(decorated, 0, NSBoldFontMask));
365 }
366
367 // Check that MatchText() styles content matches as expected.
368 TEST_F(OmniboxPopupViewMacTest, MatchTextContentsMatch) {
369   NSString* const contents = @"This is a test";
370   // Match "is".
371   const NSUInteger run_length_1 = 5, run_length_2 = 2, run_length_3 = 7;
372   // Make sure nobody messed up the inputs.
373   EXPECT_EQ(run_length_1 + run_length_2 + run_length_3, [contents length]);
374
375   AutocompleteMatch m = MakeMatch(base::SysNSStringToUTF16(contents),
376                                   string16());
377
378   // Push each run onto contents classifications.
379   m.contents_class.push_back(
380       ACMatchClassification(0, ACMatchClassification::NONE));
381   m.contents_class.push_back(
382       ACMatchClassification(run_length_1, ACMatchClassification::MATCH));
383   m.contents_class.push_back(
384       ACMatchClassification(run_length_1 + run_length_2,
385                             ACMatchClassification::NONE));
386
387   NSAttributedString* decorated =
388       OmniboxPopupViewMac::MatchText(m, font_, kLargeWidth);
389
390   // Result has same characters as the input.
391   EXPECT_EQ([decorated length], [contents length]);
392   EXPECT_TRUE([[decorated string] isEqualToString:contents]);
393
394   // Result is all one color.
395   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
396                                   NSForegroundColorAttributeName),
397             [contents length]);
398
399   // Should have three font runs, not bold, bold, then not bold again.
400   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
401                                   NSFontAttributeName), run_length_1);
402   EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask));
403
404   EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1,
405                                   NSFontAttributeName), run_length_2);
406   EXPECT_TRUE(RunHasFontTrait(decorated, run_length_1, NSBoldFontMask));
407
408   EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1 + run_length_2,
409                                   NSFontAttributeName), run_length_3);
410   EXPECT_FALSE(RunHasFontTrait(decorated, run_length_1 + run_length_2,
411                                NSBoldFontMask));
412 }
413
414 // Check that MatchText() styles description matches as expected.
415 TEST_F(OmniboxPopupViewMacTest, MatchTextDescriptionMatch) {
416   NSString* const contents = @"This is a test";
417   NSString* const description = @"That was a test";
418   // Match "That was".
419   const NSUInteger run_length_1 = 8, run_length_2 = 7;
420   // Make sure nobody messed up the inputs.
421   EXPECT_EQ(run_length_1 + run_length_2, [description length]);
422
423   AutocompleteMatch m = MakeMatch(base::SysNSStringToUTF16(contents),
424                                   base::SysNSStringToUTF16(description));
425
426   // Push each run onto contents classifications.
427   m.description_class.push_back(
428       ACMatchClassification(0, ACMatchClassification::MATCH));
429   m.description_class.push_back(
430       ACMatchClassification(run_length_1, ACMatchClassification::NONE));
431
432   NSAttributedString* decorated =
433       OmniboxPopupViewMac::MatchText(m, font_, kLargeWidth);
434
435   // Result contains the characters of the input.
436   EXPECT_GT([decorated length], [contents length] + [description length]);
437   EXPECT_TRUE([[decorated string] hasPrefix:contents]);
438   EXPECT_TRUE([[decorated string] hasSuffix:description]);
439
440   // Check that the description is a different color from the
441   // contents.
442   const NSUInteger descriptionLocation =
443       [decorated length] - [description length];
444   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
445                                   NSForegroundColorAttributeName),
446             descriptionLocation);
447   EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation,
448                                   NSForegroundColorAttributeName),
449             [description length]);
450
451   // Should have three font runs, not bold, bold, then not bold again.
452   // The first run is the contents and the separator, the second run
453   // is the first run of the description.
454   EXPECT_EQ(RunLengthForAttribute(decorated, 0U,
455                                   NSFontAttributeName), descriptionLocation);
456   EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask));
457
458   EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation,
459                                   NSFontAttributeName), run_length_1);
460   EXPECT_TRUE(RunHasFontTrait(decorated, descriptionLocation, NSBoldFontMask));
461
462   EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation + run_length_1,
463                                   NSFontAttributeName), run_length_2);
464   EXPECT_FALSE(RunHasFontTrait(decorated, descriptionLocation + run_length_1,
465                                NSBoldFontMask));
466 }
467
468 TEST_F(OmniboxPopupViewMacTest, ElideString) {
469   NSString* const contents = @"This is a test with long contents";
470   const string16 contents16(base::SysNSStringToUTF16(contents));
471
472   const float kWide = 1000.0;
473   const float kNarrow = 20.0;
474
475   NSDictionary* attributes =
476       [NSDictionary dictionaryWithObject:font_.GetNativeFont()
477                                   forKey:NSFontAttributeName];
478   base::scoped_nsobject<NSMutableAttributedString> as(
479       [[NSMutableAttributedString alloc] initWithString:contents
480                                              attributes:attributes]);
481
482   // Nothing happens if the space is really wide.
483   NSMutableAttributedString* ret =
484       OmniboxPopupViewMac::ElideString(as, contents16, font_, kWide);
485   EXPECT_TRUE(ret == as);
486   EXPECT_TRUE([[as string] isEqualToString:contents]);
487
488   // When elided, result is the same as ElideText().
489   ret = OmniboxPopupViewMac::ElideString(as, contents16, font_, kNarrow);
490   string16 elided =
491       gfx::ElideText(contents16, font_, kNarrow, gfx::ELIDE_AT_END);
492   EXPECT_TRUE(ret == as);
493   EXPECT_FALSE([[as string] isEqualToString:contents]);
494   EXPECT_TRUE([[as string] isEqualToString:base::SysUTF16ToNSString(elided)]);
495
496   // When elided, result is the same as ElideText().
497   ret = OmniboxPopupViewMac::ElideString(as, contents16, font_, 0.0);
498   elided = gfx::ElideText(contents16, font_, 0.0, gfx::ELIDE_AT_END);
499   EXPECT_TRUE(ret == as);
500   EXPECT_FALSE([[as string] isEqualToString:contents]);
501   EXPECT_TRUE([[as string] isEqualToString:base::SysUTF16ToNSString(elided)]);
502 }
503
504 TEST_F(OmniboxPopupViewMacTest, MatchTextElide) {
505   NSString* const contents = @"This is a test with long contents";
506   NSString* const description = @"That was a test";
507   // Match "long".
508   const NSUInteger run_length_1 = 20, run_length_2 = 4, run_length_3 = 9;
509   // Make sure nobody messed up the inputs.
510   EXPECT_EQ(run_length_1 + run_length_2 + run_length_3, [contents length]);
511
512   AutocompleteMatch m = MakeMatch(base::SysNSStringToUTF16(contents),
513                                   base::SysNSStringToUTF16(description));
514
515   // Push each run onto contents classifications.
516   m.contents_class.push_back(
517       ACMatchClassification(0, ACMatchClassification::NONE));
518   m.contents_class.push_back(
519       ACMatchClassification(run_length_1, ACMatchClassification::MATCH));
520   m.contents_class.push_back(
521       ACMatchClassification(run_length_1 + run_length_2,
522                             ACMatchClassification::URL));
523
524   // Figure out the width of the contents.
525   NSDictionary* attributes =
526       [NSDictionary dictionaryWithObject:font_.GetNativeFont()
527                                   forKey:NSFontAttributeName];
528   const float contentsWidth = [contents sizeWithAttributes:attributes].width;
529
530   // After accounting for the width of the image, this will force us
531   // to elide the contents.
532   float cellWidth = ceil(contentsWidth / 0.7);
533
534   NSAttributedString* decorated =
535       OmniboxPopupViewMac::MatchText(m, font_, cellWidth);
536
537   // Results contain a prefix of the contents and all of description.
538   NSString* commonPrefix =
539       [[decorated string] commonPrefixWithString:contents options:0];
540   EXPECT_GT([commonPrefix length], 0U);
541   EXPECT_LT([commonPrefix length], [contents length]);
542   EXPECT_TRUE([[decorated string] hasSuffix:description]);
543
544   // At one point the code had a bug where elided text was being
545   // marked up using pre-elided offsets, resulting in out-of-range
546   // values being passed to NSAttributedString.  Push the ellipsis
547   // through part of each run to verify that we don't continue to see
548   // such things.
549   while([commonPrefix length] > run_length_1 - 3) {
550     EXPECT_GT(cellWidth, 0.0);
551     cellWidth -= 1.0;
552     decorated = OmniboxPopupViewMac::MatchText(m, font_, cellWidth);
553     commonPrefix =
554         [[decorated string] commonPrefixWithString:contents options:0];
555     ASSERT_GT([commonPrefix length], 0U);
556   }
557 }
558
559 TEST_F(OmniboxPopupViewMacTest, UpdatePopupAppearance) {
560   base::scoped_nsobject<NSTextField> field(
561       [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 20)]);
562   [[test_window() contentView] addSubview:field];
563
564   OmniboxViewMac view(NULL, profile(), NULL, NULL);
565   MockOmniboxPopupViewMac popup_view(&view, view.model(), field);
566
567   popup_view.UpdatePopupAppearance();
568   EXPECT_FALSE(popup_view.IsOpen());
569   EXPECT_EQ(0, [popup_view.matrix() numberOfRows]);
570
571   popup_view.SetResultCount(3);
572   popup_view.UpdatePopupAppearance();
573   EXPECT_TRUE(popup_view.IsOpen());
574   EXPECT_EQ(3, [popup_view.matrix() numberOfRows]);
575
576   int old_height = popup_view.GetTargetBounds().height();
577   popup_view.SetResultCount(5);
578   popup_view.UpdatePopupAppearance();
579   EXPECT_GT(popup_view.GetTargetBounds().height(), old_height);
580   EXPECT_EQ(5, [popup_view.matrix() numberOfRows]);
581
582   popup_view.SetResultCount(0);
583   popup_view.UpdatePopupAppearance();
584   EXPECT_FALSE(popup_view.IsOpen());
585   EXPECT_EQ(0, [popup_view.matrix() numberOfRows]);
586 }
587
588 }  // namespace