blob: 8f736bdbfded927ea15daf08b7102db593e52356 [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/keep_ref_until_done.h"
Steve Anton10542f22019-01-11 09:11:00 -080014#include "rtc_base/ref_count.h"
Yves Gerey3e707812018-11-28 16:47:49 +010015#include "test/gtest.h"
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000016
17namespace rtc {
18
19namespace {
20
21void f() {}
Yves Gerey665174f2018-06-19 15:03:05 +020022int g() {
23 return 42;
24}
25int h(int x) {
26 return x * x;
27}
28void i(int& x) {
29 x *= x;
30} // NOLINT: Testing refs
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000031
perkj14f41442015-11-30 22:15:45 -080032class RefCountedBindTester : public RefCountInterface {
33 public:
34 RefCountedBindTester() : count_(0) {}
Niels Möller6f72f562017-10-19 13:15:17 +020035 void AddRef() const override { ++count_; }
36 RefCountReleaseStatus Release() const override {
37 --count_;
38 return count_ == 0 ? RefCountReleaseStatus::kDroppedLastRef
39 : RefCountReleaseStatus::kOtherRefsRemained;
perkj14f41442015-11-30 22:15:45 -080040 }
41 int RefCount() const { return count_; }
42
43 private:
44 mutable int count_;
45};
46
henrike@webrtc.orgf0488722014-05-13 18:00:26 +000047} // namespace
48
49TEST(CallbackTest, VoidReturn) {
50 Callback0<void> cb;
51 EXPECT_TRUE(cb.empty());
52 cb(); // Executing an empty callback should not crash.
53 cb = Callback0<void>(&f);
54 EXPECT_FALSE(cb.empty());
55 cb();
56}
57
58TEST(CallbackTest, IntReturn) {
59 Callback0<int> cb;
60 EXPECT_TRUE(cb.empty());
61 cb = Callback0<int>(&g);
62 EXPECT_FALSE(cb.empty());
63 EXPECT_EQ(42, cb());
64 EXPECT_EQ(42, cb());
65}
66
67TEST(CallbackTest, OneParam) {
68 Callback1<int, int> cb1(&h);
69 EXPECT_FALSE(cb1.empty());
70 EXPECT_EQ(9, cb1(-3));
71 EXPECT_EQ(100, cb1(10));
72
73 // Try clearing a callback.
74 cb1 = Callback1<int, int>();
75 EXPECT_TRUE(cb1.empty());
76
77 // Try a callback with a ref parameter.
78 Callback1<void, int&> cb2(&i);
79 int x = 3;
80 cb2(x);
81 EXPECT_EQ(9, x);
82 cb2(x);
83 EXPECT_EQ(81, x);
84}
85
perkj14f41442015-11-30 22:15:45 -080086TEST(KeepRefUntilDoneTest, simple) {
87 RefCountedBindTester t;
88 EXPECT_EQ(0, t.RefCount());
89 {
90 Callback0<void> cb = KeepRefUntilDone(&t);
91 EXPECT_EQ(1, t.RefCount());
92 cb();
93 EXPECT_EQ(1, t.RefCount());
94 cb();
95 EXPECT_EQ(1, t.RefCount());
96 }
97 EXPECT_EQ(0, t.RefCount());
98}
99
100TEST(KeepRefUntilDoneTest, copy) {
101 RefCountedBindTester t;
102 EXPECT_EQ(0, t.RefCount());
103 Callback0<void> cb2;
104 {
105 Callback0<void> cb = KeepRefUntilDone(&t);
106 EXPECT_EQ(1, t.RefCount());
107 cb2 = cb;
108 }
109 EXPECT_EQ(1, t.RefCount());
110 cb2 = Callback0<void>();
111 EXPECT_EQ(0, t.RefCount());
112}
113
114TEST(KeepRefUntilDoneTest, scopedref) {
115 RefCountedBindTester t;
116 EXPECT_EQ(0, t.RefCount());
117 {
118 scoped_refptr<RefCountedBindTester> t_scoped_ref(&t);
119 Callback0<void> cb = KeepRefUntilDone(t_scoped_ref);
120 t_scoped_ref = nullptr;
121 EXPECT_EQ(1, t.RefCount());
122 cb();
123 EXPECT_EQ(1, t.RefCount());
124 }
125 EXPECT_EQ(0, t.RefCount());
126}
127
henrike@webrtc.orgf0488722014-05-13 18:00:26 +0000128} // namespace rtc