Clementine-audio-player-Mac.../tests/closure_test.cpp

145 lines
3.3 KiB
C++
Raw Normal View History

2012-03-19 18:38:38 +01:00
#include "gtest/gtest.h"
#include <QCoreApplication>
#include <QPointer>
#include <QSharedPointer>
2012-03-19 18:38:38 +01:00
#include <QSignalSpy>
#include "config.h"
2012-03-19 18:38:38 +01:00
#include "core/closure.h"
#include "test_utils.h"
TEST(ClosureTest, ClosureInvokesReceiver) {
2012-03-19 18:38:38 +01:00
TestQObject sender;
TestQObject receiver;
2012-11-22 15:15:07 +01:00
_detail::ClosureBase* closure = NewClosure(
2012-03-19 18:38:38 +01:00
&sender, SIGNAL(Emitted()),
&receiver, SLOT(Invoke()));
EXPECT_EQ(0, receiver.invoked());
sender.Emit();
EXPECT_EQ(1, receiver.invoked());
}
TEST(ClosureTest, ClosureDeletesSelf) {
2012-03-19 18:38:38 +01:00
TestQObject sender;
TestQObject receiver;
2012-11-22 15:15:07 +01:00
_detail::ClosureBase* closure = NewClosure(
2012-03-19 18:38:38 +01:00
&sender, SIGNAL(Emitted()),
&receiver, SLOT(Invoke()));
2012-11-22 15:15:07 +01:00
_detail::ObjectHelper* helper = closure->helper();
QSignalSpy spy(helper, SIGNAL(destroyed()));
2012-03-19 18:38:38 +01:00
EXPECT_EQ(0, receiver.invoked());
sender.Emit();
EXPECT_EQ(1, receiver.invoked());
EXPECT_EQ(0, spy.count());
QEventLoop loop;
2012-11-22 15:15:07 +01:00
QObject::connect(helper, SIGNAL(destroyed()), &loop, SLOT(quit()));
2012-03-19 18:38:38 +01:00
loop.exec();
EXPECT_EQ(1, spy.count());
}
TEST(ClosureTest, ClosureDoesNotCrashWithSharedPointerSender) {
TestQObject receiver;
TestQObject* sender;
boost::scoped_ptr<QSignalSpy> spy;
2012-11-22 15:15:07 +01:00
QPointer<_detail::ObjectHelper> closure;
{
QSharedPointer<TestQObject> sender_shared(new TestQObject);
sender = sender_shared.data();
2012-11-22 15:15:07 +01:00
closure = QPointer<_detail::ObjectHelper>(NewClosure(
sender_shared, SIGNAL(Emitted()),
2012-11-22 15:15:07 +01:00
&receiver, SLOT(Invoke()))->helper());
spy.reset(new QSignalSpy(sender, SIGNAL(destroyed())));
}
2012-11-22 15:15:07 +01:00
ASSERT_EQ(0, receiver.invoked());
sender->Emit();
2012-11-22 15:15:07 +01:00
ASSERT_EQ(1, receiver.invoked());
2012-11-22 15:15:07 +01:00
ASSERT_EQ(0, spy->count());
QEventLoop loop;
QObject::connect(sender, SIGNAL(destroyed()), &loop, SLOT(quit()));
loop.exec();
2012-11-22 15:15:07 +01:00
ASSERT_EQ(1, spy->count());
EXPECT_TRUE(closure.isNull());
}
namespace {
void Foo(bool* called, int question, int* answer) {
*called = true;
*answer = question;
}
} // namespace
TEST(ClosureTest, ClosureWorksWithFunctionPointers) {
TestQObject sender;
bool called = false;
int question = 42;
int answer = 0;
NewClosure(
&sender, SIGNAL(Emitted()),
&Foo, &called, question, &answer);
EXPECT_FALSE(called);
sender.Emit();
EXPECT_TRUE(called);
EXPECT_EQ(question, answer);
}
TEST(ClosureTest, ClosureWorksWithStandardFunctions) {
TestQObject sender;
bool called = false;
int question = 42;
int answer = 0;
std::tr1::function<void(bool*,int,int*)> callback(&Foo);
NewClosure(
&sender, SIGNAL(Emitted()),
callback, &called, question, &answer);
EXPECT_FALSE(called);
sender.Emit();
EXPECT_TRUE(called);
EXPECT_EQ(question, answer);
}
namespace {
class Bar {
public:
explicit Bar(int a) : foo_(a) {}
bool Foo(int* answer) {
*answer = foo_;
return true;
}
private:
int foo_;
};
}
TEST(ClosureTest, ClosureWorksWithMemberFunctionPointers) {
TestQObject sender;
Bar receiver(42);
int q = 1;
NewClosure(
&sender, SIGNAL(Emitted()),
&receiver, &Bar::Foo, &q);
EXPECT_EQ(1, q);
sender.Emit();
EXPECT_EQ(42, q);
}
#ifdef HAVE_LAMBDAS
TEST(ClosureTest, ClosureCallsLambda) {
TestQObject sender;
bool called = false;
NewClosure(
&sender, SIGNAL(Emitted()),
[&called] () { called = true; });
EXPECT_FALSE(called);
sender.Emit();
EXPECT_TRUE(called);
}
#endif // HAVE_LAMBDAS