| 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 |