1// Copyright 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.
4
5#import "ui/base/cocoa/controls/hover_image_menu_button.h"
6
7#include "base/mac/foundation_util.h"
8#import "testing/gtest_mac.h"
9#import "ui/base/cocoa/controls/hover_image_menu_button_cell.h"
10#import "ui/gfx/test/ui_cocoa_test_helper.h"
11
12namespace ui {
13
14namespace {
15
16// Test initialization and display of the NSPopUpButton that shows the drop-
17// down menu. Don't try to show the menu, since it will block the thread.
18class HoverImageMenuButtonTest : public CocoaTest {
19 public:
20  HoverImageMenuButtonTest() {}
21
22  // CocoaTest override:
23  virtual void SetUp() OVERRIDE;
24
25 protected:
26  base::scoped_nsobject<HoverImageMenuButton> menu_button_;
27  base::scoped_nsobject<NSImage> normal_;
28  base::scoped_nsobject<NSImage> pressed_;
29  base::scoped_nsobject<NSImage> hovered_;
30
31  DISALLOW_COPY_AND_ASSIGN(HoverImageMenuButtonTest);
32};
33
34void HoverImageMenuButtonTest::SetUp() {
35  menu_button_.reset(
36      [[HoverImageMenuButton alloc] initWithFrame:NSMakeRect(0, 0, 50, 30)
37                                        pullsDown:YES]);
38
39  normal_.reset([base::mac::ObjCCastStrict<NSImage>(
40      [NSImage imageNamed:NSImageNameStatusAvailable]) retain]);
41  pressed_.reset([base::mac::ObjCCastStrict<NSImage>(
42      [NSImage imageNamed:NSImageNameStatusUnavailable]) retain]);
43  hovered_.reset([base::mac::ObjCCastStrict<NSImage>(
44      [NSImage imageNamed:NSImageNameStatusPartiallyAvailable]) retain]);
45  [[menu_button_ hoverImageMenuButtonCell] setDefaultImage:normal_];
46  [[menu_button_ hoverImageMenuButtonCell] setAlternateImage:pressed_];
47  [[menu_button_ hoverImageMenuButtonCell] setHoverImage:hovered_];
48
49  CocoaTest::SetUp();
50  [[test_window() contentView] addSubview:menu_button_];
51}
52
53}  // namespace
54
55TEST_VIEW(HoverImageMenuButtonTest, menu_button_);
56
57// Tests that the correct image is chosen, depending on the cell's state flags.
58TEST_F(HoverImageMenuButtonTest, CheckImagesForState) {
59  EXPECT_FALSE([[menu_button_ cell] isHovered]);
60  EXPECT_FALSE([[menu_button_ cell] isHighlighted]);
61  EXPECT_NSEQ(normal_, [[menu_button_ cell] imageToDraw]);
62  [menu_button_ display];
63
64  [[menu_button_ cell] setHovered:YES];
65  EXPECT_TRUE([[menu_button_ cell] isHovered]);
66  EXPECT_FALSE([[menu_button_ cell] isHighlighted]);
67  EXPECT_NSEQ(hovered_, [[menu_button_ cell] imageToDraw]);
68  [menu_button_ display];
69
70  // Highlighted takes precendece over hover.
71  [[menu_button_ cell] setHighlighted:YES];
72  EXPECT_TRUE([[menu_button_ cell] isHovered]);
73  EXPECT_TRUE([[menu_button_ cell] isHighlighted]);
74  EXPECT_NSEQ(pressed_, [[menu_button_ cell] imageToDraw]);
75  [menu_button_ display];
76
77  [[menu_button_ cell] setHovered:NO];
78  EXPECT_FALSE([[menu_button_ cell] isHovered]);
79  EXPECT_TRUE([[menu_button_ cell] isHighlighted]);
80  EXPECT_NSEQ(pressed_, [[menu_button_ cell] imageToDraw]);
81  [menu_button_ display];
82
83  [[menu_button_ cell] setHighlighted:NO];
84  EXPECT_FALSE([[menu_button_ cell] isHovered]);
85  EXPECT_FALSE([[menu_button_ cell] isHighlighted]);
86  EXPECT_NSEQ(normal_, [[menu_button_ cell] imageToDraw]);
87  [menu_button_ display];
88}
89
90// Tests that calling the various setXImage functions calls setNeedsDisplay.
91TEST_F(HoverImageMenuButtonTest, NewImageCausesDisplay) {
92  [menu_button_ display];
93  EXPECT_FALSE([menu_button_ needsDisplay]);
94
95  // Uses setDefaultImage rather than setImage to ensure the image goes into the
96  // NSPopUpButtonCell's menuItem. It is then accessible using [NSCell image].
97  EXPECT_NSEQ(normal_, [[menu_button_ cell] image]);
98  [[menu_button_ cell] setDefaultImage:pressed_];
99  EXPECT_NSEQ(pressed_, [[menu_button_ cell] image]);
100  EXPECT_TRUE([menu_button_ needsDisplay]);
101  [menu_button_ display];
102  EXPECT_FALSE([menu_button_ needsDisplay]);
103
104  // Highlighting the cell requires a redisplay.
105  [[menu_button_ cell] setHighlighted:YES];
106  EXPECT_TRUE([menu_button_ needsDisplay]);
107  [menu_button_ display];
108  EXPECT_FALSE([menu_button_ needsDisplay]);
109
110  // setAlternateImage comes from NSButtonCell. Ensure the added setHover*
111  // behaviour matches.
112  [[menu_button_ cell] setAlternateImage:normal_];
113  EXPECT_TRUE([menu_button_ needsDisplay]);
114  [menu_button_ display];
115  EXPECT_FALSE([menu_button_ needsDisplay]);
116
117  // Setting the same image should not cause a redisplay.
118  [[menu_button_ cell] setAlternateImage:normal_];
119  EXPECT_FALSE([menu_button_ needsDisplay]);
120
121  // Unhighlighting requires a redisplay.
122  [[menu_button_ cell] setHighlighted:NO];
123  EXPECT_TRUE([menu_button_ needsDisplay]);
124  [menu_button_ display];
125  EXPECT_FALSE([menu_button_ needsDisplay]);
126
127  // Changing hover state requires a redisplay.
128  [[menu_button_ cell] setHovered:YES];
129  EXPECT_TRUE([menu_button_ needsDisplay]);
130  [menu_button_ display];
131  EXPECT_FALSE([menu_button_ needsDisplay]);
132
133  // setHoverImage comes directly from storage in HoverImageMenuButtonCell.
134  [[menu_button_ cell] setHoverImage:normal_];
135  EXPECT_TRUE([menu_button_ needsDisplay]);
136  [menu_button_ display];
137  EXPECT_FALSE([menu_button_ needsDisplay]);
138
139  // Setting the same image should not cause a redisplay.
140  [[menu_button_ cell] setHoverImage:normal_];
141  EXPECT_FALSE([menu_button_ needsDisplay]);
142
143  // Unhover requires a redisplay.
144  [[menu_button_ cell] setHovered:NO];
145  EXPECT_TRUE([menu_button_ needsDisplay]);
146  [menu_button_ display];
147  EXPECT_FALSE([menu_button_ needsDisplay]);
148
149  // Changing the image while not hovered should not require a redisplay.
150  [[menu_button_ cell] setHoverImage:pressed_];
151  EXPECT_FALSE([menu_button_ needsDisplay]);
152}
153
154// Test that the mouse enter and exit is properly handled, to set hover state.
155TEST_F(HoverImageMenuButtonTest, SimulateMouseEnterExit) {
156  [menu_button_ display];
157  EXPECT_FALSE([menu_button_ needsDisplay]);
158  EXPECT_NSEQ(normal_, [[menu_button_ cell] imageToDraw]);
159
160  [menu_button_ mouseEntered:nil];
161  EXPECT_TRUE([menu_button_ needsDisplay]);
162  EXPECT_NSEQ(hovered_, [[menu_button_ cell] imageToDraw]);
163  [menu_button_ display];
164  EXPECT_FALSE([menu_button_ needsDisplay]);
165
166  [menu_button_ mouseExited:nil];
167  EXPECT_TRUE([menu_button_ needsDisplay]);
168  EXPECT_NSEQ(normal_, [[menu_button_ cell] imageToDraw]);
169  [menu_button_ display];
170  EXPECT_FALSE([menu_button_ needsDisplay]);
171}
172
173}  // namespace ui
174