File indexing completed on 2024-03-24 15:18:41

0001 /*  KStars UI tests
0002     SPDX-FileCopyrightText: 2020 Eric Dejouhanet <eric.dejouhanet@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "kstars_ui_tests.h"
0008 #include "test_ekos_simulator.h"
0009 #include "ekos/guide/guide.h"
0010 
0011 #if defined(HAVE_INDI)
0012 
0013 #include "test_ekos.h"
0014 #include "ksmessagebox.h"
0015 
0016 TestEkosSimulator::TestEkosSimulator(QObject *parent) : QObject(parent)
0017 {
0018 }
0019 
0020 void TestEkosSimulator::initTestCase()
0021 {
0022     KTRY_OPEN_EKOS();
0023     KVERIFY_EKOS_IS_OPENED();
0024 }
0025 
0026 void TestEkosSimulator::cleanupTestCase()
0027 {
0028     KTRY_CLOSE_EKOS();
0029     KVERIFY_EKOS_IS_HIDDEN();
0030 }
0031 
0032 void TestEkosSimulator::init()
0033 {
0034     KTRY_EKOS_START_SIMULATORS();
0035 
0036     // HACK: Reset clock to initial conditions
0037     KHACK_RESET_EKOS_TIME();
0038 }
0039 
0040 void TestEkosSimulator::cleanup()
0041 {
0042     foreach (QDialog * d, KStars::Instance()->findChildren<QDialog*>())
0043         if (d->isVisible())
0044             d->hide();
0045 
0046     KTRY_EKOS_STOP_SIMULATORS();
0047 }
0048 
0049 
0050 void TestEkosSimulator::testMountSlew_data()
0051 {
0052 #if QT_VERSION < 0x050900
0053     QSKIP("Skipping fixture-based test on old QT version.");
0054 #else
0055     QTest::addColumn<QString>("NAME");
0056     QTest::addColumn<QString>("RA");
0057     QTest::addColumn<QString>("DEC");
0058 
0059     // Altitude computation taken from SchedulerJob::findAltitude
0060     GeoLocation * const geo = KStarsData::Instance()->geo();
0061     KStarsDateTime const now(KStarsData::Instance()->lt());
0062     KSNumbers const numbers(now.djd());
0063     CachingDms const LST = geo->GSTtoLST(geo->LTtoUT(now).gst());
0064 
0065     // Build a list of Messier objects, 5 degree over the horizon
0066     for (int i = 1; i < 103; i += 20)
0067     {
0068         QString name = QString("M %1").arg(i);
0069         SkyObject const * const so = KStars::Instance()->data()->objectNamed(name);
0070         if (so != nullptr)
0071         {
0072             SkyObject o(*so);
0073             o.updateCoordsNow(&numbers);
0074             o.EquatorialToHorizontal(&LST, geo->lat());
0075             if (5.0 < o.alt().Degrees())
0076                 QTest::addRow("%s", name.toStdString().c_str())
0077                         << name
0078                         << o.ra().toHMSString()
0079                         << o.dec().toDMSString();
0080         }
0081     }
0082 #endif
0083 }
0084 
0085 void TestEkosSimulator::testMountSlew()
0086 {
0087 #if QT_VERSION < 0x050900
0088     QSKIP("Skipping fixture-based test on old QT version.");
0089 #else
0090     Ekos::Manager * const ekos = Ekos::Manager::Instance();
0091 
0092     QFETCH(QString, NAME);
0093     QFETCH(QString, RA);
0094     QFETCH(QString, DEC);
0095     qDebug("Test slewing to '%s' RA '%s' DEC '%s'",
0096            NAME.toStdString().c_str(),
0097            RA.toStdString().c_str(),
0098            DEC.toStdString().c_str());
0099 
0100 #if 0
0101     // In the mount tab, open the mount control
0102     KTRY_EKOS_CLICK("mountToolBoxB");
0103     QTextObject * raInput = Ekos::Manager::Instance()->findChild<QTextObject*>("targetRATextObject");
0104     QVERIFY(raInput != nullptr);
0105     raInput->setProperty("text", QVariant("07h 37m 30s"));
0106     QTest::qWait(1000);
0107     QTextObject * deInput = Ekos::Manager::Instance()->findChild<QTextObject*>("targetDETextObject");
0108     QVERIFY(deInput != nullptr);
0109     deInput->setProperty("text", QVariant("-14° 31' 50"));
0110     QTest::qWait(1000);
0111 
0112     // Too bad, not accessible...
0113     QPushButton * gotoButton = Ekos::Manager::Instance()->findChild<QPushButton*>("");
0114 
0115     QTest::qWait(5000);
0116     KTRY_EKOS_CLICK("mountToolBoxB");
0117 #else
0118     QVERIFY(ekos->mountModule()->abort());
0119     // Catch the unexpected "under horizon" and the "sun is close" dialogs
0120     // This will not catch the altitude security interval
0121     bool under_horizon_or_close_to_sun = false;
0122     QTimer::singleShot(1000, [&]
0123     {
0124         QDialog * const dialog = qobject_cast <QDialog*> (QApplication::activeModalWidget());
0125         if(dialog != nullptr)
0126         {
0127             under_horizon_or_close_to_sun = true;
0128             emit dialog->reject();
0129         }
0130     });
0131     bool const slew_result = ekos->mountModule()->slew(RA, DEC);
0132     if (under_horizon_or_close_to_sun)
0133         QEXPECT_FAIL(NAME.toStdString().c_str(),
0134                      QString("Slew target '%1' is expected to be over the horizon during night time.").arg(NAME).toStdString().c_str(), Abort);
0135     QVERIFY(slew_result);
0136 #endif
0137 
0138     // DEC slews are precise at plus/minus one arcsecond - expected or not?
0139     auto clampRA = [](QString v)
0140     {
0141         return CachingDms(v, false).arcsec();
0142     };
0143     auto clampDE = [](QString v)
0144     {
0145         return CachingDms(v, true).arcsec();
0146     };
0147 
0148     QLineEdit * raOut = ekos->findChild<QLineEdit*>("raOUT");
0149     QVERIFY(raOut != nullptr);
0150     QTRY_VERIFY_WITH_TIMEOUT(abs(clampRA(RA) - clampRA(raOut->text())) <= 2, 15000);
0151     QTest::qWait(100);
0152     if (clampRA(RA) != clampRA(raOut->text()))
0153         QWARN(QString("Target '%1', RA %2, slewed to RA %3 with offset RA %4")
0154               .arg(NAME)
0155               .arg(clampRA(RA))
0156               .arg(clampRA(raOut->text()))
0157               .arg(abs(clampRA(RA) - clampRA(raOut->text()))).toStdString().c_str());
0158 
0159     QLineEdit * deOut = Ekos::Manager::Instance()->findChild<QLineEdit*>("decOUT");
0160     QVERIFY(deOut != nullptr);
0161     QTRY_VERIFY_WITH_TIMEOUT(abs(clampDE(DEC) - clampDE(deOut->text())) <= 2, 20000);
0162     QTest::qWait(100);
0163     if (clampDE(DEC) != clampDE(deOut->text()))
0164         QWARN(QString("Target '%1', DEC %2, slewed to DEC %3 with coordinate offset DEC %4")
0165               .arg(NAME)
0166               .arg(clampDE(DEC))
0167               .arg(clampDE(deOut->text()))
0168               .arg(abs(clampDE(DEC) - clampDE(deOut->text()))).toStdString().c_str());
0169 
0170     QVERIFY(Ekos::Manager::Instance()->mountModule()->abort());
0171 #endif
0172 }
0173 
0174 void TestEkosSimulator::testColorSchemes_data()
0175 {
0176 #if QT_VERSION < QT_VERSION_CHECK(5,9,0)
0177     QSKIP("Skipping fixture-based test on old QT version.");
0178 #else
0179     QTest::addColumn<QString>("NAME");
0180     QTest::addColumn<QString>("FILENAME");
0181 
0182     QTest::addRow("Classic, friendly name") << "Default Colors" << "classic.colors";
0183     QTest::addRow("Chart, friendly name") << "Star Chart" << "chart.colors",
0184                                           QTest::addRow("Night, friendly name") << "Night Vision" << "night.colors",
0185                                           QTest::addRow("Moonless, friendly name") << "Moonless Night" << "moonless-night.colors";
0186 
0187     QTest::addRow("Classic, short name") << "classic" << "classic.colors";
0188     QTest::addRow("Chart, short name") << "chart" << "chart.colors",
0189                                        QTest::addRow("Night, short name") << "night" << "night.colors",
0190                                        QTest::addRow("Moonless, short name") << "moonless-night" << "moonless-night.colors";
0191 
0192     QTest::addRow("Classic, full name") << "classic.colors" << "classic.colors";
0193     QTest::addRow("Chart, full name") << "chart.colors" << "chart.colors",
0194                                       QTest::addRow("Night, full name") << "night.colors" << "night.colors",
0195                                       QTest::addRow("Moonless, full name") << "moonless-night.colors" << "moonless-night.colors";
0196 #endif
0197 }
0198 
0199 void TestEkosSimulator::testColorSchemes()
0200 {
0201 #if QT_VERSION < QT_VERSION_CHECK(5,9,0)
0202     QSKIP("Skipping fixture-based test on old QT version.");
0203 #else
0204     QFETCH(QString, NAME);
0205     QFETCH(QString, FILENAME);
0206 
0207     KStars::Instance()->loadColorScheme(NAME);
0208     QTRY_COMPARE_WITH_TIMEOUT(KStars::Instance()->colorScheme(), FILENAME, 1000);
0209     QVERIFY(KStars::Instance()->data()->colorScheme()->colorNamed("RAGuideError").isValid());
0210     QTRY_VERIFY_WITH_TIMEOUT(Ekos::Manager::Instance()->guideModule() != nullptr, 5000);
0211     QTRY_COMPARE_WITH_TIMEOUT(Ekos::Manager::Instance()->guideModule()->driftGraph->graph(0)->pen().color(),
0212                               KStars::Instance()->data()->colorScheme()->colorNamed("RAGuideError"), 1000);
0213     QTRY_COMPARE_WITH_TIMEOUT(Ekos::Manager::Instance()->guideModule()->driftGraph->graph(1)->pen().color(),
0214                               KStars::Instance()->data()->colorScheme()->colorNamed("DEGuideError"), 1000);
0215     QTRY_COMPARE_WITH_TIMEOUT(Ekos::Manager::Instance()->guideModule()->driftGraph->graph(2)->pen().color(),
0216                               KStars::Instance()->data()->colorScheme()->colorNamed("RAGuideError"), 1000);
0217     QTRY_COMPARE_WITH_TIMEOUT(Ekos::Manager::Instance()->guideModule()->driftGraph->graph(3)->pen().color(),
0218                               KStars::Instance()->data()->colorScheme()->colorNamed("DEGuideError"), 1000);
0219 #endif
0220 }
0221 
0222 QTEST_KSTARS_MAIN(TestEkosSimulator)
0223 
0224 #endif // HAVE_INDI