-
Notifications
You must be signed in to change notification settings - Fork 17
/
OnceTest.cpp
117 lines (96 loc) · 2.84 KB
/
OnceTest.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "TestFixtures/SimpleObject.hpp"
#include "TestFixtures/SimpleThreaded.hpp"
#include <autowiring/autowiring.h>
#include <autowiring/CoreContext.h>
#include <autowiring/once.h>
#include THREAD_HEADER
TEST(OnceTest, NoRepeatedCall) {
autowiring::once_signal<void> o;
int val = 0;
o += [&] { val++; };
o = true;
ASSERT_EQ(1, val) << "Lambda not executed when flag was set";
o = true;
ASSERT_EQ(1, val) << "Lambda was executed too many times, once flag did not properly implement idempotence";
}
TEST(OnceTest, CallAfterSet) {
autowiring::once_signal<void> o;
int val1 = 0;
o += [&] { val1++; };
o = true;
ASSERT_EQ(1, val1) << "Lambda not executed when a flag was set";
int val2 = 0;
o += [&] { val2++; };
ASSERT_EQ(1, val2) << "Lambda not executed on assignment as expected";
}
TEST(OnceTest, NoLeaks_Asserted) {
autowiring::once_signal<void> o;
auto v = std::make_shared<bool>(false);
o += [v] {};
ASSERT_EQ(2UL, v.use_count()) << "Shared pointer not properly captured by once flag";
o = true;
ASSERT_TRUE(v.unique()) << "Shared pointer leaked by once flag after execution";
o += [v] {};
ASSERT_TRUE(v.unique()) << "Shared pointer leaked by once flag after post-set attachment";
}
TEST(OnceTest, NoLeaks_NotAsserted) {
auto v = std::make_shared<bool>(false);
{
autowiring::once_signal<void()> x;
x += [v] {};
}
ASSERT_TRUE(v.unique()) << "Signal did not destroy all attached lambdas on its destruction";
}
TEST(OnceTest, MultiLambdaPending) {
autowiring::once_signal<void> o;
std::atomic<int> x{ 0 };
std::atomic<int> y{ 0 };
bool go = true;
std::thread v([&] {
while(go) {
o += [&] { x++; };
y++;
}
});
// Let the other thread zip around for awhile in both modes:
std::this_thread::sleep_for(std::chrono::milliseconds(1));
o = true;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
// Finally we verify that everything got hit as we expected:
go = false;
v.join();
ASSERT_EQ(y, x) << "Not all pended lambdas were executed as expected";
}
class PrivateSignal {
public:
autowiring::once_signal<PrivateSignal> sig;
void signal(void) {
sig.signal();
}
};
TEST(OnceTest, SignalSetWhileCalling) {
autowiring::once_signal<void> sig;
sig += [&] {
ASSERT_TRUE(sig) << "Flag was not set while handler was being invoked";
};
sig = true;
}
TEST(OnceTest, OwnedSignal) {
PrivateSignal priv;
bool hit = false;
priv.sig += [&hit] { hit = true; };
priv.signal();
ASSERT_TRUE(hit) << "Private signal did not get set as expected";
}
TEST(OnceTest, UnregisterHandler) {
autowiring::once_signal<void> sig;
bool hit = false;
auto reg = sig += [&hit] {
hit = true;
};
sig -= reg;
sig();
ASSERT_FALSE(hit) << "Handler not unregistered as expected";
}