Home | History | Annotate | Download | only in wtf
      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     EXPECT_TRUE(emptyFunction.isNull());
     43 
     44     Function<int ()> returnFortyTwoFunction = bind(returnFortyTwo);
     45     EXPECT_FALSE(returnFortyTwoFunction.isNull());
     46     EXPECT_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     EXPECT_EQ(8, multiplyFourByTwoFunction());
     63 
     64     Function<double ()> multiplyByOneAndAHalfFunction = bind(multiplyByOneAndAHalf, 3);
     65     EXPECT_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     EXPECT_EQ(8, multiplyFourByTwoFunction());
     82 
     83     Function<int ()> subtractTwoFromFourFunction = bind(subtract, 4, 2);
     84     EXPECT_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     EXPECT_EQ(10, function1());
    106 
    107     Function<int ()> function2 = bind(&A::addF, &a, 15);
    108     EXPECT_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     EXPECT_EQ(10, multiplyFiveByTwoFunction());
    144 
    145     Function<int ()> multiplyFourByTwoFunction = bind(multiplyNumberByTwo, Number::create(4));
    146     EXPECT_EQ(8, multiplyFourByTwoFunction());
    147 
    148     RefPtr<Number> six = Number::create(6);
    149     Function<int ()> multiplySixByTwoFunction = bind(multiplyNumberByTwo, six.release());
    150     EXPECT_FALSE(six);
    151     EXPECT_EQ(12, multiplySixByTwoFunction());
    152 }
    153 
    154 } // namespace
    155