Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / wtf / FunctionalTest.cpp
blobc5e8fec4f06d0787ddb452e8a21490d9c3f4ebc2
1 /*
2 * Copyright (C) 2011 Apple Inc. All rights reserved.
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.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
26 #include "config.h"
27 #include "wtf/Functional.h"
29 #include "wtf/OwnPtr.h"
30 #include "wtf/RefCounted.h"
31 #include <gtest/gtest.h>
33 namespace WTF {
35 class UnwrappedClass {
36 public:
37 explicit UnwrappedClass(int value)
38 : m_value(value)
42 int value() const { return m_value; }
44 private:
45 int m_value;
48 class WrappedClass {
49 public:
50 explicit WrappedClass(int value)
51 : m_value(value)
55 UnwrappedClass unwrap() const { return UnwrappedClass(m_value); }
57 private:
58 int m_value;
61 // This class must be wrapped in bind() and unwrapped in closure execution.
62 class ClassToBeWrapped {
63 WTF_MAKE_NONCOPYABLE(ClassToBeWrapped);
64 public:
65 explicit ClassToBeWrapped(int value)
66 : m_value(value)
70 WrappedClass wrap() const { return WrappedClass(m_value); }
72 private:
73 int m_value;
76 template<> struct ParamStorageTraits<ClassToBeWrapped> {
77 using StorageType = WrappedClass;
78 static StorageType wrap(const ClassToBeWrapped& value) { return value.wrap(); }
79 static UnwrappedClass unwrap(const StorageType& value) { return value.unwrap(); }
82 namespace {
84 int returnFortyTwo()
86 return 42;
89 TEST(FunctionalTest, Basic)
91 OwnPtr<Function<int()>> returnFortyTwoFunction = bind(returnFortyTwo);
92 EXPECT_EQ(42, (*returnFortyTwoFunction)());
95 int multiplyByTwo(int n)
97 return n * 2;
100 double multiplyByOneAndAHalf(double d)
102 return d * 1.5;
105 TEST(FunctionalTest, UnaryBind)
107 OwnPtr<Function<int()>> multiplyFourByTwoFunction = bind(multiplyByTwo, 4);
108 EXPECT_EQ(8, (*multiplyFourByTwoFunction)());
110 OwnPtr<Function<double()>> multiplyByOneAndAHalfFunction = bind(multiplyByOneAndAHalf, 3);
111 EXPECT_EQ(4.5, (*multiplyByOneAndAHalfFunction)());
114 TEST(FunctionalTest, UnaryPartBind)
116 OwnPtr<Function<int(int)>> multiplyByTwoFunction = bind<int>(multiplyByTwo);
117 EXPECT_EQ(8, (*multiplyByTwoFunction)(4));
119 OwnPtr<Function<double(double)>> multiplyByOneAndAHalfFunction = bind<double>(multiplyByOneAndAHalf);
120 EXPECT_EQ(4.5, (*multiplyByOneAndAHalfFunction)(3));
123 int multiply(int x, int y)
125 return x * y;
128 int subtract(int x, int y)
130 return x - y;
133 TEST(FunctionalTest, BinaryBind)
135 OwnPtr<Function<int()>> multiplyFourByTwoFunction = bind(multiply, 4, 2);
136 EXPECT_EQ(8, (*multiplyFourByTwoFunction)());
138 OwnPtr<Function<int()>> subtractTwoFromFourFunction = bind(subtract, 4, 2);
139 EXPECT_EQ(2, (*subtractTwoFromFourFunction)());
142 TEST(FunctionalTest, BinaryPartBind)
144 OwnPtr<Function<int(int)>> multiplyFourFunction = bind<int>(multiply, 4);
145 EXPECT_EQ(8, (*multiplyFourFunction)(2));
146 OwnPtr<Function<int(int, int)>> multiplyFunction = bind<int, int>(multiply);
147 EXPECT_EQ(8, (*multiplyFunction)(4, 2));
149 OwnPtr<Function<int(int)>> subtractFromFourFunction = bind<int>(subtract, 4);
150 EXPECT_EQ(2, (*subtractFromFourFunction)(2));
151 OwnPtr<Function<int(int, int)>> subtractFunction = bind<int, int>(subtract);
152 EXPECT_EQ(2, (*subtractFunction)(4, 2));
155 void sixArgFunc(int a, double b, char c, int* d, double* e, char* f)
157 *d = a;
158 *e = b;
159 *f = c;
162 void assertArgs(int actualInt, double actualDouble, char actualChar, int expectedInt, double expectedDouble, char expectedChar)
164 EXPECT_EQ(expectedInt, actualInt);
165 EXPECT_EQ(expectedDouble, actualDouble);
166 EXPECT_EQ(expectedChar, actualChar);
169 TEST(FunctionalTest, MultiPartBind)
171 int a = 0;
172 double b = 0.5;
173 char c = 'a';
175 OwnPtr<Function<void(int, double, char, int*, double*, char*)>> unbound =
176 bind<int, double, char, int*, double*, char*>(sixArgFunc);
177 (*unbound)(1, 1.5, 'b', &a, &b, &c);
178 assertArgs(a, b, c, 1, 1.5, 'b');
180 OwnPtr<Function<void(double, char, int*, double*, char*)>> oneBound =
181 bind<double, char, int*, double*, char*>(sixArgFunc, 2);
182 (*oneBound)(2.5, 'c', &a, &b, &c);
183 assertArgs(a, b, c, 2, 2.5, 'c');
185 OwnPtr<Function<void(char, int*, double*, char*)>> twoBound =
186 bind<char, int*, double*, char*>(sixArgFunc, 3, 3.5);
187 (*twoBound)('d', &a, &b, &c);
188 assertArgs(a, b, c, 3, 3.5, 'd');
190 OwnPtr<Function<void(int*, double*, char*)>> threeBound =
191 bind<int*, double*, char*>(sixArgFunc, 4, 4.5, 'e');
192 (*threeBound)(&a, &b, &c);
193 assertArgs(a, b, c, 4, 4.5, 'e');
195 OwnPtr<Function<void(double*, char*)>> fourBound =
196 bind<double*, char*>(sixArgFunc, 5, 5.5, 'f', &a);
197 (*fourBound)(&b, &c);
198 assertArgs(a, b, c, 5, 5.5, 'f');
200 OwnPtr<Function<void(char*)>> fiveBound =
201 bind<char*>(sixArgFunc, 6, 6.5, 'g', &a, &b);
202 (*fiveBound)(&c);
203 assertArgs(a, b, c, 6, 6.5, 'g');
205 OwnPtr<Function<void()>> sixBound =
206 bind(sixArgFunc, 7, 7.5, 'h', &a, &b, &c);
207 (*sixBound)();
208 assertArgs(a, b, c, 7, 7.5, 'h');
211 class A {
212 public:
213 explicit A(int i)
214 : m_i(i)
218 int f() { return m_i; }
219 int addF(int j) { return m_i + j; }
221 private:
222 int m_i;
225 TEST(FunctionalTest, MemberFunctionBind)
227 A a(10);
228 OwnPtr<Function<int()>> function1 = bind(&A::f, &a);
229 EXPECT_EQ(10, (*function1)());
231 OwnPtr<Function<int()>> function2 = bind(&A::addF, &a, 15);
232 EXPECT_EQ(25, (*function2)());
235 TEST(FunctionalTest, MemberFunctionPartBind)
237 A a(10);
238 OwnPtr<Function<int(class A*)>> function1 = bind<class A*>(&A::f);
239 EXPECT_EQ(10, (*function1)(&a));
241 OwnPtr<Function<int(class A*, int)>> unboundFunction2 =
242 bind<class A*, int>(&A::addF);
243 EXPECT_EQ(25, (*unboundFunction2)(&a, 15));
244 OwnPtr<Function<int(int)>> objectBoundFunction2 =
245 bind<int>(&A::addF, &a);
246 EXPECT_EQ(25, (*objectBoundFunction2)(15));
249 class Number : public RefCounted<Number> {
250 public:
251 static PassRefPtr<Number> create(int value)
253 return adoptRef(new Number(value));
256 ~Number()
258 m_value = 0;
261 int value() const { return m_value; }
263 private:
264 explicit Number(int value)
265 : m_value(value)
269 int m_value;
272 int multiplyNumberByTwo(Number* number)
274 return number->value() * 2;
277 TEST(FunctionalTest, RefCountedStorage)
279 RefPtr<Number> five = Number::create(5);
280 OwnPtr<Function<int()>> multiplyFiveByTwoFunction = bind(multiplyNumberByTwo, five);
281 EXPECT_EQ(10, (*multiplyFiveByTwoFunction)());
283 OwnPtr<Function<int()>> multiplyFourByTwoFunction = bind(multiplyNumberByTwo, Number::create(4));
284 EXPECT_EQ(8, (*multiplyFourByTwoFunction)());
286 RefPtr<Number> six = Number::create(6);
287 OwnPtr<Function<int()>> multiplySixByTwoFunction = bind(multiplyNumberByTwo, six.release());
288 EXPECT_FALSE(six);
289 EXPECT_EQ(12, (*multiplySixByTwoFunction)());
292 int processUnwrappedClass(const UnwrappedClass& u, int v)
294 return u.value() * v;
297 // Tests that:
298 // - ParamStorageTraits's wrap()/unwrap() are called, and
299 // - bind()'s arguments are passed as references to ParamStorageTraits::wrap()
300 // with no additional copies.
301 // This test would fail in compile if something is wrong,
302 // rather than in runtime.
303 TEST(FunctionalTest, WrapUnwrap)
305 OwnPtr<Function<int()>> function = bind(processUnwrappedClass, ClassToBeWrapped(3), 7);
306 EXPECT_EQ(21, (*function)());
309 TEST(FunctionalTest, WrapUnwrapInPartialBind)
311 OwnPtr<Function<int(int)>> partiallyBoundFunction = bind<int>(processUnwrappedClass, ClassToBeWrapped(3));
312 EXPECT_EQ(21, (*partiallyBoundFunction)(7));
315 } // anonymous namespace
317 } // namespace WTF