Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include "webrtc/base/bind.h"
     12 #include "webrtc/base/callback.h"
     13 #include "webrtc/base/gunit.h"
     14 #include "webrtc/base/keep_ref_until_done.h"
     15 #include "webrtc/base/refcount.h"
     16 
     17 namespace rtc {
     18 
     19 namespace {
     20 
     21 void f() {}
     22 int g() { return 42; }
     23 int h(int x) { return x * x; }
     24 void i(int& x) { x *= x; }  // NOLINT: Testing refs
     25 
     26 struct BindTester {
     27   int a() { return 24; }
     28   int b(int x) const { return x * x; }
     29 };
     30 
     31 class RefCountedBindTester : public RefCountInterface {
     32  public:
     33   RefCountedBindTester() : count_(0) {}
     34   int AddRef() const override {
     35     return ++count_;
     36   }
     37   int Release() const {
     38     return --count_;
     39   }
     40   int RefCount() const { return count_; }
     41 
     42  private:
     43   mutable int count_;
     44 };
     45 
     46 }  // namespace
     47 
     48 TEST(CallbackTest, VoidReturn) {
     49   Callback0<void> cb;
     50   EXPECT_TRUE(cb.empty());
     51   cb();  // Executing an empty callback should not crash.
     52   cb = Callback0<void>(&f);
     53   EXPECT_FALSE(cb.empty());
     54   cb();
     55 }
     56 
     57 TEST(CallbackTest, IntReturn) {
     58   Callback0<int> cb;
     59   EXPECT_TRUE(cb.empty());
     60   cb = Callback0<int>(&g);
     61   EXPECT_FALSE(cb.empty());
     62   EXPECT_EQ(42, cb());
     63   EXPECT_EQ(42, cb());
     64 }
     65 
     66 TEST(CallbackTest, OneParam) {
     67   Callback1<int, int> cb1(&h);
     68   EXPECT_FALSE(cb1.empty());
     69   EXPECT_EQ(9, cb1(-3));
     70   EXPECT_EQ(100, cb1(10));
     71 
     72   // Try clearing a callback.
     73   cb1 = Callback1<int, int>();
     74   EXPECT_TRUE(cb1.empty());
     75 
     76   // Try a callback with a ref parameter.
     77   Callback1<void, int&> cb2(&i);
     78   int x = 3;
     79   cb2(x);
     80   EXPECT_EQ(9, x);
     81   cb2(x);
     82   EXPECT_EQ(81, x);
     83 }
     84 
     85 TEST(CallbackTest, WithBind) {
     86   BindTester t;
     87   Callback0<int> cb1 = Bind(&BindTester::a, &t);
     88   EXPECT_EQ(24, cb1());
     89   EXPECT_EQ(24, cb1());
     90   cb1 = Bind(&BindTester::b, &t, 10);
     91   EXPECT_EQ(100, cb1());
     92   EXPECT_EQ(100, cb1());
     93   cb1 = Bind(&BindTester::b, &t, 5);
     94   EXPECT_EQ(25, cb1());
     95   EXPECT_EQ(25, cb1());
     96 }
     97 
     98 TEST(KeepRefUntilDoneTest, simple) {
     99   RefCountedBindTester t;
    100   EXPECT_EQ(0, t.RefCount());
    101   {
    102     Callback0<void> cb = KeepRefUntilDone(&t);
    103     EXPECT_EQ(1, t.RefCount());
    104     cb();
    105     EXPECT_EQ(1, t.RefCount());
    106     cb();
    107     EXPECT_EQ(1, t.RefCount());
    108   }
    109   EXPECT_EQ(0, t.RefCount());
    110 }
    111 
    112 TEST(KeepRefUntilDoneTest, copy) {
    113   RefCountedBindTester t;
    114   EXPECT_EQ(0, t.RefCount());
    115   Callback0<void> cb2;
    116   {
    117     Callback0<void> cb = KeepRefUntilDone(&t);
    118     EXPECT_EQ(1, t.RefCount());
    119     cb2 = cb;
    120   }
    121   EXPECT_EQ(1, t.RefCount());
    122   cb2 = Callback0<void>();
    123   EXPECT_EQ(0, t.RefCount());
    124 }
    125 
    126 TEST(KeepRefUntilDoneTest, scopedref) {
    127   RefCountedBindTester t;
    128   EXPECT_EQ(0, t.RefCount());
    129   {
    130     scoped_refptr<RefCountedBindTester> t_scoped_ref(&t);
    131     Callback0<void> cb = KeepRefUntilDone(t_scoped_ref);
    132     t_scoped_ref = nullptr;
    133     EXPECT_EQ(1, t.RefCount());
    134     cb();
    135     EXPECT_EQ(1, t.RefCount());
    136   }
    137   EXPECT_EQ(0, t.RefCount());
    138 }
    139 
    140 }  // namespace rtc
    141