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.
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "chrome_frame/infobars/infobar_content.h"
15 #include "chrome_frame/infobars/internal/displaced_window_manager.h"
16 #include "chrome_frame/infobars/internal/host_window_manager.h"
17 #include "chrome_frame/infobars/internal/infobar_window.h"
18 #include "chrome_frame/infobars/internal/subclassing_window_with_delegate.h"
19 #include "chrome_frame/test/chrome_frame_test_utils.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
25 RECT kInitialParentWindowRect
= {20, 20, 300, 300};
26 RECT kInitialChildWindowRect
= {20, 20, 280, 280};
28 MATCHER_P(EqualRect
, expected
, "") {
29 return ::EqualRect(expected
, arg
);
32 ACTION_P2(RespondToNcCalcSize
, result
, rect
) {
33 *reinterpret_cast<RECT
*>(arg1
) = *rect
;
37 ACTION_P4(RespondToNcCalcSize
, result
, rect1
, rect2
, rect3
) {
38 reinterpret_cast<RECT
*>(arg1
)[0] = rect1
;
39 reinterpret_cast<RECT
*>(arg1
)[1] = rect2
;
40 reinterpret_cast<RECT
*>(arg1
)[2] = rect3
;
44 class ParentTraits
: public CFrameWinTraits
{
46 static const wchar_t* kClassName
;
47 }; // class ParentTraits
49 class ChildTraits
: public CControlWinTraits
{
51 static const wchar_t* kClassName
;
52 }; // class ChildTraits
54 const wchar_t* ParentTraits::kClassName
= NULL
;
55 const wchar_t* ChildTraits::kClassName
= L
"Shell DocObject View";
57 template<typename TRAITS
> class MockWindow
58 : public CWindowImpl
<MockWindow
<TRAITS
>, CWindow
, TRAITS
> {
60 virtual ~MockWindow() {
64 MOCK_METHOD1(OnCreate
, int(LPCREATESTRUCT lpCreateStruct
));
65 MOCK_METHOD0(OnDestroy
, void());
66 MOCK_METHOD2(OnSize
, void(UINT nType
, CSize size
));
67 MOCK_METHOD1(OnMove
, void(CPoint ptPos
));
68 MOCK_METHOD2(OnNcCalcSize
, LRESULT(BOOL bCalcValidRects
, LPARAM lParam
));
69 DECLARE_WND_CLASS(TRAITS::kClassName
);
70 BEGIN_MSG_MAP_EX(MockWindow
)
71 MSG_WM_CREATE(OnCreate
)
72 MSG_WM_DESTROY(OnDestroy
)
75 MSG_WM_NCCALCSIZE(OnNcCalcSize
)
77 }; // class MockWindow
79 typedef MockWindow
<ParentTraits
> MockTopLevelWindow
;
80 typedef MockWindow
<ChildTraits
> MockChildWindow
;
82 class MockWindowSubclass
83 : public SubclassingWindowWithDelegate
<MockWindowSubclass
> {
85 MOCK_METHOD2(OnNcCalcSize
, LRESULT(BOOL bCalcValidRects
, LPARAM lParam
));
86 BEGIN_MSG_MAP_EX(MockWindowSubclass
)
87 MSG_WM_NCCALCSIZE(OnNcCalcSize
)
88 CHAIN_MSG_MAP(SubclassingWindowWithDelegate
<MockWindowSubclass
>)
90 virtual ~MockWindowSubclass() { Die(); }
91 MOCK_METHOD0(Die
, void());
92 }; // class MockWindowSubclass
94 template<typename T
> class MockDelegate
95 : public SubclassingWindowWithDelegate
<T
>::Delegate
{
97 virtual ~MockDelegate() { Die(); }
98 MOCK_METHOD0(Die
, void());
99 MOCK_METHOD1(AdjustDisplacedWindowDimensions
, void(RECT
* rect
));
100 }; // clas MockDelegate
102 template<typename T
> T
* Initialize(T
* t
,
104 typename
T::Delegate
* delegate
) {
105 if (t
->Initialize(hwnd
, delegate
)) {
115 TEST(InfobarsSubclassingWindowWithDelegateTest
, BasicTest
) {
116 testing::NiceMock
<MockTopLevelWindow
> window
;
117 ASSERT_TRUE(window
.Create(NULL
, kInitialParentWindowRect
) != NULL
);
119 HWND hwnd
= static_cast<HWND
>(window
);
121 ASSERT_TRUE(MockWindowSubclass::GetDelegateForHwnd(hwnd
) == NULL
);
123 MockDelegate
<MockWindowSubclass
>* delegate
=
124 new testing::StrictMock
<MockDelegate
<MockWindowSubclass
> >();
125 MockWindowSubclass
* swwd
= Initialize(
126 new testing::StrictMock
<MockWindowSubclass
>(), hwnd
, delegate
);
127 ASSERT_TRUE(swwd
!= NULL
);
128 ASSERT_EQ(static_cast<MockWindowSubclass::Delegate
*>(delegate
),
129 MockWindowSubclass::GetDelegateForHwnd(hwnd
));
131 // Since expectations are only validated upon object destruction, this test
132 // would normally pass even if the expected deletions never happened.
133 // By expecting another call, in sequence, after the deletions, we force a
134 // failure if those deletions don't occur.
135 testing::MockFunction
<void(std::string check_point_name
)> check
;
138 testing::InSequence s
;
139 EXPECT_CALL(*delegate
, Die());
140 EXPECT_CALL(*swwd
, Die());
141 EXPECT_CALL(check
, Call("checkpoint"));
144 window
.DestroyWindow();
146 check
.Call("checkpoint");
148 ASSERT_TRUE(MockWindowSubclass::GetDelegateForHwnd(hwnd
) == NULL
);
151 TEST(InfobarsSubclassingWindowWithDelegateTest
, InvalidHwndTest
) {
152 testing::NiceMock
<MockTopLevelWindow
> window
;
153 ASSERT_TRUE(window
.Create(NULL
, kInitialParentWindowRect
) != NULL
);
155 HWND hwnd
= static_cast<HWND
>(window
);
157 window
.DestroyWindow();
159 MockDelegate
<MockWindowSubclass
>* delegate
=
160 new testing::StrictMock
<MockDelegate
<MockWindowSubclass
> >();
161 MockWindowSubclass
* swwd
= new testing::StrictMock
<MockWindowSubclass
>();
163 testing::MockFunction
<void(std::string check_point_name
)> check
;
166 testing::InSequence s
;
167 EXPECT_CALL(*delegate
, Die());
168 EXPECT_CALL(check
, Call("checkpoint"));
169 EXPECT_CALL(*swwd
, Die());
172 ASSERT_FALSE(swwd
->Initialize(hwnd
, delegate
));
173 check
.Call("checkpoint"); // Make sure the delegate has been deleted
176 ASSERT_TRUE(MockWindowSubclass::GetDelegateForHwnd(hwnd
) == NULL
);
179 template <typename WINDOW
, typename DELEGATE
> void ExpectNcCalcSizeSequence(
183 RECT
* modified_rect
) {
184 testing::InSequence s
;
185 EXPECT_CALL(*mock_window
, OnNcCalcSize(true, testing::_
)).WillOnce(
186 RespondToNcCalcSize(0, natural_rect
));
187 EXPECT_CALL(*delegate
,
188 AdjustDisplacedWindowDimensions(EqualRect(natural_rect
)))
189 .WillOnce(testing::SetArgumentPointee
<0>(*modified_rect
));
190 EXPECT_CALL(*mock_window
, OnMove(CPoint(modified_rect
->left
,
191 modified_rect
->top
)));
192 EXPECT_CALL(*mock_window
,
193 OnSize(0, CSize(modified_rect
->right
- modified_rect
->left
,
194 modified_rect
->bottom
- modified_rect
->top
)));
196 EXPECT_CALL(*mock_window
, OnNcCalcSize(true, testing::_
))
197 .Times(testing::Between(0, 1))
198 .WillOnce(RespondToNcCalcSize(0, natural_rect
));
199 EXPECT_CALL(*delegate
,
200 AdjustDisplacedWindowDimensions(EqualRect(natural_rect
)))
201 .Times(testing::Between(0, 1))
202 .WillOnce(testing::SetArgumentPointee
<0>(*modified_rect
));
203 EXPECT_CALL(*mock_window
, OnMove(CPoint(modified_rect
->left
,
204 modified_rect
->top
)))
205 .Times(testing::Between(0, 1));
206 EXPECT_CALL(*mock_window
,
207 OnSize(0, CSize(modified_rect
->right
- modified_rect
->left
,
208 modified_rect
->bottom
- modified_rect
->top
)))
209 .Times(testing::Between(0, 1));
212 template <typename WINDOW
, typename DELEGATE
, typename MANAGER
>
213 void DoNcCalcSizeSequence(WINDOW
* mock_window
,
216 RECT natural_rects
[] = { {0, 0, 100, 100}, {10, 10, 120, 120} };
217 RECT modified_rects
[] = { {10, 5, 90, 95}, {25, 35, 80, 70} };
219 ExpectNcCalcSizeSequence(
220 mock_window
, delegate
, &natural_rects
[0], &natural_rects
[0]);
221 // The first time through, trigger the sizing via the manager.
222 // This is required for the HostWindowManager, since it only looks up
223 // and subclasses the displaced window on demand.
224 manager
->UpdateLayout();
226 testing::Mock::VerifyAndClearExpectations(mock_window
);
227 testing::Mock::VerifyAndClearExpectations(delegate
);
229 ExpectNcCalcSizeSequence(
230 mock_window
, delegate
, &natural_rects
[1], &natural_rects
[1]);
231 // The second time through, trigger it through the original window.
232 // By now, we expect to be observing the window in all cases.
233 ::SetWindowPos(static_cast<HWND
>(*mock_window
),
235 SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
| SWP_NOZORDER
|
238 testing::Mock::VerifyAndClearExpectations(mock_window
);
239 testing::Mock::VerifyAndClearExpectations(delegate
);
242 TEST(InfobarsDisplacedWindowManagerTest
, BasicTest
) {
243 testing::NiceMock
<MockTopLevelWindow
> window
;
244 ASSERT_TRUE(window
.Create(NULL
, kInitialParentWindowRect
) != NULL
);
246 MockDelegate
<DisplacedWindowManager
>* delegate
=
247 new testing::StrictMock
<MockDelegate
<DisplacedWindowManager
> >();
249 DisplacedWindowManager
* dwm
= new DisplacedWindowManager();
250 ASSERT_TRUE(dwm
->Initialize(static_cast<HWND
>(window
), delegate
));
251 ASSERT_NO_FATAL_FAILURE(DoNcCalcSizeSequence(&window
, delegate
, dwm
));
253 EXPECT_CALL(*delegate
, Die());
254 window
.DestroyWindow();
257 TEST(InfobarsHostWindowManagerTest
, BasicTest
) {
258 testing::NiceMock
<MockTopLevelWindow
> window
;
259 ASSERT_TRUE(window
.Create(NULL
, kInitialParentWindowRect
) != NULL
);
260 testing::NiceMock
<MockChildWindow
> child_window
;
261 ASSERT_TRUE(child_window
.Create(window
, kInitialChildWindowRect
) != NULL
);
262 testing::NiceMock
<MockChildWindow
> child_window2
;
263 testing::NiceMock
<MockChildWindow
> child_window3
;
265 MockDelegate
<HostWindowManager
>* delegate
=
266 new testing::StrictMock
<MockDelegate
<HostWindowManager
> >();
268 HostWindowManager
* hwm
= new HostWindowManager();
270 ASSERT_TRUE(hwm
->Initialize(static_cast<HWND
>(window
), delegate
));
271 ASSERT_NO_FATAL_FAILURE(DoNcCalcSizeSequence(&child_window
, delegate
, hwm
));
273 // First, destroy window 1 and subsequently create window 2
274 child_window
.DestroyWindow();
276 ASSERT_TRUE(child_window2
.Create(window
, kInitialChildWindowRect
) != NULL
);
277 ASSERT_NO_FATAL_FAILURE(DoNcCalcSizeSequence(&child_window2
, delegate
, hwm
));
279 // Next, create window 3 just before destroying window 2
280 RECT natural_rect
= {10, 15, 40, 45};
281 RECT modified_rect
= {15, 20, 35, 40};
283 ASSERT_TRUE(child_window3
.Create(window
, kInitialChildWindowRect
) != NULL
);
284 ExpectNcCalcSizeSequence(
285 &child_window3
, delegate
, &natural_rect
, &natural_rect
);
286 child_window2
.DestroyWindow();
288 ASSERT_NO_FATAL_FAILURE(DoNcCalcSizeSequence(&child_window3
, delegate
, hwm
));
290 EXPECT_CALL(*delegate
, Die());
291 window
.DestroyWindow();
294 // Must be declared in same namespace as RECT
295 void PrintTo(const RECT
& rect
, ::std::ostream
* os
) {
296 *os
<< "{" << rect
.left
<< ", " << rect
.top
<< ", " << rect
.right
<< ", "
297 << rect
.bottom
<< "}";
302 class MockHost
: public InfobarWindow::Host
{
304 MockHost(InfobarWindow
* infobar_window
,
305 const RECT
& natural_dimensions
,
307 : infobar_window_(infobar_window
),
308 natural_dimensions_(natural_dimensions
),
312 void SetNaturalDimensions(const RECT
& natural_dimensions
) {
313 natural_dimensions_
= natural_dimensions
;
317 virtual HWND
GetContainerWindow() {
321 virtual void UpdateLayout() {
322 RECT
temp(natural_dimensions_
);
323 infobar_window_
->ReserveSpace(&temp
);
324 CheckReservedSpace(&temp
);
327 MOCK_METHOD0(Die
, void(void));
329 // Convenience method for checking the result of InfobarWindow::ReserveSpace
330 MOCK_METHOD1(CheckReservedSpace
, void(RECT
* rect
));
333 InfobarWindow
* infobar_window_
;
334 RECT natural_dimensions_
;
338 class MockInfobarContent
: public InfobarContent
{
340 virtual ~MockInfobarContent() { Die(); }
342 MOCK_METHOD1(InstallInFrame
, bool(Frame
* frame
));
343 MOCK_METHOD1(SetDimensions
, void(const RECT
& dimensions
));
344 MOCK_METHOD2(GetDesiredSize
, size_t(size_t width
, size_t height
));
345 MOCK_METHOD0(Die
, void(void));
346 }; // class MockInfobarContent
349 RectHeightIsLTEToRectXHeight
, rect_x
, "height is <= to height of rect x") {
350 return arg
.bottom
- arg
.top
<= rect_x
->bottom
- rect_x
->top
;
354 RectHeightIsGTEToRectXHeight
, rect_x
, "height is >= to height of rect x") {
355 return arg
.bottom
- arg
.top
>= rect_x
->bottom
- rect_x
->top
;
358 MATCHER_P3(RectIsTopXToYOfRectZ
, x
, y
, rect_z
, "is top x to y of rect z" ) {
359 return rect_z
->top
== arg
.top
&&
360 rect_z
->left
== arg
.left
&&
361 rect_z
->right
== arg
.right
&&
362 arg
.bottom
- arg
.top
>= x
&&
363 arg
.bottom
- arg
.top
<= y
;
366 MATCHER_P2(RectAddedToRectXMakesRectY
,
369 "rect added to rect x makes rect y") {
370 if (::IsRectEmpty(rect_x
))
371 return ::EqualRect(arg
, rect_y
);
373 if (::IsRectEmpty(arg
))
374 return ::EqualRect(rect_x
, rect_y
);
376 // Either they are left and right slices, or top and bottom slices
377 if (!((rect_x
->left
== rect_y
->left
&& rect_x
->right
== rect_y
->right
&&
378 arg
->left
== rect_y
->left
&& arg
->right
== rect_y
->right
) ||
379 (rect_x
->top
== rect_y
->top
&& rect_x
->bottom
== rect_y
->bottom
&&
380 arg
->top
== rect_y
->top
&& arg
->bottom
== rect_y
->bottom
))) {
386 if (!::SubtractRect(&expected_arg
, rect_y
, rect_x
))
387 return false; // Given above checks, the difference should not be empty
389 return ::EqualRect(arg
, &expected_arg
);
392 MATCHER_P(FrameHwndIs
, hwnd
, "") {
393 return arg
!= NULL
&& arg
->GetFrameWindow() == hwnd
;
396 ACTION_P(CheckSetFlag
, flag
) {
401 ACTION_P(ResetFlag
, flag
) {
405 ACTION_P2(AsynchronousCloseOnFrame
, loop
, frame
) {
406 loop
->PostTask(FROM_HERE
, base::Bind(&InfobarContent::Frame::CloseInfobar
,
407 base::Unretained(*frame
)));
410 ACTION_P2(AsynchronousHideOnManager
, loop
, manager
) {
411 loop
->PostTask(FROM_HERE
, base::Bind(&InfobarManager::Hide
,
412 base::Unretained(manager
), TOP_INFOBAR
));
417 // The test ensures that the content is sized at least once in each of the
418 // following ranges while fully opening and closing:
420 // [0, infobar_height / 2)
421 // [infobar_height / 2, infobar_height)
422 // [infobar_height, infobar_height]
423 // (infobar_height / 2, infobar_height]
424 // [0, infobar_height / 2]
426 // If the test turns out to be flaky (i.e., because timers are not firing
427 // frequently enough to hit all the ranges), increasing the infobar_height
428 // should increase the margin (by increasing the time spent in each range).
429 TEST(InfobarsInfobarWindowTest
, SlidingTest
) {
430 int infobar_height
= 40;
432 chrome_frame_test::TimedMsgLoop message_loop
;
434 RECT natural_dimensions
= {10, 20, 90, 100 + infobar_height
};
436 // Used to verify that the last RECT given to SetDimensions is the same RECT
437 // reserved by ReserveSpace.
438 RECT current_infobar_dimensions
= {0, 0, 0, 0};
440 // Used to make sure that each SetDimensions is matched by a return from
442 bool pending_reserve_space
= false;
444 InfobarWindow
infobar_window(TOP_INFOBAR
);
446 testing::NiceMock
<MockTopLevelWindow
> window
;
447 ASSERT_TRUE(window
.Create(NULL
, kInitialParentWindowRect
));
448 HWND hwnd
= static_cast<HWND
>(window
);
449 MockInfobarContent
* content
= new MockInfobarContent();
450 scoped_ptr
<MockHost
> host(new MockHost(&infobar_window
,
454 infobar_window
.SetHost(host
.get());
456 // Used to ensure that GetDesiredSize is only called on an installed
458 testing::Expectation installed
;
460 // Will hold the frame given to us in InfobarContent::InstallInFrame.
461 InfobarContent::Frame
* frame
= NULL
;
463 // We could get any number of calls to UpdateLayout. Make sure that, each
464 // time, the space reserved by the InfobarWindow equals the space offered to
465 // the InfobarContent.
466 EXPECT_CALL(*host
, CheckReservedSpace(RectAddedToRectXMakesRectY(
467 ¤t_infobar_dimensions
, &natural_dimensions
)))
468 .Times(testing::AnyNumber())
469 .WillRepeatedly(ResetFlag(&pending_reserve_space
));
471 testing::MockFunction
<void(std::string check_point_name
)> check
;
474 testing::InSequence s
;
475 // During Show(), we get an InstallInFrame
476 installed
= EXPECT_CALL(*content
, InstallInFrame(FrameHwndIs(hwnd
)))
477 .WillOnce(testing::DoAll(testing::SaveArg
<0>(&frame
),
478 testing::Return(true)));
480 // Allow a call to SetDimensions before InstallInFrame returns.
481 EXPECT_CALL(*content
, SetDimensions(testing::AllOf(
482 RectIsTopXToYOfRectZ(0, infobar_height
/ 2 - 1, &natural_dimensions
),
483 RectHeightIsGTEToRectXHeight(¤t_infobar_dimensions
))))
484 .Times(testing::AnyNumber()).WillRepeatedly(testing::DoAll(
485 testing::SaveArg
<0>(¤t_infobar_dimensions
),
486 CheckSetFlag(&pending_reserve_space
)));
488 EXPECT_CALL(check
, Call("returned from Show"));
490 EXPECT_CALL(*content
, SetDimensions(testing::AllOf(
491 RectIsTopXToYOfRectZ(0, infobar_height
/ 2 - 1, &natural_dimensions
),
492 RectHeightIsGTEToRectXHeight(¤t_infobar_dimensions
))))
493 .Times(testing::AtLeast(1)).WillRepeatedly(testing::DoAll(
494 testing::SaveArg
<0>(¤t_infobar_dimensions
),
495 CheckSetFlag(&pending_reserve_space
)));
496 EXPECT_CALL(*content
, SetDimensions(testing::AllOf(
497 RectIsTopXToYOfRectZ(infobar_height
/ 2,
499 &natural_dimensions
),
500 RectHeightIsGTEToRectXHeight(¤t_infobar_dimensions
))))
501 .Times(testing::AtLeast(1)).WillRepeatedly(testing::DoAll(
502 testing::SaveArg
<0>(¤t_infobar_dimensions
),
503 CheckSetFlag(&pending_reserve_space
)));
504 EXPECT_CALL(*content
, SetDimensions(
505 RectIsTopXToYOfRectZ(infobar_height
,
507 &natural_dimensions
)))
508 .WillOnce(testing::DoAll(
509 testing::SaveArg
<0>(¤t_infobar_dimensions
),
510 CheckSetFlag(&pending_reserve_space
),
511 AsynchronousCloseOnFrame(&message_loop
, &frame
)));
513 EXPECT_CALL(*content
, SetDimensions(testing::AllOf(
514 RectIsTopXToYOfRectZ(infobar_height
/ 2 + 1,
516 &natural_dimensions
),
517 RectHeightIsLTEToRectXHeight(¤t_infobar_dimensions
))))
518 .Times(testing::AtLeast(1)).WillRepeatedly(testing::DoAll(
519 testing::SaveArg
<0>(¤t_infobar_dimensions
),
520 CheckSetFlag(&pending_reserve_space
)));
521 EXPECT_CALL(*content
, SetDimensions(testing::AllOf(
522 RectIsTopXToYOfRectZ(0, infobar_height
/ 2, &natural_dimensions
),
523 RectHeightIsLTEToRectXHeight(¤t_infobar_dimensions
))))
524 .Times(testing::AtLeast(1)).WillRepeatedly(testing::DoAll(
525 testing::SaveArg
<0>(¤t_infobar_dimensions
),
526 CheckSetFlag(&pending_reserve_space
)));
528 EXPECT_CALL(*content
, Die()).WillOnce(QUIT_LOOP(message_loop
));
531 EXPECT_CALL(*content
, GetDesiredSize(80, 0))
532 .Times(testing::AnyNumber()).After(installed
)
533 .WillRepeatedly(testing::Return(infobar_height
));
535 ASSERT_NO_FATAL_FAILURE(infobar_window
.Show(content
));
537 ASSERT_NO_FATAL_FAILURE(check
.Call("returned from Show"));
539 ASSERT_NO_FATAL_FAILURE(message_loop
.RunFor(
540 base::TimeDelta::FromSeconds(10)));
542 window
.DestroyWindow();
544 ASSERT_FALSE(message_loop
.WasTimedOut());
547 TEST(InfobarsInfobarManagerTest
, BasicTest
) {
548 chrome_frame_test::TimedMsgLoop message_loop
;
550 int infobar_height
= 40;
551 RECT natural_dimensions
= {10, 20, 90, 100 + infobar_height
};
553 testing::NiceMock
<MockTopLevelWindow
> window
;
554 ASSERT_TRUE(window
.Create(NULL
, kInitialParentWindowRect
) != NULL
);
555 testing::NiceMock
<MockChildWindow
> child_window
;
556 ASSERT_TRUE(child_window
.Create(window
, kInitialChildWindowRect
) != NULL
);
558 HWND parent_hwnd
= static_cast<HWND
>(window
);
559 HWND child_hwnd
= static_cast<HWND
>(child_window
);
561 MockInfobarContent
* content
= new MockInfobarContent();
562 InfobarContent::Frame
* frame
= NULL
;
564 InfobarManager
* manager
= InfobarManager::Get(parent_hwnd
);
565 ASSERT_FALSE(manager
== NULL
);
567 EXPECT_CALL(*content
, GetDesiredSize(80, 0))
568 .Times(testing::AnyNumber())
569 .WillRepeatedly(testing::Return(infobar_height
));
571 EXPECT_CALL(child_window
, OnNcCalcSize(true, testing::_
))
572 .Times(testing::AnyNumber()).WillRepeatedly(
573 RespondToNcCalcSize(0, &natural_dimensions
));
575 EXPECT_CALL(*content
, InstallInFrame(FrameHwndIs(parent_hwnd
)))
576 .WillOnce(testing::DoAll(testing::SaveArg
<0>(&frame
),
577 testing::Return(true)));
579 EXPECT_CALL(*content
, SetDimensions(testing::Not(
580 RectIsTopXToYOfRectZ(infobar_height
,
582 &natural_dimensions
)))).Times(testing::AnyNumber());
584 EXPECT_CALL(*content
, SetDimensions(
585 RectIsTopXToYOfRectZ(infobar_height
,
587 &natural_dimensions
)))
588 .Times(testing::AnyNumber())
589 .WillOnce(AsynchronousHideOnManager(&message_loop
, manager
))
590 .WillRepeatedly(testing::Return());
592 EXPECT_CALL(*content
, Die()).WillOnce(QUIT_LOOP(message_loop
));
594 ASSERT_TRUE(manager
->Show(content
, TOP_INFOBAR
));
596 message_loop
.RunFor(base::TimeDelta::FromSeconds(10));
598 window
.DestroyWindow();
600 ASSERT_FALSE(message_loop
.WasTimedOut());
603 // TODO(erikwright): Write test for variations on return from default
604 // OnNcCalcValidRects