blob: 23dfff0bdd53f83b55038d4a7349e62856b8d9fc [file] [log] [blame]
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -07001/*
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 */
10#include <string>
11#include <type_traits>
12
13#include "api/function_view.h"
Mirko Bonadei3d259352020-10-23 12:04:40 +020014#include "rtc_base/callback_list.h"
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -070015#include "test/gtest.h"
16
17namespace webrtc {
18namespace {
19
Mirko Bonadei3d259352020-10-23 12:04:40 +020020TEST(CallbackList, NoRecieverSingleMessageTest) {
21 CallbackList<std::string> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -070022
23 c.Send("message");
24}
25
Mirko Bonadei3d259352020-10-23 12:04:40 +020026TEST(CallbackList, MultipleParameterMessageTest) {
27 CallbackList<const std::string&, std::string, std::string&&, int, int*,
Lahiru Ginnaliya Gamathige52fa9922020-09-21 12:28:48 -070028 std::string&>
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -070029 c;
30 std::string str = "messege";
31 int i = 10;
32
33 c.Send(str, "message1", "message0", 123, &i, str);
34}
35
Mirko Bonadei3d259352020-10-23 12:04:40 +020036TEST(CallbackList, NoParameterMessageTest) {
37 CallbackList<> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -070038
39 c.Send();
40}
41
Mirko Bonadei3d259352020-10-23 12:04:40 +020042TEST(CallbackList, ReferenceTest) {
43 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -070044 int index = 1;
45
46 c.AddReceiver([](int& index) { index++; });
47 c.Send(index);
48
49 EXPECT_EQ(index, 2);
50}
51
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 14:33:45 -070052enum State {
53 kNew,
54 kChecking,
55};
56
Mirko Bonadei3d259352020-10-23 12:04:40 +020057TEST(CallbackList, SingleEnumValueTest) {
58 CallbackList<State> c;
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 14:33:45 -070059 State s1 = kNew;
60 int index = 0;
61
62 c.AddReceiver([&index](State s) { index++; });
63 c.Send(s1);
64
65 EXPECT_EQ(index, 1);
66}
67
Mirko Bonadei3d259352020-10-23 12:04:40 +020068TEST(CallbackList, SingleEnumReferenceTest) {
69 CallbackList<State&> c;
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 14:33:45 -070070 State s = kNew;
71
72 c.AddReceiver([](State& s) { s = kChecking; });
73 c.Send(s);
74
75 EXPECT_EQ(s, kChecking);
76}
77
Mirko Bonadei3d259352020-10-23 12:04:40 +020078TEST(CallbackList, ConstReferenceTest) {
79 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -070080 int i = 0;
81 int index = 1;
82
83 c.AddReceiver([&i](const int& index) { i = index; });
84 c.Send(index);
85
86 EXPECT_EQ(i, 1);
87}
88
Mirko Bonadei3d259352020-10-23 12:04:40 +020089TEST(CallbackList, PointerTest) {
90 CallbackList<int*> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -070091 int index = 1;
92
93 c.AddReceiver([](int* index) { (*index)++; });
94 c.Send(&index);
95
96 EXPECT_EQ(index, 2);
97}
98
Mirko Bonadei3d259352020-10-23 12:04:40 +020099TEST(CallbackList, CallByValue) {
100 CallbackList<int> c;
Karl Wibergd88b1692020-09-25 06:16:12 +0200101 int x = 17;
102
103 c.AddReceiver([&x](int n) { x += n; });
104 int y = 89;
105 c.Send(y);
106
107 EXPECT_EQ(x, 106);
108}
109
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700110void PlusOne(int& a) {
111 a++;
112}
113
Mirko Bonadei3d259352020-10-23 12:04:40 +0200114TEST(CallbackList, FunctionPtrTest) {
115 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700116 int index = 1;
117
118 c.AddReceiver(PlusOne);
119 c.Send(index);
120
121 EXPECT_EQ(index, 2);
122}
123
124struct LargeNonTrivial {
125 int a[17];
126
127 LargeNonTrivial() = default;
128 LargeNonTrivial(LargeNonTrivial&& m) {}
129 ~LargeNonTrivial() = default;
130
Mirko Bonadei54c90f22021-10-03 11:26:11 +0200131 void operator()(int& b) { b = 1; }
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700132};
133
Mirko Bonadei3d259352020-10-23 12:04:40 +0200134TEST(CallbackList, LargeNonTrivialTest) {
135 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700136 int i = 0;
Karl Wiberg84ba18a2020-10-06 12:10:59 +0200137 static_assert(sizeof(LargeNonTrivial) > UntypedFunction::kInlineStorageSize,
138 "");
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700139 c.AddReceiver(LargeNonTrivial());
140 c.Send(i);
141
142 EXPECT_EQ(i, 1);
143}
144
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700145struct LargeTrivial {
146 int a[17];
147 void operator()(int& x) { x = 1; }
148};
149
Mirko Bonadei3d259352020-10-23 12:04:40 +0200150TEST(CallbackList, LargeTrivial) {
151 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700152 LargeTrivial lt;
153 int i = 0;
154
Karl Wiberg84ba18a2020-10-06 12:10:59 +0200155 static_assert(sizeof(lt) > UntypedFunction::kInlineStorageSize, "");
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700156 c.AddReceiver(lt);
157 c.Send(i);
158
159 EXPECT_EQ(i, 1);
160}
161
162struct OnlyNonTriviallyConstructible {
163 OnlyNonTriviallyConstructible() = default;
164 OnlyNonTriviallyConstructible(OnlyNonTriviallyConstructible&& m) {}
165
166 void operator()(int& a) { a = 1; }
167};
168
Mirko Bonadei3d259352020-10-23 12:04:40 +0200169TEST(CallbackList, OnlyNonTriviallyMoveConstructible) {
170 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700171 int i = 0;
172
173 c.AddReceiver(OnlyNonTriviallyConstructible());
174 c.Send(i);
175
176 EXPECT_EQ(i, 1);
177}
178
Mirko Bonadei3d259352020-10-23 12:04:40 +0200179TEST(CallbackList, MultipleReceiverSendTest) {
180 CallbackList<int&> c;
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700181 std::function<void(int&)> plus = PlusOne;
182 int index = 1;
183
184 c.AddReceiver(plus);
185 c.AddReceiver([](int& i) { i--; });
186 c.AddReceiver(plus);
187 c.AddReceiver(plus);
188 c.Send(index);
189 c.Send(index);
190
191 EXPECT_EQ(index, 5);
192}
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 14:33:45 -0700193
194class A {
195 public:
196 void increment(int& i) const { i++; }
197};
198
Mirko Bonadei3d259352020-10-23 12:04:40 +0200199TEST(CallbackList, MemberFunctionTest) {
200 CallbackList<int&> c;
Lahiru Ginnaliya Gamathigee99c68d2020-09-30 14:33:45 -0700201 A a;
202 int index = 1;
203
204 c.AddReceiver([&a](int& i) { a.increment(i); });
205 c.Send(index);
206
207 EXPECT_EQ(index, 2);
208}
Karl Wiberg54b91412020-11-25 21:26:17 +0100209
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700210// todo(glahiru): Add a test case to catch some error for Karl's first fix
Karl Wiberg54b91412020-11-25 21:26:17 +0100211
212TEST(CallbackList, RemoveOneReceiver) {
213 int removal_tag[2];
214 CallbackList<> c;
215 int accumulator = 0;
216 c.AddReceiver([&accumulator] { accumulator += 1; });
217 c.AddReceiver(&removal_tag[0], [&accumulator] { accumulator += 10; });
218 c.AddReceiver(&removal_tag[1], [&accumulator] { accumulator += 100; });
219 c.Send();
220 EXPECT_EQ(accumulator, 111);
221 c.RemoveReceivers(&removal_tag[0]);
222 c.Send();
223 EXPECT_EQ(accumulator, 212);
224}
225
226TEST(CallbackList, RemoveZeroReceivers) {
227 int removal_tag[3];
228 CallbackList<> c;
229 int accumulator = 0;
230 c.AddReceiver([&accumulator] { accumulator += 1; });
231 c.AddReceiver(&removal_tag[0], [&accumulator] { accumulator += 10; });
232 c.AddReceiver(&removal_tag[1], [&accumulator] { accumulator += 100; });
233 c.Send();
234 EXPECT_EQ(accumulator, 111);
235 c.RemoveReceivers(&removal_tag[2]);
236 c.Send();
237 EXPECT_EQ(accumulator, 222);
238}
239
240TEST(CallbackList, RemoveManyReceivers) {
241 int removal_tag;
242 CallbackList<> c;
243 int accumulator = 0;
244 c.AddReceiver([&accumulator] { accumulator += 1; });
245 c.AddReceiver(&removal_tag, [&accumulator] { accumulator += 10; });
246 c.AddReceiver([&accumulator] { accumulator += 100; });
247 c.AddReceiver(&removal_tag, [&accumulator] { accumulator += 1000; });
248 c.Send();
249 EXPECT_EQ(accumulator, 1111);
250 c.RemoveReceivers(&removal_tag);
251 c.Send();
252 EXPECT_EQ(accumulator, 1212);
253}
254
Lahiru Ginnaliya Gamathige3e982802020-09-16 10:34:21 -0700255} // namespace
256} // namespace webrtc