1 // Copyright 2014 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 "ui/views/cocoa/bridged_native_widget.h" 6 7 #import <Cocoa/Cocoa.h> 8 9 #include "base/memory/scoped_ptr.h" 10 #import "testing/gtest_mac.h" 11 #import "ui/gfx/test/ui_cocoa_test_helper.h" 12 #import "ui/views/cocoa/bridged_content_view.h" 13 #include "ui/views/ime/input_method.h" 14 #include "ui/views/view.h" 15 16 namespace views { 17 18 class BridgedNativeWidgetTest : public ui::CocoaTest { 19 public: 20 BridgedNativeWidgetTest(); 21 virtual ~BridgedNativeWidgetTest(); 22 23 // testing::Test: 24 virtual void SetUp() OVERRIDE; 25 virtual void TearDown() OVERRIDE; 26 27 protected: 28 // TODO(tapted): Make this a EventCountView from widget_unittest.cc. 29 scoped_ptr<views::View> view_; 30 scoped_ptr<BridgedNativeWidget> bridge_; 31 32 private: 33 DISALLOW_COPY_AND_ASSIGN(BridgedNativeWidgetTest); 34 }; 35 36 BridgedNativeWidgetTest::BridgedNativeWidgetTest() { 37 } 38 39 BridgedNativeWidgetTest::~BridgedNativeWidgetTest() { 40 } 41 42 void BridgedNativeWidgetTest::SetUp() { 43 ui::CocoaTest::SetUp(); 44 45 view_.reset(new views::View); 46 bridge_.reset(new BridgedNativeWidget); 47 base::scoped_nsobject<NSWindow> window([test_window() retain]); 48 bridge_->Init(window); 49 bridge_->SetRootView(view_.get()); 50 51 [test_window() makePretendKeyWindowAndSetFirstResponder:bridge_->ns_view()]; 52 } 53 54 void BridgedNativeWidgetTest::TearDown() { 55 [test_window() clearPretendKeyWindowAndFirstResponder]; 56 57 bridge_.reset(); 58 view_.reset(); 59 60 ui::CocoaTest::TearDown(); 61 } 62 63 // The TEST_VIEW macro expects the view it's testing to have a superview. In 64 // these tests, the NSView bridge is a contentView, at the root. These mimic 65 // what TEST_VIEW usually does. 66 TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewAddRemove) { 67 base::scoped_nsobject<BridgedContentView> view([bridge_->ns_view() retain]); 68 EXPECT_NSEQ([test_window() contentView], view); 69 EXPECT_NSEQ(test_window(), [view window]); 70 71 // The superview of a contentView is an NSNextStepFrame. 72 EXPECT_TRUE([view superview]); 73 EXPECT_TRUE([view hostedView]); 74 75 // Destroying the C++ bridge should remove references to any C++ objects in 76 // the ObjectiveC object, and remove it from the hierarchy. 77 bridge_.reset(); 78 EXPECT_FALSE([view hostedView]); 79 EXPECT_FALSE([view superview]); 80 EXPECT_FALSE([view window]); 81 EXPECT_FALSE([test_window() contentView]); 82 } 83 84 TEST_F(BridgedNativeWidgetTest, BridgedNativeWidgetTest_TestViewDisplay) { 85 [bridge_->ns_view() display]; 86 } 87 88 // Test that resizing the window resizes the root view appropriately. 89 TEST_F(BridgedNativeWidgetTest, ViewSizeTracksWindow) { 90 const int kTestNewWidth = 400; 91 const int kTestNewHeight = 300; 92 93 // |test_window()| is borderless, so these should align. 94 NSSize window_size = [test_window() frame].size; 95 EXPECT_EQ(view_->width(), static_cast<int>(window_size.width)); 96 EXPECT_EQ(view_->height(), static_cast<int>(window_size.height)); 97 98 // Make sure a resize actually occurs. 99 EXPECT_NE(kTestNewWidth, view_->width()); 100 EXPECT_NE(kTestNewHeight, view_->height()); 101 102 [test_window() setFrame:NSMakeRect(0, 0, kTestNewWidth, kTestNewHeight) 103 display:NO]; 104 EXPECT_EQ(kTestNewWidth, view_->width()); 105 EXPECT_EQ(kTestNewHeight, view_->height()); 106 } 107 108 TEST_F(BridgedNativeWidgetTest, CreateInputMethod) { 109 scoped_ptr<views::InputMethod> input_method(bridge_->CreateInputMethod()); 110 EXPECT_TRUE(input_method); 111 } 112 113 TEST_F(BridgedNativeWidgetTest, GetHostInputMethod) { 114 EXPECT_TRUE(bridge_->GetHostInputMethod()); 115 } 116 117 } // namespace views 118