OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.h" | 5 #import "chrome/browser/ui/cocoa/omnibox/omnibox_popup_view_mac.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/strings/sys_string_conversions.h" | 8 #include "base/strings/sys_string_conversions.h" |
9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
10 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" | 10 #include "chrome/browser/ui/cocoa/cocoa_profile_test.h" |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1, | 320 EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1, |
321 NSFontAttributeName), run_length_2); | 321 NSFontAttributeName), run_length_2); |
322 EXPECT_TRUE(RunHasFontTrait(decorated, run_length_1, NSBoldFontMask)); | 322 EXPECT_TRUE(RunHasFontTrait(decorated, run_length_1, NSBoldFontMask)); |
323 | 323 |
324 EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1 + run_length_2, | 324 EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1 + run_length_2, |
325 NSFontAttributeName), run_length_3); | 325 NSFontAttributeName), run_length_3); |
326 EXPECT_FALSE(RunHasFontTrait(decorated, run_length_1 + run_length_2, | 326 EXPECT_FALSE(RunHasFontTrait(decorated, run_length_1 + run_length_2, |
327 NSBoldFontMask)); | 327 NSBoldFontMask)); |
328 } | 328 } |
329 | 329 |
330 // Check that matches with both contents and description come back | |
331 // with contents at the beginning, description at the end, and | |
332 // something separating them. Not being specific about the separator | |
333 // on purpose, in case it changes. | |
334 TEST_F(OmniboxPopupViewMacTest, MatchText) { | |
335 NSString* const contents = @"contents"; | |
336 NSString* const description = @"description"; | |
337 AutocompleteMatch m = MakeMatch(base::SysNSStringToUTF16(contents), | |
338 base::SysNSStringToUTF16(description)); | |
339 | |
340 NSAttributedString* decorated = | |
341 OmniboxPopupViewMac::MatchText(m, font_, kLargeWidth); | |
342 | |
343 // Result contains the characters of the input in the right places. | |
344 EXPECT_GT([decorated length], [contents length] + [description length]); | |
345 EXPECT_TRUE([[decorated string] hasPrefix:contents]); | |
346 EXPECT_TRUE([[decorated string] hasSuffix:description]); | |
347 | |
348 // Check that the description is a different color from the | |
349 // contents. | |
350 const NSUInteger descriptionLocation = | |
351 [decorated length] - [description length]; | |
352 EXPECT_EQ(RunLengthForAttribute(decorated, 0U, | |
353 NSForegroundColorAttributeName), | |
354 descriptionLocation); | |
355 EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation, | |
356 NSForegroundColorAttributeName), | |
357 [description length]); | |
358 | |
359 // Same font all the way through, nothing bold. | |
360 EXPECT_EQ(RunLengthForAttribute(decorated, 0U, | |
361 NSFontAttributeName), [decorated length]); | |
362 EXPECT_FALSE(RunHasFontTrait(decorated, 0, NSBoldFontMask)); | |
363 } | |
364 | |
365 // Check that MatchText() styles content matches as expected. | |
366 TEST_F(OmniboxPopupViewMacTest, MatchTextContentsMatch) { | |
367 NSString* const contents = @"This is a test"; | |
368 // Match "is". | |
369 const NSUInteger run_length_1 = 5, run_length_2 = 2, run_length_3 = 7; | |
370 // Make sure nobody messed up the inputs. | |
371 EXPECT_EQ(run_length_1 + run_length_2 + run_length_3, [contents length]); | |
372 | |
373 AutocompleteMatch m = MakeMatch(base::SysNSStringToUTF16(contents), | |
374 string16()); | |
375 | |
376 // Push each run onto contents classifications. | |
377 m.contents_class.push_back( | |
378 ACMatchClassification(0, ACMatchClassification::NONE)); | |
379 m.contents_class.push_back( | |
380 ACMatchClassification(run_length_1, ACMatchClassification::MATCH)); | |
381 m.contents_class.push_back( | |
382 ACMatchClassification(run_length_1 + run_length_2, | |
383 ACMatchClassification::NONE)); | |
384 | |
385 NSAttributedString* decorated = | |
386 OmniboxPopupViewMac::MatchText(m, font_, kLargeWidth); | |
387 | |
388 // Result has same characters as the input. | |
389 EXPECT_EQ([decorated length], [contents length]); | |
390 EXPECT_TRUE([[decorated string] isEqualToString:contents]); | |
391 | |
392 // Result is all one color. | |
393 EXPECT_EQ(RunLengthForAttribute(decorated, 0U, | |
394 NSForegroundColorAttributeName), | |
395 [contents length]); | |
396 | |
397 // Should have three font runs, not bold, bold, then not bold again. | |
398 EXPECT_EQ(RunLengthForAttribute(decorated, 0U, | |
399 NSFontAttributeName), run_length_1); | |
400 EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask)); | |
401 | |
402 EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1, | |
403 NSFontAttributeName), run_length_2); | |
404 EXPECT_TRUE(RunHasFontTrait(decorated, run_length_1, NSBoldFontMask)); | |
405 | |
406 EXPECT_EQ(RunLengthForAttribute(decorated, run_length_1 + run_length_2, | |
407 NSFontAttributeName), run_length_3); | |
408 EXPECT_FALSE(RunHasFontTrait(decorated, run_length_1 + run_length_2, | |
409 NSBoldFontMask)); | |
410 } | |
411 | |
412 // Check that MatchText() styles description matches as expected. | |
413 TEST_F(OmniboxPopupViewMacTest, MatchTextDescriptionMatch) { | |
414 NSString* const contents = @"This is a test"; | |
415 NSString* const description = @"That was a test"; | |
416 // Match "That was". | |
417 const NSUInteger run_length_1 = 8, run_length_2 = 7; | |
418 // Make sure nobody messed up the inputs. | |
419 EXPECT_EQ(run_length_1 + run_length_2, [description length]); | |
420 | |
421 AutocompleteMatch m = MakeMatch(base::SysNSStringToUTF16(contents), | |
422 base::SysNSStringToUTF16(description)); | |
423 | |
424 // Push each run onto contents classifications. | |
425 m.description_class.push_back( | |
426 ACMatchClassification(0, ACMatchClassification::MATCH)); | |
427 m.description_class.push_back( | |
428 ACMatchClassification(run_length_1, ACMatchClassification::NONE)); | |
429 | |
430 NSAttributedString* decorated = | |
431 OmniboxPopupViewMac::MatchText(m, font_, kLargeWidth); | |
432 | |
433 // Result contains the characters of the input. | |
434 EXPECT_GT([decorated length], [contents length] + [description length]); | |
435 EXPECT_TRUE([[decorated string] hasPrefix:contents]); | |
436 EXPECT_TRUE([[decorated string] hasSuffix:description]); | |
437 | |
438 // Check that the description is a different color from the | |
439 // contents. | |
440 const NSUInteger descriptionLocation = | |
441 [decorated length] - [description length]; | |
442 EXPECT_EQ(RunLengthForAttribute(decorated, 0U, | |
443 NSForegroundColorAttributeName), | |
444 descriptionLocation); | |
445 EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation, | |
446 NSForegroundColorAttributeName), | |
447 [description length]); | |
448 | |
449 // Should have three font runs, not bold, bold, then not bold again. | |
450 // The first run is the contents and the separator, the second run | |
451 // is the first run of the description. | |
452 EXPECT_EQ(RunLengthForAttribute(decorated, 0U, | |
453 NSFontAttributeName), descriptionLocation); | |
454 EXPECT_FALSE(RunHasFontTrait(decorated, 0U, NSBoldFontMask)); | |
455 | |
456 EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation, | |
457 NSFontAttributeName), run_length_1); | |
458 EXPECT_TRUE(RunHasFontTrait(decorated, descriptionLocation, NSBoldFontMask)); | |
459 | |
460 EXPECT_EQ(RunLengthForAttribute(decorated, descriptionLocation + run_length_1, | |
461 NSFontAttributeName), run_length_2); | |
462 EXPECT_FALSE(RunHasFontTrait(decorated, descriptionLocation + run_length_1, | |
463 NSBoldFontMask)); | |
464 } | |
465 | |
466 TEST_F(OmniboxPopupViewMacTest, ElideString) { | |
467 NSString* const contents = @"This is a test with long contents"; | |
468 const string16 contents16(base::SysNSStringToUTF16(contents)); | |
469 | |
470 const float kWide = 1000.0; | |
471 const float kNarrow = 20.0; | |
472 | |
473 NSDictionary* attributes = | |
474 [NSDictionary dictionaryWithObject:font_.GetNativeFont() | |
475 forKey:NSFontAttributeName]; | |
476 base::scoped_nsobject<NSMutableAttributedString> as( | |
477 [[NSMutableAttributedString alloc] initWithString:contents | |
478 attributes:attributes]); | |
479 | |
480 // Nothing happens if the space is really wide. | |
481 NSMutableAttributedString* ret = | |
482 OmniboxPopupViewMac::ElideString(as, contents16, font_, kWide); | |
483 EXPECT_TRUE(ret == as); | |
484 EXPECT_TRUE([[as string] isEqualToString:contents]); | |
485 | |
486 // When elided, result is the same as ElideText(). | |
487 ret = OmniboxPopupViewMac::ElideString(as, contents16, font_, kNarrow); | |
488 string16 elided = ui::ElideText(contents16, font_, kNarrow, ui::ELIDE_AT_END); | |
489 EXPECT_TRUE(ret == as); | |
490 EXPECT_FALSE([[as string] isEqualToString:contents]); | |
491 EXPECT_TRUE([[as string] isEqualToString:base::SysUTF16ToNSString(elided)]); | |
492 | |
493 // When elided, result is the same as ElideText(). | |
494 ret = OmniboxPopupViewMac::ElideString(as, contents16, font_, 0.0); | |
495 elided = ui::ElideText(contents16, font_, 0.0, ui::ELIDE_AT_END); | |
496 EXPECT_TRUE(ret == as); | |
497 EXPECT_FALSE([[as string] isEqualToString:contents]); | |
498 EXPECT_TRUE([[as string] isEqualToString:base::SysUTF16ToNSString(elided)]); | |
499 } | |
500 | |
501 TEST_F(OmniboxPopupViewMacTest, MatchTextElide) { | |
502 NSString* const contents = @"This is a test with long contents"; | |
503 NSString* const description = @"That was a test"; | |
504 // Match "long". | |
505 const NSUInteger run_length_1 = 20, run_length_2 = 4, run_length_3 = 9; | |
506 // Make sure nobody messed up the inputs. | |
507 EXPECT_EQ(run_length_1 + run_length_2 + run_length_3, [contents length]); | |
508 | |
509 AutocompleteMatch m = MakeMatch(base::SysNSStringToUTF16(contents), | |
510 base::SysNSStringToUTF16(description)); | |
511 | |
512 // Push each run onto contents classifications. | |
513 m.contents_class.push_back( | |
514 ACMatchClassification(0, ACMatchClassification::NONE)); | |
515 m.contents_class.push_back( | |
516 ACMatchClassification(run_length_1, ACMatchClassification::MATCH)); | |
517 m.contents_class.push_back( | |
518 ACMatchClassification(run_length_1 + run_length_2, | |
519 ACMatchClassification::URL)); | |
520 | |
521 // Figure out the width of the contents. | |
522 NSDictionary* attributes = | |
523 [NSDictionary dictionaryWithObject:font_.GetNativeFont() | |
524 forKey:NSFontAttributeName]; | |
525 const float contentsWidth = [contents sizeWithAttributes:attributes].width; | |
526 | |
527 // After accounting for the width of the image, this will force us | |
528 // to elide the contents. | |
529 float cellWidth = ceil(contentsWidth / 0.7); | |
530 | |
531 NSAttributedString* decorated = | |
532 OmniboxPopupViewMac::MatchText(m, font_, cellWidth); | |
533 | |
534 // Results contain a prefix of the contents and all of description. | |
535 NSString* commonPrefix = | |
536 [[decorated string] commonPrefixWithString:contents options:0]; | |
537 EXPECT_GT([commonPrefix length], 0U); | |
538 EXPECT_LT([commonPrefix length], [contents length]); | |
539 EXPECT_TRUE([[decorated string] hasSuffix:description]); | |
540 | |
541 // At one point the code had a bug where elided text was being | |
542 // marked up using pre-elided offsets, resulting in out-of-range | |
543 // values being passed to NSAttributedString. Push the ellipsis | |
544 // through part of each run to verify that we don't continue to see | |
545 // such things. | |
546 while([commonPrefix length] > run_length_1 - 3) { | |
547 EXPECT_GT(cellWidth, 0.0); | |
548 cellWidth -= 1.0; | |
549 decorated = OmniboxPopupViewMac::MatchText(m, font_, cellWidth); | |
550 commonPrefix = | |
551 [[decorated string] commonPrefixWithString:contents options:0]; | |
552 ASSERT_GT([commonPrefix length], 0U); | |
553 } | |
554 } | |
555 | |
556 TEST_F(OmniboxPopupViewMacTest, UpdatePopupAppearance) { | 330 TEST_F(OmniboxPopupViewMacTest, UpdatePopupAppearance) { |
557 base::scoped_nsobject<NSTextField> field( | 331 base::scoped_nsobject<NSTextField> field( |
558 [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 20)]); | 332 [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 20)]); |
559 [[test_window() contentView] addSubview:field]; | 333 [[test_window() contentView] addSubview:field]; |
560 | 334 |
561 OmniboxViewMac view(NULL, NULL, profile(), NULL, NULL); | 335 OmniboxViewMac view(NULL, NULL, profile(), NULL, NULL); |
562 MockOmniboxPopupViewMac popup_view(&view, view.model(), field); | 336 MockOmniboxPopupViewMac popup_view(&view, view.model(), field); |
563 | 337 |
564 popup_view.UpdatePopupAppearance(); | 338 popup_view.UpdatePopupAppearance(); |
565 EXPECT_FALSE(popup_view.IsOpen()); | 339 EXPECT_FALSE(popup_view.IsOpen()); |
(...skipping 10 matching lines...) Expand all Loading... |
576 EXPECT_GT(popup_view.GetTargetBounds().height(), old_height); | 350 EXPECT_GT(popup_view.GetTargetBounds().height(), old_height); |
577 EXPECT_EQ(5, [popup_view.matrix() numberOfRows]); | 351 EXPECT_EQ(5, [popup_view.matrix() numberOfRows]); |
578 | 352 |
579 popup_view.SetResultCount(0); | 353 popup_view.SetResultCount(0); |
580 popup_view.UpdatePopupAppearance(); | 354 popup_view.UpdatePopupAppearance(); |
581 EXPECT_FALSE(popup_view.IsOpen()); | 355 EXPECT_FALSE(popup_view.IsOpen()); |
582 EXPECT_EQ(0, [popup_view.matrix() numberOfRows]); | 356 EXPECT_EQ(0, [popup_view.matrix() numberOfRows]); |
583 } | 357 } |
584 | 358 |
585 } // namespace | 359 } // namespace |
OLD | NEW |