[SyncFS] Build indexes from FileTracker entries on disk.
[chromium-blink-merge.git] / ui / views / controls / native / native_view_host_aura_unittest.cc
blob22474d9fb634e4d99f91bc3f1fb2c2f452a09ad0
1 // Copyright (c) 2013 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.
5 #include "ui/views/controls/native/native_view_host_aura.h"
7 #include "base/basictypes.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "ui/aura/client/aura_constants.h"
10 #include "ui/aura/window.h"
11 #include "ui/base/cursor/cursor.h"
12 #include "ui/views/controls/native/native_view_host.h"
13 #include "ui/views/test/views_test_base.h"
14 #include "ui/views/view.h"
15 #include "ui/views/view_constants_aura.h"
16 #include "ui/views/widget/widget.h"
18 namespace views {
20 // Testing wrapper of the NativeViewHost
21 class NativeViewHostTesting : public NativeViewHost {
22 public:
23 NativeViewHostTesting() {}
24 virtual ~NativeViewHostTesting() { destroyed_count_++; }
26 static void ResetDestroyedCount() { destroyed_count_ = 0; }
28 static int destroyed_count() { return destroyed_count_; }
30 private:
31 static int destroyed_count_;
33 DISALLOW_COPY_AND_ASSIGN(NativeViewHostTesting);
35 int NativeViewHostTesting::destroyed_count_ = 0;
37 // Observer watching for window visibility and bounds change events. This is
38 // used to verify that the child and clipping window operations are done in the
39 // right order.
40 class NativeViewHostWindowObserver : public aura::WindowObserver {
41 public:
42 enum EventType {
43 EVENT_NONE,
44 EVENT_SHOWN,
45 EVENT_HIDDEN,
46 EVENT_BOUNDS_CHANGED,
49 NativeViewHostWindowObserver() {}
50 virtual ~NativeViewHostWindowObserver() {}
52 const std::vector<std::pair<EventType, aura::Window*> >& events() const {
53 return events_;
56 // aura::WindowObserver overrides
57 virtual void OnWindowVisibilityChanged(aura::Window* window,
58 bool visible) OVERRIDE {
59 std::pair<EventType, aura::Window*> event =
60 std::make_pair(visible ? EVENT_SHOWN : EVENT_HIDDEN, window);
62 // Dedupe events as a single Hide() call can result in several
63 // notifications.
64 if (events_.size() == 0u || events_.back() != event)
65 events_.push_back(event);
68 virtual void OnWindowBoundsChanged(aura::Window* window,
69 const gfx::Rect& old_bounds,
70 const gfx::Rect& new_bounds) OVERRIDE {
71 events_.push_back(std::make_pair(EVENT_BOUNDS_CHANGED, window));
74 private:
75 std::vector<std::pair<EventType, aura::Window*> > events_;
77 DISALLOW_COPY_AND_ASSIGN(NativeViewHostWindowObserver);
80 class NativeViewHostAuraTest : public ViewsTestBase {
81 public:
82 NativeViewHostAuraTest() {
85 NativeViewHostAura* native_host() {
86 return static_cast<NativeViewHostAura*>(host_->native_wrapper_.get());
89 Widget* toplevel() {
90 return toplevel_.get();
93 NativeViewHost* host() {
94 return host_.get();
97 Widget* child() {
98 return child_.get();
101 aura::Window* clipping_window() { return &(native_host()->clipping_window_); }
103 void CreateHost() {
104 // Create the top level widget.
105 toplevel_.reset(new Widget);
106 Widget::InitParams toplevel_params =
107 CreateParams(Widget::InitParams::TYPE_WINDOW);
108 toplevel_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
109 toplevel_->Init(toplevel_params);
111 // And the child widget.
112 View* test_view = new View;
113 child_.reset(new Widget);
114 Widget::InitParams child_params(Widget::InitParams::TYPE_CONTROL);
115 child_params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
116 child_params.parent = toplevel_->GetNativeView();
117 child_->Init(child_params);
118 child_->SetContentsView(test_view);
120 // Owned by |toplevel|.
121 host_.reset(new NativeViewHostTesting);
122 toplevel_->GetRootView()->AddChildView(host_.get());
123 host_->Attach(child_->GetNativeView());
126 void DestroyHost() {
127 host_.reset();
130 NativeViewHostTesting* ReleaseHost() { return host_.release(); }
132 void DestroyTopLevel() { toplevel_.reset(); }
134 private:
135 scoped_ptr<Widget> toplevel_;
136 scoped_ptr<NativeViewHostTesting> host_;
137 scoped_ptr<Widget> child_;
139 DISALLOW_COPY_AND_ASSIGN(NativeViewHostAuraTest);
142 // Verifies NativeViewHostAura stops observing native view on destruction.
143 TEST_F(NativeViewHostAuraTest, StopObservingNativeViewOnDestruct) {
144 CreateHost();
145 aura::Window* child_win = child()->GetNativeView();
146 NativeViewHostAura* aura_host = native_host();
148 EXPECT_TRUE(child_win->HasObserver(aura_host));
149 DestroyHost();
150 EXPECT_FALSE(child_win->HasObserver(aura_host));
153 // Tests that the kHostViewKey is correctly set and cleared.
154 TEST_F(NativeViewHostAuraTest, HostViewPropertyKey) {
155 // Create the NativeViewHost and attach a NativeView.
156 CreateHost();
157 aura::Window* child_win = child()->GetNativeView();
158 EXPECT_EQ(host(), child_win->GetProperty(views::kHostViewKey));
159 EXPECT_EQ(host()->GetWidget()->GetNativeView(),
160 child_win->GetProperty(aura::client::kHostWindowKey));
161 EXPECT_EQ(host(), clipping_window()->GetProperty(views::kHostViewKey));
163 host()->Detach();
164 EXPECT_FALSE(child_win->GetProperty(views::kHostViewKey));
165 EXPECT_FALSE(child_win->GetProperty(aura::client::kHostWindowKey));
166 EXPECT_TRUE(clipping_window()->GetProperty(views::kHostViewKey));
168 host()->Attach(child_win);
169 EXPECT_EQ(host(), child_win->GetProperty(views::kHostViewKey));
170 EXPECT_EQ(host()->GetWidget()->GetNativeView(),
171 child_win->GetProperty(aura::client::kHostWindowKey));
172 EXPECT_EQ(host(), clipping_window()->GetProperty(views::kHostViewKey));
174 DestroyHost();
175 EXPECT_FALSE(child_win->GetProperty(views::kHostViewKey));
176 EXPECT_FALSE(child_win->GetProperty(aura::client::kHostWindowKey));
179 // Tests that the NativeViewHost reports the cursor set on its native view.
180 TEST_F(NativeViewHostAuraTest, CursorForNativeView) {
181 CreateHost();
183 toplevel()->SetCursor(ui::kCursorHand);
184 child()->SetCursor(ui::kCursorWait);
185 ui::MouseEvent move_event(ui::ET_MOUSE_MOVED, gfx::Point(0, 0),
186 gfx::Point(0, 0), 0, 0);
188 EXPECT_EQ(ui::kCursorWait, host()->GetCursor(move_event).native_type());
190 DestroyHost();
193 // Test that destroying the top level widget before destroying the attached
194 // NativeViewHost works correctly. Specifically the associated NVH should be
195 // destroyed and there shouldn't be any errors.
196 TEST_F(NativeViewHostAuraTest, DestroyWidget) {
197 NativeViewHostTesting::ResetDestroyedCount();
198 CreateHost();
199 ReleaseHost();
200 EXPECT_EQ(0, NativeViewHostTesting::destroyed_count());
201 DestroyTopLevel();
202 EXPECT_EQ(1, NativeViewHostTesting::destroyed_count());
205 // Test that the fast resize path places the clipping and content windows were
206 // they are supposed to be.
207 TEST_F(NativeViewHostAuraTest, FastResizePath) {
208 CreateHost();
209 toplevel()->SetBounds(gfx::Rect(20, 20, 100, 100));
211 // Without fast resize, the clipping window should size to the native view
212 // with the native view positioned at the origin of the clipping window and
213 // the clipping window positioned where the native view was requested.
214 host()->set_fast_resize(false);
215 native_host()->ShowWidget(5, 10, 100, 100);
216 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
217 host()->native_view()->bounds().ToString());
218 EXPECT_EQ(gfx::Rect(5, 10, 100, 100).ToString(),
219 clipping_window()->bounds().ToString());
221 // With fast resize, the native view should remain the same size but be
222 // clipped the requested size.
223 host()->set_fast_resize(true);
224 native_host()->ShowWidget(10, 25, 50, 50);
225 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
226 host()->native_view()->bounds().ToString());
227 EXPECT_EQ(gfx::Rect(10, 25, 50, 50).ToString(),
228 clipping_window()->bounds().ToString());
230 // Turning off fast resize should make the native view start resizing again.
231 host()->set_fast_resize(false);
232 native_host()->ShowWidget(10, 25, 50, 50);
233 EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(),
234 host()->native_view()->bounds().ToString());
235 EXPECT_EQ(gfx::Rect(10, 25, 50, 50).ToString(),
236 clipping_window()->bounds().ToString());
238 DestroyHost();
241 // Test installing and uninstalling a clip.
242 TEST_F(NativeViewHostAuraTest, InstallClip) {
243 CreateHost();
244 toplevel()->SetBounds(gfx::Rect(20, 20, 100, 100));
246 // Without a clip, the clipping window should always be positioned at the
247 // requested coordinates with the native view positioned at the origin of the
248 // clipping window.
249 native_host()->ShowWidget(10, 20, 100, 100);
250 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
251 host()->native_view()->bounds().ToString());
252 EXPECT_EQ(gfx::Rect(10, 20, 100, 100).ToString(),
253 clipping_window()->bounds().ToString());
255 // Clip to the bottom right quarter of the native view.
256 native_host()->InstallClip(60, 70, 50, 50);
257 native_host()->ShowWidget(10, 20, 100, 100);
258 EXPECT_EQ(gfx::Rect(-50, -50, 100, 100).ToString(),
259 host()->native_view()->bounds().ToString());
260 EXPECT_EQ(gfx::Rect(60, 70, 50, 50).ToString(),
261 clipping_window()->bounds().ToString());
263 // Clip to the center of the native view.
264 native_host()->InstallClip(35, 45, 50, 50);
265 native_host()->ShowWidget(10, 20, 100, 100);
266 EXPECT_EQ(gfx::Rect(-25, -25, 100, 100).ToString(),
267 host()->native_view()->bounds().ToString());
268 EXPECT_EQ(gfx::Rect(35, 45, 50, 50).ToString(),
269 clipping_window()->bounds().ToString());
271 // Uninstalling the clip should make the clipping window match the native view
272 // again.
273 native_host()->UninstallClip();
274 native_host()->ShowWidget(10, 20, 100, 100);
275 EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(),
276 host()->native_view()->bounds().ToString());
277 EXPECT_EQ(gfx::Rect(10, 20, 100, 100).ToString(),
278 clipping_window()->bounds().ToString());
280 DestroyHost();
283 // Ensure native view is parented to the root window after detaching. This is
284 // a regression test for http://crbug.com/389261.
285 TEST_F(NativeViewHostAuraTest, ParentAfterDetach) {
286 CreateHost();
287 aura::Window* child_win = child()->GetNativeView();
288 aura::Window* root_window = child_win->GetRootWindow();
289 aura::WindowTreeHost* child_win_tree_host = child_win->GetHost();
291 host()->Detach();
292 EXPECT_EQ(root_window, child_win->GetRootWindow());
293 EXPECT_EQ(child_win_tree_host, child_win->GetHost());
295 DestroyHost();
298 // Ensure the clipping window is hidden before setting the native view's bounds.
299 // This is a regression test for http://crbug.com/388699.
300 TEST_F(NativeViewHostAuraTest, RemoveClippingWindowOrder) {
301 CreateHost();
302 toplevel()->SetBounds(gfx::Rect(20, 20, 100, 100));
303 native_host()->ShowWidget(10, 20, 100, 100);
305 NativeViewHostWindowObserver test_observer;
306 clipping_window()->AddObserver(&test_observer);
307 child()->GetNativeView()->AddObserver(&test_observer);
309 host()->Detach();
311 ASSERT_EQ(3u, test_observer.events().size());
312 EXPECT_EQ(NativeViewHostWindowObserver::EVENT_HIDDEN,
313 test_observer.events()[0].first);
314 EXPECT_EQ(clipping_window(), test_observer.events()[0].second);
315 EXPECT_EQ(NativeViewHostWindowObserver::EVENT_BOUNDS_CHANGED,
316 test_observer.events()[1].first);
317 EXPECT_EQ(child()->GetNativeView(), test_observer.events()[1].second);
318 EXPECT_EQ(NativeViewHostWindowObserver::EVENT_HIDDEN,
319 test_observer.events()[2].first);
320 EXPECT_EQ(child()->GetNativeView(), test_observer.events()[2].second);
322 clipping_window()->RemoveObserver(&test_observer);
323 child()->GetNativeView()->RemoveObserver(&test_observer);
325 DestroyHost();
328 } // namespace views