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 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
/***************************************************************************
**
** Copyright (C) 2010, 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (directui@nokia.com)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at directui@nokia.com.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/
#ifndef TESTS_UTILS_H
#define TESTS_UTILS_H
#include <QtTest>
namespace Ut_Utils
{
/*! Generic signal waiter, because signals might not arrive instantly.
*
* How to use:
*
* QObject *obj = new QObject;
* QSignalSpy spy(obj, SIGNAL(destroyed()));
* delete obj;
* Ut_Utils::waitForSignal(spy);
*/
void waitForSignal(const QSignalSpy &spy, int waitLimit = 10)
{
int waitCount = 0;
while (spy.count() < 1) {
++ waitCount;
if (waitCount > waitLimit) {
qCritical() << "Signal didn't arrive: "
<< spy.signal();
break;
}
QTest::qWait(100);
}
}
}
/*! An automated tester for common methods (and their expected behaviour),
* e.g., don't choke on self-assignment.
* TODO: add more common tests.
*
* How to use:
*
* MSetterTester<TesteeType, SetterParamType> tester(testee
* &TesteeType::setParam,
* &TesteeType::param);
* tester.set(new SetterParamType);
*
* TesteeType and SetterParamType must match the type where the function
* pointers were first declared, i.e., for non-virtual methods the most basic
* class that implements them.
*
* See Ut_MTextEdit::testSetters for an example.
*/
template<class T>
class MAbstractTester
{
public:
virtual void set(T *arg, bool checkAccidientialDestruction = true) = 0;
virtual void setReparents(T *arg, bool takesOwnership = true) = 0;
virtual T * get() = 0;
};
template <class R, class T>
class MSetterTester
: public MAbstractTester<T>
{
public:
MSetterTester(R *newObj,
void (R::*newSetterFunction)(T *arg),
T * (R::*newGetterFunction)())
: setterFunction(newSetterFunction)
, getterFunction(newGetterFunction)
, obj(newObj)
{}
virtual void set(T *arg, bool checkAccidentialDestruction = true)
{
(*obj.*setterFunction)(arg);
QCOMPARE(arg, get());
if (checkAccidentialDestruction) {
// Setting arg again should not lead to its destruction, but some
// getters cleanup whatever was previously set, and maybe forget
// to guard against self-assignment:
(*obj.*setterFunction)(arg);
delete arg;
}
}
virtual void setReparents(T *arg, bool takesOwnership = true)
{
QObject *arg2q = dynamic_cast<QObject *>(arg);
QObject *obj2q = dynamic_cast<QObject *>(obj);
if (arg2q && obj2q) {
QObject *lastParent = arg2q->parent();
arg2q->setParent(0);
(*obj.*setterFunction)(arg);
QCOMPARE(arg2q->parent(), (takesOwnership ? obj2q : 0));
arg2q->setParent(lastParent);
} else {
qWarning() << __PRETTY_FUNCTION__
<< "Cannot test ownership transferal: no QObjects";
}
}
virtual void setDoesNotReparent(T *arg)
{
setReparents(arg, false);
}
virtual T* get()
{
return (*obj.*getterFunction)();
}
private:
void (R::*setterFunction)(T *arg);
T * (R::*getterFunction)();
R *obj;
};
#endif // TEST_UTILS_H
|