Commit 1b4239d3 authored by Don Gagne's avatar Don Gagne

QGCFileDialog UnitTest support

parent c9274137
...@@ -615,7 +615,9 @@ SOURCES += \ ...@@ -615,7 +615,9 @@ SOURCES += \
src/ui/QGCUASFileView.cc \ src/ui/QGCUASFileView.cc \
src/uas/QGCUASWorker.cc \ src/uas/QGCUASWorker.cc \
src/CmdLineOptParser.cc \ src/CmdLineOptParser.cc \
src/uas/QGXPX4UAS.cc src/uas/QGXPX4UAS.cc \
src/QGCFileDialog.cc
# #
# Unit Test specific configuration goes here # Unit Test specific configuration goes here
...@@ -636,6 +638,7 @@ INCLUDEPATH += \ ...@@ -636,6 +638,7 @@ INCLUDEPATH += \
HEADERS += \ HEADERS += \
src/qgcunittest/UnitTest.h \ src/qgcunittest/UnitTest.h \
src/qgcunittest/MessageBoxTest.h \ src/qgcunittest/MessageBoxTest.h \
src/qgcunittest/FileDialogTest.h \
src/qgcunittest/UASUnitTest.h \ src/qgcunittest/UASUnitTest.h \
src/qgcunittest/MockLink.h \ src/qgcunittest/MockLink.h \
src/qgcunittest/MockLinkMissionItemHandler.h \ src/qgcunittest/MockLinkMissionItemHandler.h \
...@@ -655,8 +658,9 @@ HEADERS += \ ...@@ -655,8 +658,9 @@ HEADERS += \
SOURCES += \ SOURCES += \
src/qgcunittest/UnitTest.cc \ src/qgcunittest/UnitTest.cc \
src/qgcunittest/UASUnitTest.cc \
src/qgcunittest/MessageBoxTest.cc \ src/qgcunittest/MessageBoxTest.cc \
src/qgcunittest/FileDialogTest.cc \
src/qgcunittest/UASUnitTest.cc \
src/qgcunittest/MockLink.cc \ src/qgcunittest/MockLink.cc \
src/qgcunittest/MockLinkMissionItemHandler.cc \ src/qgcunittest/MockLinkMissionItemHandler.cc \
src/qgcunittest/MockUASManager.cc \ src/qgcunittest/MockUASManager.cc \
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "QGCFileDialog.h"
#include "QGCApplication.h"
#ifdef QT_DEBUG
#include "UnitTest.h"
#endif
QString QGCFileDialog::getExistingDirectory(QWidget* parent,
const QString& caption,
const QString& dir,
Options options)
{
_validate(NULL, options);
#ifdef QT_DEBUG
if (qgcApp()->runningUnitTests()) {
return UnitTest::_getExistingDirectory(parent, caption, dir, options);
} else
#endif
{
return QFileDialog::getExistingDirectory(parent, caption, dir, options);
}
}
QString QGCFileDialog::getOpenFileName(QWidget* parent,
const QString& caption,
const QString& dir,
const QString& filter,
QString* selectedFilter,
Options options)
{
_validate(selectedFilter, options);
#ifdef QT_DEBUG
if (qgcApp()->runningUnitTests()) {
return UnitTest::_getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
} else
#endif
{
return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
}
}
QStringList QGCFileDialog::getOpenFileNames(QWidget* parent,
const QString& caption,
const QString& dir,
const QString& filter,
QString* selectedFilter,
Options options)
{
_validate(selectedFilter, options);
#ifdef QT_DEBUG
if (qgcApp()->runningUnitTests()) {
return UnitTest::_getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
} else
#endif
{
return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
}
}
QString QGCFileDialog::getSaveFileName(QWidget* parent,
const QString& caption,
const QString& dir,
const QString& filter,
QString* selectedFilter,
Options options)
{
_validate(selectedFilter, options);
#ifdef QT_DEBUG
if (qgcApp()->runningUnitTests()) {
return UnitTest::_getSaveFileName(parent, caption, dir, filter, selectedFilter, options);
} else
#endif
{
return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options);
}
}
/// @brief Validates and updates the parameters for the file dialog calls
void QGCFileDialog::_validate(QString* selectedFilter, Options& options)
{
// You can't use QGCFileDialog if QGCApplication is not created yet.
Q_ASSERT(qgcApp());
// Support for selectedFilter is not yet implemented through the unit test framework
Q_ASSERT(selectedFilter == NULL);
// On OSX native dialog can hang so we always use Qt dialogs
options | DontUseNativeDialog;
}
...@@ -29,23 +29,46 @@ ...@@ -29,23 +29,46 @@
/// @file /// @file
/// @brief Subclass of QFileDialog which re-implements the static public functions. The reason for this /// @brief Subclass of QFileDialog which re-implements the static public functions. The reason for this
/// is that the QFileDialog implementations of these use the native os dialogs. On OSX these /// is that the QFileDialog implementations of these use the native os dialogs. On OSX these
/// these can intermittently hang. So instead here we use the native dialogs. /// these can intermittently hang. So instead here we use the native dialogs. It also allows
/// use to catch these dialogs for unit testing.
/// @author Don Gagne <don@thegagnes.com> /// @author Don Gagne <don@thegagnes.com>
class QGCFileDialog : public QFileDialog { class QGCFileDialog : public QFileDialog {
public: public:
static QString getExistingDirectory(QWidget* parent = 0, const QString& caption = QString(), const QString& dir = QString(), Options options = ShowDirsOnly) static QString getExistingDirectory(QWidget* parent = 0,
{ return QFileDialog::getExistingDirectory(parent, caption, dir, options | DontUseNativeDialog); } const QString& caption = QString(),
const QString& dir = QString(),
Options options = ShowDirsOnly);
static QString getOpenFileName(QWidget* parent = 0, const QString& caption = QString(), const QString& dir = QString(), const QString& filter = QString(), QString* selectedFilter = 0, Options options = 0) static QString getOpenFileName(QWidget* parent = 0,
{ return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options | DontUseNativeDialog); } const QString& caption = QString(),
const QString& dir = QString(),
const QString& filter = QString(),
QString* selectedFilter = 0,
Options options = 0);
static QStringList getOpenFileNames(QWidget* parent = 0, const QString& caption = QString(), const QString& dir = QString(), const QString& filter = QString(), QString* selectedFilter = 0, Options options = 0) static QStringList getOpenFileNames(QWidget* parent = 0,
{ return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options | DontUseNativeDialog); } const QString& caption = QString(),
const QString& dir = QString(),
const QString& filter = QString(),
QString* selectedFilter = 0,
Options options = 0);
static QString getSaveFileName(QWidget* parent = 0, const QString& caption = QString(), const QString& dir = QString(), const QString& filter = QString(), QString* selectedFilter = 0, Options options = 0) static QString getSaveFileName(QWidget* parent = 0,
{ return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options | DontUseNativeDialog); } const QString& caption = QString(),
const QString& dir = QString(),
const QString& filter = QString(),
QString* selectedFilter = 0,
Options options = 0);
private slots:
/// @brief The exec slot is private becasue when only want QGCFileDialog users to use the static methods. Otherwise it will break
/// unit testing.
int exec(void) { return QGCFileDialog::exec(); }
private:
static void _validate(QString* selectedFilter, Options& options);
}; };
......
This diff is collapsed.
...@@ -32,10 +32,12 @@ ...@@ -32,10 +32,12 @@
#include <QObject> #include <QObject>
#include <QtTest> #include <QtTest>
#include <QMessageBox> #include <QMessageBox>
#include <QFileDialog>
#define UT_REGISTER_TEST(className) static UnitTestWrapper<className> t(#className); #define UT_REGISTER_TEST(className) static UnitTestWrapper<className> t(#className);
class QGCMessageBox; class QGCMessageBox;
class QGCFileDialog;
class UnitTest; class UnitTest;
class UnitTest : public QObject class UnitTest : public QObject
...@@ -56,16 +58,34 @@ public: ...@@ -56,16 +58,34 @@ public:
/// @param response Response to take on message box /// @param response Response to take on message box
void setExpectedMessageBox(QMessageBox::StandardButton response); void setExpectedMessageBox(QMessageBox::StandardButton response);
/// @brief Types for UnitTest::setExpectedFileDialog
enum FileDialogType {
getExistingDirectory,
getOpenFileName,
getOpenFileNames,
getSaveFileName
};
/// @brief Sets up for an expected QGCFileDialog
/// @param type Type of expected file dialog
/// @param response Files to return from call. Multiple files only supported by getOpenFileNames
void setExpectedFileDialog(enum FileDialogType type, QStringList response);
enum { enum {
expectFailNoFailure = 1 << 0, ///< not expecting any failures expectFailNoFailure = 1 << 0, ///< not expecting any failures
expectFailNoMessageBox = 1 << 1, ///< expecting a failure due to no message box displayed expectFailNoDialog = 1 << 1, ///< expecting a failure due to no dialog displayed
expectFailBadResponseButton = 1 << 2 ///< expecting a failure due to bad button response expectFailBadResponseButton = 1 << 2, ///< expecting a failure due to bad button response (QGCMessageBox only)
expectFailWrongFileDialog = 1 << 3 ///< expecting one dialog type, got the wrong type (QGCFileDialog ony)
}; };
/// @brief Check whether a message box was displayed and correctly responded to /// @brief Check whether a message box was displayed and correctly responded to
// @param Expected failure response flags // @param Expected failure response flags
void checkExpectedMessageBox(int expectFailFlags = expectFailNoFailure); void checkExpectedMessageBox(int expectFailFlags = expectFailNoFailure);
/// @brief Check whether a message box was displayed and correctly responded to
// @param Expected failure response flags
void checkExpectedFileDialog(int expectFailFlags = expectFailNoFailure);
/// @brief Adds a unit test to the list. Should only be called by UnitTestWrapper. /// @brief Adds a unit test to the list. Should only be called by UnitTestWrapper.
static void _addTest(QObject* test); static void _addTest(QObject* test);
...@@ -74,14 +94,6 @@ protected slots: ...@@ -74,14 +94,6 @@ protected slots:
// These are all pure virtuals to force the derived class to implement each one and in turn // These are all pure virtuals to force the derived class to implement each one and in turn
// call the UnitTest private implementation. // call the UnitTest private implementation.
/// @brief Called at the initialization of the entire unit test.
/// Make sure to call _initTestCase first in your derived class.
virtual void initTestCase(void);
/// @brief Called at the end of the entire unit test.
/// Make sure to call _cleanupTestCase first in your derived class.
virtual void cleanupTestCase(void);
/// @brief Called before each test. /// @brief Called before each test.
/// Make sure to call _init first in your derived class. /// Make sure to call _init first in your derived class.
virtual void init(void); virtual void init(void);
...@@ -103,24 +115,71 @@ protected: ...@@ -103,24 +115,71 @@ protected:
/// @brief Must be called first by derived class implementation /// @brief Must be called first by derived class implementation
void _cleanup(void); void _cleanup(void);
bool _expectMissedFileDialog; // true: expect a missed file dialog, used for internal testing
bool _expectMissedMessageBox; // true: expect a missed message box, used for internal testing
private: private:
// When the app is running in unit test mode the QGCMessageBox methods are re-routed here. // When the app is running in unit test mode the QGCMessageBox methods are re-routed here.
static QMessageBox::StandardButton _messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton);
static QMessageBox::StandardButton _messageBox(QMessageBox::Icon icon,
const QString& title,
const QString& text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton);
// This allows the private call to _messageBox // This allows the private call to _messageBox
friend class QGCMessageBox; friend class QGCMessageBox;
// When the app is running in unit test mode the QGCFileDialog methods are re-routed here.
static QString _getExistingDirectory(QWidget* parent,
const QString& caption,
const QString& dir,
QFileDialog::Options options);
static QString _getOpenFileName(QWidget* parent,
const QString& caption,
const QString& dir,
const QString& filter,
QString* selectedFilter,
QFileDialog::Options options);
static QStringList _getOpenFileNames(QWidget* parent,
const QString& caption,
const QString& dir,
const QString& filter,
QString* selectedFilter,
QFileDialog::Options options);
static QString _getSaveFileName(QWidget* parent,
const QString& caption,
const QString& dir,
const QString& filter,
QString* selectedFilter,
QFileDialog::Options options);
static QString _fileDialogResponseSingle(enum FileDialogType type);
// This allows the private calls to the file dialog methods
friend class QGCFileDialog;
void _unitTestCalled(void); void _unitTestCalled(void);
static QList<QObject*>& _testList(void); static QList<QObject*>& _testList(void);
// Catch QGCMessageBox calls
static bool _messageBoxRespondedTo; ///< Message box was responded to static bool _messageBoxRespondedTo; ///< Message box was responded to
static bool _badResponseButton; ///< Attempt to repond to expected message box with button not being displayed static bool _badResponseButton; ///< Attempt to repond to expected message box with button not being displayed
static QMessageBox::StandardButton _messageBoxResponseButton; ///< Response to next message box static QMessageBox::StandardButton _messageBoxResponseButton; ///< Response to next message box
static int _missedMessageBoxCount; ///< Count of message box not checked with call to messageBoxWasDisplayed static int _missedMessageBoxCount; ///< Count of message box not checked with call to messageBoxWasDisplayed
// Catch QGCFileDialog calls
static bool _fileDialogRespondedTo; ///< File dialog was responded to
static bool _fileDialogResponseSet; ///< true: _fileDialogResponse was set by a call to UnitTest::setExpectedFileDialog
static QStringList _fileDialogResponse; ///< Response to next file dialog
static enum FileDialogType _fileDialogExpectedType; ///< type of file dialog expected to show
static int _missedFileDialogCount; ///< Count of file dialogs not checked with call to UnitTest::fileDialogWasDisplayed
bool _unitTestRun; ///< true: Unit Test was run bool _unitTestRun; ///< true: Unit Test was run
bool _initTestCaseCalled; ///< true: UnitTest::_initTestCase was called
bool _cleanupTestCaseCalled; ///< true: UnitTest::_cleanupTestCase was called
bool _initCalled; ///< true: UnitTest::_init was called bool _initCalled; ///< true: UnitTest::_init was called
bool _cleanupCalled; ///< true: UnitTest::_cleanup was called bool _cleanupCalled; ///< true: UnitTest::_cleanup was called
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment