| Index: ui/views/controls/menu/menu_controller_unittest.cc
|
| diff --git a/ui/views/controls/menu/menu_controller_unittest.cc b/ui/views/controls/menu/menu_controller_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7aa23a317f5567796374d48308f376f97ab516ae
|
| --- /dev/null
|
| +++ b/ui/views/controls/menu/menu_controller_unittest.cc
|
| @@ -0,0 +1,153 @@
|
| +// Copyright 2014 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 "ui/views/controls/menu/menu_controller.h"
|
| +
|
| +#include "base/run_loop.h"
|
| +#include "ui/aura/window.h"
|
| +#include "ui/events/platform/platform_event_source.h"
|
| +#include "ui/views/test/views_test_base.h"
|
| +#include "ui/wm/public/dispatcher_client.h"
|
| +
|
| +#if defined(OS_WIN)
|
| +#include "base/message_loop/message_pump_dispatcher.h"
|
| +#elif defined(USE_X11)
|
| +#include <X11/Xlib.h>
|
| +#undef Bool
|
| +#undef None
|
| +#endif
|
| +
|
| +namespace views {
|
| +
|
| +namespace {
|
| +
|
| +class TestPlatformEventSource : public ui::PlatformEventSource {
|
| + public:
|
| + TestPlatformEventSource() {}
|
| + virtual ~TestPlatformEventSource() {}
|
| +
|
| + uint32_t Dispatch(const ui::PlatformEvent& event) {
|
| + return DispatchEvent(event);
|
| + }
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(TestPlatformEventSource);
|
| +};
|
| +
|
| +class TestDispatcherClient : public aura::client::DispatcherClient {
|
| + public:
|
| + TestDispatcherClient() : dispatcher_(NULL) {}
|
| + virtual ~TestDispatcherClient() {}
|
| +
|
| + base::MessagePumpDispatcher* dispatcher() {
|
| + return dispatcher_;
|
| + }
|
| +
|
| + // aura::client::DispatcherClient:
|
| + virtual void RunWithDispatcher(
|
| + base::MessagePumpDispatcher* dispatcher) OVERRIDE {
|
| + base::AutoReset<base::MessagePumpDispatcher*> reset_dispatcher(&dispatcher_,
|
| + dispatcher);
|
| + base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
|
| + base::MessageLoop::ScopedNestableTaskAllower allow(loop);
|
| + base::RunLoop run_loop;
|
| + quit_callback_ = run_loop.QuitClosure();
|
| + run_loop.Run();
|
| + }
|
| +
|
| + virtual void QuitNestedMessageLoop() OVERRIDE { quit_callback_.Run(); }
|
| +
|
| + private:
|
| + base::MessagePumpDispatcher* dispatcher_;
|
| + base::Closure quit_callback_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestDispatcherClient);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class MenuControllerTest : public ViewsTestBase {
|
| + public:
|
| + MenuControllerTest() : controller_(NULL) {}
|
| + virtual ~MenuControllerTest() {}
|
| +
|
| + // Dispatches |count| number of items, each in a separate iteration of the
|
| + // message-loop, by posting a task.
|
| + void Step3_DispatchEvents(int count) {
|
| + base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
|
| + base::MessageLoop::ScopedNestableTaskAllower allow(loop);
|
| + controller_->exit_type_ = MenuController::EXIT_ALL;
|
| +
|
| +#if defined(USE_X11)
|
| + XEvent xevent;
|
| + memset(&xevent, 0, sizeof(xevent));
|
| + event_source_.Dispatch(&xevent);
|
| +#else
|
| + MSG msg;
|
| + memset(&msg, 0, sizeof(MSG));
|
| + dispatcher_client_.dispatcher()->Dispatch(msg);
|
| +#endif
|
| +
|
| + if (count) {
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&MenuControllerTest::Step3_DispatchEvents,
|
| + base::Unretained(this),
|
| + count - 1));
|
| + } else {
|
| + EXPECT_TRUE(run_loop_->running());
|
| + run_loop_->Quit();
|
| + }
|
| + }
|
| +
|
| + // Runs a nested message-loop that does not involve the menu itself.
|
| + void Step2_RunNestedLoop() {
|
| + base::MessageLoopForUI* loop = base::MessageLoopForUI::current();
|
| + base::MessageLoop::ScopedNestableTaskAllower allow(loop);
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&MenuControllerTest::Step3_DispatchEvents,
|
| + base::Unretained(this),
|
| + 3));
|
| + run_loop_.reset(new base::RunLoop());
|
| + run_loop_->Run();
|
| + }
|
| +
|
| + void Step1_RunMenu() {
|
| + Widget widget;
|
| + Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_POPUP);
|
| + params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
|
| + widget.Init(params);
|
| + widget.Show();
|
| +
|
| + aura::client::SetDispatcherClient(widget.GetNativeWindow()->GetRootWindow(),
|
| + &dispatcher_client_);
|
| +
|
| + controller_ = new MenuController(NULL, true, NULL);
|
| + controller_->owner_ = &widget;
|
| + base::MessageLoop::current()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&MenuControllerTest::Step2_RunNestedLoop,
|
| + base::Unretained(this)));
|
| + controller_->RunMessageLoop(false);
|
| + }
|
| +
|
| + private:
|
| + MenuController* controller_;
|
| + scoped_ptr<base::RunLoop> run_loop_;
|
| + TestPlatformEventSource event_source_;
|
| + TestDispatcherClient dispatcher_client_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(MenuControllerTest);
|
| +};
|
| +
|
| +TEST_F(MenuControllerTest, Basic) {
|
| + base::MessageLoop::ScopedNestableTaskAllower allow_nested(
|
| + base::MessageLoop::current());
|
| + message_loop()->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&MenuControllerTest::Step1_RunMenu, base::Unretained(this)));
|
| +}
|
| +
|
| +} // namespace views
|
|
|