1 // Copyright 2019 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 #include "third_party/blink/renderer/platform/geometry/length.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "third_party/blink/renderer/platform/geometry/calculation_expression_node.h"
9 #include "third_party/blink/renderer/platform/geometry/calculation_value.h"
10
11 namespace blink {
12
13 namespace {
14
15 const PixelsAndPercent ten_px(10, 0);
16 const PixelsAndPercent twenty_px(20, 0);
17 const PixelsAndPercent ten_percent(0, 10);
18 const PixelsAndPercent twenty_percent(0, 20);
19
20 } // namespace
21
22 class LengthTest : public ::testing::Test {
23 public:
24 using Pointer = scoped_refptr<const CalculationExpressionNode>;
25
Leaf(PixelsAndPercent value)26 Pointer Leaf(PixelsAndPercent value) {
27 return base::MakeRefCounted<CalculationExpressionLeafNode>(value);
28 }
29
Add(Pointer lhs,Pointer rhs)30 Pointer Add(Pointer lhs, Pointer rhs) {
31 return base::MakeRefCounted<CalculationExpressionAdditiveNode>(
32 std::move(lhs), std::move(rhs),
33 CalculationExpressionAdditiveNode::Type::kAdd);
34 }
35
Subtract(Pointer lhs,Pointer rhs)36 Pointer Subtract(Pointer lhs, Pointer rhs) {
37 return base::MakeRefCounted<CalculationExpressionAdditiveNode>(
38 std::move(lhs), std::move(rhs),
39 CalculationExpressionAdditiveNode::Type::kSubtract);
40 }
41
Multiply(Pointer node,float factor)42 Pointer Multiply(Pointer node, float factor) {
43 return base::MakeRefCounted<CalculationExpressionMultiplicationNode>(
44 std::move(node), factor);
45 }
46
Min(Pointer op1,Pointer op2)47 Pointer Min(Pointer op1, Pointer op2) {
48 Vector<Pointer> operands;
49 operands.push_back(std::move(op1));
50 operands.push_back(std::move(op2));
51 return base::MakeRefCounted<CalculationExpressionComparisonNode>(
52 std::move(operands), CalculationExpressionComparisonNode::Type::kMin);
53 }
54
Max(Pointer op1,Pointer op2)55 Pointer Max(Pointer op1, Pointer op2) {
56 Vector<Pointer> operands;
57 operands.push_back(std::move(op1));
58 operands.push_back(std::move(op2));
59 return base::MakeRefCounted<CalculationExpressionComparisonNode>(
60 std::move(operands), CalculationExpressionComparisonNode::Type::kMax);
61 }
62
CreateLength(Pointer expression)63 Length CreateLength(Pointer expression) {
64 return Length(CalculationValue::CreateSimplified(std::move(expression),
65 kValueRangeAll));
66 }
67 };
68
TEST_F(LengthTest,EvaluateSimpleComparison)69 TEST_F(LengthTest, EvaluateSimpleComparison) {
70 // min(10px, 20px)
71 {
72 Length length = CreateLength(Min(Leaf(ten_px), Leaf(twenty_px)));
73 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(-200));
74 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(-100));
75 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(0));
76 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(100));
77 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(200));
78 }
79
80 // min(10%, 20%)
81 {
82 Length length = CreateLength(Min(Leaf(ten_percent), Leaf(twenty_percent)));
83 EXPECT_EQ(-40.0f, length.GetCalculationValue().Evaluate(-200));
84 EXPECT_EQ(-20.0f, length.GetCalculationValue().Evaluate(-100));
85 EXPECT_EQ(0.0f, length.GetCalculationValue().Evaluate(0));
86 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(100));
87 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(200));
88 }
89
90 // min(10px, 10%)
91 {
92 Length length = CreateLength(Min(Leaf(ten_px), Leaf(twenty_percent)));
93 EXPECT_EQ(-40.0f, length.GetCalculationValue().Evaluate(-200));
94 EXPECT_EQ(-20.0f, length.GetCalculationValue().Evaluate(-100));
95 EXPECT_EQ(0.0f, length.GetCalculationValue().Evaluate(0));
96 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(100));
97 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(200));
98 }
99
100 // max(10px, 20px)
101 {
102 Length length = CreateLength(Max(Leaf(ten_px), Leaf(twenty_px)));
103 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(-200));
104 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(-100));
105 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(0));
106 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(100));
107 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(200));
108 }
109
110 // max(10%, 20%)
111 {
112 Length length = CreateLength(Max(Leaf(ten_percent), Leaf(twenty_percent)));
113 EXPECT_EQ(-20.0f, length.GetCalculationValue().Evaluate(-200));
114 EXPECT_EQ(-10.0f, length.GetCalculationValue().Evaluate(-100));
115 EXPECT_EQ(0.0f, length.GetCalculationValue().Evaluate(0));
116 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(100));
117 EXPECT_EQ(40.0f, length.GetCalculationValue().Evaluate(200));
118 }
119
120 // max(10px, 10%)
121 {
122 Length length = CreateLength(Max(Leaf(ten_px), Leaf(ten_percent)));
123 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(-200));
124 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(-100));
125 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(0));
126 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(100));
127 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(200));
128 }
129 }
130
TEST_F(LengthTest,EvaluateNestedComparisons)131 TEST_F(LengthTest, EvaluateNestedComparisons) {
132 // max(10px, min(10%, 20px))
133 {
134 Length length = CreateLength(
135 Max(Leaf(ten_px), Min(Leaf(ten_percent), Leaf(twenty_px))));
136 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(50));
137 EXPECT_EQ(15.0f, length.GetCalculationValue().Evaluate(150));
138 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(250));
139 }
140
141 // max(10%, min(10px, 20%))
142 {
143 Length length = CreateLength(
144 Max(Leaf(ten_percent), Min(Leaf(ten_px), Leaf(twenty_percent))));
145 EXPECT_EQ(5.0f, length.GetCalculationValue().Evaluate(25));
146 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(50));
147 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(75));
148 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(100));
149 EXPECT_EQ(12.5f, length.GetCalculationValue().Evaluate(125));
150 }
151
152 // min(max(10px, 10%), 20px)
153 {
154 Length length = CreateLength(
155 Min(Max(Leaf(ten_px), Leaf(ten_percent)), Leaf(twenty_px)));
156 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(50));
157 EXPECT_EQ(15.0f, length.GetCalculationValue().Evaluate(150));
158 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(250));
159 }
160
161 // min(max(10%, 10px), 20%)
162 {
163 Length length = CreateLength(
164 Min(Max(Leaf(ten_percent), Leaf(ten_px)), Leaf(twenty_percent)));
165 EXPECT_EQ(5.0f, length.GetCalculationValue().Evaluate(25));
166 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(50));
167 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(75));
168 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(100));
169 EXPECT_EQ(12.5f, length.GetCalculationValue().Evaluate(125));
170 }
171 }
172
TEST_F(LengthTest,EvaluateAdditive)173 TEST_F(LengthTest, EvaluateAdditive) {
174 // min(10%, 10px) + 10px
175 {
176 Length length =
177 CreateLength(Add(Min(Leaf(ten_percent), Leaf(ten_px)), Leaf(ten_px)));
178 EXPECT_EQ(15.0f, length.GetCalculationValue().Evaluate(50));
179 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(100));
180 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(150));
181 }
182
183 // min(10%, 10px) - 10px
184 {
185 Length length = CreateLength(
186 Subtract(Min(Leaf(ten_percent), Leaf(ten_px)), Leaf(ten_px)));
187 EXPECT_EQ(-5.0f, length.GetCalculationValue().Evaluate(50));
188 EXPECT_EQ(0.0f, length.GetCalculationValue().Evaluate(100));
189 EXPECT_EQ(0.0f, length.GetCalculationValue().Evaluate(150));
190 }
191
192 // 10px + max(10%, 10px)
193 {
194 Length length =
195 CreateLength(Add(Leaf(ten_px), Max(Leaf(ten_percent), Leaf(ten_px))));
196 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(50));
197 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(100));
198 EXPECT_EQ(25.0f, length.GetCalculationValue().Evaluate(150));
199 }
200
201 // 10px - max(10%, 10px)
202 {
203 Length length = CreateLength(
204 Subtract(Leaf(ten_px), Max(Leaf(ten_percent), Leaf(ten_px))));
205 EXPECT_EQ(0.0f, length.GetCalculationValue().Evaluate(50));
206 EXPECT_EQ(0.0f, length.GetCalculationValue().Evaluate(100));
207 EXPECT_EQ(-5.0f, length.GetCalculationValue().Evaluate(150));
208 }
209 }
210
TEST_F(LengthTest,EvaluateMultiplicative)211 TEST_F(LengthTest, EvaluateMultiplicative) {
212 // min(10px, 10%) * 2
213 {
214 Length length =
215 CreateLength(Multiply(Min(Leaf(ten_px), Leaf(ten_percent)), 2));
216 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(50));
217 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(100));
218 EXPECT_EQ(20.0f, length.GetCalculationValue().Evaluate(150));
219 }
220
221 // max(10px, 10%) * 0.5
222 {
223 Length length =
224 CreateLength(Multiply(Max(Leaf(ten_px), Leaf(ten_percent)), 0.5));
225 EXPECT_EQ(5.0f, length.GetCalculationValue().Evaluate(50));
226 EXPECT_EQ(5.0f, length.GetCalculationValue().Evaluate(100));
227 EXPECT_EQ(10.0f, length.GetCalculationValue().Evaluate(200));
228 }
229 }
230
TEST_F(LengthTest,BlendExpressions)231 TEST_F(LengthTest, BlendExpressions) {
232 // From: min(10px, 20%)
233 // To: max(20px, 10%)
234 // Progress: 0.25
235
236 Length from_length = CreateLength(Min(Leaf(ten_px), Leaf(twenty_percent)));
237 Length to_length = CreateLength(Max(Leaf(twenty_px), Leaf(ten_percent)));
238 Length blended = to_length.Blend(from_length, 0.25, kValueRangeAll);
239
240 EXPECT_EQ(8.75f, blended.GetCalculationValue().Evaluate(25));
241 EXPECT_EQ(12.5f, blended.GetCalculationValue().Evaluate(50));
242 EXPECT_EQ(12.5f, blended.GetCalculationValue().Evaluate(100));
243 EXPECT_EQ(12.5f, blended.GetCalculationValue().Evaluate(200));
244 EXPECT_EQ(17.5f, blended.GetCalculationValue().Evaluate(400));
245 }
246
TEST_F(LengthTest,ZoomExpression)247 TEST_F(LengthTest, ZoomExpression) {
248 // Original: min(10px, 10%)
249 // Factor: 2.0
250 {
251 Length original = CreateLength(Min(Leaf(ten_px), Leaf(ten_percent)));
252 Length zoomed = original.Zoom(2);
253 EXPECT_EQ(10.0f, zoomed.GetCalculationValue().Evaluate(100));
254 EXPECT_EQ(20.0f, zoomed.GetCalculationValue().Evaluate(200));
255 EXPECT_EQ(20.0f, zoomed.GetCalculationValue().Evaluate(400));
256 }
257
258 // Original: max(10px, 10%)
259 // Factor: 0.5
260 {
261 Length original = CreateLength(Max(Leaf(ten_px), Leaf(ten_percent)));
262 Length zoomed = original.Zoom(0.5);
263 EXPECT_EQ(5.0f, zoomed.GetCalculationValue().Evaluate(25));
264 EXPECT_EQ(5.0f, zoomed.GetCalculationValue().Evaluate(50));
265 EXPECT_EQ(10.0f, zoomed.GetCalculationValue().Evaluate(100));
266 }
267 }
268
TEST_F(LengthTest,SubtractExpressionFromOneHundredPercent)269 TEST_F(LengthTest, SubtractExpressionFromOneHundredPercent) {
270 // min(10px, 20%)
271 {
272 Length original = CreateLength(Min(Leaf(ten_px), Leaf(twenty_percent)));
273 Length result = original.SubtractFromOneHundredPercent();
274 EXPECT_EQ(20.0f, result.GetCalculationValue().Evaluate(25));
275 EXPECT_EQ(40.0f, result.GetCalculationValue().Evaluate(50));
276 EXPECT_EQ(90.0f, result.GetCalculationValue().Evaluate(100));
277 }
278
279 // max(20px, 10%)
280 {
281 Length original = CreateLength(Max(Leaf(twenty_px), Leaf(ten_percent)));
282 Length result = original.SubtractFromOneHundredPercent();
283 EXPECT_EQ(80.0f, result.GetCalculationValue().Evaluate(100));
284 EXPECT_EQ(180.0f, result.GetCalculationValue().Evaluate(200));
285 EXPECT_EQ(360.0f, result.GetCalculationValue().Evaluate(400));
286 }
287 }
288
289 } // namespace blink
290