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