Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 1 | /* |
| 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 Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 14 | #include "rtc_base/callback_list.h" |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 15 | #include "test/gtest.h" |
| 16 | |
| 17 | namespace webrtc { |
| 18 | namespace { |
| 19 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 20 | TEST(CallbackList, NoRecieverSingleMessageTest) { |
| 21 | CallbackList<std::string> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 22 | |
| 23 | c.Send("message"); |
| 24 | } |
| 25 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 26 | TEST(CallbackList, MultipleParameterMessageTest) { |
| 27 | CallbackList<const std::string&, std::string, std::string&&, int, int*, |
Lahiru Ginnaliya Gamathige | 52fa992 | 2020-09-21 12:28:48 -0700 | [diff] [blame] | 28 | std::string&> |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 29 | c; |
| 30 | std::string str = "messege"; |
| 31 | int i = 10; |
| 32 | |
| 33 | c.Send(str, "message1", "message0", 123, &i, str); |
| 34 | } |
| 35 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 36 | TEST(CallbackList, NoParameterMessageTest) { |
| 37 | CallbackList<> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 38 | |
| 39 | c.Send(); |
| 40 | } |
| 41 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 42 | TEST(CallbackList, ReferenceTest) { |
| 43 | CallbackList<int&> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 44 | int index = 1; |
| 45 | |
| 46 | c.AddReceiver([](int& index) { index++; }); |
| 47 | c.Send(index); |
| 48 | |
| 49 | EXPECT_EQ(index, 2); |
| 50 | } |
| 51 | |
Lahiru Ginnaliya Gamathige | e99c68d | 2020-09-30 14:33:45 -0700 | [diff] [blame] | 52 | enum State { |
| 53 | kNew, |
| 54 | kChecking, |
| 55 | }; |
| 56 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 57 | TEST(CallbackList, SingleEnumValueTest) { |
| 58 | CallbackList<State> c; |
Lahiru Ginnaliya Gamathige | e99c68d | 2020-09-30 14:33:45 -0700 | [diff] [blame] | 59 | 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 Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 68 | TEST(CallbackList, SingleEnumReferenceTest) { |
| 69 | CallbackList<State&> c; |
Lahiru Ginnaliya Gamathige | e99c68d | 2020-09-30 14:33:45 -0700 | [diff] [blame] | 70 | State s = kNew; |
| 71 | |
| 72 | c.AddReceiver([](State& s) { s = kChecking; }); |
| 73 | c.Send(s); |
| 74 | |
| 75 | EXPECT_EQ(s, kChecking); |
| 76 | } |
| 77 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 78 | TEST(CallbackList, ConstReferenceTest) { |
| 79 | CallbackList<int&> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 80 | 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 Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 89 | TEST(CallbackList, PointerTest) { |
| 90 | CallbackList<int*> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 91 | int index = 1; |
| 92 | |
| 93 | c.AddReceiver([](int* index) { (*index)++; }); |
| 94 | c.Send(&index); |
| 95 | |
| 96 | EXPECT_EQ(index, 2); |
| 97 | } |
| 98 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 99 | TEST(CallbackList, CallByValue) { |
| 100 | CallbackList<int> c; |
Karl Wiberg | d88b169 | 2020-09-25 06:16:12 +0200 | [diff] [blame] | 101 | 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 Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 110 | void PlusOne(int& a) { |
| 111 | a++; |
| 112 | } |
| 113 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 114 | TEST(CallbackList, FunctionPtrTest) { |
| 115 | CallbackList<int&> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 116 | int index = 1; |
| 117 | |
| 118 | c.AddReceiver(PlusOne); |
| 119 | c.Send(index); |
| 120 | |
| 121 | EXPECT_EQ(index, 2); |
| 122 | } |
| 123 | |
| 124 | struct LargeNonTrivial { |
| 125 | int a[17]; |
| 126 | |
| 127 | LargeNonTrivial() = default; |
| 128 | LargeNonTrivial(LargeNonTrivial&& m) {} |
| 129 | ~LargeNonTrivial() = default; |
| 130 | |
Mirko Bonadei | 54c90f2 | 2021-10-03 11:26:11 +0200 | [diff] [blame] | 131 | void operator()(int& b) { b = 1; } |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 132 | }; |
| 133 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 134 | TEST(CallbackList, LargeNonTrivialTest) { |
| 135 | CallbackList<int&> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 136 | int i = 0; |
Karl Wiberg | 84ba18a | 2020-10-06 12:10:59 +0200 | [diff] [blame] | 137 | static_assert(sizeof(LargeNonTrivial) > UntypedFunction::kInlineStorageSize, |
| 138 | ""); |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 139 | c.AddReceiver(LargeNonTrivial()); |
| 140 | c.Send(i); |
| 141 | |
| 142 | EXPECT_EQ(i, 1); |
| 143 | } |
| 144 | |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 145 | struct LargeTrivial { |
| 146 | int a[17]; |
| 147 | void operator()(int& x) { x = 1; } |
| 148 | }; |
| 149 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 150 | TEST(CallbackList, LargeTrivial) { |
| 151 | CallbackList<int&> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 152 | LargeTrivial lt; |
| 153 | int i = 0; |
| 154 | |
Karl Wiberg | 84ba18a | 2020-10-06 12:10:59 +0200 | [diff] [blame] | 155 | static_assert(sizeof(lt) > UntypedFunction::kInlineStorageSize, ""); |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 156 | c.AddReceiver(lt); |
| 157 | c.Send(i); |
| 158 | |
| 159 | EXPECT_EQ(i, 1); |
| 160 | } |
| 161 | |
| 162 | struct OnlyNonTriviallyConstructible { |
| 163 | OnlyNonTriviallyConstructible() = default; |
| 164 | OnlyNonTriviallyConstructible(OnlyNonTriviallyConstructible&& m) {} |
| 165 | |
| 166 | void operator()(int& a) { a = 1; } |
| 167 | }; |
| 168 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 169 | TEST(CallbackList, OnlyNonTriviallyMoveConstructible) { |
| 170 | CallbackList<int&> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 171 | int i = 0; |
| 172 | |
| 173 | c.AddReceiver(OnlyNonTriviallyConstructible()); |
| 174 | c.Send(i); |
| 175 | |
| 176 | EXPECT_EQ(i, 1); |
| 177 | } |
| 178 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 179 | TEST(CallbackList, MultipleReceiverSendTest) { |
| 180 | CallbackList<int&> c; |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 181 | 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 Gamathige | e99c68d | 2020-09-30 14:33:45 -0700 | [diff] [blame] | 193 | |
| 194 | class A { |
| 195 | public: |
| 196 | void increment(int& i) const { i++; } |
| 197 | }; |
| 198 | |
Mirko Bonadei | 3d25935 | 2020-10-23 12:04:40 +0200 | [diff] [blame] | 199 | TEST(CallbackList, MemberFunctionTest) { |
| 200 | CallbackList<int&> c; |
Lahiru Ginnaliya Gamathige | e99c68d | 2020-09-30 14:33:45 -0700 | [diff] [blame] | 201 | 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 Wiberg | 54b9141 | 2020-11-25 21:26:17 +0100 | [diff] [blame] | 209 | |
Lahiru Ginnaliya Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 210 | // todo(glahiru): Add a test case to catch some error for Karl's first fix |
Karl Wiberg | 54b9141 | 2020-11-25 21:26:17 +0100 | [diff] [blame] | 211 | |
| 212 | TEST(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 | |
| 226 | TEST(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 | |
| 240 | TEST(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 Gamathige | 3e98280 | 2020-09-16 10:34:21 -0700 | [diff] [blame] | 255 | } // namespace |
| 256 | } // namespace webrtc |