1 /* 2 * Copyright (C) 2011 Apple 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'' 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. 24 */ 25 26 #include "config.h" 27 28 #include "wtf/RefCounted.h" 29 #include "wtf/Functional.h" 30 #include <gtest/gtest.h> 31 32 namespace { 33 34 static int returnFortyTwo() 35 { 36 return 42; 37 } 38 39 TEST(FunctionalTest, Basic) 40 { 41 Function<int ()> emptyFunction; 42 ASSERT_TRUE(emptyFunction.isNull()); 43 44 Function<int ()> returnFortyTwoFunction = bind(returnFortyTwo); 45 ASSERT_FALSE(returnFortyTwoFunction.isNull()); 46 ASSERT_EQ(42, returnFortyTwoFunction()); 47 } 48 49 static int multiplyByTwo(int n) 50 { 51 return n * 2; 52 } 53 54 static double multiplyByOneAndAHalf(double d) 55 { 56 return d * 1.5; 57 } 58 59 TEST(FunctionalTest, UnaryBind) 60 { 61 Function<int ()> multiplyFourByTwoFunction = bind(multiplyByTwo, 4); 62 ASSERT_EQ(8, multiplyFourByTwoFunction()); 63 64 Function<double ()> multiplyByOneAndAHalfFunction = bind(multiplyByOneAndAHalf, 3); 65 ASSERT_EQ(4.5, multiplyByOneAndAHalfFunction()); 66 } 67 68 static int multiply(int x, int y) 69 { 70 return x * y; 71 } 72 73 static int subtract(int x, int y) 74 { 75 return x - y; 76 } 77 78 TEST(FunctionalTest, BinaryBind) 79 { 80 Function<int ()> multiplyFourByTwoFunction = bind(multiply, 4, 2); 81 ASSERT_EQ(8, multiplyFourByTwoFunction()); 82 83 Function<int ()> subtractTwoFromFourFunction = bind(subtract, 4, 2); 84 ASSERT_EQ(2, subtractTwoFromFourFunction()); 85 } 86 87 class A { 88 public: 89 explicit A(int i) 90 : m_i(i) 91 { 92 } 93 94 int f() { return m_i; } 95 int addF(int j) { return m_i + j; } 96 97 private: 98 int m_i; 99 }; 100 101 TEST(FunctionalTest, MemberFunctionBind) 102 { 103 A a(10); 104 Function<int ()> function1 = bind(&A::f, &a); 105 ASSERT_EQ(10, function1()); 106 107 Function<int ()> function2 = bind(&A::addF, &a, 15); 108 ASSERT_EQ(25, function2()); 109 } 110 111 class Number : public RefCounted<Number> { 112 public: 113 static PassRefPtr<Number> create(int value) 114 { 115 return adoptRef(new Number(value)); 116 } 117 118 ~Number() 119 { 120 m_value = 0; 121 } 122 123 int value() const { return m_value; } 124 125 private: 126 explicit Number(int value) 127 : m_value(value) 128 { 129 } 130 131 int m_value; 132 }; 133 134 static int multiplyNumberByTwo(Number* number) 135 { 136 return number->value() * 2; 137 } 138 139 TEST(FunctionalTest, RefCountedStorage) 140 { 141 RefPtr<Number> five = Number::create(5); 142 Function<int ()> multiplyFiveByTwoFunction = bind(multiplyNumberByTwo, five); 143 ASSERT_EQ(10, multiplyFiveByTwoFunction()); 144 145 Function<int ()> multiplyFourByTwoFunction = bind(multiplyNumberByTwo, Number::create(4)); 146 ASSERT_EQ(8, multiplyFourByTwoFunction()); 147 148 RefPtr<Number> six = Number::create(6); 149 Function<int ()> multiplySixByTwoFunction = bind(multiplyNumberByTwo, six.release()); 150 ASSERT_FALSE(six); 151 ASSERT_EQ(12, multiplySixByTwoFunction()); 152 } 153 154 } // namespace 155