blob: 86c2009fe3b2c148e3e4f04b431ef3358d4d7ae7 [file] [log] [blame]
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:211/*
2 * Copyright 2020 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 */
Jared Siskin802e8e52023-04-20 00:35:2810#include "rtc_base/callback_list.h"
11
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:2112#include <string>
13#include <type_traits>
14
15#include "api/function_view.h"
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:2116#include "test/gtest.h"
17
18namespace webrtc {
19namespace {
20
Niels Möllerbe74b802022-03-18 13:10:1521TEST(CallbackList, NoReceiverSingleMessageTest) {
Mirko Bonadei3d259352020-10-23 10:04:4022 CallbackList<std::string> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:2123
24 c.Send("message");
25}
26
Mirko Bonadei3d259352020-10-23 10:04:4027TEST(CallbackList, MultipleParameterMessageTest) {
28 CallbackList<const std::string&, std::string, std::string&&, int, int*,
Jared Siskin802e8e52023-04-20 00:35:2829 std::string&>
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:2130 c;
31 std::string str = "messege";
32 int i = 10;
33
34 c.Send(str, "message1", "message0", 123, &i, str);
35}
36
Mirko Bonadei3d259352020-10-23 10:04:4037TEST(CallbackList, NoParameterMessageTest) {
38 CallbackList<> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:2139
40 c.Send();
41}
42
Mirko Bonadei3d259352020-10-23 10:04:4043TEST(CallbackList, ReferenceTest) {
44 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:2145 int index = 1;
46
47 c.AddReceiver([](int& index) { index++; });
48 c.Send(index);
49
50 EXPECT_EQ(index, 2);
51}
52
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 21:33:4553enum State {
54 kNew,
55 kChecking,
56};
57
Mirko Bonadei3d259352020-10-23 10:04:4058TEST(CallbackList, SingleEnumValueTest) {
59 CallbackList<State> c;
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 21:33:4560 State s1 = kNew;
61 int index = 0;
62
63 c.AddReceiver([&index](State s) { index++; });
64 c.Send(s1);
65
66 EXPECT_EQ(index, 1);
67}
68
Mirko Bonadei3d259352020-10-23 10:04:4069TEST(CallbackList, SingleEnumReferenceTest) {
70 CallbackList<State&> c;
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 21:33:4571 State s = kNew;
72
73 c.AddReceiver([](State& s) { s = kChecking; });
74 c.Send(s);
75
76 EXPECT_EQ(s, kChecking);
77}
78
Mirko Bonadei3d259352020-10-23 10:04:4079TEST(CallbackList, ConstReferenceTest) {
80 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:2181 int i = 0;
82 int index = 1;
83
84 c.AddReceiver([&i](const int& index) { i = index; });
85 c.Send(index);
86
87 EXPECT_EQ(i, 1);
88}
89
Mirko Bonadei3d259352020-10-23 10:04:4090TEST(CallbackList, PointerTest) {
91 CallbackList<int*> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:2192 int index = 1;
93
94 c.AddReceiver([](int* index) { (*index)++; });
95 c.Send(&index);
96
97 EXPECT_EQ(index, 2);
98}
99
Mirko Bonadei3d259352020-10-23 10:04:40100TEST(CallbackList, CallByValue) {
101 CallbackList<int> c;
Karl Wibergd88b1692020-09-25 04:16:12102 int x = 17;
103
104 c.AddReceiver([&x](int n) { x += n; });
105 int y = 89;
106 c.Send(y);
107
108 EXPECT_EQ(x, 106);
109}
110
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21111void PlusOne(int& a) {
112 a++;
113}
114
Mirko Bonadei3d259352020-10-23 10:04:40115TEST(CallbackList, FunctionPtrTest) {
116 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21117 int index = 1;
118
119 c.AddReceiver(PlusOne);
120 c.Send(index);
121
122 EXPECT_EQ(index, 2);
123}
124
125struct LargeNonTrivial {
126 int a[17];
127
128 LargeNonTrivial() = default;
129 LargeNonTrivial(LargeNonTrivial&& m) {}
130 ~LargeNonTrivial() = default;
131
Mirko Bonadei54c90f22021-10-03 09:26:11132 void operator()(int& b) { b = 1; }
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21133};
134
Mirko Bonadei3d259352020-10-23 10:04:40135TEST(CallbackList, LargeNonTrivialTest) {
136 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21137 int i = 0;
Karl Wiberg84ba18a2020-10-06 10:10:59138 static_assert(sizeof(LargeNonTrivial) > UntypedFunction::kInlineStorageSize,
139 "");
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21140 c.AddReceiver(LargeNonTrivial());
141 c.Send(i);
142
143 EXPECT_EQ(i, 1);
144}
145
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21146struct LargeTrivial {
147 int a[17];
148 void operator()(int& x) { x = 1; }
149};
150
Mirko Bonadei3d259352020-10-23 10:04:40151TEST(CallbackList, LargeTrivial) {
152 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21153 LargeTrivial lt;
154 int i = 0;
155
Karl Wiberg84ba18a2020-10-06 10:10:59156 static_assert(sizeof(lt) > UntypedFunction::kInlineStorageSize, "");
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21157 c.AddReceiver(lt);
158 c.Send(i);
159
160 EXPECT_EQ(i, 1);
161}
162
163struct OnlyNonTriviallyConstructible {
164 OnlyNonTriviallyConstructible() = default;
165 OnlyNonTriviallyConstructible(OnlyNonTriviallyConstructible&& m) {}
166
167 void operator()(int& a) { a = 1; }
168};
169
Mirko Bonadei3d259352020-10-23 10:04:40170TEST(CallbackList, OnlyNonTriviallyMoveConstructible) {
171 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21172 int i = 0;
173
174 c.AddReceiver(OnlyNonTriviallyConstructible());
175 c.Send(i);
176
177 EXPECT_EQ(i, 1);
178}
179
Mirko Bonadei3d259352020-10-23 10:04:40180TEST(CallbackList, MultipleReceiverSendTest) {
181 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21182 std::function<void(int&)> plus = PlusOne;
183 int index = 1;
184
185 c.AddReceiver(plus);
186 c.AddReceiver([](int& i) { i--; });
187 c.AddReceiver(plus);
188 c.AddReceiver(plus);
189 c.Send(index);
190 c.Send(index);
191
192 EXPECT_EQ(index, 5);
193}
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 21:33:45194
195class A {
196 public:
197 void increment(int& i) const { i++; }
198};
199
Mirko Bonadei3d259352020-10-23 10:04:40200TEST(CallbackList, MemberFunctionTest) {
201 CallbackList<int&> c;
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 21:33:45202 A a;
203 int index = 1;
204
205 c.AddReceiver([&a](int& i) { a.increment(i); });
206 c.Send(index);
207
208 EXPECT_EQ(index, 2);
209}
Karl Wiberg54b91412020-11-25 20:26:17210
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21211// todo(glahiru): Add a test case to catch some error for Karl's first fix
Karl Wiberg54b91412020-11-25 20:26:17212
213TEST(CallbackList, RemoveOneReceiver) {
214 int removal_tag[2];
215 CallbackList<> c;
216 int accumulator = 0;
217 c.AddReceiver([&accumulator] { accumulator += 1; });
218 c.AddReceiver(&removal_tag[0], [&accumulator] { accumulator += 10; });
219 c.AddReceiver(&removal_tag[1], [&accumulator] { accumulator += 100; });
220 c.Send();
221 EXPECT_EQ(accumulator, 111);
222 c.RemoveReceivers(&removal_tag[0]);
223 c.Send();
224 EXPECT_EQ(accumulator, 212);
225}
226
227TEST(CallbackList, RemoveZeroReceivers) {
228 int removal_tag[3];
229 CallbackList<> c;
230 int accumulator = 0;
231 c.AddReceiver([&accumulator] { accumulator += 1; });
232 c.AddReceiver(&removal_tag[0], [&accumulator] { accumulator += 10; });
233 c.AddReceiver(&removal_tag[1], [&accumulator] { accumulator += 100; });
234 c.Send();
235 EXPECT_EQ(accumulator, 111);
236 c.RemoveReceivers(&removal_tag[2]);
237 c.Send();
238 EXPECT_EQ(accumulator, 222);
239}
240
241TEST(CallbackList, RemoveManyReceivers) {
242 int removal_tag;
243 CallbackList<> c;
244 int accumulator = 0;
245 c.AddReceiver([&accumulator] { accumulator += 1; });
246 c.AddReceiver(&removal_tag, [&accumulator] { accumulator += 10; });
247 c.AddReceiver([&accumulator] { accumulator += 100; });
248 c.AddReceiver(&removal_tag, [&accumulator] { accumulator += 1000; });
249 c.Send();
250 EXPECT_EQ(accumulator, 1111);
251 c.RemoveReceivers(&removal_tag);
252 c.Send();
253 EXPECT_EQ(accumulator, 1212);
254}
255
Tomas Gunnarsson8bd5d482022-04-09 15:49:00256TEST(CallbackList, RemoveFromSend) {
257 int removal_tag = 0;
258 CallbackList<> c;
259 c.AddReceiver(&removal_tag, [&] {
260 c.RemoveReceivers(&removal_tag);
261 // Do after RemoveReceivers to make sure the lambda is still valid.
262 ++removal_tag;
263 });
264 c.Send();
265 c.Send();
266 EXPECT_EQ(removal_tag, 1);
267}
268
Lahiru Ginnaliya Gamathige3e982802020-09-16 17:34:21269} // namespace
270} // namespace webrtc