1 /*************************************************************************** 2 * SPDX-FileCopyrightText: 2021 S. MANKOWSKI stephane@mankowski.fr 3 * SPDX-FileCopyrightText: 2021 G. DE BURE support@mankowski.fr 4 * SPDX-License-Identifier: GPL-3.0-or-later 5 ***************************************************************************/ 6 #ifndef SKGTESTMACRO_H 7 #define SKGTESTMACRO_H 8 /** @file 9 * This file contains macro for unit tests. 10 * 11 * @author Stephane MANKOWSKI / Guillaume DE BURE 12 */ 13 #include <qcoreapplication.h> 14 #include <qdir.h> 15 #include <qfile.h> 16 17 #include <kaboutdata.h> 18 19 #include "skgdocument.h" 20 #include "skgerror.h" 21 #include "skgnodeobject.h" 22 #include "skgpropertyobject.h" 23 #include "skgservices.h" 24 #include "skgtraces.h" 25 #include "skgtransactionmng.h" 26 27 class SKGTest 28 { 29 public: 30 /** 31 * Return the test directory 32 * @param iPath can be IN or OUT or REF 33 * @return the test directory 34 */ getTestPath(const QString & iPath)35 static QString getTestPath(const QString& iPath) 36 { 37 QString pPath = SKGServices::getEnvVariable(iPath); 38 if (pPath.isEmpty()) { 39 return QStringLiteral("./tests/") % (iPath == QStringLiteral("IN") ? "input" : (iPath == QStringLiteral("OUT") ? "output" : "ref")); 40 } 41 return pPath; 42 } 43 }; 44 45 /** 46 * @def SKGINITTEST(SHOWERRONLY) 47 * Initialise the test 48 */ 49 #ifndef Q_OS_WIN 50 #define SKGINITTEST(SHOWERRONLY) \ 51 QCoreApplication app(argc, argv); \ 52 app.setApplicationName(QStringLiteral("qttest") ); \ 53 KAboutData::setApplicationData(KAboutData(QStringLiteral("qttest"), QStringLiteral("qttest"), QStringLiteral("1.0"))); \ 54 SKGTRACESEPARATOR; \ 55 SKGTRACE << "STARTING TEST" << SKGENDL << SKGFLUSH; \ 56 SKGTRACE << "homePath=" << QDir::homePath() << SKGENDL << SKGFLUSH; \ 57 SKGTRACESEPARATOR; \ 58 bool showonlyfailures = SHOWERRONLY; \ 59 if (showonlyfailures) {SKGTRACE << "Only failures will be displayed" << SKGENDL;}\ 60 int nberror = 0; \ 61 int nbcheck = 0; 62 #else 63 #define SKGINITTEST(SHOWERRONLY) \ 64 QCoreApplication app(argc, argv); \ 65 app.setApplicationName(QStringLiteral("qttest")); \ 66 KAboutData::setApplicationData(KAboutData(QStringLiteral("qttest"), QStringLiteral("qttest"), QStringLiteral("1.0"))); \ 67 SKGTRACESEPARATOR; \ 68 SKGTRACE << "STARTING TEST" << SKGENDL << SKGFLUSH; \ 69 SKGTRACE << "homePath=" << QDir::homePath() << SKGENDL << SKGFLUSH; \ 70 SKGTRACESEPARATOR; \ 71 bool showonlyfailures = SHOWERRONLY; \ 72 if (showonlyfailures) {SKGTRACE << "Only failures will be displayed" << SKGENDL;}\ 73 int nberror = 0; \ 74 int nbcheck = 0; 75 #endif 76 77 /* 78 79 */ 80 /** 81 * @def SKGENDTEST() 82 * Exit test 83 */ 84 #define SKGENDTEST()\ 85 if (nbcheck > 0) \ 86 { \ 87 SKGTRACE << nberror << " errors / " << nbcheck << " checks =" << (100.0*(static_cast<double>(nberror)) / (static_cast<double>(nbcheck))) << "%" << SKGENDL;\ 88 } \ 89 SKGTraces::dumpProfilingStatistics();\ 90 return nberror; 91 92 /** 93 * @def SKGRETURNTEST() 94 * Return test 95 */ 96 #define SKGRETURNTEST()\ 97 if (nbcheck > 0) \ 98 { \ 99 SKGTRACE << nberror << " errors / " << nbcheck << " checks =" << (100.0*(static_cast<double>(nberror)) / (static_cast<double>(nbcheck))) << "%" << SKGENDL;\ 100 } \ 101 return nberror; 102 103 /** 104 * @def SKGTEST(MESSAGE, RESULT, EXPECTEDRESULT) 105 * To check the return of a method 106 * Example of usage: 107 * @code 108 * SKGTEST(QStringLiteral("ERR:getHistoricalSize"), err.getHistoricalSize(), 0) 109 * @endcode 110 */ 111 #define SKGTEST(MESSAGE, RESULT, EXPECTEDRESULT) \ 112 if ((RESULT) == (EXPECTEDRESULT))\ 113 {\ 114 if (!showonlyfailures) {SKGTRACE << "Test [" << (MESSAGE) << "] : OK" << SKGENDL;}\ 115 }\ 116 else\ 117 {\ 118 SKGTRACE << "!!! Test [" << (MESSAGE) << "] : KO in line " << __LINE__ << SKGENDL;\ 119 SKGTRACE << " Expected: [" << (EXPECTEDRESULT) << ']' << SKGENDL;\ 120 SKGTRACE << " Result : [" << (RESULT) << ']' << SKGENDL;\ 121 ++nberror;\ 122 }\ 123 ++nbcheck; 124 /** 125 * @def SKGTESTBOOL(MESSAGE, RESULT, EXPECTEDRESULT) 126 * To check the return of a method returning a boll 127 * Example of usage: 128 * @code 129 * SKGTESTBOOL("isWarning", err.isWarning(), true) 130 * @endcode 131 */ 132 #define SKGTESTBOOL(MESSAGE, RESULT, EXPECTEDRESULT) \ 133 if ((RESULT) == (EXPECTEDRESULT))\ 134 {\ 135 if (!showonlyfailures) {SKGTRACE << "Test [" << (MESSAGE) << "] : OK" << SKGENDL;}\ 136 }\ 137 else\ 138 {\ 139 SKGTRACE << "!!! Test [" << (MESSAGE) << "] : KO in line " << __LINE__ << SKGENDL;\ 140 SKGTRACE << " Expected: [" << ((EXPECTEDRESULT) ? "TRUE" : "FALSE") << ']' << SKGENDL;\ 141 SKGTRACE << " Result : [" << ((RESULT) ? "TRUE" : "FALSE") << ']' << SKGENDL;\ 142 ++nberror;\ 143 }\ 144 ++nbcheck; 145 146 /** 147 * @def SKGTESTERROR(MESSAGE, RESULT, EXPECTEDRESULT) 148 * To check the return of a method 149 * Example of usage: 150 * @code 151 * SKGTESTERROR(QStringLiteral("DOC:setParameter"), document1.setParameter(QStringLiteral("ATT1"), QStringLiteral("VAL1")), true) 152 * @endcode 153 */ 154 #define SKGTESTERROR(MESSAGE, RESULT, EXPECTEDRESULT) \ 155 { \ 156 SKGError _err_ = RESULT; \ 157 if (!_err_ == (EXPECTEDRESULT)) { \ 158 if (!showonlyfailures) { \ 159 SKGTRACE << "Test [" << (MESSAGE) << "] : OK" << SKGENDL; \ 160 if (!(EXPECTEDRESULT)) { \ 161 SKGTRACE << " Error Message :\n" << _err_.getFullMessageWithHistorical() << SKGENDL; \ 162 } \ 163 }\ 164 } else {\ 165 SKGTRACE << "!!! Test [" << (MESSAGE) << "] : KO in line " << __LINE__ << SKGENDL;\ 166 SKGTRACE << " Expected: [" << ((EXPECTEDRESULT) ? "TRUE" : "FALSE") << ']' << SKGENDL;\ 167 SKGTRACE << " Result : [" << (!_err_ ? "TRUE" : "FALSE") << ']' << SKGENDL;\ 168 SKGTRACE << " Error Message :\n" << _err_.getFullMessageWithHistorical() << SKGENDL;\ 169 ++nberror;\ 170 }\ 171 ++nbcheck;\ 172 } 173 174 /** 175 * @def SKGTESTACCOUNT(DOC, ACCOUNT, AMOUNT) 176 * To check the account amount 177 * Example of usage: 178 * @code 179 * SKGTESTACCOUNT(document1, QStringLiteral("act1"), 12345); 180 * @endcode 181 */ 182 #define SKGTESTACCOUNT(DOC, ACCOUNT, AMOUNT) \ 183 { \ 184 SKGAccountObject account(&(DOC)); \ 185 SKGTESTERROR((ACCOUNT) % ".setName(QStringLiteral(" % (ACCOUNT) % "))", account.setName(ACCOUNT), true) \ 186 SKGTESTERROR((ACCOUNT) % ".load(QStringLiteral(" % (ACCOUNT) % "))", account.load(), true) \ 187 if (qAbs(account.getCurrentAmount()-AMOUNT) > 10e-4) {\ 188 SKGTEST((ACCOUNT) % ".getCurrentAmount(" % (ACCOUNT) % ")", SKGServices::toCurrencyString(account.getCurrentAmount(), QStringLiteral("Euros"), 2), SKGServices::toCurrencyString(AMOUNT, QStringLiteral("Euros"), 2))\ 189 }\ 190 } 191 #endif 192 193 /** 194 * @def SKGTESTTRIGGERACTION(PLUGIN) 195 * To trigger an action 196 */ 197 #define SKGTESTTRIGGERACTION(NAME) \ 198 { \ 199 QAction* act = plugin.action(NAME); \ 200 QVERIFY(act != nullptr); \ 201 act->trigger(); \ 202 } 203 204 /** 205 * @def SKGTESTPLUGIN(PLUGIN) 206 * To do common checks on a plugin 207 */ 208 #define SKGTESTPLUGIN(PLUGIN, DOC) \ 209 { \ 210 QVERIFY(!PLUGIN.setupActions(nullptr)); \ 211 QVERIFY(PLUGIN.setupActions(&DOC)); \ 212 QVERIFY(!PLUGIN.title().isEmpty()); \ 213 QVERIFY(!PLUGIN.icon().isEmpty()); \ 214 QVERIFY(!PLUGIN.toolTip().isEmpty()); \ 215 QVERIFY(!PLUGIN.statusTip().isEmpty()); \ 216 QVERIFY(PLUGIN.getOrder() > 0); \ 217 SKGTabPage* page = plugin.getWidget(); \ 218 plugin.getPreferenceWidget(); \ 219 plugin.getPreferenceSkeleton(); \ 220 plugin.savePreferences(); \ 221 if (page) page->setState(page->getState()); \ 222 int nb = PLUGIN.getNbDashboardWidgets(); \ 223 for (int i = 0; i < nb; ++i) { \ 224 QVERIFY(!PLUGIN.getDashboardWidgetTitle(i).isEmpty()); \ 225 } \ 226 auto tips = PLUGIN.tips(); \ 227 for (int i = 0; i < tips.count(); ++i) { \ 228 QVERIFY(!tips.at(i).isEmpty()); \ 229 } \ 230 auto subplugins = PLUGIN.subPlugins(); \ 231 for (int i = 0; i < subplugins.count(); ++i) { \ 232 QVERIFY(!subplugins.at(i).isEmpty()); \ 233 } \ 234 QStringList iIgnoredAdvice; \ 235 SKGAdviceList adv = PLUGIN.advice(iIgnoredAdvice); \ 236 for (int i = 0; i < adv.count(); ++i) { \ 237 QVERIFY(!adv.at(i).getUUID().isEmpty()); \ 238 } \ 239 } 240