UnitTest.cc 15.1 KB
Newer Older
1 2 3 4 5 6 7 8 9
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

Don Gagne's avatar
Don Gagne committed
10 11 12 13 14 15 16 17

/// @file
///     @brief Base class for all unit tests
///
///     @author Don Gagne <don@thegagnes.com>

#include "UnitTest.h"
#include "QGCApplication.h"
18
#include "MAVLinkProtocol.h"
19
#include "MainWindow.h"
20
#include "Vehicle.h"
Don Gagne's avatar
Don Gagne committed
21

22 23 24
#include <QTemporaryFile>
#include <QTime>

Don Gagne's avatar
Don Gagne committed
25 26 27 28 29
bool UnitTest::_messageBoxRespondedTo = false;
bool UnitTest::_badResponseButton = false;
QMessageBox::StandardButton UnitTest::_messageBoxResponseButton = QMessageBox::NoButton;
int UnitTest::_missedMessageBoxCount = 0;

30 31 32 33 34 35
bool UnitTest::_fileDialogRespondedTo = false;
bool UnitTest::_fileDialogResponseSet = false;
QStringList UnitTest::_fileDialogResponse;
enum UnitTest::FileDialogType UnitTest::_fileDialogExpectedType = getOpenFileName;
int UnitTest::_missedFileDialogCount = 0;

36 37 38 39
UnitTest::UnitTest(void)
    : _linkManager(NULL)
    , _mockLink(NULL)
    , _mainWindow(NULL)
40
    , _vehicle(NULL)
41 42 43 44 45 46 47
    , _expectMissedFileDialog(false)
    , _expectMissedMessageBox(false)
    , _unitTestRun(false)
    , _initCalled(false)
    , _cleanupCalled(false)
{    

Don Gagne's avatar
Don Gagne committed
48 49 50 51 52 53 54 55 56 57 58 59 60
}

UnitTest::~UnitTest()
{
    if (_unitTestRun) {
        // Derived classes must call base class implementations
        Q_ASSERT(_initCalled);
        Q_ASSERT(_cleanupCalled);
    }
}

void UnitTest::_addTest(QObject* test)
{
Don Gagne's avatar
Don Gagne committed
61 62 63
	QList<QObject*>& tests = _testList();

    Q_ASSERT(!tests.contains(test));
Don Gagne's avatar
Don Gagne committed
64
    
Don Gagne's avatar
Don Gagne committed
65
    tests.append(test);
Don Gagne's avatar
Don Gagne committed
66 67 68 69 70 71 72
}

void UnitTest::_unitTestCalled(void)
{
    _unitTestRun = true;
}

Don Gagne's avatar
Don Gagne committed
73 74 75 76 77 78 79
/// @brief Returns the list of unit tests.
QList<QObject*>& UnitTest::_testList(void)
{
	static QList<QObject*> tests;
	return tests;
}

80
int UnitTest::run(QString& singleTest)
Don Gagne's avatar
Don Gagne committed
81 82 83
{
    int ret = 0;
    
Don Gagne's avatar
Don Gagne committed
84
    foreach (QObject* test, _testList()) {
Don Gagne's avatar
Don Gagne committed
85
        if (singleTest.isEmpty() || singleTest == test->objectName()) {
86 87 88
            QStringList args;
            args << "*" << "-maxwarnings" << "0";
            ret += QTest::qExec(test, args);
Don Gagne's avatar
Don Gagne committed
89 90 91 92 93 94 95 96 97 98 99
        }
    }
    
    return ret;
}

/// @brief Called before each test.
///         Make sure to call first in your derived class
void UnitTest::init(void)
{
    _initCalled = true;
100 101 102 103 104

    if (!_linkManager) {
        _linkManager = qgcApp()->toolbox()->linkManager();
        connect(_linkManager, &LinkManager::linkDeleted, this, &UnitTest::_linkDeleted);
    }
105 106

    _linkManager->restart();
Don Gagne's avatar
Don Gagne committed
107 108 109 110 111
    
    _messageBoxRespondedTo = false;
    _missedMessageBoxCount = 0;
    _badResponseButton = false;
    _messageBoxResponseButton = QMessageBox::NoButton;
112 113 114 115 116
    
    _fileDialogRespondedTo = false;
    _missedFileDialogCount = 0;
    _fileDialogResponseSet = false;
    _fileDialogResponse.clear();
Don Gagne's avatar
Don Gagne committed
117

118 119 120
    _expectMissedFileDialog = false;
    _expectMissedMessageBox = false;
    
121
    MAVLinkProtocol::deleteTempLogFiles();
Don Gagne's avatar
Don Gagne committed
122 123 124 125 126 127 128
}

/// @brief Called after each test.
///         Make sure to call first in your derived class
void UnitTest::cleanup(void)
{
    _cleanupCalled = true;
129

130 131 132
    _disconnectMockLink();
    _closeMainWindow();

133 134 135
    // We add a slight delay here to allow for deleteLater and Qml cleanup
    QTest::qWait(200);

136 137 138 139 140 141 142 143 144
    // Keep in mind that any code below these QCOMPARE may be skipped if the compare fails
    if (_expectMissedMessageBox) {
        QEXPECT_FAIL("", "Expecting failure due internal testing", Continue);
    }
    QCOMPARE(_missedMessageBoxCount, 0);
    if (_expectMissedFileDialog) {
        QEXPECT_FAIL("", "Expecting failure due internal testing", Continue);
    }
    QCOMPARE(_missedFileDialogCount, 0);
Don Gagne's avatar
Don Gagne committed
145 146 147 148
}

void UnitTest::setExpectedMessageBox(QMessageBox::StandardButton response)
{
149
    // This means that there was an expected message box but no call to checkExpectedMessageBox
Don Gagne's avatar
Don Gagne committed
150 151 152 153 154
    Q_ASSERT(!_messageBoxRespondedTo);
    
    Q_ASSERT(response != QMessageBox::NoButton);
    Q_ASSERT(_messageBoxResponseButton == QMessageBox::NoButton);
    
155
    // Make sure we haven't missed any previous message boxes
Don Gagne's avatar
Don Gagne committed
156 157 158 159 160 161 162
    int missedMessageBoxCount = _missedMessageBoxCount;
    _missedMessageBoxCount = 0;
    QCOMPARE(missedMessageBoxCount, 0);
    
    _messageBoxResponseButton = response;
}

163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
void UnitTest::setExpectedFileDialog(enum FileDialogType type, QStringList response)
{
    // This means that there was an expected file dialog but no call to checkExpectedFileDialog
    Q_ASSERT(!_fileDialogRespondedTo);
    
    // Multiple responses must be expected getOpenFileNames
    Q_ASSERT(response.count() <= 1 || type == getOpenFileNames);

    // Make sure we haven't missed any previous file dialogs
    int missedFileDialogCount = _missedFileDialogCount;
    _missedFileDialogCount = 0;
    QCOMPARE(missedFileDialogCount, 0);
    
    _fileDialogResponseSet = true;
    _fileDialogResponse = response;
    _fileDialogExpectedType = type;
}

Don Gagne's avatar
Don Gagne committed
181 182 183 184 185 186 187 188 189 190 191 192
void UnitTest::checkExpectedMessageBox(int expectFailFlags)
{
    // Previous call to setExpectedMessageBox should have already checked this
    Q_ASSERT(_missedMessageBoxCount == 0);
    
    // Check for a valid response
    
    if (expectFailFlags & expectFailBadResponseButton) {
        QEXPECT_FAIL("", "Expecting failure due to bad button response", Continue);
    }
    QCOMPARE(_badResponseButton, false);
    
193
    if (expectFailFlags & expectFailNoDialog) {
Don Gagne's avatar
Don Gagne committed
194