diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index cd61aa08bdda33253b88653e4658cb970052b53c..ed1ea5698cd9c955b2522e967e3157971911b71c 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -615,7 +615,9 @@ SOURCES += \ src/ui/QGCUASFileView.cc \ src/uas/QGCUASWorker.cc \ src/CmdLineOptParser.cc \ - src/uas/QGXPX4UAS.cc + src/uas/QGXPX4UAS.cc \ + src/QGCFileDialog.cc + # # Unit Test specific configuration goes here @@ -636,6 +638,7 @@ INCLUDEPATH += \ HEADERS += \ src/qgcunittest/UnitTest.h \ src/qgcunittest/MessageBoxTest.h \ + src/qgcunittest/FileDialogTest.h \ src/qgcunittest/UASUnitTest.h \ src/qgcunittest/MockLink.h \ src/qgcunittest/MockLinkMissionItemHandler.h \ @@ -655,8 +658,9 @@ HEADERS += \ SOURCES += \ src/qgcunittest/UnitTest.cc \ - src/qgcunittest/UASUnitTest.cc \ src/qgcunittest/MessageBoxTest.cc \ + src/qgcunittest/FileDialogTest.cc \ + src/qgcunittest/UASUnitTest.cc \ src/qgcunittest/MockLink.cc \ src/qgcunittest/MockLinkMissionItemHandler.cc \ src/qgcunittest/MockUASManager.cc \ diff --git a/src/QGCFileDialog.cc b/src/QGCFileDialog.cc new file mode 100644 index 0000000000000000000000000000000000000000..f547d16c3e274f1a764ca0df086a57f2eb5456e8 --- /dev/null +++ b/src/QGCFileDialog.cc @@ -0,0 +1,116 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + 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 . + + ======================================================================*/ + +#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_UNUSED(selectedFilter); + Q_ASSERT(selectedFilter == NULL); + + // On OSX native dialog can hang so we always use Qt dialogs + options | DontUseNativeDialog; +} diff --git a/src/QGCFileDialog.h b/src/QGCFileDialog.h index 9b342612218d81f67848edad1d7fd65e154704fe..b8ff76fa7776b03feaa57bcef6699c714dea1507 100644 --- a/src/QGCFileDialog.h +++ b/src/QGCFileDialog.h @@ -29,23 +29,46 @@ /// @file /// @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 -/// 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 class QGCFileDialog : public QFileDialog { public: - static QString getExistingDirectory(QWidget* parent = 0, const QString& caption = QString(), const QString& dir = QString(), Options options = ShowDirsOnly) - { return QFileDialog::getExistingDirectory(parent, caption, dir, options | DontUseNativeDialog); } + static QString getExistingDirectory(QWidget* parent = 0, + 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) - { return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options | DontUseNativeDialog); } + 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 QStringList getOpenFileNames(QWidget* parent = 0, const QString& caption = QString(), const QString& dir = QString(), const QString& filter = QString(), QString* selectedFilter = 0, Options options = 0) - { return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options | DontUseNativeDialog); } + 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 QString getSaveFileName(QWidget* parent = 0, const QString& caption = QString(), const QString& dir = QString(), const QString& filter = QString(), QString* selectedFilter = 0, Options options = 0) - { return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options | DontUseNativeDialog); } + static QString getSaveFileName(QWidget* parent = 0, + 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); }; diff --git a/src/qgcunittest/FileDialogTest.cc b/src/qgcunittest/FileDialogTest.cc new file mode 100644 index 0000000000000000000000000000000000000000..d98d0eabe1e2b4d1ebb629035fe3bc2cef762b63 --- /dev/null +++ b/src/qgcunittest/FileDialogTest.cc @@ -0,0 +1,113 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + 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 . + + ======================================================================*/ + +/// @file +/// @brief Unit test for QGCFileDialog catching mechanism. +/// +/// @author Don Gagne + +#include "FileDialogTest.h" +#include "QGCFileDialog.h" + +UT_REGISTER_TEST(FileDialogTest) + +FileDialogTest::FileDialogTest(void) +{ + +} + +void FileDialogTest::_fileDialogExpected_test(void) +{ + QStringList response; + response << "" << "response"; + + for (int i=0; i responseList; + QStringList list; + + responseList.append(QStringList()); + responseList.append(QStringList("response1")); + list << "response1" << "response2"; + responseList.append(list); + + for (int i=0; i + + 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 . + + ======================================================================*/ + +/// @file +/// @brief Unit test for QGCFileDialog catching mechanism. +/// +/// @author Don Gagne + +#ifndef FILEDIALOGTEST_H +#define FILEDIALOGTEST_H + +#include "UnitTest.h" + +class FileDialogTest : public UnitTest +{ + Q_OBJECT + +public: + FileDialogTest(void); + +private slots: + void _fileDialogExpected_test(void); + void _fileDialogUnexpected_test(void); + void _previousFileDialog_test(void); + void _noFileDialog_test(void); + void _fileDialogExpectedIncorrect_test(void); +}; + +#endif diff --git a/src/qgcunittest/MessageBoxTest.cc b/src/qgcunittest/MessageBoxTest.cc index 79329edf0c713c88cc14e17c2539462f9602aaa2..72cf44bfc58fc55d7ecea199bddd040b7591ca78 100644 --- a/src/qgcunittest/MessageBoxTest.cc +++ b/src/qgcunittest/MessageBoxTest.cc @@ -31,21 +31,11 @@ UT_REGISTER_TEST(MessageBoxTest) -MessageBoxTest::MessageBoxTest(void) : - _expectMissedMessageBox(false) +MessageBoxTest::MessageBoxTest(void) { } -void MessageBoxTest::cleanup(void) -{ - if (_expectMissedMessageBox) { - _expectMissedMessageBox = false; - QEXPECT_FAIL("", "Supposed to fail in cleanup with a missed message box", Continue); - } - UnitTest::cleanup(); -} - void MessageBoxTest::_messageBoxExpected_test(void) { setExpectedMessageBox(QMessageBox::Ok); @@ -57,7 +47,7 @@ void MessageBoxTest::_messageBoxExpected_test(void) void MessageBoxTest::_messageBoxUnexpected_test(void) { - // This should cause the test to fail in the cleanup method + // This should cause an expected failure in the cleanup method QGCMessageBox::information(QString(), QString()); _expectMissedMessageBox = true; } @@ -75,7 +65,7 @@ void MessageBoxTest::_previousMessageBox_test(void) void MessageBoxTest::_noMessageBox_test(void) { setExpectedMessageBox(QMessageBox::Ok); - checkExpectedMessageBox(expectFailNoMessageBox); + checkExpectedMessageBox(expectFailNoDialog); } void MessageBoxTest::_badResponseButton_test(void) diff --git a/src/qgcunittest/MessageBoxTest.h b/src/qgcunittest/MessageBoxTest.h index 388c4c0bb1d22a8bca5dd2d99d5d94e993aa068e..f831829e0b3af1b4a2147946fdf4c4e38dba9fc0 100644 --- a/src/qgcunittest/MessageBoxTest.h +++ b/src/qgcunittest/MessageBoxTest.h @@ -39,16 +39,11 @@ public: MessageBoxTest(void); private slots: - void cleanup(void); - void _messageBoxExpected_test(void); void _messageBoxUnexpected_test(void); void _previousMessageBox_test(void); void _noMessageBox_test(void); void _badResponseButton_test(void); - -private: - bool _expectMissedMessageBox; }; #endif diff --git a/src/qgcunittest/PX4RCCalibrationTest.cc b/src/qgcunittest/PX4RCCalibrationTest.cc index a1550bbc84ce63f4dfe02a1ebf8fc8bcfbfc63e1..f4e5ac35c7ed819248e8dfa992742800613544f2 100644 --- a/src/qgcunittest/PX4RCCalibrationTest.cc +++ b/src/qgcunittest/PX4RCCalibrationTest.cc @@ -139,8 +139,6 @@ PX4RCCalibrationTest::PX4RCCalibrationTest(void) : /// @brief Called one time before any test cases are run. void PX4RCCalibrationTest::initTestCase(void) { - UnitTest::initTestCase(); - // Validate that our function to channel mapping is still correct. for (int function=0; functiondestroySingletonsForUnitTest(); qgcApp()->createSingletonsForUnitTest(); @@ -133,30 +122,52 @@ void UnitTest::init(void) void UnitTest::cleanup(void) { _cleanupCalled = true; - - int missedMessageBoxCount = _missedMessageBoxCount; - _missedMessageBoxCount = 0; - - // Make sure to reset any needed variables since this can fall and cause the rest of the method to be skipped - QCOMPARE(missedMessageBoxCount, 0); + + // 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); } void UnitTest::setExpectedMessageBox(QMessageBox::StandardButton response) { + // This means that there was an expected message box but no call to checkExpectedMessageBox Q_ASSERT(!_messageBoxRespondedTo); - // We use an obsolete StandardButton value to signal that response button has not been set. So you can't use this. Q_ASSERT(response != QMessageBox::NoButton); Q_ASSERT(_messageBoxResponseButton == QMessageBox::NoButton); + // Make sure we haven't missed any previous message boxes int missedMessageBoxCount = _missedMessageBoxCount; _missedMessageBoxCount = 0; - QCOMPARE(missedMessageBoxCount, 0); _messageBoxResponseButton = response; } +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; +} + void UnitTest::checkExpectedMessageBox(int expectFailFlags) { // Previous call to setExpectedMessageBox should have already checked this @@ -169,10 +180,36 @@ void UnitTest::checkExpectedMessageBox(int expectFailFlags) } QCOMPARE(_badResponseButton, false); - if (expectFailFlags & expectFailNoMessageBox) { + if (expectFailFlags & expectFailNoDialog) { QEXPECT_FAIL("", "Expecting failure due to no message box", Continue); } - QCOMPARE(_messageBoxRespondedTo, true); + + // Clear this flag before QCOMPARE since anything after QCOMPARE will be skipped on failure + bool messageBoxRespondedTo = _messageBoxRespondedTo; + _messageBoxRespondedTo = false; + + QCOMPARE(messageBoxRespondedTo, true); +} + +void UnitTest::checkExpectedFileDialog(int expectFailFlags) +{ + // Internal testing + + if (expectFailFlags & expectFailNoDialog) { + QEXPECT_FAIL("", "Expecting failure due to no file dialog", Continue); + } + if (expectFailFlags & expectFailWrongFileDialog) { + QEXPECT_FAIL("", "Expecting failure due to incorrect file dialog", Continue); + } else { + // Previous call to setExpectedFileDialog should have already checked this + Q_ASSERT(_missedFileDialogCount == 0); + } + + // Clear this flag before QCOMPARE since anything after QCOMPARE will be skipped on failure + bool fileDialogRespondedTo = _fileDialogRespondedTo; + _fileDialogRespondedTo = false; + + QCOMPARE(fileDialogRespondedTo, true); } QMessageBox::StandardButton UnitTest::_messageBox(QMessageBox::Icon icon, const QString& title, const QString& text, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton) @@ -205,3 +242,112 @@ QMessageBox::StandardButton UnitTest::_messageBox(QMessageBox::Icon icon, const return retButton; } +/// @brief Response to a file dialog which returns a single file +QString UnitTest::_fileDialogResponseSingle(enum FileDialogType type) +{ + QString retFile; + + if (!_fileDialogResponseSet || _fileDialogExpectedType != type) { + // If no response is set or the type does not match what we expected it means we were not expecting this file dialog. + // Respond with no selection. + _missedFileDialogCount++; + } else { + Q_ASSERT(_fileDialogResponse.count() <= 1); + if (_fileDialogResponse.count() == 1) { + retFile = _fileDialogResponse[0]; + } + _fileDialogRespondedTo = true; + } + + // Clear response for next message box + _fileDialogResponse.clear(); + _fileDialogResponseSet = false; + + return retFile; +} + +QString UnitTest::_getExistingDirectory(QWidget* parent, + const QString& caption, + const QString& dir, + QFileDialog::Options options) +{ + Q_UNUSED(parent); + Q_UNUSED(caption); + Q_UNUSED(dir); + Q_UNUSED(options); + + return _fileDialogResponseSingle(getExistingDirectory); +} + +QString UnitTest::_getOpenFileName(QWidget* parent, + const QString& caption, + const QString& dir, + const QString& filter, + QString* selectedFilter, + QFileDialog::Options options) +{ + Q_UNUSED(parent); + Q_UNUSED(caption); + Q_UNUSED(dir); + Q_UNUSED(filter); + Q_UNUSED(options); + + // Support for selectedFilter is not yet implemented + Q_ASSERT(selectedFilter == NULL); + + return _fileDialogResponseSingle(getOpenFileName); +} + +QStringList UnitTest::_getOpenFileNames(QWidget* parent, + const QString& caption, + const QString& dir, + const QString& filter, + QString* selectedFilter, + QFileDialog::Options options) +{ + Q_UNUSED(parent); + Q_UNUSED(caption); + Q_UNUSED(dir); + Q_UNUSED(filter); + Q_UNUSED(options); + + // Support for selectedFilter is not yet implemented + Q_ASSERT(selectedFilter == NULL); + + QStringList retFiles; + + if (!_fileDialogResponseSet || _fileDialogExpectedType != getOpenFileNames) { + // If no response is set or the type does not match what we expected it means we were not expecting this file dialog. + // Respond with no selection. + _missedFileDialogCount++; + retFiles.clear(); + } else { + retFiles = _fileDialogResponse; + _fileDialogRespondedTo = true; + } + + // Clear response for next message box + _fileDialogResponse.clear(); + _fileDialogResponseSet = false; + + return retFiles; +} + +QString UnitTest::_getSaveFileName(QWidget* parent, + const QString& caption, + const QString& dir, + const QString& filter, + QString* selectedFilter, + QFileDialog::Options options) +{ + Q_UNUSED(parent); + Q_UNUSED(caption); + Q_UNUSED(dir); + Q_UNUSED(filter); + Q_UNUSED(options); + + // Support for selectedFilter is not yet implemented + Q_ASSERT(selectedFilter == NULL); + + return _fileDialogResponseSingle(getSaveFileName); +} diff --git a/src/qgcunittest/UnitTest.h b/src/qgcunittest/UnitTest.h index 531a9423d559312e2c1de97253c8b898301067e6..cb27d3a20a337b9bcfeef4b94211495b1f28162d 100644 --- a/src/qgcunittest/UnitTest.h +++ b/src/qgcunittest/UnitTest.h @@ -32,10 +32,12 @@ #include #include #include +#include #define UT_REGISTER_TEST(className) static UnitTestWrapper t(#className); class QGCMessageBox; +class QGCFileDialog; class UnitTest; class UnitTest : public QObject @@ -56,16 +58,34 @@ public: /// @param response Response to take on message box 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 { expectFailNoFailure = 1 << 0, ///< not expecting any failures - expectFailNoMessageBox = 1 << 1, ///< expecting a failure due to no message box displayed - expectFailBadResponseButton = 1 << 2 ///< expecting a failure due to bad button response + expectFailNoDialog = 1 << 1, ///< expecting a failure due to no dialog displayed + 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 // @param Expected failure response flags 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. static void _addTest(QObject* test); @@ -74,14 +94,6 @@ protected slots: // These are all pure virtuals to force the derived class to implement each one and in turn // 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. /// Make sure to call _init first in your derived class. virtual void init(void); @@ -103,24 +115,71 @@ protected: /// @brief Must be called first by derived class implementation 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: // 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 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); static QList& _testList(void); + // Catch QGCMessageBox calls static bool _messageBoxRespondedTo; ///< Message box was responded to 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 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 _initTestCaseCalled; ///< true: UnitTest::_initTestCase was called - bool _cleanupTestCaseCalled; ///< true: UnitTest::_cleanupTestCase was called bool _initCalled; ///< true: UnitTest::_init was called bool _cleanupCalled; ///< true: UnitTest::_cleanup was called };