File indexing completed on 2024-04-14 14:12:00

0001 /*
0002     SPDX-FileCopyrightText: 2021 Kwon-Young Choi <kwon-young.choi@hotmail.fr>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 /* Project Includes */
0008 #include "test_placeholderpath.h"
0009 #include "ekos/capture/sequencejob.h"
0010 #include "ekos/capture/capturedeviceadaptor.h"
0011 #include "ekos/scheduler/schedulerjob.h"
0012 #include "ekos/capture/placeholderpath.h"
0013 
0014 #include <QFile>
0015 #include <QRegularExpression>
0016 #include <QRegularExpressionMatch>
0017 
0018 using Ekos::SequenceJob;
0019 
0020 TestPlaceholderPath::TestPlaceholderPath() : QObject()
0021 {
0022 }
0023 
0024 void TestPlaceholderPath::initTestCase()
0025 {
0026     QDir("/tmp").mkdir("kstars");
0027 }
0028 
0029 TestPlaceholderPath::~TestPlaceholderPath()
0030 {
0031 }
0032 
0033 // helper functions
0034 void parseCSV(const QString filename, const QList<const char*> columns)
0035 {
0036     QFile testDataFile(filename);
0037 
0038     if (!testDataFile.open(QIODevice::ReadOnly))
0039     {
0040         QDir cwd(".");
0041         qDebug() << QString("%1/%2").arg(cwd.absolutePath()).arg(filename) << ":" << testDataFile.errorString();
0042         QFAIL("error");
0043     }
0044 
0045     // checking csv header
0046     int columnCpt = 0;
0047     QByteArray line = testDataFile.readLine().replace("\n", "");
0048 
0049     for (auto el : line.split(','))
0050     {
0051         if (columns.size() <= columnCpt)
0052             QFAIL("too many csv columns");
0053         else if (el != columns[columnCpt])
0054         {
0055             QFAIL(QString("csv columns incorrect %1 %2").arg(el, columns[columnCpt]).toStdString().c_str());
0056         }
0057         columnCpt++;
0058     }
0059 
0060     if (columns.size() != columnCpt)
0061         QFAIL("not enough csv columns");
0062 
0063     int cpt = 0;
0064 
0065     while (!testDataFile.atEnd())
0066     {
0067         QByteArray line = testDataFile.readLine().replace("\n", "");
0068         QTestData &row = QTest::addRow("%d", cpt);
0069         for (auto el : line.split(','))
0070         {
0071             row << QString::fromStdString(el.toStdString());
0072         }
0073         cpt++;
0074     }
0075 }
0076 
0077 XMLEle* buildXML(
0078     QString Exposure,
0079     QString Filter,
0080     QString Type,
0081     QString Prefix,
0082     QString TargetName,
0083     QString FilterEnabled,
0084     QString ExpEnabled,
0085     QString TimeStampEnabled,
0086     QString FITSDirectory,
0087     QString PlaceholderFormat,
0088     QString PlaceholderSuffix
0089 )
0090 {
0091     XMLEle *root = nullptr;
0092     XMLEle *ep, *subEP;
0093     root = addXMLEle(root, "root");
0094 
0095     if (!Exposure.isEmpty())
0096     {
0097         ep = addXMLEle(root, "Exposure");
0098         editXMLEle(ep, Exposure.toStdString().c_str());
0099     }
0100 
0101     if (!Filter.isEmpty())
0102     {
0103         ep = addXMLEle(root, "Filter");
0104         editXMLEle(ep, Filter.toStdString().c_str());
0105     }
0106 
0107     if (!Type.isEmpty())
0108     {
0109         ep = addXMLEle(root, "Type");
0110         editXMLEle(ep, Type.toStdString().c_str());
0111     }
0112 
0113     if (!TargetName.isEmpty())
0114     {
0115         ep = addXMLEle(root, "TargetName");
0116         editXMLEle(ep, TargetName.toStdString().c_str());
0117     }
0118 
0119     if (!Prefix.isEmpty())
0120     {
0121         ep = addXMLEle(root, "Prefix");
0122         if (!FilterEnabled.isEmpty())
0123         {
0124             subEP = addXMLEle(ep, "FilterEnabled");
0125             editXMLEle(subEP, FilterEnabled.toStdString().c_str());
0126         }
0127         if (!ExpEnabled.isEmpty())
0128         {
0129             subEP = addXMLEle(ep, "ExpEnabled");
0130             editXMLEle(subEP, ExpEnabled.toStdString().c_str());
0131         }
0132         if (!TimeStampEnabled.isEmpty())
0133         {
0134             subEP = addXMLEle(ep, "TimeStampEnabled");
0135             editXMLEle(subEP, TimeStampEnabled.toStdString().c_str());
0136         }
0137     }
0138 
0139     if (!FITSDirectory.isEmpty())
0140     {
0141         ep = addXMLEle(root, "FITSDirectory");
0142         editXMLEle(ep, FITSDirectory.toStdString().c_str());
0143     }
0144 
0145     if (!PlaceholderFormat.isEmpty())
0146     {
0147         ep = addXMLEle(root, "PlaceholderFormat");
0148         editXMLEle(ep, PlaceholderFormat.toStdString().c_str());
0149     }
0150 
0151     if (!PlaceholderSuffix.isEmpty())
0152     {
0153         ep = addXMLEle(root, "PlaceholderSuffix");
0154         editXMLEle(ep, PlaceholderSuffix.toStdString().c_str());
0155     }
0156 
0157     return root;
0158 }
0159 
0160 void TestPlaceholderPath::testSchedulerProcessJobInfo_data()
0161 {
0162 #if QT_VERSION < 0x050900
0163     QSKIP("Skipping fixture-based test on old QT version.");
0164 #else
0165     const QList<const char*> columns =
0166     {
0167         "Exposure",
0168         "Filter",
0169         "Type",
0170         "Prefix",
0171         "RawPrefix",
0172         "FilterEnabled",
0173         "ExpEnabled",
0174         "FITSDirectory",
0175         "PlaceholderFormat",
0176         "PlaceholderSuffix",
0177         "targetName",
0178         "signature",
0179     };
0180     for (const auto &column : columns)
0181     {
0182         QTest::addColumn<QString>(column);
0183     }
0184     parseCSV("testSchedulerProcessJobInfo_data.csv", columns);
0185 
0186 #endif
0187 }
0188 
0189 void TestPlaceholderPath::testSchedulerProcessJobInfo()
0190 {
0191 #if QT_VERSION < 0x050900
0192     QSKIP("Skipping fixture-based test on old QT version.");
0193 #else
0194     QFETCH(QString, Exposure);
0195     QFETCH(QString, Filter);
0196     QFETCH(QString, Type);
0197     QFETCH(QString, Prefix);
0198     QFETCH(QString, FilterEnabled);
0199     QFETCH(QString, ExpEnabled);
0200     QFETCH(QString, FITSDirectory);
0201     QFETCH(QString, PlaceholderFormat);
0202     QFETCH(QString, PlaceholderSuffix);
0203     QFETCH(QString, targetName);
0204     QFETCH(QString, signature);
0205 
0206     XMLEle *root = buildXML(
0207                        Exposure,
0208                        Filter,
0209                        Type,
0210                        Prefix,
0211                        targetName,
0212                        FilterEnabled,
0213                        ExpEnabled,
0214                        "",
0215                        FITSDirectory,
0216                        PlaceholderFormat,
0217                        PlaceholderSuffix);
0218 
0219     Ekos::SequenceJob job(root, targetName);
0220     auto placeholderPath = Ekos::PlaceholderPath();
0221     placeholderPath.processJobInfo(&job);
0222 
0223     QCOMPARE(job.getSignature(), signature);
0224 
0225     delXMLEle(root);
0226 #endif
0227 }
0228 
0229 //void TestPlaceholderPath::testCCDGenerateFilename_data()
0230 //{
0231 //#if QT_VERSION < 0x050900
0232 //    QSKIP("Skipping fixture-based test on old QT version.");
0233 //#else
0234 //    QTest::addColumn<QString>("format");
0235 //    QTest::addColumn<bool>("batch_mode");
0236 //    QTest::addColumn<QString>("fitsDir");
0237 //    QTest::addColumn<QString>("seqPrefix");
0238 //    QTest::addColumn<int>("nextSequenceID");
0239 //    QTest::addColumn<QString>("desiredFilename");
0240 //
0241 //    // format
0242 //    QTest::addRow("0")  << ""      << false << ""    << ""            << 0 << "/.+/kstars/000";
0243 //    QTest::addRow("1")  << ""      << false << ""    << ""            << 1 << "/.+/kstars/001";
0244 //    QTest::addRow("2")  << ""      << false << ""    << "_ISO8601"    << 0 <<
0245 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000";
0246 //    QTest::addRow("3")  << ""      << false << ""    << "_ISO8601"    << 1 <<
0247 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001";
0248 //    QTest::addRow("4")  << ""      << false << ""    << "_ISO8601bar" << 0 <<
0249 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000";
0250 //    QTest::addRow("5")  << ""      << false << ""    << "_ISO8601bar" << 1 <<
0251 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001";
0252 //    QTest::addRow("6")  << ""      << false << ""    << "bar"         << 0 << "/.+/kstars/bar_000";
0253 //    QTest::addRow("7")  << ""      << false << ""    << "bar"         << 1 << "/.+/kstars/bar_001";
0254 //    QTest::addRow("8")  << ""      << false << "foo" << ""            << 0 << "/.+/kstars/000";
0255 //    QTest::addRow("9")  << ""      << false << "foo" << ""            << 1 << "/.+/kstars/001";
0256 //    QTest::addRow("10") << ""      << false << "foo" << "_ISO8601"    << 0 <<
0257 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000";
0258 //    QTest::addRow("11") << ""      << false << "foo" << "_ISO8601"    << 1 <<
0259 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001";
0260 //    QTest::addRow("12") << ""      << false << "foo" << "_ISO8601bar" << 0 <<
0261 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000";
0262 //    QTest::addRow("13") << ""      << false << "foo" << "_ISO8601bar" << 1 <<
0263 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001";
0264 //    QTest::addRow("14") << ""      << false << "foo" << "bar"         << 0 << "/.+/kstars/bar_000";
0265 //    QTest::addRow("15") << ""      << false << "foo" << "bar"         << 1 << "/.+/kstars/bar_001";
0266 //    QTest::addRow("16") << ""      << true  << ""    << ""            << 0 << "/.+/000";
0267 //    QTest::addRow("17") << ""      << true  << ""    << ""            << 1 << "/.+/001";
0268 //    QTest::addRow("18") << ""      << true  << ""    << "_ISO8601"    << 0 <<
0269 //                        "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000";
0270 //    QTest::addRow("19") << ""      << true  << ""    << "_ISO8601"    << 1 <<
0271 //                        "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001";
0272 //    QTest::addRow("20") << ""      << true  << ""    << "_ISO8601bar" << 0 <<
0273 //                        "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000";
0274 //    QTest::addRow("21") << ""      << true  << ""    << "_ISO8601bar" << 1 <<
0275 //                        "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001";
0276 //    QTest::addRow("22") << ""      << true  << ""    << "bar"         << 0 << "/.+/bar_000";
0277 //    QTest::addRow("23") << ""      << true  << ""    << "bar"         << 1 << "/.+/bar_001";
0278 //    QTest::addRow("24") << ""      << true  << "foo" << ""            << 0 << "foo/000";
0279 //    QTest::addRow("25") << ""      << true  << "foo" << ""            << 1 << "foo/001";
0280 //    QTest::addRow("26") << ""      << true  << "foo" << "_ISO8601"    << 0 <<
0281 //                        "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000";
0282 //    QTest::addRow("27") << ""      << true  << "foo" << "_ISO8601"    << 1 <<
0283 //                        "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001";
0284 //    QTest::addRow("28") << ""      << true  << "foo" << "_ISO8601bar" << 0 <<
0285 //                        "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000";
0286 //    QTest::addRow("29") << ""      << true  << "foo" << "_ISO8601bar" << 1 <<
0287 //                        "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001";
0288 //    QTest::addRow("30") << ""      << true  << "foo" << "bar"         << 0 << "foo/bar_000";
0289 //    QTest::addRow("31") << ""      << true  << "foo" << "bar"         << 1 << "foo/bar_001";
0290 //    QTest::addRow("32") << ".fits" << false << ""    << ""            << 0 << "/.+/kstars/000.fits";
0291 //    QTest::addRow("33") << ".fits" << false << ""    << ""            << 1 << "/.+/kstars/001.fits";
0292 //    QTest::addRow("34") << ".fits" << false << ""    << "_ISO8601"    << 0 <<
0293 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000.fits";
0294 //    QTest::addRow("35") << ".fits" << false << ""    << "_ISO8601"    << 1 <<
0295 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001.fits";
0296 //    QTest::addRow("36") << ".fits" << false << ""    << "_ISO8601bar" << 0 <<
0297 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000.fits";
0298 //    QTest::addRow("37") << ".fits" << false << ""    << "_ISO8601bar" << 1 <<
0299 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001.fits";
0300 //    QTest::addRow("38") << ".fits" << false << ""    << "bar"         << 0 << "/.+/kstars/bar_000.fits";
0301 //    QTest::addRow("39") << ".fits" << false << ""    << "bar"         << 1 << "/.+/kstars/bar_001.fits";
0302 //    QTest::addRow("40") << ".fits" << false << "foo" << ""            << 0 << "/.+/kstars/000.fits";
0303 //    QTest::addRow("41") << ".fits" << false << "foo" << ""            << 1 << "/.+/kstars/001.fits";
0304 //    QTest::addRow("42") << ".fits" << false << "foo" << "_ISO8601"    << 0 <<
0305 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000.fits";
0306 //    QTest::addRow("43") << ".fits" << false << "foo" << "_ISO8601"    << 1 <<
0307 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001.fits";
0308 //    QTest::addRow("44") << ".fits" << false << "foo" << "_ISO8601bar" << 0 <<
0309 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000.fits";
0310 //    QTest::addRow("45") << ".fits" << false << "foo" << "_ISO8601bar" << 1 <<
0311 //                        "/.+/kstars/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001.fits";
0312 //    QTest::addRow("46") << ".fits" << false << "foo" << "bar"         << 0 << "/.+/kstars/bar_000.fits";
0313 //    QTest::addRow("47") << ".fits" << false << "foo" << "bar"         << 1 << "/.+/kstars/bar_001.fits";
0314 //    QTest::addRow("48") << ".fits" << true  << ""    << ""            << 0 << "/.+/000.fits";
0315 //    QTest::addRow("49") << ".fits" << true  << ""    << ""            << 1 << "/.+/001.fits";
0316 //    QTest::addRow("50") << ".fits" << true  << ""    << "_ISO8601"    << 0 <<
0317 //                        "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000.fits";
0318 //    QTest::addRow("51") << ".fits" << true  << ""    << "_ISO8601"    << 1 <<
0319 //                        "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001.fits";
0320 //    QTest::addRow("52") << ".fits" << true  << ""    << "_ISO8601bar" << 0 <<
0321 //                        "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000.fits";
0322 //    QTest::addRow("53") << ".fits" << true  << ""    << "_ISO8601bar" << 1 <<
0323 //                        "/.+/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001.fits";
0324 //    QTest::addRow("54") << ".fits" << true  << ""    << "bar"         << 0 << "/.+/bar_000.fits";
0325 //    QTest::addRow("55") << ".fits" << true  << ""    << "bar"         << 1 << "/.+/bar_001.fits";
0326 //    QTest::addRow("56") << ".fits" << true  << "foo" << ""            << 0 << "foo/000.fits";
0327 //    QTest::addRow("57") << ".fits" << true  << "foo" << ""            << 1 << "foo/001.fits";
0328 //    QTest::addRow("58") << ".fits" << true  << "foo" << "_ISO8601"    << 0 <<
0329 //                        "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_000.fits";
0330 //    QTest::addRow("59") << ".fits" << true  << "foo" << "_ISO8601"    << 1 <<
0331 //                        "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_001.fits";
0332 //    QTest::addRow("60") << ".fits" << true  << "foo" << "_ISO8601bar" << 0 <<
0333 //                        "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_000.fits";
0334 //    QTest::addRow("61") << ".fits" << true  << "foo" << "_ISO8601bar" << 1 <<
0335 //                        "foo/_\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}bar_001.fits";
0336 //    QTest::addRow("62") << ".fits" << true  << "foo" << "bar"         << 0 << "foo/bar_000.fits";
0337 //    QTest::addRow("63") << ".fits" << true  << "foo" << "bar"         << 1 << "foo/bar_001.fits";
0338 //#endif
0339 //}
0340 
0341 //void TestPlaceholderPath::testCCDGenerateFilename()
0342 //{
0343 //#if QT_VERSION < 0x050900
0344 //    QSKIP("Skipping fixture-based test on old QT version.");
0345 //#else
0346 //    QFETCH(QString, format);
0347 //    QFETCH(bool, batch_mode);
0348 //    QFETCH(QString, fitsDir);
0349 //    QFETCH(QString, seqPrefix);
0350 //    QFETCH(int, nextSequenceID);
0351 //    QFETCH(QString, desiredFilename);
0352 //
0353 //    QString filename;
0354 //    auto placeholderPath = Ekos::PlaceholderPath();
0355 //    placeholderPath.generateFilenameOld(format, batch_mode, &filename, fitsDir, seqPrefix, nextSequenceID);
0356 //
0357 //    QVERIFY(QRegularExpression(desiredFilename).match(filename).hasMatch());
0358 //#endif
0359 //}
0360 
0361 //void TestPlaceholderPath::testFullNamingSequence_data()
0362 //{
0363 //#if QT_VERSION < 0x050900
0364 //    QSKIP("Skipping fixture-based test on old QT version.");
0365 //#else
0366 //    const QList<const char*> columns =
0367 //    {
0368 //        "Exposure",
0369 //        "Filter",
0370 //        "Type",
0371 //        "Prefix",
0372 //        "RawPrefix",
0373 //        "FilterEnabled",
0374 //        "ExpEnabled",
0375 //        "TimeStampEnabled",
0376 //        "FITSDirectory",
0377 //        "targetName",
0378 //        "batch_mode",
0379 //        "nextSequenceID",
0380 //        "result",
0381 //    };
0382 //    for (const auto &column : columns)
0383 //    {
0384 //        QTest::addColumn<QString>(column);
0385 //    }
0386 //    parseCSV("testFullNamingSequence_data_small.csv", columns);
0387 //#endif
0388 //}
0389 
0390 //void TestPlaceholderPath::testFullNamingSequence()
0391 //{
0392 //#if QT_VERSION < 0x050900
0393 //    QSKIP("Skipping fixture-based test on old QT version.");
0394 //#else
0395 //
0396 //    QFETCH(QString, Exposure);
0397 //    QFETCH(QString, Filter);
0398 //    QFETCH(QString, Type);
0399 //    QFETCH(QString, Prefix);
0400 //    QFETCH(QString, RawPrefix);
0401 //    QFETCH(QString, FilterEnabled);
0402 //    QFETCH(QString, ExpEnabled);
0403 //    QFETCH(QString, TimeStampEnabled);
0404 //    QFETCH(QString, FITSDirectory);
0405 //    QFETCH(QString, targetName);
0406 //    QFETCH(QString, batch_mode);
0407 //    QFETCH(QString, nextSequenceID);
0408 //    QFETCH(QString, result);
0409 //
0410 //    XMLEle *root = buildXML(
0411 //                       Exposure,
0412 //                       Filter,
0413 //                       Type,
0414 //                       Prefix,
0415 //                       RawPrefix,
0416 //                       FilterEnabled,
0417 //                       ExpEnabled,
0418 //                       TimeStampEnabled,
0419 //                       FITSDirectory);
0420 //
0421 //    Ekos::SequenceJob job(root);
0422 //    auto placeholderPath = Ekos::PlaceholderPath();
0423 //    // for addJob, targetName should already be sanitized
0424 //    // taken from scheduler.cpp:2491-2495
0425 //    targetName = targetName.replace( QRegularExpression("\\s|/|\\(|\\)|:|\\*|~|\"" ), "_" )
0426 //                 // Remove any two or more __
0427 //                 .replace( QRegularExpression("_{2,}"), "_")
0428 //                 // Remove any _ at the end
0429 //                 .replace( QRegularExpression("_$"), "");
0430 //    placeholderPath.addJob(&job, targetName);
0431 //    QString fitsDir, filename;
0432 //    // from sequencejob.cpp:302-303
0433 //    auto localDir = job.getCoreProperty(SequenceJob::SJ_LocalDirectory).toString();
0434 //    if (localDir.isEmpty() == false)
0435 //        fitsDir = localDir + job.getCoreProperty(SequenceJob::SJ_DirectoryPostfix).toString();
0436 //    placeholderPath.generateFilenameOld(".fits",
0437 //                                        bool(batch_mode.toInt()),
0438 //                                        &filename,
0439 //                                        fitsDir,
0440 //                                        job.getCoreProperty(SequenceJob::SJ_FullPrefix).toString(),
0441 //                                        nextSequenceID.toInt());
0442 //    QVERIFY2(QRegularExpression(result).match(filename).hasMatch(),
0443 //             QString("\nExpected: %1\nObtained: %2\n").arg(result, filename).toStdString().c_str());
0444 //
0445 //#endif
0446 //}
0447 
0448 void TestPlaceholderPath::testFlexibleNaming_data()
0449 {
0450 #if QT_VERSION < 0x050900
0451     QSKIP("Skipping fixture-based test on old QT version.");
0452 #else
0453     const QList<const char*> columns =
0454     {
0455         "Exposure",
0456         "Filter",
0457         "Type",
0458         "Prefix",
0459         "RawPrefix",
0460         "FilterEnabled",
0461         "ExpEnabled",
0462         "TimeStampEnabled",
0463         "seqFilename",
0464         "targetName",
0465         "batch_mode",
0466         "nextSequenceID",
0467         "FITSDirectory",
0468         "PlaceholderFormat",
0469         "PlaceholderSuffix",
0470         "result",
0471     };
0472     for (const auto &column : columns)
0473     {
0474         QTest::addColumn<QString>(column);
0475     }
0476     QTest::addRow("f")  << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0477                         "1" << "" << "" << "/%f" << "1"  << "^/100x30s_RGB_0\\.fits$";
0478     // %p & %d tags disabled for simplicity
0479     //    QTest::addRow("p")  << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0480     //                        "1" << "" << "%p"  << "^/home/user/Images/NGC7635\\.fits$";
0481     //    QTest::addRow("p1") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0482     //                        "1" << "" << "%p1" << "^/home/user/Images/NGC7635\\.fits$";
0483     //    QTest::addRow("p2") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0484     //                        "1" << "" << "%p2" << "^/home/user/Images\\.fits$";
0485     //    QTest::addRow("p3") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0486     //                        "1" << "" << "%p3" << "^/home/user\\.fits$";
0487     //    QTest::addRow("p4") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0488     //                        "1" << "" << "%p4" << "^/home\\.fits$";
0489     //    QTest::addRow("d")  << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0490     //                        "1" << "" << "%d"  << "^NGC7635\\.fits$";
0491     //    QTest::addRow("d1") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0492     //                        "1" << "" << "%d1" << "^NGC7635\\.fits$";
0493     //    QTest::addRow("d2") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0494     //                        "1" << "" << "%d2" << "^Images\\.fits$";
0495     //    QTest::addRow("d3") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0496     //                        "1" << "" << "%d3" << "^user\\.fits$";
0497     //    QTest::addRow("d4") << "" << "" << "" << "" << "" << "" << "" << "" << "/home/user/Images/NGC7635/100x30s_RGB.esq" << "" <<
0498     //                        "1" << "" << "%d4" << "^home\\.fits$";
0499 
0500     QTest::addRow("t")  << ""      << ""      << ""      << ""       << "" << ""  << ""  << ""  << "" << "target" << "" << ""
0501                         << "" << "%t" << "1"  << "^/tmp/kstars/target_0\\.fits$";
0502     QTest::addRow("T")  << ""      << ""      << "Light" << ""       << "" << ""  << ""  << ""  << "" << ""       << "" << ""
0503                         << "" << "%T" << "1"  << "^/tmp/kstars/Light_0\\.fits$";
0504     QTest::addRow("F")  << ""      << "H_Alpha" << "" << "prefix" << "" << "1" << ""  << ""  << "" << ""       << "" << ""
0505                         << "" << "%F" << "1"  << "^/tmp/kstars/H_Alpha_0\\.fits$";
0506     QTest::addRow("e")  << "0.001" << ""      << ""      << "prefix" << "" << ""  << "1" << ""  << "" << ""       << "" << ""
0507                         << "" << "%e" << "1"  << "^/tmp/kstars/0.001_secs_0\\.fits$";
0508     QTest::addRow("D")  << ""      << ""      << ""      << "prefix" << "" << ""  << ""  << "1" << "" << ""       << "" << ""
0509                         << "" << "%D" << "1"  << "^/tmp/kstars/\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}_0\\.fits$";
0510     QTest::addRow("s1") << ""      << ""      << ""      << ""       << "" << ""  << ""  << ""  << "" << ""       << "" << "1"
0511                         << "" << "" << "1" << "^/tmp/kstars/_1\\.fits$";
0512     QTest::addRow("s2") << ""      << ""      << ""      << ""       << "" << ""  << ""  << ""  << "" << ""       << "" << "1"
0513                         << "" << "" << "2" << "^/tmp/kstars/_01\\.fits$";
0514     QTest::addRow("s3") << ""      << ""      << ""      << ""       << "" << ""  << ""  << ""  << "" << ""       << "" << "1"
0515                         << "" << "" << "3" << "^/tmp/kstars/_001\\.fits$";
0516     QTest::addRow("s4") << ""      << ""      << ""      << ""       << "" << ""  << ""  << ""  << "" << ""       << "" << "1"
0517                         << "" << "" << "4" << "^/tmp/kstars/_0001\\.fits$";
0518 
0519     QTest::addRow("_s") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "1" << "" << "" << "1" <<
0520                         "^/tmp/kstars/_1\\.fits$";
0521     QTest::addRow("unknown1") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "%b" << "" <<
0522                               "^/tmp/kstars/%b_0\\.fits$";
0523     QTest::addRow("unknown2") << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "" << "%f_%a_%t" << ""
0524                               <<
0525                               "^/tmp/kstars/%a_0\\.fits$";
0526 
0527     parseCSV("testFlexibleNaming_data_small.csv", columns);
0528 
0529 #endif
0530 }
0531 
0532 void TestPlaceholderPath::testFlexibleNaming()
0533 {
0534 #if QT_VERSION < 0x050900
0535     QSKIP("Skipping fixture-based test on old QT version.");
0536 #else
0537     QFETCH(QString, Exposure);
0538     QFETCH(QString, Filter);
0539     QFETCH(QString, Type);
0540     QFETCH(QString, Prefix);
0541     QFETCH(QString, RawPrefix);
0542     QFETCH(QString, FilterEnabled);
0543     QFETCH(QString, ExpEnabled);
0544     QFETCH(QString, TimeStampEnabled);
0545     QFETCH(QString, seqFilename);
0546     QFETCH(QString, targetName);
0547     QFETCH(QString, batch_mode);
0548     QFETCH(QString, nextSequenceID);
0549     QFETCH(QString, FITSDirectory);
0550     QFETCH(QString, PlaceholderFormat);
0551     QFETCH(QString, PlaceholderSuffix);
0552     QFETCH(QString, result);
0553 
0554     XMLEle *root = buildXML(
0555                        Exposure,
0556                        Filter,
0557                        Type,
0558                        Prefix,
0559                        targetName,
0560                        FilterEnabled,
0561                        ExpEnabled,
0562                        TimeStampEnabled,
0563                        FITSDirectory,
0564                        PlaceholderFormat,
0565                        PlaceholderSuffix);
0566 
0567     Ekos::SequenceJob job(root, targetName);
0568     auto placeholderPath = Ekos::PlaceholderPath(seqFilename);
0569     bool bm = bool(batch_mode.toInt());
0570     int i = nextSequenceID.toInt();
0571     QString filename = placeholderPath.generateSequenceFilename(job, true, bm, i, ".fits", "");
0572     QVERIFY2(QRegularExpression(result).match(filename).hasMatch(),
0573              QString("\nExpected: %1\nObtained: %2\n").arg(result, filename).toStdString().c_str());
0574 
0575     placeholderPath.setGenerateFilenameSettings(job);
0576     filename = placeholderPath.generateOutputFilename(true, bm, i, ".fits", "");
0577     QVERIFY2(QRegularExpression(result).match(filename).hasMatch(),
0578              QString("\nExpected: %1\nObtained: %2\n").arg(result, filename).toStdString().c_str());
0579 #endif
0580 }
0581 
0582 void TestPlaceholderPath::testFlexibleNamingGlob_data()
0583 {
0584 #if QT_VERSION < 0x050900
0585     QSKIP("Skipping fixture-based test on old QT version.");
0586 #else
0587     const QList<const char*> columns =
0588     {
0589         "TimeStampEnabled",
0590         "nextSequenceID",
0591         "FITSDirectory",
0592         "PlaceholderFormat",
0593         "PlaceholderSuffix",
0594         "result",
0595     };
0596     for (const auto &column : columns)
0597     {
0598         QTest::addColumn<QString>(column);
0599     }
0600     QTest::addRow("D")  << "1" << "" << "" << "%D" << "1" <<
0601                         "/tmp/kstars/\\d\\d\\d\\d-\\d\\d-\\d\\dT\\d\\d-\\d\\d-\\d\\d_(?<id>\\d+).fits";
0602     QTest::addRow("s1") << "0"  << "1" << "" << "" << "1" << "/tmp/kstars/_(?<id>\\d+).fits";
0603     QTest::addRow("s2") << "0"  << "1" << "" << "" << "2" << "/tmp/kstars/_(?<id>\\d+).fits";
0604     QTest::addRow("s3") << "0"  << "1" << "" << "" << "3" << "/tmp/kstars/_(?<id>\\d+).fits";
0605     QTest::addRow("s4") << "0"  << "1" << "" << "" << "4" << "/tmp/kstars/_(?<id>\\d+).fits";
0606 #endif
0607 }
0608 
0609 void TestPlaceholderPath::testFlexibleNamingGlob()
0610 {
0611 #if QT_VERSION < 0x050900
0612     QSKIP("Skipping fixture-based test on old QT version.");
0613 #else
0614     QFETCH(QString, TimeStampEnabled);
0615     QFETCH(QString, nextSequenceID);
0616     QFETCH(QString, FITSDirectory);
0617     QFETCH(QString, PlaceholderFormat);
0618     QFETCH(QString, PlaceholderSuffix);
0619     QFETCH(QString, result);
0620 
0621     XMLEle *root = buildXML(
0622                        "",
0623                        "",
0624                        "",
0625                        "prefix",
0626                        "",
0627                        "",
0628                        "",
0629                        TimeStampEnabled,
0630                        FITSDirectory,
0631                        PlaceholderFormat,
0632                        PlaceholderSuffix);
0633 
0634     Ekos::SequenceJob job(root, "");
0635     auto placeholderPath = Ekos::PlaceholderPath("");
0636     bool bm = false;
0637     int i = nextSequenceID.toInt();
0638     QString filename = placeholderPath.generateSequenceFilename(job, true, bm, i, ".fits", "", true);
0639     QCOMPARE(filename, result);
0640     placeholderPath.setGenerateFilenameSettings(job);
0641     filename = placeholderPath.generateOutputFilename(true, bm, i, ".fits", "", true);
0642     QCOMPARE(filename, result);
0643 #endif
0644 }
0645 
0646 void TestPlaceholderPath::testRemainingPlaceholders_data()
0647 {
0648 #if QT_VERSION < 0x050900
0649     QSKIP("Skipping fixture-based test on old QT version.");
0650 #else
0651     QTest::addColumn<QString>("Filename");
0652     QTest::addColumn<QStringList>("Result");
0653     QTest::addRow("0")  << "test.fits" << QStringList();
0654     QTest::addRow("1")  << "%f_test.fits" << QStringList({"%f"});
0655     QTest::addRow("2")  << "%p/%f_test.fits" << QStringList({"%p", "%f"});
0656 #endif
0657 }
0658 
0659 void TestPlaceholderPath::testRemainingPlaceholders()
0660 {
0661 #if QT_VERSION < 0x050900
0662     QSKIP("Skipping fixture-based test on old QT version.");
0663 #else
0664     QFETCH(QString, Filename);
0665     QFETCH(QStringList, Result);
0666 
0667     auto remainingPlaceholders = Ekos::PlaceholderPath::remainingPlaceholders(Filename);
0668     QCOMPARE(remainingPlaceholders, Result);
0669 #endif
0670 }
0671 
0672 void TestPlaceholderPath::testGetCompletedFileIds_data()
0673 {
0674 #if QT_VERSION < 0x050900
0675     QSKIP("Skipping fixture-based test on old QT version.");
0676 #else
0677     const QList<const char*> columns =
0678     {
0679         "Exposure",
0680         "Filter",
0681         "Type",
0682         "Prefix",
0683         "RawPrefix",
0684         "FilterEnabled",
0685         "ExpEnabled",
0686         "TimeStampEnabled",
0687         "seqFilename",
0688         "targetName",
0689         "PlaceholderFormat",
0690         "PlaceholderSuffix"
0691     };
0692     for (const auto &column : columns)
0693     {
0694         QTest::addColumn<QString>(column);
0695     }
0696 
0697     // tags %d & %p disabled for simplicity
0698     //    QTest::addRow("f1") << "0.001" << "H_Alpha" << "Light" << "prefix" << "" << "1" << "1" << "1" <<
0699     //                        "/tmp/kstars/NGC7635/100x30s_RGB.esq" << "M42" << "%p1/%t/%T/%F/%t_%T_%F_%e_%D" << "3";
0700     //    QTest::addRow("f2") << "0.001" << "H_Alpha" << "Light" << "prefix" << "" << "1" << "1" << "1" <<
0701     //                        "/tmp/kstars/NGC7635/100x30s_RGB.esq" << "M42" << "%p1/%t/%T/%F/%D_%t_%T_%F_%e" << "3";
0702     //    QTest::addRow("f3") << "0.001" << "H_Alpha" << "Light" << "prefix" << "" << "1" << "1" << "0" <<
0703     //                        "/tmp/kstars/NGC7635/100x30s_RGB.esq" << "M42" << "%p1/%t/%T/%F/%t_%T_%F_%e << "3"";
0704     QTest::addRow("f1") << "0.001" << "H_Alpha" << "Light" << "prefix" << "" << "1" << "1" << "1" <<
0705                         "/tmp/kstars/NGC7635/100x30s_RGB.esq" << "M42" << "/tmp/kstars/%t/%T/%F/%t_%T_%F_%e_%D" << "3";
0706     QTest::addRow("f2") << "0.001" << "H_Alpha" << "Light" << "prefix" << "" << "1" << "1" << "1" <<
0707                         "/tmp/kstars/NGC7635/100x30s_RGB.esq" << "M42" << "/tmp/kstars/%t/%T/%F/%D_%t_%T_%F_%e" << "3";
0708     QTest::addRow("f3") << "0.001" << "H_Alpha" << "Light" << "prefix" << "" << "1" << "1" << "1" <<
0709                         "/tmp/kstars/NGC7635/100x30s_RGB.esq" << "M42" << "/tmp/kstars/%t/%T/%F/%t_%T_%e_%F" << "3";
0710 #endif
0711 }
0712 
0713 void TestPlaceholderPath::testGetCompletedFileIds()
0714 {
0715 #if QT_VERSION < 0x050900
0716     QSKIP("Skipping fixture-based test on old QT version.");
0717 #else
0718     QFETCH(QString, Exposure);
0719     QFETCH(QString, Filter);
0720     QFETCH(QString, Type);
0721     QFETCH(QString, Prefix);
0722     QFETCH(QString, FilterEnabled);
0723     QFETCH(QString, ExpEnabled);
0724     QFETCH(QString, TimeStampEnabled);
0725     QFETCH(QString, seqFilename);
0726     QFETCH(QString, targetName);
0727     QFETCH(QString, PlaceholderFormat);
0728     QFETCH(QString, PlaceholderSuffix);
0729 
0730 
0731     XMLEle *root = buildXML(
0732                        Exposure,
0733                        Filter,
0734                        Type,
0735                        Prefix,
0736                        targetName,
0737                        FilterEnabled,
0738                        ExpEnabled,
0739                        TimeStampEnabled,
0740                        "",
0741                        PlaceholderFormat,
0742                        "1");
0743 
0744     Ekos::SequenceJob job(root, targetName);
0745     auto placeholderPath = Ekos::PlaceholderPath(seqFilename);
0746     bool bm = true;
0747     placeholderPath.setGenerateFilenameSettings(job);
0748     int nextSequenceID;
0749     for (int id = 1; id < 4; id++)
0750     {
0751         nextSequenceID = placeholderPath.getCompletedFiles(job);
0752         QCOMPARE(nextSequenceID, id - 1);
0753         nextSequenceID = placeholderPath.checkSeqBoundary(job);
0754         QCOMPARE(nextSequenceID, id);
0755         QString filename = placeholderPath.generateOutputFilename(true, bm, id, ".fits", "");
0756         QDir path;
0757         path.mkpath(QFileInfo(filename).dir().path());
0758         QFile(filename).open(QIODevice::WriteOnly);
0759     }
0760 
0761 #endif
0762 }
0763 
0764 void TestPlaceholderPath::cleanupTestCase()
0765 {
0766     QDir("/tmp/kstars").removeRecursively();
0767 }
0768 
0769 QTEST_GUILESS_MAIN(TestPlaceholderPath)