OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 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/strings/utf_string_conversions.h" | |
8 #import "ui/gfx/test/ui_cocoa_test_helper.h" | |
9 #import "ui/views/cocoa/bridged_content_view.h" | |
10 #import "ui/views/cocoa/bridged_native_widget.h" | |
11 #include "ui/views/cocoa/drag_drop_client_mac.h" | |
tapted
2016/05/24 08:06:01
nit: This should be at the top of the file (and #i
spqchan
2016/05/26 01:56:53
Done.
| |
12 #include "ui/views/view.h" | |
13 #include "ui/views/widget/native_widget_mac.h" | |
14 #include "ui/views/widget/root_view.h" | |
15 #include "ui/views/widget/widget.h" | |
16 | |
17 using base::ASCIIToUTF16; | |
18 | |
19 // Mocks the NSDraggingInfo sent to the DragDropClientMac's DragUpdate() and | |
20 // Drop() methods. Out of the required methods of NSDraggingInfo, only | |
21 // draggingLocation and draggingPasteboard are used. | |
22 @interface MockDraggingInfo : NSObject<NSDraggingInfo> { | |
23 NSPasteboard* pasteboard_; | |
24 } | |
25 | |
26 @property BOOL animatesToDestination; | |
27 @property NSInteger numberOfValidItemsForDrop; | |
28 @property NSDraggingFormation draggingFormation; | |
tapted
2016/05/24 08:06:01
looks like the 10.11 SDK "requires" this to implem
spqchan
2016/05/26 01:56:53
Done.
| |
29 | |
30 @end | |
31 | |
32 @implementation MockDraggingInfo | |
33 | |
34 @synthesize animatesToDestination; | |
35 @synthesize numberOfValidItemsForDrop; | |
36 @synthesize draggingFormation; | |
37 | |
38 - (id)initWithPasteboard:(NSPasteboard*)pasteboard { | |
39 if ((self = [super init])) { | |
40 pasteboard_ = pasteboard; | |
41 } | |
42 return self; | |
43 } | |
44 | |
45 - (NSPoint)draggingLocation { | |
46 return NSMakePoint(50, 50); | |
47 } | |
48 | |
tapted
2016/05/24 08:06:01
let's squish all these together by removing these
spqchan
2016/05/26 01:56:53
Done.
| |
49 - (NSPasteboard*)draggingPasteboard { | |
50 return pasteboard_; | |
51 } | |
52 | |
53 - (NSInteger)draggingSequenceNumber { | |
54 return 0; | |
55 } | |
56 | |
57 - (id)draggingSource { | |
58 return nil; | |
59 } | |
60 | |
61 - (NSDragOperation)draggingSourceOperationMask { | |
62 return NSDragOperationNone; | |
63 } | |
64 | |
65 - (NSWindow*)draggingDestinationWindow { | |
66 return nil; | |
67 } | |
68 | |
69 - (NSArray*)namesOfPromisedFilesDroppedAtDestination:(NSURL*)dropDestination { | |
70 return nil; | |
71 } | |
72 | |
73 - (NSImage*)draggedImage { | |
74 return nil; | |
75 } | |
76 | |
77 - (NSPoint)draggedImageLocation { | |
78 return NSZeroPoint; | |
79 } | |
80 | |
81 - (void)slideDraggedImageTo:(NSPoint)aPoint { | |
82 } | |
83 | |
84 - (void) | |
85 enumerateDraggingItemsWithOptions:(NSDraggingItemEnumerationOptions)enumOpts | |
86 forView:(NSView*)view | |
87 classes:(NSArray*)classArray | |
88 searchOptions:(NSDictionary*)searchOptions | |
89 usingBlock:(void (^)(NSDraggingItem* draggingItem, | |
90 NSInteger idx, | |
91 BOOL* stop))block { | |
92 } | |
93 | |
94 - (void)resetSpringLoading { | |
95 } | |
96 | |
97 @end | |
98 | |
99 namespace views { | |
100 namespace test { | |
101 | |
102 // Provides the |parent| argument to construct a BridgedNativeWidget. | |
103 class DragDropTestNativeWidgetMac : public NativeWidgetMac { | |
tapted
2016/05/24 08:06:01
I think we won't need this
spqchan
2016/05/26 01:56:54
Done.
| |
104 public: | |
105 DragDropTestNativeWidgetMac(Widget* delegate) : NativeWidgetMac(delegate) {} | |
106 | |
107 DragDropClientMac* drag_drop_client() { return bridge_->drag_drop_client(); } | |
108 | |
109 BridgedNativeWidget* bridge() { return bridge_.get(); } | |
110 | |
111 // internal::NativeWidgetPrivate: | |
112 void InitNativeWidget(const Widget::InitParams& params) override { | |
113 ownership_ = params.ownership; | |
114 } | |
115 | |
116 void ReorderNativeViews() override { | |
117 // Called via Widget::Init to set the content view. No-op in these tests. | |
118 } | |
119 | |
120 private: | |
121 DISALLOW_COPY_AND_ASSIGN(DragDropTestNativeWidgetMac); | |
122 }; | |
123 | |
124 // View object that will receive and process dropped data from the test. | |
125 class DragDropView : public View { | |
126 public: | |
127 bool GetDropFormats( | |
tapted
2016/05/24 08:06:01
// View:
(i.e. to indicate overrides)
spqchan
2016/05/26 01:56:54
Done.
| |
128 int* formats, | |
129 std::set<ui::Clipboard::FormatType>* format_types) override { | |
130 *formats |= formats_; | |
131 return true; | |
132 } | |
133 | |
134 bool CanDrop(const OSExchangeData& data) override { return true; } | |
135 | |
tapted
2016/05/24 08:06:01
nit: these overrides can be squished together too
spqchan
2016/05/26 01:56:54
The line will be > 80 characters if I squish them
tapted
2016/05/26 12:31:41
Ah, I just meant remove the blank lines between th
| |
136 int OnDragUpdated(const ui::DropTargetEvent& event) override { | |
137 return ui::DragDropTypes::DRAG_COPY; | |
138 } | |
139 | |
140 int OnPerformDrop(const ui::DropTargetEvent& event) override { | |
141 return ui::DragDropTypes::DRAG_COPY; | |
142 } | |
143 | |
144 void SetDropFormats(int formats) { formats_ = formats; } | |
tapted
2016/05/24 08:06:01
nit: move this above the overrides, and call it se
| |
145 | |
146 private: | |
147 // Drop formats accepted by this View object. | |
148 int formats_; | |
tapted
2016/05/24 08:06:01
= 0;
(needs to be initialized)
spqchan
2016/05/26 01:56:54
Done.
| |
149 }; | |
tapted
2016/05/24 08:06:01
nit: DISALLOW_COPY_AND_ASSIGN(..)
spqchan
2016/05/26 01:56:54
Done.
| |
150 | |
151 class CocoaDragDropTest : public ui::CocoaTest { | |
tapted
2016/05/24 08:06:01
hopefuly inheriting from WidgetTest will get us be
spqchan
2016/05/26 01:56:54
Done.
| |
152 public: | |
153 CocoaDragDropTest() | |
154 : widget_(new Widget), | |
155 native_widget_mac_(new DragDropTestNativeWidgetMac(widget_.get())) {} | |
156 | |
157 DragDropClientMac* drag_drop_client() { | |
158 return native_widget_mac_->drag_drop_client(); | |
159 } | |
160 | |
161 // Overridden from testing::Test: | |
162 void SetUp() override { | |
163 ui::CocoaTest::SetUp(); | |
164 | |
165 init_params_.native_widget = native_widget_mac_; | |
166 | |
167 // Use a frameless window, otherwise Widget will try to center the window | |
168 // before the tests covering the Init() flow are ready to do that. | |
169 init_params_.type = Widget::InitParams::TYPE_WINDOW_FRAMELESS; | |
170 | |
171 // To control the lifetime without an actual window that must be closed, | |
172 // tests in this file need to use WIDGET_OWNS_NATIVE_WIDGET. | |
173 init_params_.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | |
174 | |
175 init_params_.bounds = gfx::Rect(100, 100, 100, 100); | |
176 native_widget_mac_->GetWidget()->Init(init_params_); | |
177 | |
178 view_.reset(new views::internal::RootView(widget_.get())); | |
179 base::scoped_nsobject<NSWindow> window([test_window() retain]); | |
180 | |
181 BridgedNativeWidget* bridge = native_widget_mac_->bridge(); | |
182 | |
183 // BridgedNativeWidget expects to be initialized with a hidden (deferred) | |
184 // window. | |
185 [window orderOut:nil]; | |
186 EXPECT_FALSE([window delegate]); | |
187 bridge->Init(window, init_params_); | |
188 | |
189 // The delegate should exist before setting the root view. | |
190 EXPECT_TRUE([window delegate]); | |
191 bridge->SetRootView(view_.get()); | |
192 ns_view_ = bridge->ns_view(); | |
193 | |
194 // Add target view | |
195 target_.reset(new DragDropView()); | |
196 target_->SetBounds(0, 0, 100, 100); | |
197 view_->AddChildView(target_.get()); | |
198 | |
199 drag_drop_client()->operation_ = ui::DragDropTypes::DRAG_COPY; | |
200 } | |
201 | |
202 void TearDown() override { | |
203 BridgedNativeWidget* bridge = native_widget_mac_->bridge(); | |
204 if (bridge) | |
205 bridge->SetRootView(nullptr); | |
206 target_.reset(); | |
207 view_.reset(); | |
208 CocoaTest::TearDown(); | |
209 } | |
210 | |
211 NSDragOperation DragUpdate(NSPasteboard* pasteboard) { | |
212 DragDropClientMac* client = drag_drop_client(); | |
213 MockDraggingInfo* info = | |
214 [[MockDraggingInfo alloc] initWithPasteboard:pasteboard]; | |
215 return client->DragUpdate(info); | |
216 } | |
217 | |
218 NSDragOperation Drop(NSPasteboard* pasteboard) { | |
219 DragDropClientMac* client = drag_drop_client(); | |
220 MockDraggingInfo* info = | |
221 [[MockDraggingInfo alloc] initWithPasteboard:pasteboard]; | |
222 return client->Drop(info); | |
223 } | |
224 | |
225 void SetData(OSExchangeData& data) { | |
226 drag_drop_client()->data_source_.reset( | |
227 [[CocoaDragDropDataProvider alloc] initWithData:data]); | |
228 } | |
229 | |
230 protected: | |
231 std::unique_ptr<views::View> view_; | |
tapted
2016/05/24 08:06:01
normally views are owned by the Widget* (via its R
spqchan
2016/05/26 01:56:54
Done.
| |
232 BridgedContentView* ns_view_; | |
tapted
2016/05/24 08:06:01
This can be retrieved from widget_->GetNativeView(
spqchan
2016/05/26 01:56:54
Done.
| |
233 std::unique_ptr<Widget> widget_; | |
tapted
2016/05/24 08:06:01
It's more common for NativeWidgets to own themselv
spqchan
2016/05/26 01:56:53
Done.
spqchan
2016/05/26 01:56:54
Done.
| |
234 DragDropTestNativeWidgetMac* native_widget_mac_; // Weak. Owned by |widget_|. | |
235 std::unique_ptr<DragDropView> target_; | |
236 | |
237 // Make the InitParams available to tests to cover initialization codepaths. | |
238 Widget::InitParams init_params_; | |
239 }; | |
tapted
2016/05/24 08:06:01
nit: private: DISALLOW_COPY_AND_ASSIGN(..)
spqchan
2016/05/26 01:56:54
Done.
| |
240 | |
241 // Tests if the drag and drop target receives the dropped data. | |
242 TEST_F(CocoaDragDropTest, BasicDragDrop) { | |
243 // Create the drop data | |
244 OSExchangeData data; | |
245 const base::string16& text = ASCIIToUTF16("text"); | |
246 data.SetString(text); | |
247 SetData(data); | |
248 | |
249 target_->SetDropFormats(ui::OSExchangeData::STRING | ui::OSExchangeData::URL); | |
250 | |
251 // Check if the target receives the data from a drop and returns the expected | |
252 // operation. | |
253 EXPECT_NE(DragUpdate(nil), NSDragOperationNone); | |
254 EXPECT_NE(Drop(nil), NSDragOperationNone); | |
255 } | |
256 | |
257 // Tests if the drag and drop target rejects the dropped data with the | |
258 // incorrect format. | |
259 TEST_F(CocoaDragDropTest, InvalidFormatDragDrop) { | |
260 OSExchangeData data; | |
261 const base::string16& text = ASCIIToUTF16("text"); | |
262 data.SetString(text); | |
263 SetData(data); | |
264 | |
265 target_->SetDropFormats(ui::OSExchangeData::URL); | |
266 | |
267 // Check if the target receives the data from a drop and returns the expected | |
268 // operation. | |
269 EXPECT_EQ(DragUpdate(nil), NSDragOperationNone); | |
270 EXPECT_EQ(Drop(nil), NSDragOperationNone); | |
271 } | |
272 | |
273 // Tests if the drag and drop target can accept data without an OSExchangeData | |
274 // object. | |
275 TEST_F(CocoaDragDropTest, PasteboardToOSExchangeTest) { | |
276 target_->SetDropFormats(ui::OSExchangeData::STRING); | |
277 | |
278 NSPasteboard* pasteboard = [NSPasteboard pasteboardWithUniqueName]; | |
279 | |
280 EXPECT_EQ(DragUpdate(pasteboard), NSDragOperationNone); | |
281 EXPECT_EQ(Drop(pasteboard), NSDragOperationNone); | |
282 drag_drop_client()->EndDrag(); | |
283 | |
284 [pasteboard setString:@"text" forType:NSPasteboardTypeString]; | |
285 | |
286 EXPECT_NE(DragUpdate(pasteboard), NSDragOperationNone); | |
287 EXPECT_NE(Drop(pasteboard), NSDragOperationNone); | |
288 } | |
289 | |
290 } // namespace test | |
291 } // namespace views | |
OLD | NEW |