diff --git a/src/app/tape/main.cpp b/src/app/tape/main.cpp index 931fce5a1..e2ba5da14 100644 --- a/src/app/tape/main.cpp +++ b/src/app/tape/main.cpp @@ -54,5 +54,5 @@ int main(int argc, char *argv[]) } app.InitOptions(); app.ParseCommandLine(app.arguments()); - return app.exec(); + return app.IsTestMode() ? 0 : app.exec(); // single return point is always better than more } diff --git a/src/app/tape/mapplication.cpp b/src/app/tape/mapplication.cpp index f2532bcd2..7e714acf2 100644 --- a/src/app/tape/mapplication.cpp +++ b/src/app/tape/mapplication.cpp @@ -99,7 +99,7 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con switch (type) { case QtDebugMsg: - std::cerr << msg.toUtf8().constData() << std::endl; + std::cout << msg.toUtf8().constData() << std::endl; return; case QtWarningMsg: messageBox.setIcon(QMessageBox::Warning); @@ -116,13 +116,20 @@ inline void noisyFailureMsgHandler(QtMsgType type, const QMessageLogContext &con if (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg) { - if (topWinAllowsPop) + if (not qApp->IsTestMode()) { - messageBox.setInformativeText(msg); - messageBox.setStandardButtons(QMessageBox::Ok); - messageBox.setWindowModality(Qt::ApplicationModal); - messageBox.setModal(true); - messageBox.exec(); + if (topWinAllowsPop) + { + messageBox.setInformativeText(msg); + messageBox.setStandardButtons(QMessageBox::Ok); + messageBox.setWindowModality(Qt::ApplicationModal); + messageBox.setModal(true); + messageBox.exec(); + } + } + else + { + std::cerr << msg.toUtf8().constData() << std::endl; } } @@ -146,7 +153,8 @@ MApplication::MApplication(int &argc, char **argv) mainWindows(), localServer(nullptr), trVars(nullptr), - dataBase(QPointer()) + dataBase(QPointer()), + testMode(false) { setApplicationDisplayName(VER_PRODUCTNAME_STR); setApplicationName(VER_INTERNALNAME_STR); @@ -256,6 +264,12 @@ bool MApplication::notify(QObject *receiver, QEvent *event) return false; } +//--------------------------------------------------------------------------------------------------------------------- +bool MApplication::IsTestMode() const +{ + return testMode; +} + //--------------------------------------------------------------------------------------------------------------------- bool MApplication::IsTheOnly() const { @@ -496,6 +510,11 @@ void MApplication::ParseCommandLine(const QStringList &arguments) QCoreApplication::translate("main", "The pattern unit")); parser.addOption(unitOption); //----- + QCommandLineOption testOption(QStringList() << "test", + QCoreApplication::translate("main", "Use for unit testing. Run the program and open a file without showing a " + "window.")); + parser.addOption(testOption); + //----- parser.process(arguments); bool flagHeight = false; @@ -568,9 +587,18 @@ void MApplication::ParseCommandLine(const QStringList &arguments) } } + testMode = parser.isSet(testOption); + const QStringList args = parser.positionalArguments(); if (args.count() > 0) { + if (testMode && args.count() > 1) + { + fprintf(stderr, "%s\n", qPrintable(QCoreApplication::translate("main", + "Error: Test mode doesn't support openning several files."))); + parser.showHelp(1); + } + for (int i = 0; i < args.size(); ++i) { NewMainWindow(); @@ -594,7 +622,10 @@ void MApplication::ParseCommandLine(const QStringList &arguments) } else { - NewMainWindow(); + if (not testMode) + { + NewMainWindow(); + } } } @@ -629,7 +660,10 @@ TMainWindow *MApplication::NewMainWindow() { TMainWindow *tape = new TMainWindow(); mainWindows.prepend(tape); - tape->show(); + if (not qApp->IsTestMode()) + { + tape->show(); + } return tape; } diff --git a/src/app/tape/mapplication.h b/src/app/tape/mapplication.h index 2b31b114a..8ca35bee7 100644 --- a/src/app/tape/mapplication.h +++ b/src/app/tape/mapplication.h @@ -54,6 +54,7 @@ public: virtual bool notify(QObject * receiver, QEvent * event) Q_DECL_OVERRIDE; + bool IsTestMode() const; bool IsTheOnly() const; TMainWindow *MainWindow(); QList MainWindows(); @@ -94,6 +95,7 @@ private: QLocalServer *localServer; VTranslateVars *trVars; QPointer dataBase; + bool testMode; void Clean(); }; diff --git a/src/test/ValentinaTest/ValentinaTest.pro b/src/test/ValentinaTest/ValentinaTest.pro index 3eeac216d..31f52e3e9 100644 --- a/src/test/ValentinaTest/ValentinaTest.pro +++ b/src/test/ValentinaTest/ValentinaTest.pro @@ -43,7 +43,8 @@ SOURCES += \ tst_vlayoutdetail.cpp \ tst_varc.cpp \ stable.cpp \ - tst_measurementregexp.cpp + tst_measurementregexp.cpp \ + tst_tapecommandline.cpp HEADERS += \ tst_vposter.h \ @@ -54,7 +55,8 @@ HEADERS += \ tst_vlayoutdetail.h \ tst_varc.h \ stable.h \ - tst_measurementregexp.h + tst_measurementregexp.h \ + tst_tapecommandline.h # Set using ccache. Function enable_ccache() defined in common.pri. $$enable_ccache() @@ -169,3 +171,23 @@ else:unix: LIBS += -L$${OUT_PWD}/../../libs/qmuparser/$${DESTDIR} -lqmuparser INCLUDEPATH += $${PWD}/../../libs/qmuparser DEPENDPATH += $${PWD}/../../libs/qmuparser + +# Only for adding path to LD_LIBRARY_PATH +# VPropertyExplorer library +win32:CONFIG(release, debug|release): LIBS += -L$${OUT_PWD}/../../libs/vpropertyexplorer/$${DESTDIR} -lvpropertyexplorer +else:win32:CONFIG(debug, debug|release): LIBS += -L$${OUT_PWD}/../../libs/vpropertyexplorer/$${DESTDIR} -lvpropertyexplorer +else:unix: LIBS += -L$${OUT_PWD}/../../libs/vpropertyexplorer/$${DESTDIR} -lvpropertyexplorer + +INCLUDEPATH += $${PWD}/../../libs/vpropertyexplorer +DEPENDPATH += $${PWD}/../../libs/vpropertyexplorer + +TAPE_TEST_FILES += \ + tst_tape/keiko.vit + +for(DIR, TAPE_TEST_FILES) { + #add these absolute paths to a variable which + #ends up as 'mkcommands = path1 path2 path3 ...' + tape_path += $${PWD}/$$DIR +} + +copyToDestdir($$tape_path, $$shell_path($${OUT_PWD}/$$DESTDIR/tst_tape)) diff --git a/src/test/ValentinaTest/abstracttest.cpp b/src/test/ValentinaTest/abstracttest.cpp index 415688a54..934a089a2 100644 --- a/src/test/ValentinaTest/abstracttest.cpp +++ b/src/test/ValentinaTest/abstracttest.cpp @@ -47,3 +47,103 @@ void AbstractTest::Comparison(const QVector &ekv, const QVectorsetWorkingDirectory(info.absoluteDir().absolutePath()); + process->start(program, arguments); + + if (not process->waitForFinished())// 30 sec + { + const QString msg = QString("The operation timed out or an error occurred.\n%1").arg(parameters); + QWARN(msg.toUtf8().constData()); + return false; + } + + if (process->exitStatus() == QProcess::CrashExit) + { + const QString msg = QString("Program crashed.\n%1\n%2").arg(parameters) + .arg(QString(process->readAllStandardError())); + QWARN(msg.toUtf8().constData()); + return false; + } + + if (process->exitCode() != 0) + { + const QString msg = QString("Failed.\n%1\n%2").arg(parameters) + .arg(QString(process->readAllStandardError())); + QWARN(msg.toUtf8().constData()); + return false; + } + + delete process; + return true; +} + +//--------------------------------------------------------------------------------------------------------------------- +bool AbstractTest::CopyRecursively(const QString &srcFilePath, const QString &tgtFilePath) const +{ + QFileInfo srcFileInfo(srcFilePath); + if (srcFileInfo.isDir()) + { + QDir targetDir(tgtFilePath); + targetDir.cdUp(); + if (not targetDir.mkdir(QFileInfo(tgtFilePath).fileName())) + { + return false; + } + QDir sourceDir(srcFilePath); + QStringList fileNames = sourceDir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | + QDir::System); + foreach (const QString &fileName, fileNames) + { + const QString newSrcFilePath = srcFilePath + QLatin1Char('/') + fileName; + const QString newTgtFilePath = tgtFilePath + QLatin1Char('/') + fileName; + if (not CopyRecursively(newSrcFilePath, newTgtFilePath)) + { + return false; + } + } + } else + { + if (not QFile::copy(srcFilePath, tgtFilePath)) + { + return false; + } + } + return true; +} diff --git a/src/test/ValentinaTest/abstracttest.h b/src/test/ValentinaTest/abstracttest.h index 953989cdb..f62131b3e 100644 --- a/src/test/ValentinaTest/abstracttest.h +++ b/src/test/ValentinaTest/abstracttest.h @@ -40,6 +40,11 @@ public: protected: void Comparison(const QVector &ekv, const QVector &ekvOrig) const; + QString ValentinaPath() const; + QString TapePath() const; + + bool Run(const QString &program, const QStringList &arguments); + bool CopyRecursively(const QString &srcFilePath, const QString &tgtFilePath) const; }; #endif // ABSTRACTTEST_H diff --git a/src/test/ValentinaTest/qttestmainlambda.cpp b/src/test/ValentinaTest/qttestmainlambda.cpp index 53346a4e0..16f24b183 100644 --- a/src/test/ValentinaTest/qttestmainlambda.cpp +++ b/src/test/ValentinaTest/qttestmainlambda.cpp @@ -35,6 +35,7 @@ #include "tst_vlayoutdetail.h" #include "tst_varc.h" #include "tst_measurementregexp.h" +#include "tst_tapecommandline.h" int main(int argc, char** argv) { @@ -54,6 +55,7 @@ int main(int argc, char** argv) ASSERT_TEST(new TST_VLayoutDetail()); ASSERT_TEST(new TST_VArc()); ASSERT_TEST(new TST_MeasurementRegExp()); + ASSERT_TEST(new TST_TapeCommandLine()); return status; } diff --git a/src/test/ValentinaTest/tst_tape/keiko.vit b/src/test/ValentinaTest/tst_tape/keiko.vit new file mode 100644 index 000000000..b2d3ae567 --- /dev/null +++ b/src/test/ValentinaTest/tst_tape/keiko.vit @@ -0,0 +1,143 @@ + + + + 0.3.0 + false + + cm + + + + 1900-01-01 + male + username@example.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/ValentinaTest/tst_tapecommandline.cpp b/src/test/ValentinaTest/tst_tapecommandline.cpp new file mode 100644 index 000000000..a1c041e8e --- /dev/null +++ b/src/test/ValentinaTest/tst_tapecommandline.cpp @@ -0,0 +1,87 @@ +/************************************************************************ + ** + ** @file tst_tapecommandline.cpp + ** @author Roman Telezhynskyi + ** @date 25 9, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina 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. + ** + ** Valentina 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 Valentina. If not, see . + ** + *************************************************************************/ + +#include "tst_tapecommandline.h" + +#include + +const QString tmpTestFolder = QStringLiteral("tst_tape_tmp"); + +//--------------------------------------------------------------------------------------------------------------------- +TST_TapeCommandLine::TST_TapeCommandLine(QObject *parent) + :AbstractTest(parent) +{ +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_TapeCommandLine::init() +{ + QDir tmpDir(tmpTestFolder); + if (not tmpDir.removeRecursively()) + { + QFAIL("Fail to remove temp directory."); + } + + if (not CopyRecursively(QApplication::applicationDirPath() + QLatin1Char('/') + QStringLiteral("tst_tape"), + QApplication::applicationDirPath() + QLatin1Char('/') + tmpTestFolder)) + { + QFAIL("Fail to prepare files for testing."); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_TapeCommandLine::OpenMeasurements_data() const +{ + QTest::addColumn("file"); + QTest::addColumn("result"); + + QTest::newRow("Send wrong path to file") << "wrongPath.vit" << false; // The file doesn't exist! + QTest::newRow("Old individual format to new version") << "keiko.vit" << true; +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_TapeCommandLine::OpenMeasurements() +{ + QFETCH(QString, file); + QFETCH(bool, result); + + const bool res = Run(TapePath(), QStringList() << "--test" + << QApplication::applicationDirPath() + QLatin1Char('/') + tmpTestFolder + QLatin1Char('/') + file); + + QCOMPARE(res, result); +} + +//--------------------------------------------------------------------------------------------------------------------- +void TST_TapeCommandLine::cleanup() +{ + QDir tmpDir(tmpTestFolder); + if (not tmpDir.removeRecursively()) + { + QWARN("Fail to remove temp directory."); + } +} diff --git a/src/test/ValentinaTest/tst_tapecommandline.h b/src/test/ValentinaTest/tst_tapecommandline.h new file mode 100644 index 000000000..98f97a7dd --- /dev/null +++ b/src/test/ValentinaTest/tst_tapecommandline.h @@ -0,0 +1,51 @@ +/************************************************************************ + ** + ** @file tst_tapecommandline.h + ** @author Roman Telezhynskyi + ** @date 25 9, 2015 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentine project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2015 Valentina project + ** All Rights Reserved. + ** + ** Valentina 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. + ** + ** Valentina 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 Valentina. If not, see . + ** + *************************************************************************/ + +#ifndef TST_TAPECOMMANDLINE_H +#define TST_TAPECOMMANDLINE_H + +#include "abstracttest.h" + +class TST_TapeCommandLine : public AbstractTest +{ + Q_OBJECT +public: + TST_TapeCommandLine(QObject *parent = 0); + +private slots: + void init(); + void OpenMeasurements_data() const; + void OpenMeasurements(); + void cleanup(); + +private: + Q_DISABLE_COPY(TST_TapeCommandLine) + +}; + +#endif // TST_TAPECOMMANDLINE_H