1 #include <gtest/gtest.h>
2
3 #include <pajlada/signals/signal.hpp>
4 #include <vector>
5
6 using namespace pajlada::Signals;
7 using namespace std;
8
9 // TODO(pajlada): Make tests that try to put connections/signals in various STL containers
10
TEST(Signal,SingleConnect)11 TEST(Signal, SingleConnect)
12 {
13 Signal<int> incrementSignal;
14
15 int a = 0;
16
17 auto IncrementA = [&a](int incrementBy) {
18 a += incrementBy; //
19 };
20
21 EXPECT_EQ(a, 0);
22
23 incrementSignal.invoke(1);
24
25 EXPECT_EQ(a, 0);
26
27 incrementSignal.connect(IncrementA);
28
29 incrementSignal.invoke(1);
30
31 EXPECT_EQ(a, 1);
32
33 incrementSignal.invoke(2);
34
35 EXPECT_EQ(a, 3);
36 }
37
TEST(Signal,MultipleConnect)38 TEST(Signal, MultipleConnect)
39 {
40 Signal<int> incrementSignal;
41
42 int a = 0;
43
44 auto IncrementA = [&a](int incrementBy) {
45 a += incrementBy; //
46 };
47
48 EXPECT_EQ(a, 0);
49
50 incrementSignal.invoke(1);
51
52 EXPECT_EQ(a, 0);
53
54 incrementSignal.connect(IncrementA);
55 incrementSignal.connect(IncrementA);
56
57 incrementSignal.invoke(1);
58
59 EXPECT_EQ(a, 2);
60
61 incrementSignal.invoke(2);
62
63 EXPECT_EQ(a, 6);
64 }
65
TEST(Connection,IsConnected)66 TEST(Connection, IsConnected)
67 {
68 Signal<int> incrementSignal;
69 int a = 0;
70 auto IncrementA = [&a](int incrementBy) {
71 a += incrementBy; //
72 };
73 EXPECT_EQ(a, 0);
74
75 auto conn = incrementSignal.connect(IncrementA);
76
77 incrementSignal.invoke(1);
78
79 EXPECT_EQ(a, 1);
80
81 EXPECT_TRUE(conn.isConnected());
82 conn.disconnect();
83 EXPECT_FALSE(conn.isConnected());
84 conn.disconnect();
85 EXPECT_FALSE(conn.isConnected());
86
87 incrementSignal.invoke(1);
88
89 EXPECT_EQ(a, 1);
90 }
91
TEST(Connection,Blocking)92 TEST(Connection, Blocking)
93 {
94 Signal<int> incrementSignal;
95 int a = 0;
96 auto IncrementA = [&a](int incrementBy) {
97 a += incrementBy; //
98 };
99 EXPECT_EQ(a, 0);
100
101 auto conn = incrementSignal.connect(IncrementA);
102
103 incrementSignal.invoke(1);
104
105 EXPECT_EQ(a, 1);
106
107 EXPECT_FALSE(conn.isBlocked());
108 EXPECT_TRUE(conn.block());
109 EXPECT_TRUE(conn.isBlocked());
110 EXPECT_FALSE(conn.block());
111 EXPECT_TRUE(conn.isBlocked());
112
113 incrementSignal.invoke(1);
114
115 EXPECT_EQ(a, 1);
116
117 EXPECT_TRUE(conn.unblock());
118 EXPECT_FALSE(conn.isBlocked());
119 EXPECT_FALSE(conn.unblock());
120 EXPECT_FALSE(conn.isBlocked());
121
122 incrementSignal.invoke(2);
123
124 EXPECT_EQ(a, 3);
125 }
126
TEST(Connection,BlockDisconnected)127 TEST(Connection, BlockDisconnected)
128 {
129 Signal<int> incrementSignal;
130 int a = 0;
131 auto IncrementA = [&a](int incrementBy) {
132 a += incrementBy; //
133 };
134 EXPECT_EQ(a, 0);
135
136 auto conn = incrementSignal.connect(IncrementA);
137
138 incrementSignal.invoke(1);
139
140 EXPECT_EQ(a, 1);
141
142 EXPECT_TRUE(conn.isConnected());
143 conn.disconnect();
144 EXPECT_FALSE(conn.isConnected());
145
146 incrementSignal.invoke(1);
147
148 EXPECT_EQ(a, 1);
149
150 EXPECT_FALSE(conn.isBlocked());
151 EXPECT_FALSE(conn.block());
152 EXPECT_FALSE(conn.isBlocked());
153 EXPECT_FALSE(conn.unblock());
154 EXPECT_FALSE(conn.isBlocked());
155 }
156
TEST(Connection,Copying)157 TEST(Connection, Copying)
158 {
159 Signal<int> incrementSignal;
160 int a = 0;
161 auto IncrementA = [&a](int incrementBy) {
162 a += incrementBy; //
163 };
164 EXPECT_EQ(a, 0);
165
166 auto conn = incrementSignal.connect(IncrementA);
167
168 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
169 EXPECT_EQ(conn.getSubscriberRefCount().count, 1);
170
171 incrementSignal.invoke(1);
172 EXPECT_EQ(a, 1);
173
174 // Test copying of connection
175 auto connCopy = conn;
176 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
177 EXPECT_EQ(conn.getSubscriberRefCount().count, 2);
178
179 incrementSignal.invoke(1);
180 EXPECT_EQ(a, 2);
181
182 EXPECT_TRUE(connCopy.disconnect());
183
184 incrementSignal.invoke(1);
185 EXPECT_EQ(a, 3);
186
187 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
188 EXPECT_EQ(conn.getSubscriberRefCount().count, 1);
189
190 EXPECT_TRUE(conn.disconnect());
191
192 EXPECT_FALSE(conn.getSubscriberRefCount().connected);
193
194 incrementSignal.invoke(1);
195 EXPECT_EQ(a, 3);
196 }
197
TEST(Connection,AssignmentOperatorCopySelf)198 TEST(Connection, AssignmentOperatorCopySelf)
199 {
200 Signal<int> incrementSignal;
201 int a = 0;
202 auto IncrementA = [&a](int incrementBy) {
203 a += incrementBy; //
204 };
205 EXPECT_EQ(a, 0);
206
207 auto conn = incrementSignal.connect(IncrementA);
208
209 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
210 EXPECT_EQ(conn.getSubscriberRefCount().count, 1);
211
212 incrementSignal.invoke(1);
213 EXPECT_EQ(a, 1);
214
215 // Test copying of connection
216 auto connCopy = conn;
217 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
218 EXPECT_EQ(conn.getSubscriberRefCount().count, 2);
219
220 incrementSignal.invoke(1);
221 EXPECT_EQ(a, 2);
222
223 connCopy = connCopy;
224
225 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
226 EXPECT_EQ(conn.getSubscriberRefCount().count, 2);
227
228 incrementSignal.invoke(1);
229 EXPECT_EQ(a, 3);
230
231 EXPECT_TRUE(connCopy.disconnect());
232
233 incrementSignal.invoke(1);
234 EXPECT_EQ(a, 4);
235
236 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
237 EXPECT_EQ(conn.getSubscriberRefCount().count, 1);
238
239 EXPECT_TRUE(conn.disconnect());
240
241 EXPECT_FALSE(conn.getSubscriberRefCount().connected);
242
243 incrementSignal.invoke(1);
244 EXPECT_EQ(a, 4);
245 }
246
TEST(Connection,AssignmentOperatorMove)247 TEST(Connection, AssignmentOperatorMove)
248 {
249 Signal<int> incrementSignal;
250 int a = 0;
251 auto IncrementA = [&a](int incrementBy) {
252 a += incrementBy; //
253 };
254 EXPECT_EQ(a, 0);
255
256 auto conn = incrementSignal.connect(IncrementA);
257
258 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
259 EXPECT_EQ(conn.getSubscriberRefCount().count, 1);
260
261 incrementSignal.invoke(1);
262 EXPECT_EQ(a, 1);
263
264 // Test copying of connection
265 auto yoinkedConn = std::move(conn);
266 EXPECT_FALSE(conn.getSubscriberRefCount().connected);
267 EXPECT_EQ(conn.getSubscriberRefCount().count, 0);
268 EXPECT_TRUE(yoinkedConn.getSubscriberRefCount().connected);
269 EXPECT_EQ(yoinkedConn.getSubscriberRefCount().count, 1);
270
271 incrementSignal.invoke(1);
272 EXPECT_EQ(a, 2);
273
274 EXPECT_TRUE(yoinkedConn.disconnect());
275
276 incrementSignal.invoke(1);
277 EXPECT_EQ(a, 2);
278 }
279
TEST(Connection,AssignmentOperatorMoveSelf)280 TEST(Connection, AssignmentOperatorMoveSelf)
281 {
282 Signal<int> incrementSignal;
283 int a = 0;
284 auto IncrementA = [&a](int incrementBy) {
285 a += incrementBy; //
286 };
287 EXPECT_EQ(a, 0);
288
289 auto conn = incrementSignal.connect(IncrementA);
290
291 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
292 EXPECT_EQ(conn.getSubscriberRefCount().count, 1);
293
294 incrementSignal.invoke(1);
295 EXPECT_EQ(a, 1);
296
297 // Test copying of connection
298 auto yoinkedConn = std::move(conn);
299 EXPECT_FALSE(conn.getSubscriberRefCount().connected);
300 EXPECT_EQ(conn.getSubscriberRefCount().count, 0);
301 EXPECT_TRUE(yoinkedConn.getSubscriberRefCount().connected);
302 EXPECT_EQ(yoinkedConn.getSubscriberRefCount().count, 1);
303
304 incrementSignal.invoke(1);
305 EXPECT_EQ(a, 2);
306
307 yoinkedConn = std::move(yoinkedConn);
308
309 EXPECT_TRUE(yoinkedConn.getSubscriberRefCount().connected);
310 EXPECT_EQ(yoinkedConn.getSubscriberRefCount().count, 1);
311
312 incrementSignal.invoke(1);
313 EXPECT_EQ(a, 3);
314
315 EXPECT_TRUE(yoinkedConn.disconnect());
316
317 incrementSignal.invoke(1);
318 EXPECT_EQ(a, 3);
319 }
320
TEST(ScopedConnection,MoveConstructorFromBase)321 TEST(ScopedConnection, MoveConstructorFromBase)
322 {
323 Signal<int> incrementSignal;
324 int a = 0;
325 auto IncrementA = [&a](int incrementBy) {
326 a += incrementBy; //
327 };
328 EXPECT_EQ(a, 0);
329
330 {
331 ScopedConnection scopedConn(incrementSignal.connect(IncrementA));
332
333 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
334 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 1);
335
336 incrementSignal.invoke(1);
337 EXPECT_EQ(a, 1);
338 }
339
340 incrementSignal.invoke(1);
341 EXPECT_EQ(a, 1);
342 }
343
TEST(ScopedConnection,ConstructFromImplicitlyMovedConnection)344 TEST(ScopedConnection, ConstructFromImplicitlyMovedConnection)
345 {
346 Signal<int> incrementSignal;
347 int a = 0;
348 auto IncrementA = [&a](int incrementBy) {
349 a += incrementBy; //
350 };
351 EXPECT_EQ(a, 0);
352
353 incrementSignal.invoke(1);
354
355 EXPECT_EQ(a, 0);
356
357 {
358 ScopedConnection scopedConn(incrementSignal.connect(IncrementA));
359
360 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
361 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 1);
362
363 incrementSignal.invoke(1);
364 EXPECT_EQ(a, 1);
365 }
366
367 incrementSignal.invoke(1);
368 EXPECT_EQ(a, 1);
369 }
370
TEST(ScopedConnection,ConstructFromCopiedConnection)371 TEST(ScopedConnection, ConstructFromCopiedConnection)
372 {
373 Signal<int> incrementSignal;
374 int a = 0;
375 auto IncrementA = [&a](int incrementBy) {
376 a += incrementBy; //
377 };
378 EXPECT_EQ(a, 0);
379
380 {
381 auto conn = incrementSignal.connect(IncrementA);
382
383 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
384 EXPECT_EQ(conn.getSubscriberRefCount().count, 1);
385
386 ScopedConnection scopedConn(conn);
387
388 EXPECT_TRUE(conn.getSubscriberRefCount().connected);
389 EXPECT_EQ(conn.getSubscriberRefCount().count, 2);
390
391 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
392 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 2);
393
394 incrementSignal.invoke(1);
395 EXPECT_EQ(a, 1);
396
397 EXPECT_TRUE(conn.disconnect());
398 }
399
400 incrementSignal.invoke(1);
401 EXPECT_EQ(a, 1);
402 }
403
TEST(ScopedConnection,ConstructFromCopiedScopedConnection)404 TEST(ScopedConnection, ConstructFromCopiedScopedConnection)
405 {
406 Signal<int> incrementSignal;
407 int a = 0;
408 auto IncrementA = [&a](int incrementBy) {
409 a += incrementBy; //
410 };
411 EXPECT_EQ(a, 0);
412
413 {
414 ScopedConnection scopedConn(incrementSignal.connect(IncrementA));
415
416 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
417 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 1);
418
419 ScopedConnection scopedConnCopy(scopedConn);
420
421 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
422 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 2);
423
424 EXPECT_TRUE(scopedConnCopy.c().getSubscriberRefCount().connected);
425 EXPECT_EQ(scopedConnCopy.c().getSubscriberRefCount().count, 2);
426
427 incrementSignal.invoke(1);
428 EXPECT_EQ(a, 1);
429 }
430
431 incrementSignal.invoke(1);
432 EXPECT_EQ(a, 1);
433 }
434
TEST(ScopedConnection,STLContainer)435 TEST(ScopedConnection, STLContainer)
436 {
437 Signal<int> incrementSignal;
438 int a = 0;
439 auto IncrementA = [&a](int incrementBy) {
440 a += incrementBy; //
441 };
442 EXPECT_EQ(a, 0);
443
444 vector<ScopedConnection> scopedConnections;
445
446 {
447 ScopedConnection scopedConn(incrementSignal.connect(IncrementA));
448
449 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
450 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 1);
451
452 ScopedConnection scopedConnCopy(scopedConn);
453
454 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
455 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 2);
456
457 ScopedConnection scopedConnMoved(move(scopedConn));
458
459 EXPECT_TRUE(scopedConnMoved.c().getSubscriberRefCount().connected);
460 EXPECT_EQ(scopedConnMoved.c().getSubscriberRefCount().count, 2);
461
462 EXPECT_TRUE(scopedConnCopy.c().getSubscriberRefCount().connected);
463 EXPECT_EQ(scopedConnCopy.c().getSubscriberRefCount().count, 2);
464
465 scopedConnections.emplace_back(move(scopedConnCopy));
466
467 EXPECT_TRUE(scopedConnMoved.c().getSubscriberRefCount().connected);
468 EXPECT_EQ(scopedConnMoved.c().getSubscriberRefCount().count, 2);
469
470 scopedConnections.emplace_back(move(scopedConnMoved));
471
472 EXPECT_TRUE(
473 scopedConnections.front().c().getSubscriberRefCount().connected);
474 EXPECT_EQ(scopedConnections.front().c().getSubscriberRefCount().count,
475 2);
476
477 incrementSignal.invoke(1);
478 EXPECT_EQ(a, 1);
479 }
480
481 incrementSignal.invoke(1);
482 EXPECT_EQ(a, 2);
483
484 scopedConnections.clear();
485
486 incrementSignal.invoke(1);
487 EXPECT_EQ(a, 2);
488 }
489
TEST(ScopedConnection,VectorPushBack)490 TEST(ScopedConnection, VectorPushBack)
491 {
492 Signal<int> incrementSignal;
493 int a = 0;
494 auto IncrementA = [&a](int incrementBy) {
495 a += incrementBy; //
496 };
497 EXPECT_EQ(a, 0);
498
499 vector<ScopedConnection> scopedConnections;
500
501 {
502 scopedConnections.push_back(incrementSignal.connect(IncrementA));
503
504 incrementSignal.invoke(1);
505 EXPECT_EQ(a, 1);
506 }
507
508 incrementSignal.invoke(1);
509 EXPECT_EQ(a, 2);
510
511 scopedConnections.clear();
512
513 incrementSignal.invoke(1);
514 EXPECT_EQ(a, 2);
515 }
516
TEST(ScopedConnection,VectorEmplaceBack)517 TEST(ScopedConnection, VectorEmplaceBack)
518 {
519 Signal<int> incrementSignal;
520 int a = 0;
521 auto IncrementA = [&a](int incrementBy) {
522 a += incrementBy; //
523 };
524 EXPECT_EQ(a, 0);
525
526 vector<ScopedConnection> scopedConnections;
527
528 {
529 scopedConnections.emplace_back(incrementSignal.connect(IncrementA));
530
531 incrementSignal.invoke(1);
532 EXPECT_EQ(a, 1);
533 }
534
535 incrementSignal.invoke(1);
536 EXPECT_EQ(a, 2);
537
538 scopedConnections.clear();
539
540 incrementSignal.invoke(1);
541 EXPECT_EQ(a, 2);
542 }
543
TEST(ScopedConnection,AssignmentOperatorCopyConnection)544 TEST(ScopedConnection, AssignmentOperatorCopyConnection)
545 {
546 Signal<int> incrementSignal;
547 int a = 0;
548 auto IncrementA = [&a](int incrementBy) {
549 a += incrementBy; //
550 };
551 EXPECT_EQ(a, 0);
552
553 // Nothing connected, should not change
554 incrementSignal.invoke(1);
555 EXPECT_EQ(a, 0);
556
557 {
558 Connection connA = incrementSignal.connect(IncrementA);
559
560 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
561 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
562
563 Connection connB = incrementSignal.connect(IncrementA);
564
565 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
566 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
567
568 // 2 connections connected
569 incrementSignal.invoke(1);
570 EXPECT_EQ(a, 2);
571
572 {
573 ScopedConnection scopedConn(connA);
574
575 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
576 EXPECT_EQ(connA.getSubscriberRefCount().count, 2);
577 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
578 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
579
580 scopedConn = connB;
581
582 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
583 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
584 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
585 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 2);
586
587 scopedConn = connA;
588
589 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
590 EXPECT_EQ(connA.getSubscriberRefCount().count, 2);
591 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
592 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
593
594 // 2 connections still connected
595 incrementSignal.invoke(1);
596 EXPECT_EQ(a, 4);
597 }
598
599 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
600 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
601 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
602 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
603 }
604 }
605
TEST(ScopedConnection,AssignmentOperatorCopyScopedConnection)606 TEST(ScopedConnection, AssignmentOperatorCopyScopedConnection)
607 {
608 Signal<int> incrementSignal;
609 int a = 0;
610 auto IncrementA = [&a](int incrementBy) {
611 a += incrementBy; //
612 };
613 EXPECT_EQ(a, 0);
614
615 // Nothing connected, should not change
616 incrementSignal.invoke(1);
617 EXPECT_EQ(a, 0);
618
619 {
620 Connection connA = incrementSignal.connect(IncrementA);
621
622 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
623 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
624
625 Connection connB = incrementSignal.connect(IncrementA);
626
627 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
628 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
629
630 // 2 connections connected
631 incrementSignal.invoke(1);
632 EXPECT_EQ(a, 2);
633
634 {
635 ScopedConnection scopedConn(connA);
636 ScopedConnection scB(connB);
637
638 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
639 EXPECT_EQ(connA.getSubscriberRefCount().count, 2);
640 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
641 EXPECT_EQ(connB.getSubscriberRefCount().count, 2);
642
643 scopedConn = scB;
644
645 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
646 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
647 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
648 EXPECT_EQ(connB.getSubscriberRefCount().count, 3);
649
650 // 2 connections still connected
651 incrementSignal.invoke(1);
652 EXPECT_EQ(a, 4);
653 }
654
655 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
656 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
657 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
658 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
659 }
660 }
661
TEST(ScopedConnection,AssignmentOperatorMoveScopedConnection)662 TEST(ScopedConnection, AssignmentOperatorMoveScopedConnection)
663 {
664 Signal<int> incrementSignal;
665 int a = 0;
666 auto IncrementA = [&a](int incrementBy) {
667 a += incrementBy; //
668 };
669 EXPECT_EQ(a, 0);
670
671 // Nothing connected, should not change
672 incrementSignal.invoke(1);
673 EXPECT_EQ(a, 0);
674
675 {
676 Connection connA = incrementSignal.connect(IncrementA);
677
678 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
679 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
680
681 Connection connB = incrementSignal.connect(IncrementA);
682
683 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
684 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
685
686 // 2 connections connected
687 incrementSignal.invoke(1);
688 EXPECT_EQ(a, 2);
689
690 {
691 ScopedConnection scopedConn(connA);
692 ScopedConnection scB(connB);
693
694 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
695 EXPECT_EQ(connA.getSubscriberRefCount().count, 2);
696 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
697 EXPECT_EQ(connB.getSubscriberRefCount().count, 2);
698
699 scopedConn = std::move(scB);
700
701 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
702 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
703 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
704 EXPECT_EQ(connB.getSubscriberRefCount().count, 2);
705
706 // 2 connections still connected
707 incrementSignal.invoke(1);
708 EXPECT_EQ(a, 4);
709 }
710
711 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
712 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
713 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
714 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
715 }
716 }
717
TEST(ScopedConnection,AssignmentOperatorMoveScopedConnectionSelf)718 TEST(ScopedConnection, AssignmentOperatorMoveScopedConnectionSelf)
719 {
720 Signal<int> incrementSignal;
721 int a = 0;
722 auto IncrementA = [&a](int incrementBy) {
723 a += incrementBy; //
724 };
725 EXPECT_EQ(a, 0);
726
727 // Nothing connected, should not change
728 incrementSignal.invoke(1);
729 EXPECT_EQ(a, 0);
730
731 {
732 Connection connA = incrementSignal.connect(IncrementA);
733
734 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
735 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
736
737 Connection connB = incrementSignal.connect(IncrementA);
738
739 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
740 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
741
742 // 2 connections connected
743 incrementSignal.invoke(1);
744 EXPECT_EQ(a, 2);
745
746 {
747 ScopedConnection scopedConn(connA);
748
749 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
750 EXPECT_EQ(connA.getSubscriberRefCount().count, 2);
751 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
752 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
753
754 scopedConn = std::move(scopedConn);
755
756 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
757 EXPECT_EQ(connA.getSubscriberRefCount().count, 2);
758 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
759 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
760
761 // 2 connections still connected
762 incrementSignal.invoke(1);
763 EXPECT_EQ(a, 4);
764 }
765
766 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
767 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
768 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
769 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
770 }
771 }
772
TEST(ScopedConnection,AssignmentOperatorMove)773 TEST(ScopedConnection, AssignmentOperatorMove)
774 {
775 Signal<int> incrementSignal;
776 int a = 0;
777 auto IncrementA = [&a](int incrementBy) {
778 a += incrementBy; //
779 };
780 EXPECT_EQ(a, 0);
781
782 // Nothing connected, should not change
783 incrementSignal.invoke(1);
784 EXPECT_EQ(a, 0);
785
786 {
787 Connection connA = incrementSignal.connect(IncrementA);
788
789 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
790 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
791
792 Connection connB = incrementSignal.connect(IncrementA);
793
794 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
795 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
796
797 // 2 connections connected
798 incrementSignal.invoke(1);
799 EXPECT_EQ(a, 2);
800
801 {
802 ScopedConnection scopedConn(connA);
803
804 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
805 EXPECT_EQ(connA.getSubscriberRefCount().count, 2);
806 EXPECT_TRUE(connB.getSubscriberRefCount().connected);
807 EXPECT_EQ(connB.getSubscriberRefCount().count, 1);
808
809 scopedConn = std::move(connB);
810
811 // 2 connections still connected
812 incrementSignal.invoke(1);
813 EXPECT_EQ(a, 4);
814
815 EXPECT_TRUE(connA.getSubscriberRefCount().connected);
816 EXPECT_EQ(connA.getSubscriberRefCount().count, 1);
817 EXPECT_FALSE(connB.getSubscriberRefCount().connected);
818 EXPECT_EQ(connB.getSubscriberRefCount().count, 0);
819 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
820 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 1);
821
822 scopedConn = std::move(connA);
823
824 // connB is gone now, so only 1 should be connected
825 incrementSignal.invoke(1);
826 EXPECT_EQ(a, 5);
827
828 EXPECT_FALSE(connA.getSubscriberRefCount().connected);
829 EXPECT_EQ(connA.getSubscriberRefCount().count, 0);
830 EXPECT_FALSE(connB.getSubscriberRefCount().connected);
831 EXPECT_EQ(connB.getSubscriberRefCount().count, 0);
832
833 EXPECT_TRUE(scopedConn.c().getSubscriberRefCount().connected);
834 EXPECT_EQ(scopedConn.c().getSubscriberRefCount().count, 1);
835 }
836
837 // connB and connA are gone now, since connA was moved into the scoped connection
838 // so nothing should change
839 incrementSignal.invoke(1);
840 EXPECT_EQ(a, 5);
841
842 EXPECT_FALSE(connA.getSubscriberRefCount().connected);
843 EXPECT_EQ(connA.getSubscriberRefCount().count, 0);
844 EXPECT_FALSE(connB.getSubscriberRefCount().connected);
845 EXPECT_EQ(connB.getSubscriberRefCount().count, 0);
846 }
847 }
848
TEST(SelfDisconnectingSignal,MultipleConnects)849 TEST(SelfDisconnectingSignal, MultipleConnects)
850 {
851 NoArgSelfDisconnectingSignal signal;
852
853 int a = 0;
854 int b = 0;
855
856 signal.connect([&] {
857 a++;
858 return a == 1;
859 });
860
861 signal.connect([&] {
862 b++;
863 return b == 2;
864 });
865
866 signal.invoke();
867
868 EXPECT_EQ(a, 1);
869 EXPECT_EQ(b, 1);
870
871 signal.invoke();
872
873 EXPECT_EQ(a, 1);
874 EXPECT_EQ(b, 2);
875
876 signal.invoke();
877
878 EXPECT_EQ(a, 1);
879 EXPECT_EQ(b, 2);
880 }
881