Home | History | Annotate | Download | only in bubble
      1 // Copyright (c) 2011 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 #include "chrome/browser/ui/views/bubble/border_contents.h"
      6 #include "testing/gtest/include/gtest/gtest.h"
      7 
      8 typedef testing::Test BorderContentsTest;
      9 
     10 class TestBorderContents : public BorderContents {
     11  public:
     12   TestBorderContents() {}
     13 
     14   void set_monitor_bounds(const gfx::Rect& bounds) {
     15     monitor_bounds_ = bounds;
     16   }
     17 
     18   BubbleBorder* bubble_border() const { return bubble_border_; }
     19 
     20  protected:
     21   virtual gfx::Rect GetMonitorBounds(const gfx::Rect& rect) {
     22     return monitor_bounds_;
     23   }
     24 
     25  private:
     26   gfx::Rect monitor_bounds_;
     27 
     28   DISALLOW_COPY_AND_ASSIGN(TestBorderContents);
     29 };
     30 
     31 // Tests that the arrow is moved appropriately when the info-bubble does not fit
     32 // the screen.
     33 TEST_F(BorderContentsTest, BorderContentsSizeAndGetBounds) {
     34   TestBorderContents border_contents;
     35   border_contents.Init();
     36 
     37   // Test that the info bubble displays normally when it fits.
     38   gfx::Rect contents_bounds;
     39   gfx::Rect window_bounds;
     40   border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000));
     41   border_contents.SizeAndGetBounds(
     42       gfx::Rect(100, 100, 50, 50),  // |position_relative_to|
     43       BubbleBorder::TOP_LEFT,
     44       false,                        // |allow_bubble_offscreen|
     45       gfx::Size(500, 500),          // |contents_size|
     46       &contents_bounds, &window_bounds);
     47   // The arrow shouldn't have changed from TOP_LEFT.
     48   BubbleBorder::ArrowLocation arrow_location =
     49       border_contents.bubble_border()->arrow_location();
     50   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
     51   EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location));
     52   EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location));
     53   EXPECT_GT(window_bounds.x(), 100);
     54   EXPECT_GT(window_bounds.y(), 100 + 50 - 10);  // -10 to roughly compensate for
     55                                                 // arrow overlap.
     56 
     57   // Test bubble not fitting on left.
     58   border_contents.SizeAndGetBounds(
     59       gfx::Rect(100, 100, 50, 50),  // |position_relative_to|
     60       BubbleBorder::TOP_RIGHT,
     61       false,                        // |allow_bubble_offscreen|
     62       gfx::Size(500, 500),          // |contents_size|
     63       &contents_bounds, &window_bounds);
     64   arrow_location = border_contents.bubble_border()->arrow_location();
     65   // The arrow should have changed to TOP_LEFT.
     66   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
     67   EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location));
     68   EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location));
     69   EXPECT_GT(window_bounds.x(), 100);
     70   EXPECT_GT(window_bounds.y(), 100 + 50 - 10);  // -10 to roughly compensate for
     71                                                 // arrow overlap.
     72 
     73   // Test bubble not fitting on left or top.
     74   border_contents.SizeAndGetBounds(
     75       gfx::Rect(100, 100, 50, 50),  // |position_relative_to|
     76       BubbleBorder::BOTTOM_RIGHT,
     77       false,                        // |allow_bubble_offscreen|
     78       gfx::Size(500, 500),          // |contents_size|
     79       &contents_bounds, &window_bounds);
     80   arrow_location = border_contents.bubble_border()->arrow_location();
     81   // The arrow should have changed to TOP_LEFT.
     82   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
     83   EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location));
     84   EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location));
     85   EXPECT_GT(window_bounds.x(), 100);
     86   EXPECT_GT(window_bounds.y(), 100 + 50 - 10);  // -10 to roughly compensate for
     87                                                 // arrow overlap.
     88 
     89   // Test bubble not fitting on top.
     90   border_contents.SizeAndGetBounds(
     91       gfx::Rect(100, 100, 50, 50),  // |position_relative_to|
     92       BubbleBorder::BOTTOM_LEFT,
     93       false,                        // |allow_bubble_offscreen|
     94       gfx::Size(500, 500),          // |contents_size|
     95       &contents_bounds, &window_bounds);
     96   arrow_location = border_contents.bubble_border()->arrow_location();
     97   // The arrow should have changed to TOP_LEFT.
     98   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
     99   EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location));
    100   EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location));
    101   EXPECT_GT(window_bounds.x(), 100);
    102   EXPECT_GT(window_bounds.y(), 100 + 50 - 10);  // -10 to roughly compensate for
    103                                                 // arrow overlap.
    104 
    105   // Test bubble not fitting on top and right.
    106   border_contents.SizeAndGetBounds(
    107       gfx::Rect(900, 100, 50, 50),  // |position_relative_to|
    108       BubbleBorder::BOTTOM_LEFT,
    109       false,                        // |allow_bubble_offscreen|
    110       gfx::Size(500, 500),          // |contents_size|
    111       &contents_bounds, &window_bounds);
    112   arrow_location = border_contents.bubble_border()->arrow_location();
    113   // The arrow should have changed to TOP_RIGHT.
    114   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
    115   EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location));
    116   EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location));
    117   EXPECT_LT(window_bounds.x(), 900 + 50 - 500);
    118   EXPECT_GT(window_bounds.y(), 100 + 50 - 10);  // -10 to roughly compensate for
    119                                                 // arrow overlap.
    120 
    121  // Test bubble not fitting on right.
    122   border_contents.SizeAndGetBounds(
    123       gfx::Rect(900, 100, 50, 50),  // |position_relative_to|
    124       BubbleBorder::TOP_LEFT,
    125       false,                        // |allow_bubble_offscreen|
    126       gfx::Size(500, 500),          // |contents_size|
    127       &contents_bounds, &window_bounds);
    128   arrow_location = border_contents.bubble_border()->arrow_location();
    129   // The arrow should have changed to TOP_RIGHT.
    130   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
    131   EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location));
    132   EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location));
    133   EXPECT_LT(window_bounds.x(), 900 + 50 - 500);
    134   EXPECT_GT(window_bounds.y(), 100 + 50 - 10);  // -10 to roughly compensate for
    135                                                 // arrow overlap.
    136 
    137   // Test bubble not fitting on bottom and right.
    138   border_contents.SizeAndGetBounds(
    139       gfx::Rect(900, 900, 50, 50),  // |position_relative_to|
    140       BubbleBorder::TOP_LEFT,
    141       false,                        // |allow_bubble_offscreen|
    142       gfx::Size(500, 500),          // |contents_size|
    143       &contents_bounds, &window_bounds);
    144   arrow_location = border_contents.bubble_border()->arrow_location();
    145   // The arrow should have changed to BOTTOM_RIGHT.
    146   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
    147   EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location));
    148   EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location));
    149   EXPECT_LT(window_bounds.x(), 900 + 50 - 500);
    150   EXPECT_LT(window_bounds.y(), 900 - 500 - 15);  // -15 to roughly compensate
    151                                                  // for arrow height.
    152 
    153   // Test bubble not fitting at the bottom.
    154   border_contents.SizeAndGetBounds(
    155       gfx::Rect(100, 900, 50, 50),  // |position_relative_to|
    156       BubbleBorder::TOP_LEFT,
    157       false,                        // |allow_bubble_offscreen|
    158       gfx::Size(500, 500),          // |contents_size|
    159       &contents_bounds, &window_bounds);
    160   arrow_location = border_contents.bubble_border()->arrow_location();
    161   // The arrow should have changed to BOTTOM_LEFT.
    162   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
    163   EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location));
    164   EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location));
    165   // The window should be right aligned with the position_relative_to.
    166   EXPECT_LT(window_bounds.x(), 900 + 50 - 500);
    167   EXPECT_LT(window_bounds.y(), 900 - 500 - 15);  // -15 to roughly compensate
    168                                                  // for arrow height.
    169 
    170   // Test bubble not fitting at the bottom and left.
    171   border_contents.SizeAndGetBounds(
    172       gfx::Rect(100, 900, 50, 50),  // |position_relative_to|
    173       BubbleBorder::TOP_RIGHT,
    174       false,                        // |allow_bubble_offscreen|
    175       gfx::Size(500, 500),          // |contents_size|
    176       &contents_bounds, &window_bounds);
    177   arrow_location = border_contents.bubble_border()->arrow_location();
    178   // The arrow should have changed to BOTTOM_LEFT.
    179   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
    180   EXPECT_FALSE(BubbleBorder::is_arrow_on_top(arrow_location));
    181   EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location));
    182   // The window should be right aligned with the position_relative_to.
    183   EXPECT_LT(window_bounds.x(), 900 + 50 - 500);
    184   EXPECT_LT(window_bounds.y(), 900 - 500 - 15);  // -15 to roughly compensate
    185                                                  // for arrow height.
    186 }
    187 
    188 // Tests that the arrow is not moved when the info-bubble does not fit the
    189 // screen but moving it would make matter worse.
    190 TEST_F(BorderContentsTest, BorderContentsSizeAndGetBoundsDontMoveArrow) {
    191   TestBorderContents border_contents;
    192   border_contents.Init();
    193   gfx::Rect contents_bounds;
    194   gfx::Rect window_bounds;
    195   border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000));
    196   border_contents.SizeAndGetBounds(
    197       gfx::Rect(400, 100, 50, 50),  // |position_relative_to|
    198       BubbleBorder::TOP_LEFT,
    199       false,                        // |allow_bubble_offscreen|
    200       gfx::Size(500, 700),          // |contents_size|
    201       &contents_bounds, &window_bounds);
    202 
    203   // The arrow should not have changed, as it would make it the bubble even more
    204   // offscreen.
    205   BubbleBorder::ArrowLocation arrow_location =
    206       border_contents.bubble_border()->arrow_location();
    207   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
    208   EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location));
    209   EXPECT_TRUE(BubbleBorder::is_arrow_on_left(arrow_location));
    210 }
    211 
    212 // Test that the 'allow offscreen' prevents the bubble from moving.
    213 TEST_F(BorderContentsTest, BorderContentsSizeAndGetBoundsAllowOffscreen) {
    214   TestBorderContents border_contents;
    215   border_contents.Init();
    216   gfx::Rect contents_bounds;
    217   gfx::Rect window_bounds;
    218   border_contents.set_monitor_bounds(gfx::Rect(0, 0, 1000, 1000));
    219   border_contents.SizeAndGetBounds(
    220       gfx::Rect(100, 900, 50, 50),  // |position_relative_to|
    221       BubbleBorder::TOP_RIGHT,
    222       true,                         // |allow_bubble_offscreen|
    223       gfx::Size(500, 500),          // |contents_size|
    224       &contents_bounds, &window_bounds);
    225 
    226   // The arrow should not have changed (eventhough the bubble does not fit).
    227   BubbleBorder::ArrowLocation arrow_location =
    228       border_contents.bubble_border()->arrow_location();
    229   EXPECT_TRUE(BubbleBorder::has_arrow(arrow_location));
    230   EXPECT_TRUE(BubbleBorder::is_arrow_on_top(arrow_location));
    231   EXPECT_FALSE(BubbleBorder::is_arrow_on_left(arrow_location));
    232   // The coordinates should be pointing to 'positive relative to' from
    233   // TOP_RIGHT.
    234   EXPECT_LT(window_bounds.x(), 100 + 50 - 500);
    235   EXPECT_GT(window_bounds.y(), 900 + 50 - 10);  // -10 to roughly compensate for
    236                                                 // arrow overlap.
    237 }
    238