1 #include "gtest/gtest.h"
2
3 #include <functional>
4 #include <memory>
5
6 #include <QCoreApplication>
7 #include <QPointer>
8 #include <QSharedPointer>
9 #include <QSignalSpy>
10
11 #include "config.h"
12 #include "core/closure.h"
13 #include "test_utils.h"
14
TEST(ClosureTest,ClosureInvokesReceiver)15 TEST(ClosureTest, ClosureInvokesReceiver) {
16 TestQObject sender;
17 TestQObject receiver;
18 _detail::ClosureBase* closure = NewClosure(
19 &sender, SIGNAL(Emitted()),
20 &receiver, SLOT(Invoke()));
21 EXPECT_EQ(0, receiver.invoked());
22 sender.Emit();
23 EXPECT_EQ(1, receiver.invoked());
24 }
25
TEST(ClosureTest,ClosureDeletesSelf)26 TEST(ClosureTest, ClosureDeletesSelf) {
27 TestQObject sender;
28 TestQObject receiver;
29 _detail::ClosureBase* closure = NewClosure(
30 &sender, SIGNAL(Emitted()),
31 &receiver, SLOT(Invoke()));
32 _detail::ObjectHelper* helper = closure->helper();
33 QSignalSpy spy(helper, SIGNAL(destroyed()));
34 EXPECT_EQ(0, receiver.invoked());
35 sender.Emit();
36 EXPECT_EQ(1, receiver.invoked());
37
38 EXPECT_EQ(0, spy.count());
39 QEventLoop loop;
40 QObject::connect(helper, SIGNAL(destroyed()), &loop, SLOT(quit()));
41 loop.exec();
42 EXPECT_EQ(1, spy.count());
43 }
44
TEST(ClosureTest,ClosureDoesNotCrashWithSharedPointerSender)45 TEST(ClosureTest, ClosureDoesNotCrashWithSharedPointerSender) {
46 TestQObject receiver;
47 TestQObject* sender;
48 std::unique_ptr<QSignalSpy> spy;
49 QPointer<_detail::ObjectHelper> closure;
50 {
51 QSharedPointer<TestQObject> sender_shared(new TestQObject);
52 sender = sender_shared.data();
53 closure = QPointer<_detail::ObjectHelper>(NewClosure(
54 sender_shared, SIGNAL(Emitted()),
55 &receiver, SLOT(Invoke()))->helper());
56 spy.reset(new QSignalSpy(sender, SIGNAL(destroyed())));
57 }
58 ASSERT_EQ(0, receiver.invoked());
59 sender->Emit();
60 ASSERT_EQ(1, receiver.invoked());
61
62 ASSERT_EQ(0, spy->count());
63 QEventLoop loop;
64 QObject::connect(sender, SIGNAL(destroyed()), &loop, SLOT(quit()));
65 loop.exec();
66 ASSERT_EQ(1, spy->count());
67 EXPECT_TRUE(closure.isNull());
68 }
69
70 namespace {
71
Foo(bool * called,int question,int * answer)72 void Foo(bool* called, int question, int* answer) {
73 *called = true;
74 *answer = question;
75 }
76
77 } // namespace
78
TEST(ClosureTest,ClosureWorksWithFunctionPointers)79 TEST(ClosureTest, ClosureWorksWithFunctionPointers) {
80 TestQObject sender;
81 bool called = false;
82 int question = 42;
83 int answer = 0;
84 NewClosure(
85 &sender, SIGNAL(Emitted()),
86 &Foo, &called, question, &answer);
87 EXPECT_FALSE(called);
88 sender.Emit();
89 EXPECT_TRUE(called);
90 EXPECT_EQ(question, answer);
91 }
92
TEST(ClosureTest,ClosureWorksWithStandardFunctions)93 TEST(ClosureTest, ClosureWorksWithStandardFunctions) {
94 TestQObject sender;
95 bool called = false;
96 int question = 42;
97 int answer = 0;
98 std::function<void(bool*,int,int*)> callback(&Foo);
99 NewClosure(
100 &sender, SIGNAL(Emitted()),
101 callback, &called, question, &answer);
102 EXPECT_FALSE(called);
103 sender.Emit();
104 EXPECT_TRUE(called);
105 EXPECT_EQ(question, answer);
106 }
107
108 namespace {
109
110 class Bar {
111 public:
Bar(int a)112 explicit Bar(int a) : foo_(a) {}
Foo(int * answer)113 bool Foo(int* answer) {
114 *answer = foo_;
115 return true;
116 }
117
118 private:
119 int foo_;
120 };
121
122 }
123
TEST(ClosureTest,ClosureWorksWithMemberFunctionPointers)124 TEST(ClosureTest, ClosureWorksWithMemberFunctionPointers) {
125 TestQObject sender;
126 Bar receiver(42);
127 int q = 1;
128 NewClosure(
129 &sender, SIGNAL(Emitted()),
130 &receiver, &Bar::Foo, &q);
131 EXPECT_EQ(1, q);
132 sender.Emit();
133 EXPECT_EQ(42, q);
134 }
135
TEST(ClosureTest,ClosureCallsLambda)136 TEST(ClosureTest, ClosureCallsLambda) {
137 TestQObject sender;
138 bool called = false;
139 NewClosure(
140 &sender, SIGNAL(Emitted()),
141 [&called] () { called = true; });
142 EXPECT_FALSE(called);
143 sender.Emit();
144 EXPECT_TRUE(called);
145 }
146