Home | History | Annotate | Download | only in gtk
      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 "base/message_loop.h"
      6 #include "chrome/browser/ui/gtk/reload_button_gtk.h"
      7 #include "testing/gtest/include/gtest/gtest.h"
      8 
      9 class ReloadButtonGtkTest : public testing::Test {
     10  public:
     11   ReloadButtonGtkTest();
     12 
     13   void CheckState(bool enabled,
     14                   ReloadButtonGtk::Mode intended_mode,
     15                   ReloadButtonGtk::Mode visible_mode,
     16                   bool double_click_timer_running,
     17                   bool stop_to_reload_timer_running);
     18 
     19   // These accessors eliminate the need to declare each testcase as a friend.
     20   void set_mouse_hovered(bool hovered) {
     21     reload_.testing_mouse_hovered_ = hovered;
     22   }
     23   int reload_count() { return reload_.testing_reload_count_; }
     24   void fake_mouse_leave() { reload_.OnLeaveNotify(reload_.widget(), NULL); }
     25 
     26  protected:
     27   // We need a message loop for the timers to post events.
     28   MessageLoop loop_;
     29 
     30   ReloadButtonGtk reload_;
     31 };
     32 
     33 ReloadButtonGtkTest::ReloadButtonGtkTest() : reload_(NULL, NULL) {
     34   // Set the timer delays to 0 so that timers will fire as soon as we tell the
     35   // message loop to run pending tasks.
     36   reload_.double_click_timer_delay_ = base::TimeDelta();
     37   reload_.stop_to_reload_timer_delay_ = base::TimeDelta();
     38 }
     39 
     40 void ReloadButtonGtkTest::CheckState(bool enabled,
     41                                      ReloadButtonGtk::Mode intended_mode,
     42                                      ReloadButtonGtk::Mode visible_mode,
     43                                      bool double_click_timer_running,
     44                                      bool stop_to_reload_timer_running) {
     45   EXPECT_NE(enabled, reload_.stop_.paint_override() == GTK_STATE_INSENSITIVE);
     46   EXPECT_EQ(intended_mode, reload_.intended_mode_);
     47   EXPECT_EQ(visible_mode, reload_.visible_mode_);
     48   EXPECT_EQ(double_click_timer_running,
     49             reload_.double_click_timer_.IsRunning());
     50   EXPECT_EQ(stop_to_reload_timer_running,
     51             reload_.stop_to_reload_timer_.IsRunning());
     52 }
     53 
     54 TEST_F(ReloadButtonGtkTest, Basic) {
     55   // The stop/reload button starts in the "enabled reload" state with no timers
     56   // running.
     57   CheckState(true, ReloadButtonGtk::MODE_RELOAD, ReloadButtonGtk::MODE_RELOAD,
     58              false, false);
     59 
     60   // Press the button.  This should start the double-click timer.
     61   gtk_button_clicked(GTK_BUTTON(reload_.widget()));
     62   CheckState(true, ReloadButtonGtk::MODE_RELOAD, ReloadButtonGtk::MODE_RELOAD,
     63              true, false);
     64 
     65   // Now change the mode (as if the browser had started loading the page).  This
     66   // should cancel the double-click timer since the button is not hovered.
     67   reload_.ChangeMode(ReloadButtonGtk::MODE_STOP, false);
     68   CheckState(true, ReloadButtonGtk::MODE_STOP, ReloadButtonGtk::MODE_STOP,
     69              false, false);
     70 
     71   // Press the button again.  This should change back to reload.
     72   gtk_button_clicked(GTK_BUTTON(reload_.widget()));
     73   CheckState(true, ReloadButtonGtk::MODE_RELOAD, ReloadButtonGtk::MODE_RELOAD,
     74              false, false);
     75 }
     76 
     77 TEST_F(ReloadButtonGtkTest, DoubleClickTimer) {
     78   // Start by pressing the button.
     79   gtk_button_clicked(GTK_BUTTON(reload_.widget()));
     80 
     81   // Try to press the button again.  This should do nothing because the timer is
     82   // running.
     83   int original_reload_count = reload_count();
     84   gtk_button_clicked(GTK_BUTTON(reload_.widget()));
     85   CheckState(true, ReloadButtonGtk::MODE_RELOAD, ReloadButtonGtk::MODE_RELOAD,
     86              true, false);
     87   EXPECT_EQ(original_reload_count, reload_count());
     88 
     89   // Hover the button, and change mode.  The visible mode should not change,
     90   // again because the timer is running.
     91   set_mouse_hovered(true);
     92   reload_.ChangeMode(ReloadButtonGtk::MODE_STOP, false);
     93   CheckState(true, ReloadButtonGtk::MODE_STOP, ReloadButtonGtk::MODE_RELOAD,
     94              true, false);
     95 
     96   // Now fire the timer.  This should complete the mode change.
     97   loop_.RunAllPending();
     98   CheckState(true, ReloadButtonGtk::MODE_STOP, ReloadButtonGtk::MODE_STOP,
     99              false, false);
    100 }
    101 
    102 TEST_F(ReloadButtonGtkTest, DisableOnHover) {
    103   // Change to stop and hover.
    104   gtk_button_clicked(GTK_BUTTON(reload_.widget()));
    105   reload_.ChangeMode(ReloadButtonGtk::MODE_STOP, false);
    106   set_mouse_hovered(true);
    107 
    108   // Now change back to reload.  This should result in a disabled stop button
    109   // due to the hover.
    110   reload_.ChangeMode(ReloadButtonGtk::MODE_RELOAD, false);
    111   CheckState(false, ReloadButtonGtk::MODE_RELOAD, ReloadButtonGtk::MODE_STOP,
    112              false, true);
    113 
    114   // Un-hover the button, which should allow it to reset.
    115   set_mouse_hovered(false);
    116   fake_mouse_leave();
    117   CheckState(true, ReloadButtonGtk::MODE_RELOAD, ReloadButtonGtk::MODE_RELOAD,
    118              false, false);
    119 }
    120 
    121 TEST_F(ReloadButtonGtkTest, ResetOnClick) {
    122   // Change to stop and hover.
    123   gtk_button_clicked(GTK_BUTTON(reload_.widget()));
    124   reload_.ChangeMode(ReloadButtonGtk::MODE_STOP, false);
    125   set_mouse_hovered(true);
    126 
    127   // Press the button.  This should change back to reload despite the hover,
    128   // because it's a direct user action.
    129   gtk_button_clicked(GTK_BUTTON(reload_.widget()));
    130   CheckState(true, ReloadButtonGtk::MODE_RELOAD, ReloadButtonGtk::MODE_RELOAD,
    131              false, false);
    132 }
    133 
    134 TEST_F(ReloadButtonGtkTest, ResetOnTimer) {
    135   // Change to stop, hover, and change back to reload.
    136   gtk_button_clicked(GTK_BUTTON(reload_.widget()));
    137   reload_.ChangeMode(ReloadButtonGtk::MODE_STOP, false);
    138   set_mouse_hovered(true);
    139   reload_.ChangeMode(ReloadButtonGtk::MODE_RELOAD, false);
    140 
    141   // Now fire the stop-to-reload timer.  This should reset the button.
    142   loop_.RunAllPending();
    143   CheckState(true, ReloadButtonGtk::MODE_RELOAD, ReloadButtonGtk::MODE_RELOAD,
    144              false, false);
    145 }
    146