diff options
author | scheib@chromium.org <scheib@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-10 00:03:12 +0000 |
---|---|---|
committer | scheib@chromium.org <scheib@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-10 00:03:12 +0000 |
commit | c36000e00d75b51321a18aff9260ee7f66f2b54e (patch) | |
tree | 0edd7507571527900e040bc9fccfb2c1411320e4 /chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc | |
parent | b3a259b88b030ec2786bd13a7dc79a951d7e4fb7 (diff) | |
download | chromium_src-c36000e00d75b51321a18aff9260ee7f66f2b54e.zip chromium_src-c36000e00d75b51321a18aff9260ee7f66f2b54e.tar.gz chromium_src-c36000e00d75b51321a18aff9260ee7f66f2b54e.tar.bz2 |
Refactor Fullscreen Controller State Machine tests to Interactive tests and Unit Tests.
Previously the state machine tests ran only as unit tests, and were not verified against actual operating system window behavior.
R=yzshen, phajdan.jr
chrome/browser/ui/fullscreen/*,
chrome/test/base/in_process_browser_test.cc
TBR=ben
chrome/chrome_tests.gypi &
chrome/browser/ui/cocoa/browser_window_controller.mm
BUG=146666
Review URL: https://chromiumcodereview.appspot.com/11264021
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@167011 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc')
-rw-r--r-- | chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc b/chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc new file mode 100644 index 0000000..160f3b3 --- /dev/null +++ b/chrome/browser/ui/fullscreen/fullscreen_controller_state_unittest.cc @@ -0,0 +1,457 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "build/build_config.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_tabstrip.h" +#include "chrome/browser/ui/fullscreen/fullscreen_controller.h" +#include "chrome/browser/ui/fullscreen/fullscreen_controller_state_test.h" +#include "chrome/test/base/browser_with_test_window_test.h" +#include "content/public/browser/web_contents.h" +#include "content/public/common/url_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +// The FullscreenControllerStateUnitTest unit test suite exhastively tests +// the FullscreenController through all permutations of events. The behavior +// of the BrowserWindow is mocked via FullscreenControllerTestWindow. +// +// FullscreenControllerStateInteractiveTest is an interactive test suite +// used to verify that the FullscreenControllerTestWindow models the behavior +// of actual windows accurately. The interactive tests are too flaky to run +// on infrastructure, and so those tests are disabled. Run them with: +// interactive_ui_tests +// --gtest_filter="FullscreenControllerStateInteractiveTest.*" +// --gtest_also_run_disabled_tests + +// A BrowserWindow used for testing FullscreenController. ---------------------- +class FullscreenControllerTestWindow : public TestBrowserWindow { + public: + // Simulate the window state with an enumeration. + enum WindowState { + NORMAL, + FULLSCREEN, + // No TO_ state for METRO_SNAP, the windows implementation is synchronous. + METRO_SNAP, + TO_NORMAL, + TO_FULLSCREEN, + }; + + FullscreenControllerTestWindow(); + virtual ~FullscreenControllerTestWindow() {} + + // BrowserWindow Interface: + virtual void EnterFullscreen(const GURL& url, + FullscreenExitBubbleType type) OVERRIDE; + virtual void EnterFullscreen(); + virtual void ExitFullscreen() OVERRIDE; + virtual bool IsFullscreen() const OVERRIDE; +#if defined(OS_WIN) + virtual void SetMetroSnapMode(bool enable) OVERRIDE; + virtual bool IsInMetroSnapMode() const OVERRIDE; +#endif +#if defined(OS_MACOSX) + virtual void EnterPresentationMode( + const GURL& url, + FullscreenExitBubbleType bubble_type) OVERRIDE; + virtual void ExitPresentationMode() OVERRIDE; + virtual bool InPresentationMode() OVERRIDE; +#endif + + static const char* GetWindowStateString(WindowState state); + WindowState state() const { return state_; } + void set_browser(Browser* browser) { browser_ = browser; } + void set_reentrant(bool value) { reentrant_ = value; } + bool reentrant() const { return reentrant_; } + + // Simulates the window changing state. + void ChangeWindowFullscreenState(); + // Calls ChangeWindowFullscreenState() if |reentrant_| is true. + void ChangeWindowFullscreenStateIfReentrant(); + + private: + WindowState state_; + bool mac_presentation_mode_; + Browser* browser_; + + // Causes reentrant calls to be made by calling + // browser_->WindowFullscreenStateChanged() from the BrowserWindow + // interface methods. + bool reentrant_; +}; + +FullscreenControllerTestWindow::FullscreenControllerTestWindow() + : state_(NORMAL), + mac_presentation_mode_(false), + browser_(NULL), + reentrant_(false) { +} + +void FullscreenControllerTestWindow::EnterFullscreen( + const GURL& url, FullscreenExitBubbleType type) { + EnterFullscreen(); +} + +void FullscreenControllerTestWindow::EnterFullscreen() { + if (!IsFullscreen()) { + state_ = TO_FULLSCREEN; + ChangeWindowFullscreenStateIfReentrant(); + } +} + +void FullscreenControllerTestWindow::ExitFullscreen() { + if (IsFullscreen()) { + state_ = TO_NORMAL; + mac_presentation_mode_ = false; + ChangeWindowFullscreenStateIfReentrant(); + } +} + +bool FullscreenControllerTestWindow::IsFullscreen() const { +#if defined(OS_MACOSX) + return state_ == FULLSCREEN || state_ == TO_FULLSCREEN; +#else + return state_ == FULLSCREEN || state_ == TO_NORMAL; +#endif +} + +#if defined(OS_WIN) +void FullscreenControllerTestWindow::SetMetroSnapMode(bool enable) { + if (enable != IsInMetroSnapMode()) { + if (enable) + state_ = METRO_SNAP; + else + state_ = NORMAL; + } + ChangeWindowFullscreenStateIfReentrant(); +} + +bool FullscreenControllerTestWindow::IsInMetroSnapMode() const { + return state_ == METRO_SNAP; +} +#endif + +#if defined(OS_MACOSX) +void FullscreenControllerTestWindow::EnterPresentationMode( + const GURL& url, + FullscreenExitBubbleType bubble_type) { + mac_presentation_mode_ = true; + EnterFullscreen(); +} + +void FullscreenControllerTestWindow::ExitPresentationMode() { + if (InPresentationMode()) { + mac_presentation_mode_ = false; + ExitFullscreen(); + } +} + +bool FullscreenControllerTestWindow::InPresentationMode() { + return mac_presentation_mode_; +} +#endif + +// static +const char* FullscreenControllerTestWindow::GetWindowStateString( + WindowState state) { + switch (state) { + case NORMAL: + return "NORMAL"; + case FULLSCREEN: + return "FULLSCREEN"; + case METRO_SNAP: + return "METRO_SNAP"; + case TO_FULLSCREEN: + return "TO_FULLSCREEN"; + case TO_NORMAL: + return "TO_NORMAL"; + default: + NOTREACHED() << "No string for state " << state; + return "WindowState-Unknown"; + } +} + +void FullscreenControllerTestWindow::ChangeWindowFullscreenState() { + // Several states result in "no operation" intentionally. The tests + // assume that all possible states and event pairs can be tested, even + // though window managers will not generate all of these. + switch (state_) { + case NORMAL: + break; + case FULLSCREEN: + break; + case METRO_SNAP: + break; + case TO_FULLSCREEN: + state_ = FULLSCREEN; + break; + case TO_NORMAL: + state_ = NORMAL; + break; + default: + NOTREACHED(); + } + // Emit a change event from every state to ensure the Fullscreen Controller + // handles it in all circumstances. + browser_->WindowFullscreenStateChanged(); +} + +void FullscreenControllerTestWindow::ChangeWindowFullscreenStateIfReentrant() { + if (reentrant_) + ChangeWindowFullscreenState(); +} + +// Unit test fixture testing Fullscreen Controller through its states. --------- +class FullscreenControllerStateUnitTest : public BrowserWithTestWindowTest, + public FullscreenControllerStateTest { + public: + FullscreenControllerStateUnitTest(); + + // FullscreenControllerStateTest: + virtual void SetUp() OVERRIDE; + virtual void ChangeWindowFullscreenState() OVERRIDE; + virtual const char* GetWindowStateString() OVERRIDE; + virtual void VerifyWindowState() OVERRIDE; + + protected: + // FullscreenControllerStateTest: + virtual bool ShouldSkipStateAndEventPair(State state, Event event) OVERRIDE; + virtual void TestStateAndEvent(State state, + Event event, + bool reentrant) OVERRIDE; + virtual Browser* GetBrowser() OVERRIDE; + FullscreenControllerTestWindow* window_; +}; + +FullscreenControllerStateUnitTest::FullscreenControllerStateUnitTest () + : window_(NULL) { +} + +void FullscreenControllerStateUnitTest::SetUp() { + window_ = new FullscreenControllerTestWindow(); + set_window(window_); // BrowserWithTestWindowTest takes ownership. + BrowserWithTestWindowTest::SetUp(); + window_->set_browser(browser()); +} + +void FullscreenControllerStateUnitTest::ChangeWindowFullscreenState() { + window_->ChangeWindowFullscreenState(); +} + +const char* FullscreenControllerStateUnitTest::GetWindowStateString() { + return FullscreenControllerTestWindow::GetWindowStateString(window_->state()); +} + +void FullscreenControllerStateUnitTest::VerifyWindowState() { + switch (state_) { + case STATE_NORMAL: + EXPECT_EQ(FullscreenControllerTestWindow::NORMAL, + window_->state()) << GetAndClearDebugLog(); + break; + case STATE_BROWSER_FULLSCREEN_NO_CHROME: + EXPECT_EQ(FullscreenControllerTestWindow::FULLSCREEN, + window_->state()) << GetAndClearDebugLog(); + break; +#if defined(OS_WIN) + case STATE_METRO_SNAP: + EXPECT_EQ(FullscreenControllerTestWindow::METRO_SNAP, + window_->state()) << GetAndClearDebugLog(); + break; +#endif + case STATE_TAB_FULLSCREEN: + EXPECT_EQ(FullscreenControllerTestWindow::FULLSCREEN, + window_->state()) << GetAndClearDebugLog(); + break; + case STATE_TAB_BROWSER_FULLSCREEN: + EXPECT_EQ(FullscreenControllerTestWindow::FULLSCREEN, + window_->state()) << GetAndClearDebugLog(); + break; + case STATE_TO_NORMAL: + EXPECT_EQ(FullscreenControllerTestWindow::TO_NORMAL, + window_->state()) << GetAndClearDebugLog(); + break; + case STATE_TO_BROWSER_FULLSCREEN_NO_CHROME: + EXPECT_EQ(FullscreenControllerTestWindow::TO_FULLSCREEN, + window_->state()) << GetAndClearDebugLog(); + break; + case STATE_TO_TAB_FULLSCREEN: + EXPECT_EQ(FullscreenControllerTestWindow::TO_FULLSCREEN, + window_->state()) << GetAndClearDebugLog(); + break; + default: + NOTREACHED() << GetAndClearDebugLog(); + } + + FullscreenControllerStateTest::VerifyWindowState(); +} + +bool FullscreenControllerStateUnitTest::ShouldSkipStateAndEventPair( + State state, Event event) { +#if defined(OS_MACOSX) + // TODO(scheib) Toggle, Window Event, Toggle, Toggle on Mac as exposed by + // test *.STATE_TO_NORMAL__TOGGLE_FULLSCREEN runs interactively and exits to + // Normal. This doesn't appear to be the desired result, and would add + // too much complexity to mimic in our simple FullscreenControllerTestWindow. + // http://crbug.com/156968 + if ((state == STATE_TO_NORMAL || + state == STATE_TO_BROWSER_FULLSCREEN_NO_CHROME || + state == STATE_TO_TAB_FULLSCREEN) && + event == TOGGLE_FULLSCREEN) + return true; +#endif + + return FullscreenControllerStateTest::ShouldSkipStateAndEventPair(state, + event); +} + +void FullscreenControllerStateUnitTest::TestStateAndEvent(State state, + Event event, + bool reentrant) { + window_->set_reentrant(reentrant); + FullscreenControllerStateTest::TestStateAndEvent(state, event, reentrant); +} + +Browser* FullscreenControllerStateUnitTest::GetBrowser() { + return BrowserWithTestWindowTest::browser(); +} + +// Tests ----------------------------------------------------------------------- + +#define TEST_EVENT_INNER(state, event, reentrant, reentrant_id) \ + TEST_F(FullscreenControllerStateUnitTest, \ + state##__##event##reentrant_id) { \ + AddTab(browser(), GURL(chrome::kAboutBlankURL)); \ + ASSERT_NO_FATAL_FAILURE(TestStateAndEvent(state, event, reentrant)) \ + << GetAndClearDebugLog(); \ + } + // Progress of tests can be examined by inserting the following line: + // LOG(INFO) << GetAndClearDebugLog(); } + +#define TEST_EVENT(state, event) \ + TEST_EVENT_INNER(state, event, false, ); \ + TEST_EVENT_INNER(state, event, true, _Reentrant); + +// Individual tests for each pair of state and event: + +TEST_EVENT(STATE_NORMAL, TOGGLE_FULLSCREEN); +TEST_EVENT(STATE_NORMAL, TAB_FULLSCREEN_TRUE); +TEST_EVENT(STATE_NORMAL, TAB_FULLSCREEN_FALSE); +#if defined(OS_WIN) +TEST_EVENT(STATE_NORMAL, METRO_SNAP_TRUE); +TEST_EVENT(STATE_NORMAL, METRO_SNAP_FALSE); +#endif +TEST_EVENT(STATE_NORMAL, WINDOW_CHANGE); + +TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, TOGGLE_FULLSCREEN); +TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, TAB_FULLSCREEN_TRUE); +TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, TAB_FULLSCREEN_FALSE); +#if defined(OS_WIN) +TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, METRO_SNAP_TRUE); +TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, METRO_SNAP_FALSE); +#endif +TEST_EVENT(STATE_BROWSER_FULLSCREEN_NO_CHROME, WINDOW_CHANGE); + +#if defined(OS_WIN) +TEST_EVENT(STATE_METRO_SNAP, TOGGLE_FULLSCREEN); +TEST_EVENT(STATE_METRO_SNAP, TAB_FULLSCREEN_TRUE); +TEST_EVENT(STATE_METRO_SNAP, TAB_FULLSCREEN_FALSE); +TEST_EVENT(STATE_METRO_SNAP, METRO_SNAP_TRUE); +TEST_EVENT(STATE_METRO_SNAP, METRO_SNAP_FALSE); +TEST_EVENT(STATE_METRO_SNAP, WINDOW_CHANGE); +#endif + +TEST_EVENT(STATE_TAB_FULLSCREEN, TOGGLE_FULLSCREEN); +TEST_EVENT(STATE_TAB_FULLSCREEN, TAB_FULLSCREEN_TRUE); +TEST_EVENT(STATE_TAB_FULLSCREEN, TAB_FULLSCREEN_FALSE); +#if defined(OS_WIN) +TEST_EVENT(STATE_TAB_FULLSCREEN, METRO_SNAP_TRUE); +TEST_EVENT(STATE_TAB_FULLSCREEN, METRO_SNAP_FALSE); +#endif +TEST_EVENT(STATE_TAB_FULLSCREEN, WINDOW_CHANGE); + +TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, TOGGLE_FULLSCREEN); +TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, TAB_FULLSCREEN_TRUE); +TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, TAB_FULLSCREEN_FALSE); +#if defined(OS_WIN) +TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, METRO_SNAP_TRUE); +TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, METRO_SNAP_FALSE); +#endif +TEST_EVENT(STATE_TAB_BROWSER_FULLSCREEN, WINDOW_CHANGE); + +TEST_EVENT(STATE_TO_NORMAL, TOGGLE_FULLSCREEN); +TEST_EVENT(STATE_TO_NORMAL, TAB_FULLSCREEN_TRUE); +TEST_EVENT(STATE_TO_NORMAL, TAB_FULLSCREEN_FALSE); +#if defined(OS_WIN) +TEST_EVENT(STATE_TO_NORMAL, METRO_SNAP_TRUE); +TEST_EVENT(STATE_TO_NORMAL, METRO_SNAP_FALSE); +#endif +TEST_EVENT(STATE_TO_NORMAL, WINDOW_CHANGE); + +TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, TOGGLE_FULLSCREEN); +TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, TAB_FULLSCREEN_TRUE); +TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, TAB_FULLSCREEN_FALSE); +#if defined(OS_WIN) +TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, METRO_SNAP_TRUE); +TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, METRO_SNAP_FALSE); +#endif +TEST_EVENT(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME, WINDOW_CHANGE); + +TEST_EVENT(STATE_TO_TAB_FULLSCREEN, TOGGLE_FULLSCREEN); +TEST_EVENT(STATE_TO_TAB_FULLSCREEN, TAB_FULLSCREEN_TRUE); +TEST_EVENT(STATE_TO_TAB_FULLSCREEN, TAB_FULLSCREEN_FALSE); +#if defined(OS_WIN) +TEST_EVENT(STATE_TO_TAB_FULLSCREEN, METRO_SNAP_TRUE); +TEST_EVENT(STATE_TO_TAB_FULLSCREEN, METRO_SNAP_FALSE); +#endif +TEST_EVENT(STATE_TO_TAB_FULLSCREEN, WINDOW_CHANGE); + +// Specific one-off tests for known issues: + +// TODO(scheib) Toggling Tab fullscreen while pending Tab or +// Browser fullscreen is broken currently http://crbug.com/154196 +TEST_F(FullscreenControllerStateUnitTest, + DISABLED_ToggleTabWhenPendingBrowser) { +#if !defined(OS_WIN) // Only possible without reentrancy + AddTab(browser(), GURL(chrome::kAboutBlankURL)); + ASSERT_NO_FATAL_FAILURE( + TransitionToState(STATE_TO_BROWSER_FULLSCREEN_NO_CHROME)) + << GetAndClearDebugLog(); + + ASSERT_TRUE(InvokeEvent(TAB_FULLSCREEN_TRUE)) << GetAndClearDebugLog(); + ASSERT_TRUE(InvokeEvent(TAB_FULLSCREEN_FALSE)) << GetAndClearDebugLog(); + ASSERT_TRUE(InvokeEvent(WINDOW_CHANGE)) << GetAndClearDebugLog(); +#endif +} + +// TODO(scheib) Toggling Tab fullscreen while pending Tab or +// Browser fullscreen is broken currently http://crbug.com/154196 +TEST_F(FullscreenControllerStateUnitTest, DISABLED_ToggleTabWhenPendingTab) { +#if !defined(OS_WIN) // Only possible without reentrancy + AddTab(browser(), GURL(chrome::kAboutBlankURL)); + ASSERT_NO_FATAL_FAILURE( + TransitionToState(STATE_TO_TAB_FULLSCREEN)) + << GetAndClearDebugLog(); + + ASSERT_TRUE(InvokeEvent(TAB_FULLSCREEN_TRUE)) << GetAndClearDebugLog(); + ASSERT_TRUE(InvokeEvent(TAB_FULLSCREEN_FALSE)) << GetAndClearDebugLog(); + ASSERT_TRUE(InvokeEvent(WINDOW_CHANGE)) << GetAndClearDebugLog(); +#endif +} + +// Soak tests: + +// Tests all states with all permutations of multiple events to detect lingering +// state issues that would bleed over to other states. +// I.E. for each state test all combinations of events E1, E2, E3. +// +// This produces coverage for event sequences that may happen normally but +// would not be exposed by traversing to each state via TransitionToState(). +// TransitionToState() always takes the same path even when multiple paths +// exist. +TEST_F(FullscreenControllerStateUnitTest, TransitionsForEachState) { + // A tab is needed for tab fullscreen. + AddTab(browser(), GURL(chrome::kAboutBlankURL)); + TestTransitionsForEachState(); + // Progress of test can be examined via LOG(INFO) << GetAndClearDebugLog(); +} + |