blob: 89e4b93911569e2fdfcb1ac2e1355248f0f7ff40 [file] [log] [blame]
// 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.
#ifndef UI_VIEWS_TEST_VIEWS_TEST_BASE_H_
#define UI_VIEWS_TEST_VIEWS_TEST_BASE_H_
#include <memory>
#include <utility>
#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
#include "ui/base/ui_base_features.h"
#include "ui/views/test/scoped_views_test_helper.h"
#include "ui/views/test/test_views_delegate.h"
#include "ui/views/widget/widget.h"
#if defined(OS_WIN)
#include "ui/base/win/scoped_ole_initializer.h"
#endif
#if defined(USE_AURA)
#include "ui/aura/test/aura_test_helper.h"
#include "ui/aura/window_tree_host.h"
#endif
namespace views {
// A base class for views unit test. It creates a message loop necessary
// to drive UI events and takes care of OLE initialization for windows.
class ViewsTestBase : public PlatformTest {
public:
enum class NativeWidgetType {
// On Aura, corresponds to NativeWidgetAura.
kDefault,
// On chromeos, corresponds to NativeWidgetAura (DesktopNativeWidgetAura
// is not used on ChromeOS).
kDesktop,
};
// This class can be used as a deleter for std::unique_ptr<Widget>
// to call function Widget::CloseNow automatically.
struct WidgetCloser {
void operator()(Widget* widget) const;
};
using WidgetAutoclosePtr = std::unique_ptr<Widget, WidgetCloser>;
// Constructs a ViewsTestBase with |traits| being forwarded to its
// TaskEnvironment. MainThreadType always defaults to UI and must not be
// specified.
template <typename... TaskEnvironmentTraits>
NOINLINE explicit ViewsTestBase(TaskEnvironmentTraits&&... traits)
: ViewsTestBase(std::make_unique<base::test::TaskEnvironment>(
base::test::TaskEnvironment::MainThreadType::UI,
std::forward<TaskEnvironmentTraits>(traits)...)) {}
// Alternatively a subclass may pass a TaskEnvironment directly.
explicit ViewsTestBase(
std::unique_ptr<base::test::TaskEnvironment> task_environment);
ViewsTestBase(const ViewsTestBase&) = delete;
ViewsTestBase& operator=(const ViewsTestBase&) = delete;
~ViewsTestBase() override;
// testing::Test:
void SetUp() override;
void TearDown() override;
// This copies some of the setup done in ViewsTestSuite, so it's only
// necessary for a ViewsTestBase that runs out of that test suite, such as in
// interactive ui tests.
void SetUpForInteractiveTests();
void RunPendingMessages();
// Returns CreateParams for a widget of type |type|. This is used by
// CreateParamsForTestWidget() and thus by CreateTestWidget(), and may also be
// used directly. The default implementation sets the context to
// GetContext().
virtual Widget::InitParams CreateParams(Widget::InitParams::Type type);
virtual std::unique_ptr<Widget> CreateTestWidget(
Widget::InitParams::Type type =
Widget::InitParams::TYPE_WINDOW_FRAMELESS);
bool HasCompositingManager() const;
// Simulate an OS-level destruction of the native window held by |widget|.
void SimulateNativeDestroy(Widget* widget);
// Get the system reserved height at the top of the screen. On Mac, this
// includes the menu bar and title bar.
static int GetSystemReservedHeightAtTopOfScreen();
protected:
base::test::TaskEnvironment* task_environment() {
return task_environment_.get();
}
TestViewsDelegate* test_views_delegate() const {
return test_helper_->test_views_delegate();
}
void set_native_widget_type(NativeWidgetType native_widget_type) {
DCHECK(!setup_called_);
native_widget_type_ = native_widget_type;
}
void set_views_delegate(std::unique_ptr<TestViewsDelegate> views_delegate) {
DCHECK(!setup_called_);
views_delegate_for_setup_.swap(views_delegate);
}
#if defined(USE_AURA)
aura::Window* root_window() {
return aura::test::AuraTestHelper::GetInstance()->GetContext();
}
ui::EventSink* GetEventSink() { return host()->GetEventSink(); }
aura::WindowTreeHost* host() {
return aura::test::AuraTestHelper::GetInstance()->GetHost();
}
#endif
// Returns a context view. In aura builds, this will be the RootWindow.
gfx::NativeWindow GetContext();
// Factory for creating the native widget when |native_widget_type_| is set to
// kDesktop.
NativeWidget* CreateNativeWidgetForTest(
const Widget::InitParams& init_params,
internal::NativeWidgetDelegate* delegate);
// Instantiates a Widget for CreateTestWidget(), but does no other
// initialization. Overriding this allows subclasses to customize the Widget
// subclass returned from CreateTestWidget().
virtual std::unique_ptr<Widget> AllocateTestWidget();
// Constructs the params for CreateTestWidget().
Widget::InitParams CreateParamsForTestWidget(
Widget::InitParams::Type type =
Widget::InitParams::TYPE_WINDOW_FRAMELESS);
private:
std::unique_ptr<base::test::TaskEnvironment> task_environment_;
// Controls what type of widget will be created by default for a test (i.e.
// when creating a Widget and leaving InitParams::native_widget unspecified).
// kDefault will allow the system default to be used (typically
// NativeWidgetAura on Aura). kDesktop forces DesktopNativeWidgetAura on Aura.
// There are exceptions, such as for modal dialog widgets, for which this
// value is ignored.
NativeWidgetType native_widget_type_ = NativeWidgetType::kDefault;
std::unique_ptr<TestViewsDelegate> views_delegate_for_setup_;
std::unique_ptr<ScopedViewsTestHelper> test_helper_;
bool interactive_setup_called_ = false;
bool setup_called_ = false;
bool teardown_called_ = false;
bool has_compositing_manager_ = false;
#if defined(OS_WIN)
ui::ScopedOleInitializer ole_initializer_;
#endif
};
class ViewsTestBaseWithNativeWidgetType
: public ViewsTestBase,
public testing::WithParamInterface<ViewsTestBase::NativeWidgetType> {
public:
using ViewsTestBase::ViewsTestBase;
ViewsTestBaseWithNativeWidgetType(const ViewsTestBaseWithNativeWidgetType&) =
delete;
ViewsTestBaseWithNativeWidgetType& operator=(
const ViewsTestBaseWithNativeWidgetType&) = delete;
~ViewsTestBaseWithNativeWidgetType() override = default;
// ViewsTestBase:
void SetUp() override;
};
// A helper that makes it easier to declare basic views tests that want to test
// desktop native widgets. See |ViewsTestBase::native_wiget_type_| and
// |ViewsTestBase::CreateNativeWidgetForTest|. In short, for Aura, this will
// result in most Widgets automatically being backed by a
// DesktopNativeWidgetAura. For Mac, it has no impact as a NativeWidgetMac is
// used either way.
class ViewsTestWithDesktopNativeWidget : public ViewsTestBase {
public:
using ViewsTestBase::ViewsTestBase;
ViewsTestWithDesktopNativeWidget(const ViewsTestWithDesktopNativeWidget&) =
delete;
ViewsTestWithDesktopNativeWidget& operator=(
const ViewsTestWithDesktopNativeWidget&) = delete;
~ViewsTestWithDesktopNativeWidget() override = default;
// ViewsTestBase:
void SetUp() override;
};
} // namespace views
#endif // UI_VIEWS_TEST_VIEWS_TEST_BASE_H_