Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / PopupContainerTest.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "web/PopupContainer.h"
28
29 #include <gtest/gtest.h>
30
31 using namespace blink;
32
33 class MockPopupContent : public PopupContent {
34 public:
35     virtual void setMaxHeight(int max) OVERRIDE { maxHeight = max; }
36     virtual int popupContentHeight() const OVERRIDE { return height; }
37     virtual ~MockPopupContent() { }
38
39     virtual void layout() OVERRIDE
40     {
41         layoutCount++;
42         width = std::min(maxWidth, width);
43         height = std::min(maxHeight, height);
44         height -= height % 16;
45     }
46
47     virtual void setMaxWidthAndLayout(int max) OVERRIDE
48     {
49         maxWidth = max;
50         layout();
51     }
52
53     MockPopupContent(const IntSize& widgetSize)
54         : width(widgetSize.width() - borderSize * 2)
55         , height(widgetSize.height() - borderSize * 2)
56         , maxWidth(width)
57         , maxHeight(height)
58         , layoutCount(0)
59     {
60     }
61
62     int width;
63     int height;
64     int maxWidth;
65     int maxHeight;
66     unsigned layoutCount;
67
68     static const int borderSize = 1; // Should match to kBorderSize in PopupContainer.cpp.
69 };
70
71 const int screenMaxX = 1024;
72 const int screenMaxY = 768;
73 const int targetControlWidth = 130;
74
75 static IntRect calculatePositionWithTransformAndRTL(const IntRect& initialRect, const IntSize& transformOffset, int verticalOffset, PopupContent* content)
76 {
77     const bool isRTL = true;
78     const int targetControlHeight = 20;
79     const FloatRect screenRect(0, 0, screenMaxX, screenMaxY);
80     const FloatRect windowRect(0, 0, 512, 512);
81     int rtlOffset = targetControlWidth - initialRect.width();
82     bool needToResizeView = false;
83     return PopupContainer::layoutAndCalculateWidgetRectInternal(initialRect, targetControlHeight, windowRect, screenRect, !isRTL, rtlOffset, verticalOffset, transformOffset, content, needToResizeView);
84 }
85
86 static IntRect calculatePosition(const IntRect& initialRect, PopupContent* content, FloatRect windowRect = FloatRect(0, 0, 512, 512), bool isRTL = true)
87 {
88     const int targetControlHeight = 20;
89     const FloatRect screenRect(0, 0, screenMaxX, screenMaxY);
90     int rtlOffset = (targetControlWidth - initialRect.width()) * (isRTL ? 1 : -1);
91     bool needToResizeView = false;
92     return PopupContainer::layoutAndCalculateWidgetRectInternal(initialRect, targetControlHeight, windowRect, screenRect, !isRTL, rtlOffset, 0, IntSize(), content, needToResizeView);
93 }
94
95 TEST(PopupContainerTest, PopupPosition)
96 {
97     // Suppose that initialRect.location is the bottom-left corner of the target
98     // control such as <select>.
99
100     {
101         // If initialRect is in the screen, nothing should happen.
102         IntRect initialRect(100, 100, 256, 258);
103         MockPopupContent content(initialRect.size());
104         IntRect resultRect = calculatePosition(initialRect, &content);
105         EXPECT_EQ(initialRect, resultRect);
106         EXPECT_EQ(0u, content.layoutCount);
107     }
108
109     {
110         // If the left edge of the control is projecting from the screen, making
111         // the widget aligned to the right edge of the control.
112         IntRect initialRect(-10, 100, 100, 258);
113         MockPopupContent content(initialRect.size());
114         IntRect resultRect = calculatePosition(initialRect, &content);
115         EXPECT_EQ(IntRect(20, 100, 100, 258), resultRect);
116     }
117
118     {
119         // Made the widget aligned to the right edge. But it's still projecting
120         // from the screen.
121         IntRect initialRect(-10, 100, targetControlWidth, 258);
122         MockPopupContent content(initialRect.size());
123         IntRect resultRect = calculatePosition(initialRect, &content);
124         EXPECT_EQ(IntRect(0, 100, 120, 258), resultRect);
125         EXPECT_EQ(118, content.width);
126         EXPECT_TRUE(content.layoutCount);
127     }
128
129     {
130         // If the right edge of the control is projecting from the screen,
131         // shrink the width of the widget.
132         IntRect initialRect(screenMaxX - 100, 100, targetControlWidth, 258);
133         MockPopupContent content(initialRect.size());
134         IntRect resultRect = calculatePosition(initialRect, &content);
135         EXPECT_EQ(IntRect(screenMaxX - 100, 100, 100, 258), resultRect);
136         EXPECT_EQ(98, content.width);
137         EXPECT_TRUE(content.layoutCount);
138     }
139
140     {
141         // If there is no enough room below, move the widget upwards.
142         IntRect initialRect(100, 700, targetControlWidth, 258);
143         MockPopupContent content(initialRect.size());
144         IntRect resultRect = calculatePosition(initialRect, &content);
145         EXPECT_EQ(IntRect(100, 422, targetControlWidth, 258), resultRect);
146         EXPECT_EQ(0u, content.layoutCount);
147     }
148
149     {
150         // There is no enough room below and above, and the below space is larger.
151         IntRect initialRect(100, 300, targetControlWidth, 514);
152         MockPopupContent content(initialRect.size());
153         IntRect resultRect = calculatePosition(initialRect, &content);
154         EXPECT_EQ(IntRect(100, 300, targetControlWidth, 466), resultRect);
155         EXPECT_TRUE(content.layoutCount);
156         EXPECT_EQ(464, content.height);
157     }
158
159     {
160         // There is no enough room below and above, and the above space is larger.
161         IntRect initialRect(100, 400, targetControlWidth, 514);
162         MockPopupContent content(initialRect.size());
163         IntRect resultRect = calculatePosition(initialRect, &content);
164         EXPECT_EQ(IntRect(100, 10, targetControlWidth, 370), resultRect);
165         EXPECT_TRUE(content.layoutCount);
166         EXPECT_EQ(368, content.height);
167     }
168
169     {
170         // There is not enough room to the right, so open the popup menu to the left.
171         IntRect initialRect(screenMaxX - targetControlWidth - 6, 100, targetControlWidth * 2, 100);
172         MockPopupContent content(initialRect.size());
173         IntRect resultRect = calculatePosition(initialRect, &content, FloatRect(0, 0, screenMaxX, screenMaxY), false);
174         EXPECT_EQ(IntRect(758, 100, 260, 100), resultRect);
175     }
176
177     {
178         // Test for --webkit-transform:rotate(53deg).
179         IntRect initialRect(100, 700, targetControlWidth, 258);
180         MockPopupContent content(initialRect.size());
181         IntSize transformOffset(-4, -8);
182         IntRect resultRect = calculatePositionWithTransformAndRTL(initialRect, transformOffset, -104, &content);
183         EXPECT_EQ(IntRect(104, 430, targetControlWidth, 258), resultRect);
184         EXPECT_EQ(0u, content.layoutCount);
185     }
186
187     {
188         // Test for --webkit-transform:rotate(-53deg).
189         IntRect initialRect(100, 700, targetControlWidth, 258);
190         MockPopupContent content(initialRect.size());
191         IntSize transformOffset(4, -8);
192         IntRect resultRect = calculatePositionWithTransformAndRTL(initialRect, transformOffset, 104, &content);
193         EXPECT_EQ(IntRect(96, 430, targetControlWidth, 258), resultRect);
194         EXPECT_EQ(0u, content.layoutCount);
195     }
196 }