1
0
mirror of https://github.com/clementine-player/Clementine synced 2024-12-29 02:51:27 +01:00
Clementine-audio-player-Mac.../tests/closure_test.cpp
2014-02-06 18:24:46 +01:00

148 lines
3.3 KiB
C++

#include "gtest/gtest.h"
#include <functional>
#include <memory>
#include <QCoreApplication>
#include <QPointer>
#include <QSharedPointer>
#include <QSignalSpy>
#include "config.h"
#include "core/closure.h"
#include "test_utils.h"
TEST(ClosureTest, ClosureInvokesReceiver) {
TestQObject sender;
TestQObject receiver;
_detail::ClosureBase* closure = NewClosure(
&sender, SIGNAL(Emitted()),
&receiver, SLOT(Invoke()));
EXPECT_EQ(0, receiver.invoked());
sender.Emit();
EXPECT_EQ(1, receiver.invoked());
}
TEST(ClosureTest, ClosureDeletesSelf) {
TestQObject sender;
TestQObject receiver;
_detail::ClosureBase* closure = NewClosure(
&sender, SIGNAL(Emitted()),
&receiver, SLOT(Invoke()));
_detail::ObjectHelper* helper = closure->helper();
QSignalSpy spy(helper, SIGNAL(destroyed()));
EXPECT_EQ(0, receiver.invoked());
sender.Emit();
EXPECT_EQ(1, receiver.invoked());
EXPECT_EQ(0, spy.count());
QEventLoop loop;
QObject::connect(helper, SIGNAL(destroyed()), &loop, SLOT(quit()));
loop.exec();
EXPECT_EQ(1, spy.count());
}
TEST(ClosureTest, ClosureDoesNotCrashWithSharedPointerSender) {
TestQObject receiver;
TestQObject* sender;
std::unique_ptr<QSignalSpy> spy;
QPointer<_detail::ObjectHelper> closure;
{
QSharedPointer<TestQObject> sender_shared(new TestQObject);
sender = sender_shared.data();
closure = QPointer<_detail::ObjectHelper>(NewClosure(
sender_shared, SIGNAL(Emitted()),
&receiver, SLOT(Invoke()))->helper());
spy.reset(new QSignalSpy(sender, SIGNAL(destroyed())));
}
ASSERT_EQ(0, receiver.invoked());
sender->Emit();
ASSERT_EQ(1, receiver.invoked());
ASSERT_EQ(0, spy->count());
QEventLoop loop;
QObject::connect(sender, SIGNAL(destroyed()), &loop, SLOT(quit()));
loop.exec();
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::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