Home | History | Annotate | Download | only in window
      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 #include "base/basictypes.h"
      6 #include "base/strings/utf_string_conversions.h"
      7 #include "testing/gtest/include/gtest/gtest.h"
      8 #include "ui/base/ui_base_types.h"
      9 #include "ui/views/controls/button/label_button.h"
     10 #include "ui/views/test/test_views.h"
     11 #include "ui/views/window/dialog_client_view.h"
     12 #include "ui/views/window/dialog_delegate.h"
     13 
     14 namespace views {
     15 
     16 class TestDialogClientView : public DialogClientView {
     17  public:
     18   TestDialogClientView(View* contents_view,
     19                        DialogDelegate* dialog_delegate)
     20       : DialogClientView(contents_view),
     21         dialog_(dialog_delegate) {}
     22   virtual ~TestDialogClientView() {}
     23 
     24   // DialogClientView implementation.
     25   virtual DialogDelegate* GetDialogDelegate() const OVERRIDE { return dialog_; }
     26 
     27   View* GetContentsView() { return contents_view(); }
     28 
     29   void CreateExtraViews() {
     30     CreateExtraView();
     31     CreateFootnoteView();
     32   }
     33 
     34  private:
     35   DialogDelegate* dialog_;
     36 
     37   DISALLOW_COPY_AND_ASSIGN(TestDialogClientView);
     38 };
     39 
     40 class DialogClientViewTest : public testing::Test,
     41                              public DialogDelegateView {
     42  public:
     43   DialogClientViewTest()
     44       : dialog_buttons_(ui::DIALOG_BUTTON_NONE),
     45         extra_view_(NULL),
     46         footnote_view_(NULL) {}
     47   virtual ~DialogClientViewTest() {}
     48 
     49   // testing::Test implementation.
     50   virtual void SetUp() OVERRIDE {
     51     dialog_buttons_ = ui::DIALOG_BUTTON_NONE;
     52     contents_.reset(new StaticSizedView(gfx::Size(100, 200)));
     53     client_view_.reset(new TestDialogClientView(contents_.get(), this));
     54   }
     55 
     56   // DialogDelegateView implementation.
     57   virtual View* GetContentsView() OVERRIDE { return contents_.get(); }
     58   virtual View* CreateExtraView() OVERRIDE { return extra_view_; }
     59   virtual View* CreateFootnoteView() OVERRIDE { return footnote_view_; }
     60   virtual int GetDialogButtons() const OVERRIDE { return dialog_buttons_; }
     61 
     62  protected:
     63   gfx::Rect GetUpdatedClientBounds() {
     64     client_view_->SizeToPreferredSize();
     65     client_view_->Layout();
     66     return client_view_->bounds();
     67   }
     68 
     69   // Makes sure that the content view is sized correctly. Width must be at least
     70   // the requested amount, but height should always match exactly.
     71   void CheckContentsIsSetToPreferredSize() {
     72     const gfx::Rect client_bounds = GetUpdatedClientBounds();
     73     const gfx::Size preferred_size = contents_->GetPreferredSize();
     74     EXPECT_EQ(preferred_size.height(), contents_->bounds().height());
     75     EXPECT_LE(preferred_size.width(), contents_->bounds().width());
     76     EXPECT_EQ(contents_->bounds().origin(), client_bounds.origin());
     77     EXPECT_EQ(contents_->bounds().right(), client_bounds.right());
     78   }
     79 
     80   // Sets the buttons to show in the dialog and refreshes the dialog.
     81   void SetDialogButtons(int dialog_buttons) {
     82     dialog_buttons_ = dialog_buttons;
     83     client_view_->UpdateDialogButtons();
     84   }
     85 
     86   // Sets the extra view.
     87   void SetExtraView(View* view) {
     88     DCHECK(!extra_view_);
     89     extra_view_ = view;
     90     client_view_->CreateExtraViews();
     91   }
     92 
     93   // Sets the footnote view.
     94   void SetFootnoteView(View* view) {
     95     DCHECK(!footnote_view_);
     96     footnote_view_ = view;
     97     client_view_->CreateExtraViews();
     98   }
     99 
    100   TestDialogClientView* client_view() { return client_view_.get(); }
    101 
    102  private:
    103   // The contents of the dialog.
    104   scoped_ptr<View> contents_;
    105   // The DialogClientView that's being tested.
    106   scoped_ptr<TestDialogClientView> client_view_;
    107   // The bitmask of buttons to show in the dialog.
    108   int dialog_buttons_;
    109   View* extra_view_;  // weak
    110   View* footnote_view_;  // weak
    111 
    112   DISALLOW_COPY_AND_ASSIGN(DialogClientViewTest);
    113 };
    114 
    115 TEST_F(DialogClientViewTest, UpdateButtons) {
    116   // This dialog should start with no buttons.
    117   EXPECT_EQ(GetDialogButtons(), ui::DIALOG_BUTTON_NONE);
    118   EXPECT_EQ(NULL, client_view()->ok_button());
    119   EXPECT_EQ(NULL, client_view()->cancel_button());
    120   const int height_without_buttons = GetUpdatedClientBounds().height();
    121 
    122   // Update to use both buttons.
    123   SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
    124   EXPECT_TRUE(client_view()->ok_button()->is_default());
    125   EXPECT_FALSE(client_view()->cancel_button()->is_default());
    126   const int height_with_buttons = GetUpdatedClientBounds().height();
    127   EXPECT_GT(height_with_buttons, height_without_buttons);
    128 
    129   // Remove the dialog buttons.
    130   SetDialogButtons(ui::DIALOG_BUTTON_NONE);
    131   EXPECT_EQ(NULL, client_view()->ok_button());
    132   EXPECT_EQ(NULL, client_view()->cancel_button());
    133   EXPECT_EQ(GetUpdatedClientBounds().height(), height_without_buttons);
    134 
    135   // Reset with just an ok button.
    136   SetDialogButtons(ui::DIALOG_BUTTON_OK);
    137   EXPECT_TRUE(client_view()->ok_button()->is_default());
    138   EXPECT_EQ(NULL, client_view()->cancel_button());
    139   EXPECT_EQ(GetUpdatedClientBounds().height(), height_with_buttons);
    140 
    141   // Reset with just a cancel button.
    142   SetDialogButtons(ui::DIALOG_BUTTON_CANCEL);
    143   EXPECT_EQ(NULL, client_view()->ok_button());
    144   EXPECT_TRUE(client_view()->cancel_button()->is_default());
    145   EXPECT_EQ(GetUpdatedClientBounds().height(), height_with_buttons);
    146 }
    147 
    148 TEST_F(DialogClientViewTest, RemoveAndUpdateButtons) {
    149   // Removing buttons from another context should clear the local pointer.
    150   SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
    151   delete client_view()->ok_button();
    152   EXPECT_EQ(NULL, client_view()->ok_button());
    153   delete client_view()->cancel_button();
    154   EXPECT_EQ(NULL, client_view()->cancel_button());
    155 
    156   // Updating should restore the requested buttons properly.
    157   SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
    158   EXPECT_TRUE(client_view()->ok_button()->is_default());
    159   EXPECT_FALSE(client_view()->cancel_button()->is_default());
    160 }
    161 
    162 // Test that the contents view gets its preferred size in the basic dialog
    163 // configuration.
    164 TEST_F(DialogClientViewTest, ContentsSize) {
    165   CheckContentsIsSetToPreferredSize();
    166   EXPECT_EQ(GetContentsView()->bounds().bottom(),
    167             client_view()->bounds().bottom());
    168 }
    169 
    170 // Test the effect of the button strip on layout.
    171 TEST_F(DialogClientViewTest, LayoutWithButtons) {
    172   SetDialogButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
    173   CheckContentsIsSetToPreferredSize();
    174   EXPECT_LT(GetContentsView()->bounds().bottom(),
    175             client_view()->bounds().bottom());
    176   gfx::Size no_extra_view_size = client_view()->bounds().size();
    177 
    178   View* extra_view = new StaticSizedView(gfx::Size(200, 200));
    179   SetExtraView(extra_view);
    180   CheckContentsIsSetToPreferredSize();
    181   EXPECT_GT(client_view()->bounds().height(), no_extra_view_size.height());
    182   int width_of_extra_view = extra_view->bounds().width();
    183 
    184   // Visibility of extra view is respected.
    185   extra_view->SetVisible(false);
    186   CheckContentsIsSetToPreferredSize();
    187   EXPECT_EQ(no_extra_view_size.height(), client_view()->bounds().height());
    188   EXPECT_EQ(no_extra_view_size.width(), client_view()->bounds().width());
    189 
    190   // Try with a reduced-size dialog.
    191   extra_view->SetVisible(true);
    192   client_view()->SetBoundsRect(gfx::Rect(gfx::Point(0, 0), no_extra_view_size));
    193   client_view()->Layout();
    194   DCHECK_GT(width_of_extra_view, extra_view->bounds().width());
    195 }
    196 
    197 // Test the effect of the footnote view on layout.
    198 TEST_F(DialogClientViewTest, LayoutWithFootnote) {
    199   CheckContentsIsSetToPreferredSize();
    200   gfx::Size no_footnote_size = client_view()->bounds().size();
    201 
    202   View* footnote_view = new StaticSizedView(gfx::Size(200, 200));
    203   SetFootnoteView(footnote_view);
    204   CheckContentsIsSetToPreferredSize();
    205   EXPECT_GT(client_view()->bounds().height(), no_footnote_size.height());
    206   EXPECT_EQ(200, footnote_view->bounds().height());
    207   gfx::Size with_footnote_size = client_view()->bounds().size();
    208   EXPECT_EQ(with_footnote_size.width(), footnote_view->bounds().width());
    209 
    210   SetDialogButtons(ui::DIALOG_BUTTON_CANCEL);
    211   CheckContentsIsSetToPreferredSize();
    212   EXPECT_LE(with_footnote_size.height(), client_view()->bounds().height());
    213   EXPECT_LE(with_footnote_size.width(), client_view()->bounds().width());
    214   gfx::Size with_footnote_and_button_size = client_view()->bounds().size();
    215 
    216   SetDialogButtons(ui::DIALOG_BUTTON_NONE);
    217   footnote_view->SetVisible(false);
    218   CheckContentsIsSetToPreferredSize();
    219   EXPECT_EQ(no_footnote_size.height(), client_view()->bounds().height());
    220   EXPECT_EQ(no_footnote_size.width(), client_view()->bounds().width());
    221 }
    222 
    223 // Test that GetHeightForWidth is respected for the footnote view.
    224 TEST_F(DialogClientViewTest, LayoutWithFootnoteHeightForWidth) {
    225   CheckContentsIsSetToPreferredSize();
    226   gfx::Size no_footnote_size = client_view()->bounds().size();
    227 
    228   View* footnote_view = new ProportionallySizedView(3);
    229   SetFootnoteView(footnote_view);
    230   CheckContentsIsSetToPreferredSize();
    231   EXPECT_GT(client_view()->bounds().height(), no_footnote_size.height());
    232   EXPECT_EQ(footnote_view->bounds().width() * 3,
    233             footnote_view->bounds().height());
    234 }
    235 
    236 }  // namespace views
    237