File: view_event_test_base.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (150 lines) | stat: -rw-r--r-- 5,414 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_VIEWS_TEST_VIEW_EVENT_TEST_BASE_H_
#define CHROME_BROWSER_UI_VIEWS_TEST_VIEW_EVENT_TEST_BASE_H_

#include "base/memory/raw_ptr.h"
#include "base/task/single_thread_task_runner.h"

// We only want to use ViewEventTestBase in test targets which properly
// isolate each test case by running each test in a separate process.
// This way if a test hangs the test launcher can reliably terminate it.
#if !defined(HAS_OUT_OF_PROC_TEST_RUNNER)
#error Can't reliably terminate hanging event tests without OOP test runner.
#endif

#include <memory>

#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "chrome/test/views/chrome_views_test_base.h"
#include "ui/accessibility/platform/ax_platform_for_test.h"

#if defined(USE_AURA) && !BUILDFLAG(IS_CHROMEOS)
namespace display {
class Screen;
}
#endif

namespace gfx {
class Size;
}

class TestBaseWidgetDelegate;

// Base class for Views based tests that dispatch events.
//
// As views based event test involves waiting for events to be processed,
// writing a views based test is slightly different than that of writing
// other unit tests. In particular when the test fails or is done you need
// to stop the message loop. This can be done by way of invoking the Done
// method.
//
// Any delayed callbacks should be done by way of CreateEventTask.
// CreateEventTask checks to see if ASSERT_XXX has been invoked after invoking
// the task. If there was a failure Done is invoked and the test stops.
//
// ViewEventTestBase creates a Window with the View returned from
// CreateContentsView. The preferred size for the view can be customized by
// overriding GetPreferredSizeForContents. If you do not override
// GetPreferredSizeForContents the preferred size of the view returned from
// CreateContentsView is used.
//
// Subclasses of ViewEventTestBase must implement two methods:
// . DoTestOnMessageLoop: invoked when the message loop is running. Run your
//   test here, invoke Done when done.
// . CreateContentsView: returns the view to place in the window.
//
// Once you have created a ViewEventTestBase use the macro VIEW_TEST to define
// the fixture.
//
// Testing drag and drop is tricky because the mouse move that initiates drag
// and drop may trigger a nested native event loop that waits for more mouse
// messages.  Once a drag begins, all UI events until the drag ends must be
// driven from observer callbacks and posted on the task runner returned by
// GetDragTaskRunner().

class ViewEventTestBase : public ChromeViewsTestBase {
 public:
  ViewEventTestBase();
  ViewEventTestBase(const ViewEventTestBase&) = delete;
  ViewEventTestBase& operator=(const ViewEventTestBase&) = delete;
  ~ViewEventTestBase() override;

  static void SetUpTestSuite();

  // ChromeViewsTestBase:
  void SetUp() override;
  void TearDown() override;
  views::Widget::InitParams CreateParams(
      views::Widget::InitParams::Ownership ownership,
      views::Widget::InitParams::Type type) override;

  // Returns the view that is added to the window.
  virtual std::unique_ptr<views::View> CreateContentsView() = 0;

  // Returns an empty Size. Subclasses that want a preferred size other than
  // that of the View returned by CreateContentsView should override this
  // appropriately.
  virtual gfx::Size GetPreferredSizeForContents() const;

  // Invoke when done either because of failure or success. Quits the message
  // loop.
  void Done();

  views::Widget* window() { return window_; }

 protected:
  // Called once the message loop is running.
  virtual void DoTestOnMessageLoop() = 0;

  // Invoke from test main. Shows the window, starts the message loop and
  // schedules a task that invokes DoTestOnMessageLoop.
  void StartMessageLoopAndRunTest();

  // Creates a task that calls the specified method back. The specified
  // method is called in such a way that if there are any test failures
  // Done is invoked.
  template <class T, class Method>
  base::OnceClosure CreateEventTask(T* target, Method method) {
    return base::BindOnce(&ViewEventTestBase::RunTestMethod,
                          base::Unretained(this),
                          base::BindOnce(method, base::Unretained(target)));
  }

  // Callback from CreateEventTask. Runs the supplied task and if there are
  // failures invokes Done.
  void RunTestMethod(base::OnceClosure task);

  // Returns a task runner to use for drag-related mouse events.
  scoped_refptr<base::SingleThreadTaskRunner> GetDragTaskRunner();

 private:
  friend class TestBaseWidgetDelegate;

  ui::AXPlatformForTest ax_platform_;

#if defined(USE_AURA) && !BUILDFLAG(IS_CHROMEOS)
  std::unique_ptr<display::Screen> screen_;
#endif

  // Thread for posting background drag events.
  std::unique_ptr<base::Thread> drag_event_thread_;

  base::RunLoop run_loop_;
  raw_ptr<views::Widget> window_ = nullptr;
};

// Convenience macro for defining a ViewEventTestBase. See class description
// of ViewEventTestBase for details.
#define VIEW_TEST(test_class, name) \
  TEST_F(test_class, name) {        \
    StartMessageLoopAndRunTest();   \
  }

#endif  // CHROME_BROWSER_UI_VIEWS_TEST_VIEW_EVENT_TEST_BASE_H_