1// Copyright (c) 2012 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.
4
5#import <Cocoa/Cocoa.h>
6
7#include "base/mac/scoped_nsobject.h"
8#include "testing/gtest/include/gtest/gtest.h"
9#include "testing/platform_test.h"
10#import "ui/base/cocoa/focus_tracker.h"
11#import "ui/gfx/test/ui_cocoa_test_helper.h"
12
13namespace {
14
15class FocusTrackerTest : public ui::CocoaTest {
16 public:
17  virtual void SetUp() {
18    ui::CocoaTest::SetUp();
19    base::scoped_nsobject<NSView> view(
20        [[NSView alloc] initWithFrame:NSZeroRect]);
21    viewA_ = view.get();
22    [[test_window() contentView] addSubview:viewA_];
23
24    view.reset([[NSView alloc] initWithFrame:NSZeroRect]);
25    viewB_ = view.get();
26    [[test_window() contentView] addSubview:viewB_];
27  }
28
29 protected:
30  NSView* viewA_;
31  NSView* viewB_;
32};
33
34TEST_F(FocusTrackerTest, SaveRestore) {
35  NSWindow* window = test_window();
36  ASSERT_TRUE([window makeFirstResponder:viewA_]);
37  base::scoped_nsobject<FocusTracker> tracker(
38      [[FocusTracker alloc] initWithWindow:window]);
39  // Give focus to |viewB_|, then try and restore it to view1.
40  ASSERT_TRUE([window makeFirstResponder:viewB_]);
41  EXPECT_TRUE([tracker restoreFocusInWindow:window]);
42  EXPECT_EQ(viewA_, [window firstResponder]);
43}
44
45TEST_F(FocusTrackerTest, SaveRestoreWithTextView) {
46  // Valgrind will complain if the text field has zero size.
47  NSRect frame = NSMakeRect(0, 0, 100, 20);
48  NSWindow* window = test_window();
49  base::scoped_nsobject<NSTextField> text(
50      [[NSTextField alloc] initWithFrame:frame]);
51  [[window contentView] addSubview:text];
52
53  ASSERT_TRUE([window makeFirstResponder:text]);
54  base::scoped_nsobject<FocusTracker> tracker(
55      [[FocusTracker alloc] initWithWindow:window]);
56  // Give focus to |viewB_|, then try and restore it to the text field.
57  ASSERT_TRUE([window makeFirstResponder:viewB_]);
58  EXPECT_TRUE([tracker restoreFocusInWindow:window]);
59  EXPECT_TRUE([[window firstResponder] isKindOfClass:[NSTextView class]]);
60}
61
62TEST_F(FocusTrackerTest, DontRestoreToViewNotInWindow) {
63  NSWindow* window = test_window();
64  base::scoped_nsobject<NSView> viewC(
65      [[NSView alloc] initWithFrame:NSZeroRect]);
66  [[window contentView] addSubview:viewC];
67
68  ASSERT_TRUE([window makeFirstResponder:viewC]);
69  base::scoped_nsobject<FocusTracker> tracker(
70      [[FocusTracker alloc] initWithWindow:window]);
71
72  // Give focus to |viewB_|, then remove viewC from the hierarchy and try
73  // to restore focus.  The restore should fail.
74  ASSERT_TRUE([window makeFirstResponder:viewB_]);
75  [viewC removeFromSuperview];
76  EXPECT_FALSE([tracker restoreFocusInWindow:window]);
77}
78
79TEST_F(FocusTrackerTest, DontRestoreFocusToViewInDifferentWindow) {
80  NSWindow* window = test_window();
81  ASSERT_TRUE([window makeFirstResponder:viewA_]);
82  base::scoped_nsobject<FocusTracker> tracker(
83      [[FocusTracker alloc] initWithWindow:window]);
84
85  // Give focus to |viewB_|, then try and restore focus in a different
86  // window.  It is ok to pass a nil NSWindow here because we only use
87  // it for direct comparison.
88  ASSERT_TRUE([window makeFirstResponder:viewB_]);
89  EXPECT_FALSE([tracker restoreFocusInWindow:nil]);
90}
91
92
93}  // namespace
94