diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 84c0d30629c91eec5864975c649252fad891a5df..3b1208d2caf63a0f9e34d22a887989b95909d293 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -751,13 +751,15 @@ CONFIG(debug, debug|release) { src/qgcunittest/UASUnitTest.h \ src/qgcunittest/MockUASManager.h \ src/qgcunittest/MockUAS.h \ - src/qgcunittest/MockQGCUASParamManager.h + src/qgcunittest/MockQGCUASParamManager.h \ + src/qgcunittest/FlightModeConfigTest.h SOURCES += \ src/qgcunittest/UASUnitTest.cc \ src/qgcunittest/MockUASManager.cc \ src/qgcunittest/MockUAS.cc \ - src/qgcunittest/MockQGCUASParamManager.cc + src/qgcunittest/MockQGCUASParamManager.cc \ + src/qgcunittest/FlightModeConfigTest.cc } # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler diff --git a/src/qgcunittest/FlightModeConfigTest.cc b/src/qgcunittest/FlightModeConfigTest.cc new file mode 100644 index 0000000000000000000000000000000000000000..67d581279ece8cb0d3a97bcfe5ee8ec91d608324 --- /dev/null +++ b/src/qgcunittest/FlightModeConfigTest.cc @@ -0,0 +1,306 @@ +/*===================================================================== + + 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 "FlightModeConfigTest.h" +#include "FlightModeConfig.h" +#include "UASManager.h" +#include "MockQGCUASParamManager.h" + +/// @file +/// @brief FlightModeConfig unit test +/// +/// @author Don Gagne + +FlightModeConfigUnitTest::FlightModeConfigUnitTest(void) : + _mockUASManager(NULL) +{ + +} + +void FlightModeConfigUnitTest::init(void) +{ + _mockUASManager = new MockUASManager(); + Q_ASSERT(_mockUASManager); + + UASManager::setMockUASManager(_mockUASManager); + + _mockUAS = new MockUAS(); + Q_ASSERT(_mockUAS); +} + +void FlightModeConfigUnitTest::cleanup(void) +{ + Q_ASSERT(_mockUAS); + delete _mockUAS; + + UASManager::setMockUASManager(NULL); + + Q_ASSERT(_mockUASManager); + delete _mockUASManager; +} + +void FlightModeConfigUnitTest::_nullUAS_test(void) +{ + // When there is no UAS the widget should be disabled + FlightModeConfig* fmc = new FlightModeConfig(); + QCOMPARE(fmc->isEnabled(), false); +} + +void FlightModeConfigUnitTest::_validUAS_test(void) +{ + // With an active UAS widget should be enabled + _mockUASManager->setMockActiveUAS(_mockUAS); + FlightModeConfig* fmc = new FlightModeConfig(); + QCOMPARE(fmc->isEnabled(), true); +} + +void FlightModeConfigUnitTest::_nullToValidUAS_test(void) +{ + // start with no UAS + FlightModeConfig* fmc = new FlightModeConfig(); + + // clear it out and validate widget gets disabled + _mockUASManager->setMockActiveUAS(NULL); + QCOMPARE(fmc->isEnabled(), false); +} + +void FlightModeConfigUnitTest::_simpleModeFixedWing_test(void) +{ + // Fixed wing does not have simple mode, all checkboxes should be disabled + _mockUAS->setMockSystemType(MAV_TYPE_FIXED_WING); + _mockUASManager->setMockActiveUAS(_mockUAS); + FlightModeConfig* fmc = new FlightModeConfig(); + _findControls(fmc); + + for (size_t i=0; i<_cCombo; i++) { + QCOMPARE(_rgSimpleModeCheckBox[i]->isEnabled(), false); + } +} + +void FlightModeConfigUnitTest::_simpleModeRover_test(void) +{ + // Rover does not have simple mode, all checkboxes should be disabled + _mockUAS->setMockSystemType(MAV_TYPE_GROUND_ROVER); + _mockUASManager->setMockActiveUAS(_mockUAS); + FlightModeConfig* fmc = new FlightModeConfig(); + _findControls(fmc); + + for (size_t i=0; i<_cCombo; i++) { + QCOMPARE(_rgSimpleModeCheckBox[i]->isEnabled(), false); + } +} + +void FlightModeConfigUnitTest::_simpleModeRotor_test(void) +{ + // Rotor has simple mode, all checkboxes should be enabled + _mockUAS->setMockSystemType(MAV_TYPE_QUADROTOR); + _mockUASManager->setMockActiveUAS(_mockUAS); + FlightModeConfig* fmc = new FlightModeConfig(); + _findControls(fmc); + + for (size_t i=0; i<_cCombo; i++) { + QCOMPARE(_rgSimpleModeCheckBox[i]->isEnabled(), true); + } +} + +void FlightModeConfigUnitTest::_modeSwitchParam_test(void) +{ + _mockUAS->setMockSystemType(MAV_TYPE_QUADROTOR); + _mockUASManager->setMockActiveUAS(_mockUAS); + FlightModeConfig* fmc = new FlightModeConfig(); + _findControls(fmc); + + const char* rgModeSwitchParam[_cCombo] = { "FLTMODE1", "FLTMODE2", "FLTMODE3", "FLTMODE4", "FLTMODE5", "FLTMODE6" }; + const int rgModeSwitchValue[_cCombo] = { 0, 2, 4, 6, 8, 10 }; + + MockQGCUASParamManager::ParamMap_t mapParams; + for (size_t i=0; i<_cCombo; i++) { + mapParams[rgModeSwitchParam[i]] = QVariant(QChar(rgModeSwitchValue[i])); + } + + int simpleModeBitMask = 21; + mapParams["SIMPLE"] = QVariant(QChar(simpleModeBitMask)); + _mockUAS->setMockParametersAndSignal(mapParams); + + // Check that the UI is showing the correct information + for (size_t i=0; i<_cCombo; i++) { + QComboBox* combo = _rgCombo[i]; + + // Check for the correct selection in the combo boxes. Combo boxes store the mode + // in the item data, so use that to compare + QCOMPARE(combo->itemData(combo->currentIndex()), mapParams[rgModeSwitchParam[i]]); + + // Make sure the text for the current selection doesn't contain the text Unknown + // which means that it received an unsupported mode + QCOMPARE(combo->currentText().contains("unknown", Qt::CaseInsensitive), QBool(false)); + + // Check that the right simple mode check boxes are checked + QCOMPARE(_rgSimpleModeCheckBox[i]->isChecked(), !!((1 << i) & simpleModeBitMask)); + } + + + // Click Save button and make sure we get the same values back through setParameter calls + QTest::mouseClick(_saveButton, Qt::LeftButton); + MockQGCUASParamManager* paramMgr = _mockUAS->getMockQGCUASParamManager(); + MockQGCUASParamManager::ParamMap_t mapParamsSet = paramMgr->getMockSetParameters(); + QMapIterator i(mapParams); + while (i.hasNext()) { + i.next(); + QCOMPARE(mapParamsSet.contains(i.key()), true); + int receivedValue = mapParamsSet[i.key()].toInt(); + int expectedValue = i.value().toInt(); + QCOMPARE(receivedValue, expectedValue); + } +} + +void FlightModeConfigUnitTest::_pwmTestWorker(int systemType, int modeSwitchChannel, const char* modeSwitchParam) +{ + _mockUAS->setMockSystemType(systemType); + _mockUASManager->setMockActiveUAS(_mockUAS); + FlightModeConfig* fmc = new FlightModeConfig(); + _findControls(fmc); + + MockQGCUASParamManager::ParamMap_t mapParams; + if (modeSwitchParam != NULL) { + // Param is 1-based, code in here is all 0-base + mapParams[modeSwitchParam] = QVariant(QChar(modeSwitchChannel+1)); + _mockUAS->setMockParametersAndSignal(mapParams); + } + + const int pwmBoundary[] = { 1230, 1360, 1490, 1620, 1749, 1900 }; + + int lowerPWM = 0; + for (size_t i=0; i<_cCombo; i++) { + // emit a PWM value at the mid point of the switch position + int pwmMidPoint = ((pwmBoundary[i] - lowerPWM) / 2) + lowerPWM; + _mockUAS->emitRemoteControlChannelRawChanged(modeSwitchChannel, pwmMidPoint); + + // Make sure that only the correct pwm label has a style set on it for highlight + for (size_t j=0; j<_cCombo; j++) { + if (j == i) { + QVERIFY(_rgPWMLabel[j]->styleSheet().length() > 0); + } else { + QCOMPARE(_rgPWMLabel[j]->styleSheet().length(), 0); + } + } + + lowerPWM = pwmBoundary[i]; + } +} + +void FlightModeConfigUnitTest::_pwmFixedWing_test(void) +{ + // FixedWing has mode switch channel on FLTMODE_CH param + _pwmTestWorker(MAV_TYPE_FIXED_WING, 7, "FLTMODE_CH"); +} + +void FlightModeConfigUnitTest::_pwmRotor_test(void) +{ + // Rotor is hardwired to 0-based rc channel 4 for mode wsitch + _pwmTestWorker(MAV_TYPE_QUADROTOR, 4, NULL); +} + +void FlightModeConfigUnitTest::_pwmRover_test(void) +{ + // Rover has mode switch channel on MODE_CH param + _pwmTestWorker(MAV_TYPE_GROUND_ROVER, 7, "MODE_CH"); +} + +void FlightModeConfigUnitTest::_pwmInvalidChannel_test(void) +{ + // Rover has mode switch channel on MODE_CH param + _mockUAS->setMockSystemType(MAV_TYPE_GROUND_ROVER); + _mockUASManager->setMockActiveUAS(_mockUAS); + FlightModeConfig* fmc = new FlightModeConfig(); + _findControls(fmc); + + int modeSwitchChannel = 7; + MockQGCUASParamManager::ParamMap_t mapParams; + mapParams["MODE_CH"] = QVariant(QChar(modeSwitchChannel+1)); // 1-based + _mockUAS->setMockParametersAndSignal(mapParams); + + const int pwmBoundary[] = { 1230, 1360, 1490, 1620, 1749, 1900 }; + + int lowerPWM = 0; + for (size_t i=0; i<_cCombo; i++) { + // emit a PWM value at the mid point of the switch position + int pwmMidPoint = ((pwmBoundary[i] - lowerPWM) / 2) + lowerPWM; + // emit rc values on wrong channel + _mockUAS->emitRemoteControlChannelRawChanged(modeSwitchChannel-1, pwmMidPoint); + + // Make sure no label have a style set on it for highlight + for (size_t j=0; j<_cCombo; j++) { + QCOMPARE(_rgPWMLabel[j]->styleSheet().length(), 0); + } + + lowerPWM = pwmBoundary[i]; + } +} + +void FlightModeConfigUnitTest::_unknownSystemType_test(void) +{ + // Set the system type to something we can't handle, make sure we are disabled + _mockUAS->setMockSystemType(MAV_TYPE_ENUM_END); + _mockUASManager->setMockActiveUAS(_mockUAS); + FlightModeConfig* fmc = new FlightModeConfig(); + QCOMPARE(fmc->isEnabled(), false); +} + +void FlightModeConfigUnitTest::_unknownMode_test(void) +{ + _mockUAS->setMockSystemType(MAV_TYPE_QUADROTOR); + _mockUASManager->setMockActiveUAS(_mockUAS); + FlightModeConfig* fmc = new FlightModeConfig(); + _findControls(fmc); + + // Set an unknown mode + MockQGCUASParamManager::ParamMap_t mapParams; + mapParams["FLTMODE1"] = QVariant(QChar(100)); + _mockUAS->setMockParametersAndSignal(mapParams); + + // Check for the correct selection in the combo boxes. Combo boxes store the mode + // in the item data, so use that to compare + QCOMPARE(_rgCombo[0]->itemData(_rgCombo[0]->currentIndex()), mapParams["FLTMODE1"]); + + // Make sure the text for the current selection contains the text Unknown + QCOMPARE(_rgCombo[0]->currentText().contains("unknown", Qt::CaseInsensitive), QBool(true)); +} + +void FlightModeConfigUnitTest::_findControls(QObject* fmc) +{ + // Find all the controls + for (size_t i=0; i<_cCombo; i++) { + _rgLabel[i] = fmc->findChild(QString("mode%1Label").arg(i)); + _rgCombo[i] = fmc->findChild(QString("mode%1ComboBox").arg(i)); + _rgSimpleModeCheckBox[i] = fmc->findChild(QString("mode%1SimpleCheckBox").arg(i)); + _rgPWMLabel[i] = fmc->findChild(QString("mode%1PWMLabel").arg(i)); + Q_ASSERT(_rgLabel[i]); + Q_ASSERT(_rgCombo[i]); + Q_ASSERT(_rgSimpleModeCheckBox[i]); + Q_ASSERT(_rgPWMLabel[i]); + } + + _saveButton = fmc->findChild("savePushButton"); + Q_ASSERT(_saveButton); +} + diff --git a/src/qgcunittest/FlightModeConfigTest.h b/src/qgcunittest/FlightModeConfigTest.h new file mode 100644 index 0000000000000000000000000000000000000000..89b5d38f8c36ad4b65edf4819a0f85c76065aa84 --- /dev/null +++ b/src/qgcunittest/FlightModeConfigTest.h @@ -0,0 +1,87 @@ +/*===================================================================== + + 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 . + + ======================================================================*/ + +#ifndef FLIGHTMODECONFIGTEST_H +#define FLIGHTMODECONFIGTEST_H + +#include "AutoTest.h" +#include "MockUASManager.h" +#include "MockUAS.h" +#include +#include +#include +#include +#include + +class FlightModeConfig; + +/// @file +/// @brief FlightModeConfig unit test +/// +/// @author Don Gagne + +class FlightModeConfigUnitTest : public QObject +{ + Q_OBJECT + +public: + FlightModeConfigUnitTest(void); + +private slots: + void init(void); + void cleanup(void); + + void _nullUAS_test(void); + void _validUAS_test(void); + void _nullToValidUAS_test(void); + void _simpleModeFixedWing_test(void); + void _simpleModeRover_test(void); + void _simpleModeRotor_test(void); + void _modeSwitchParam_test(void); + void _pwmFixedWing_test(void); + void _pwmRotor_test(void); + void _pwmRover_test(void); + void _pwmInvalidChannel_test(void); + void _unknownSystemType_test(void); + void _unknownMode_test(void); + +private: + void _findControls(QObject* fmc); + void _pwmTestWorker(int systemType, int modeSwitchChannel, const char* modeSwitchParam); + +private: + MockUASManager* _mockUASManager; + MockUAS* _mockUAS; + + // FlightModeConfig ui elements + static const size_t _cCombo = 6; + QLabel* _rgLabel[_cCombo]; + QComboBox* _rgCombo[_cCombo]; + QCheckBox* _rgSimpleModeCheckBox[_cCombo]; + QLabel* _rgPWMLabel[_cCombo]; + QPushButton* _saveButton; +}; + +DECLARE_TEST(FlightModeConfigUnitTest) + +#endif