blob: 876729570c26d99e987800fbef37d0c46d9afa0a [file] [log] [blame]
henrike@webrtc.orgf0488722014-05-13 18:00:26 +00001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "rtc_base/callback.h"
Yves Gerey3e707812018-11-28 16:47:49 +010012
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "rtc_base/bind.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "rtc_base/keep_ref_until_done.h"
Steve Anton10542f22019-01-11 09:11:00 -080015#include "rtc_base/ref_count.h"
Yves Gerey3e707812018-11-28 16:47:49 +010016#include "test/gtest.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000017
18namespace rtc {
19
20namespace {
21
22void f() {}
Yves Gerey665174f2018-06-19 15:03:05 +020023int g() {
24 return 42;
25}
26int h(int x) {
27 return x * x;
28}
29void i(int& x) {
30 x *= x;
31} // NOLINT: Testing refs
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000032
33struct BindTester {
34 int a() { return 24; }
35 int b(int x) const { return x * x; }
36};
37
perkj14f41442015-11-30 22:15:45 -080038class RefCountedBindTester : public RefCountInterface {
39 public:
40 RefCountedBindTester() : count_(0) {}
Niels Möller6f72f562017-10-19 13:15:17 +020041 void AddRef() const override { ++count_; }
42 RefCountReleaseStatus Release() const override {
43 --count_;
44 return count_ == 0 ? RefCountReleaseStatus::kDroppedLastRef
45 : RefCountReleaseStatus::kOtherRefsRemained;
perkj14f41442015-11-30 22:15:45 -080046 }
47 int RefCount() const { return count_; }
48
49 private:
50 mutable int count_;
51};
52
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000053} // namespace
54
55TEST(CallbackTest, VoidReturn) {
56 Callback0<void> cb;
57 EXPECT_TRUE(cb.empty());
58 cb(); // Executing an empty callback should not crash.
59 cb = Callback0<void>(&f);
60 EXPECT_FALSE(cb.empty());
61 cb();
62}
63
64TEST(CallbackTest, IntReturn) {
65 Callback0<int> cb;
66 EXPECT_TRUE(cb.empty());
67 cb = Callback0<int>(&g);
68 EXPECT_FALSE(cb.empty());
69 EXPECT_EQ(42, cb());
70 EXPECT_EQ(42, cb());
71}
72
73TEST(CallbackTest, OneParam) {
74 Callback1<int, int> cb1(&h);
75 EXPECT_FALSE(cb1.empty());
76 EXPECT_EQ(9, cb1(-3));
77 EXPECT_EQ(100, cb1(10));
78
79 // Try clearing a callback.
80 cb1 = Callback1<int, int>();
81 EXPECT_TRUE(cb1.empty());
82
83 // Try a callback with a ref parameter.
84 Callback1<void, int&> cb2(&i);
85 int x = 3;
86 cb2(x);
87 EXPECT_EQ(9, x);
88 cb2(x);
89 EXPECT_EQ(81, x);
90}
91
92TEST(CallbackTest, WithBind) {
93 BindTester t;
94 Callback0<int> cb1 = Bind(&BindTester::a, &t);
95 EXPECT_EQ(24, cb1());
96 EXPECT_EQ(24, cb1());
97 cb1 = Bind(&BindTester::b, &t, 10);
98 EXPECT_EQ(100, cb1());
99 EXPECT_EQ(100, cb1());
100 cb1 = Bind(&BindTester::b, &t, 5);
101 EXPECT_EQ(25, cb1());
102 EXPECT_EQ(25, cb1());
103}
104
perkj14f41442015-11-30 22:15:45 -0800105TEST(KeepRefUntilDoneTest, simple) {
106 RefCountedBindTester t;
107 EXPECT_EQ(0, t.RefCount());
108 {
109 Callback0<void> cb = KeepRefUntilDone(&t);
110 EXPECT_EQ(1, t.RefCount());
111 cb();
112 EXPECT_EQ(1, t.RefCount());
113 cb();
114 EXPECT_EQ(1, t.RefCount());
115 }
116 EXPECT_EQ(0, t.RefCount());
117}
118
119TEST(KeepRefUntilDoneTest, copy) {
120 RefCountedBindTester t;
121 EXPECT_EQ(0, t.RefCount());
122 Callback0<void> cb2;
123 {
124 Callback0<void> cb = KeepRefUntilDone(&t);
125 EXPECT_EQ(1, t.RefCount());
126 cb2 = cb;
127 }
128 EXPECT_EQ(1, t.RefCount());
129 cb2 = Callback0<void>();
130 EXPECT_EQ(0, t.RefCount());
131}
132
133TEST(KeepRefUntilDoneTest, scopedref) {
134 RefCountedBindTester t;
135 EXPECT_EQ(0, t.RefCount());
136 {
137 scoped_refptr<RefCountedBindTester> t_scoped_ref(&t);
138 Callback0<void> cb = KeepRefUntilDone(t_scoped_ref);
139 t_scoped_ref = nullptr;
140 EXPECT_EQ(1, t.RefCount());
141 cb();
142 EXPECT_EQ(1, t.RefCount());
143 }
144 EXPECT_EQ(0, t.RefCount());
145}
146
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000147} // namespace rtc