1 | /**************************************************************************** |
2 | ** |
3 | ** Copyright (C) 2016 The Qt Company Ltd. |
4 | ** Contact: https://www.qt.io/licensing/ |
5 | ** |
6 | ** This file is part of the test suite of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and The Qt Company. For licensing terms |
14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
15 | ** information use the contact form at https://www.qt.io/contact-us. |
16 | ** |
17 | ** GNU General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU |
19 | ** General Public License version 3 as published by the Free Software |
20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
21 | ** included in the packaging of this file. Please review the following |
22 | ** information to ensure the GNU General Public License requirements will |
23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
24 | ** |
25 | ** $QT_END_LICENSE$ |
26 | ** |
27 | ****************************************************************************/ |
28 | #include <QtTest/QtTest> |
29 | |
30 | #include <QtCore/QUrl> |
31 | #include <QtCore/QFileInfo> |
32 | #include <QtCore/QScopeGuard> |
33 | #include <QtSql/QSqlDatabase> |
34 | #include <QtSql/QSqlQuery> |
35 | |
36 | #include <QtHelp/QHelpEngineCore> |
37 | |
38 | class tst_QHelpEngineCore : public QObject |
39 | { |
40 | Q_OBJECT |
41 | |
42 | private slots: |
43 | void init(); |
44 | |
45 | void setupData(); |
46 | void collectionFile(); |
47 | void setCollectionFile(); |
48 | void copyCollectionFile(); |
49 | |
50 | void namespaceName(); |
51 | void registeredDocumentations(); |
52 | void registerDocumentation(); |
53 | void unregisterDocumentation(); |
54 | void documentationFileName(); |
55 | |
56 | void customFilters(); |
57 | void removeCustomFilter(); |
58 | void addCustomFilter(); |
59 | void filterAttributes(); |
60 | void currentFilter(); |
61 | void setCurrentFilter(); |
62 | |
63 | void filterAttributeSets(); |
64 | void files(); |
65 | void fileData(); |
66 | |
67 | void linksForIdentifier(); |
68 | |
69 | void customValue(); |
70 | void setCustomValue(); |
71 | void removeCustomValue(); |
72 | |
73 | void setAutoSaveFilter(); |
74 | |
75 | void metaData(); |
76 | |
77 | private: |
78 | QString m_path; |
79 | QString m_colFile; |
80 | }; |
81 | |
82 | void tst_QHelpEngineCore::init() |
83 | { |
84 | // defined in profile |
85 | m_path = QLatin1String(SRCDIR); |
86 | |
87 | m_path = QFileInfo(m_path).absoluteFilePath(); |
88 | |
89 | m_colFile = m_path + QLatin1String("/data/col.qhc" ); |
90 | if (QFile::exists(fileName: m_colFile)) |
91 | QDir::current().remove(fileName: m_colFile); |
92 | if (!QFile::copy(fileName: m_path + "/data/collection.qhc" , newName: m_colFile)) |
93 | QFAIL("Cannot copy file!" ); |
94 | QFile f(m_colFile); |
95 | f.setPermissions(QFile::WriteUser|QFile::ReadUser); |
96 | } |
97 | |
98 | void tst_QHelpEngineCore::setupData() |
99 | { |
100 | QHelpEngineCore help(m_colFile, 0); |
101 | QCOMPARE(help.setupData(), true); |
102 | } |
103 | |
104 | void tst_QHelpEngineCore::collectionFile() |
105 | { |
106 | QHelpEngineCore help(m_colFile, 0); |
107 | QCOMPARE(help.collectionFile(), QFileInfo(m_colFile).absoluteFilePath()); |
108 | } |
109 | |
110 | void tst_QHelpEngineCore::setCollectionFile() |
111 | { |
112 | QHelpEngineCore help(m_colFile, 0); |
113 | QCOMPARE(help.collectionFile(), QFileInfo(m_colFile).absoluteFilePath()); |
114 | |
115 | QString col1File = m_path + QLatin1String("/data/collection1.qhc" ); |
116 | help.setCollectionFile(col1File); |
117 | QCOMPARE(help.collectionFile(), QFileInfo(col1File).absoluteFilePath()); |
118 | |
119 | QStringList docs = help.registeredDocumentations(); |
120 | QCOMPARE(docs.count(), 1); |
121 | QCOMPARE(docs.first(), QLatin1String("trolltech.com.1.0.0.test" )); |
122 | } |
123 | |
124 | void tst_QHelpEngineCore::copyCollectionFile() |
125 | { |
126 | QHelpEngineCore help(m_colFile, 0); |
127 | QCOMPARE(help.collectionFile(), QFileInfo(m_colFile).absoluteFilePath()); |
128 | |
129 | QString copiedFile = m_path + QLatin1String("/collectionCopy.qhc" ); |
130 | if (QFile::exists(fileName: copiedFile)) |
131 | QDir::current().remove(fileName: copiedFile); |
132 | |
133 | QCOMPARE(help.copyCollectionFile(copiedFile), true); |
134 | |
135 | { |
136 | QSqlDatabase db = QSqlDatabase::addDatabase(type: "QSQLITE" , connectionName: "testdb" ); |
137 | db.setDatabaseName(copiedFile); |
138 | if (!db.open()) { |
139 | QSqlDatabase::removeDatabase(connectionName: "testdb" ); |
140 | QFAIL("Created database seems to be corrupt!" ); |
141 | } |
142 | QSqlQuery *m_query = new QSqlQuery(db); |
143 | |
144 | m_query->exec(query: "SELECT Key, Value FROM SettingsTable" ); |
145 | if (m_query->next()) { |
146 | QCOMPARE(m_query->value(0).toString(), QString("CurrentFilter" )); |
147 | QCOMPARE(m_query->value(1).toString(), QString("unfiltered" )); |
148 | } else { |
149 | QFAIL("Settingstable is corrupt!" ); |
150 | } |
151 | |
152 | m_query->exec(query: "SELECT NameId, FilterAttributeId FROM FilterTable" ); |
153 | int i = 0; |
154 | while (m_query->next()) { |
155 | if (i == 3) { |
156 | QCOMPARE(m_query->value(0).toInt(), 2); |
157 | QCOMPARE(m_query->value(1).toInt(), 6); |
158 | } |
159 | ++i; |
160 | } |
161 | QCOMPARE(i, 7); |
162 | m_query->clear(); |
163 | |
164 | m_query->exec(query: "SELECT Name, FilePath FROM NamespaceTable" ); |
165 | i = 0; |
166 | while (m_query->next()) { |
167 | if (i == 0) { |
168 | QCOMPARE(m_query->value(0).toString(), QString("trolltech.com.3-3-8.qmake" )); |
169 | QCOMPARE(m_query->value(1).toString(), QString("data/qmake-3.3.8.qch" )); |
170 | } |
171 | ++i; |
172 | } |
173 | QCOMPARE(i, 3); |
174 | |
175 | m_query->clear(); |
176 | delete m_query; |
177 | } |
178 | QSqlDatabase::removeDatabase(connectionName: "testdb" ); |
179 | } |
180 | |
181 | void tst_QHelpEngineCore::namespaceName() |
182 | { |
183 | QCOMPARE(QHelpEngineCore::namespaceName(m_path + "/data/qmake-3.3.8.qch" ), |
184 | QString("trolltech.com.3-3-8.qmake" )); |
185 | QCOMPARE(QHelpEngineCore::namespaceName(m_path + "/data/linguist-3.3.8.qch" ), |
186 | QString("trolltech.com.3-3-8.linguist" )); |
187 | } |
188 | |
189 | void tst_QHelpEngineCore::registeredDocumentations() |
190 | { |
191 | QHelpEngineCore help(m_colFile, 0); |
192 | QCOMPARE(help.setupData(), true); |
193 | const QStringList docs = help.registeredDocumentations(); |
194 | QCOMPARE(docs.count(), 3); |
195 | QStringList lst; |
196 | lst << "trolltech.com.3-3-8.qmake" << "trolltech.com.4-3-0.qmake" |
197 | << "trolltech.com.1.0.0.test" ; |
198 | for (const QString &s : docs) |
199 | lst.removeAll(t: s); |
200 | QCOMPARE(lst.isEmpty(), true); |
201 | } |
202 | |
203 | void tst_QHelpEngineCore::registerDocumentation() |
204 | { |
205 | if (QFile::exists(fileName: m_colFile)) |
206 | QDir::current().remove(fileName: m_colFile); |
207 | { |
208 | QHelpEngineCore c(m_colFile); |
209 | QCOMPARE(c.setupData(), true); |
210 | c.registerDocumentation(documentationFileName: m_path + "/data/qmake-3.3.8.qch" ); |
211 | QCOMPARE(c.registeredDocumentations().count(), 1); |
212 | c.registerDocumentation(documentationFileName: m_path + "/data/qmake-3.3.8.qch" ); |
213 | QCOMPARE(c.registeredDocumentations().count(), 1); |
214 | c.registerDocumentation(documentationFileName: m_path + "/data/linguist-3.3.8.qch" ); |
215 | QCOMPARE(c.registeredDocumentations().count(), 2); |
216 | } |
217 | |
218 | { |
219 | QSqlDatabase db = QSqlDatabase::addDatabase(type: "QSQLITE" , connectionName: "testdb" ); |
220 | db.setDatabaseName(m_colFile); |
221 | if (!db.open()) { |
222 | QSqlDatabase::removeDatabase(connectionName: "testdb" ); |
223 | QFAIL("Created database seems to be corrupt!" ); |
224 | } |
225 | QSqlQuery query(db); |
226 | query.exec(query: "SELECT FilePath FROM NamespaceTable WHERE " |
227 | "Name=\'trolltech.com.3-3-8.linguist\'" ); |
228 | if (query.next()) |
229 | QCOMPARE(query.value(0).toString(), |
230 | QString("linguist-3.3.8.qch" )); |
231 | else |
232 | QFAIL("Query error!" ); |
233 | } |
234 | QSqlDatabase::removeDatabase(connectionName: "testdb" ); |
235 | } |
236 | |
237 | void tst_QHelpEngineCore::unregisterDocumentation() |
238 | { |
239 | QHelpEngineCore c(m_colFile); |
240 | QCOMPARE(c.setupData(), true); |
241 | QCOMPARE(c.registeredDocumentations().count(), 3); |
242 | c.unregisterDocumentation(namespaceName: "trolltech.com.3-3-8.qmake" ); |
243 | QCOMPARE(c.registeredDocumentations().count(), 2); |
244 | QCOMPARE(c.unregisterDocumentation("noexisting" ), false); |
245 | } |
246 | |
247 | void tst_QHelpEngineCore::documentationFileName() |
248 | { |
249 | QHelpEngineCore c(m_colFile); |
250 | QCOMPARE(c.setupData(), true); |
251 | QCOMPARE(c.documentationFileName(QLatin1String("trolltech.com.3-3-8.qmake" )), |
252 | QString(m_path + "/data/qmake-3.3.8.qch" )); |
253 | QCOMPARE(c.documentationFileName(QLatin1String("trolltech.com.1.0.0.test" )), |
254 | QString(m_path + "/data/test.qch" )); |
255 | QCOMPARE(c.documentationFileName(QLatin1String("trolltech.com.empty" )), |
256 | QString()); |
257 | } |
258 | |
259 | void tst_QHelpEngineCore::customFilters() |
260 | { |
261 | QHelpEngineCore help(m_colFile, 0); |
262 | QCOMPARE(help.setupData(), true); |
263 | const QStringList custom = help.customFilters(); |
264 | QCOMPARE(custom.count(), 4); |
265 | QStringList lst; |
266 | lst << "qmake Manual" << "Custom Filter 1" |
267 | << "Custom Filter 2" << "unfiltered" ; |
268 | for (const QString &s : custom) |
269 | lst.removeAll(t: s); |
270 | QCOMPARE(lst.count(), 0); |
271 | } |
272 | |
273 | void tst_QHelpEngineCore::removeCustomFilter() |
274 | { |
275 | QHelpEngineCore help(m_colFile, 0); |
276 | QCOMPARE(help.setupData(), true); |
277 | help.removeCustomFilter(filterName: "Custom Filter 1" ); |
278 | QStringList custom = help.customFilters(); |
279 | QCOMPARE(custom.count(), 3); |
280 | QCOMPARE((bool)custom.contains("Custom Filter 1" ), false); |
281 | } |
282 | |
283 | void tst_QHelpEngineCore::addCustomFilter() |
284 | { |
285 | QHelpEngineCore help(m_colFile, 0); |
286 | QCOMPARE(help.setupData(), true); |
287 | help.addCustomFilter(filterName: "Qt Tools" , attributes: QStringList() << "tools" << "qt" ); |
288 | QStringList custom = help.customFilters(); |
289 | QCOMPARE(custom.count(), 5); |
290 | QCOMPARE((bool)custom.contains("Qt Tools" ), true); |
291 | } |
292 | |
293 | void tst_QHelpEngineCore::filterAttributes() |
294 | { |
295 | QHelpEngineCore help(m_colFile, 0); |
296 | QCOMPARE(help.setupData(), true); |
297 | const QStringList atts = help.filterAttributes(filterName: "qmake Manual" ); |
298 | QCOMPARE(atts.count(), 3); |
299 | QStringList lst; |
300 | lst << "qmake" << "tools" << "qt" ; |
301 | for (const QString &s : atts) |
302 | lst.removeAll(t: s); |
303 | QCOMPARE(lst.count(), 0); |
304 | } |
305 | |
306 | void tst_QHelpEngineCore::currentFilter() |
307 | { |
308 | QHelpEngineCore help(m_colFile, 0); |
309 | QCOMPARE(help.setupData(), true); |
310 | QCOMPARE(help.currentFilter(), QString("unfiltered" )); |
311 | } |
312 | |
313 | void tst_QHelpEngineCore::setCurrentFilter() |
314 | { |
315 | QHelpEngineCore help(m_colFile, 0); |
316 | QCOMPARE(help.setupData(), true); |
317 | QCOMPARE(help.currentFilter(), QString("unfiltered" )); |
318 | help.setCurrentFilter("qmake Manual" ); |
319 | QCOMPARE(help.currentFilter(), QString("qmake Manual" )); |
320 | QCOMPARE(help.customValue("CurrentFilter" ).toString(), |
321 | QString("qmake Manual" )); |
322 | } |
323 | |
324 | void tst_QHelpEngineCore::filterAttributeSets() |
325 | { |
326 | QHelpEngineCore help(m_colFile, 0); |
327 | QCOMPARE(help.setupData(), true); |
328 | QList<QStringList> lst = help.filterAttributeSets(namespaceName: "trolltech.com.1.0.0.test" ); |
329 | QCOMPARE(lst.count(), 2); |
330 | QCOMPARE(lst.first().count(), 2); |
331 | QCOMPARE((bool)lst.first().contains("filter1" ), true); |
332 | QCOMPARE((bool)lst.last().contains("filter2" ), true); |
333 | } |
334 | |
335 | void tst_QHelpEngineCore::files() |
336 | { |
337 | QHelpEngineCore help(m_colFile, 0); |
338 | QCOMPARE(help.setupData(), true); |
339 | QList<QUrl> lst = help.files(namespaceName: "trolltech.com.4-3-0.qmake" , |
340 | filterAttributes: QStringList()); |
341 | QCOMPARE(lst.count(), 16); |
342 | lst = help.files(namespaceName: "trolltech.com.4-3-0.qmake" , |
343 | filterAttributes: QStringList(), extensionFilter: "png" ); |
344 | QCOMPARE(lst.count(), 2); |
345 | lst = help.files(namespaceName: "trolltech.com.4-3-0.qmake" , |
346 | filterAttributes: QStringList() << "qt" , extensionFilter: "html" ); |
347 | QCOMPARE(lst.count(), 13); |
348 | lst = help.files(namespaceName: "trolltech.com.4-3-0.qmake" , |
349 | filterAttributes: QStringList() << "qt" << "qmake" , extensionFilter: "html" ); |
350 | QCOMPARE(lst.count(), 13); |
351 | lst = help.files(namespaceName: "trolltech.com.4-3-0.qmake" , |
352 | filterAttributes: QStringList() << "qt" << "qmake" << "bla" , extensionFilter: "html" ); |
353 | QCOMPARE(lst.count(), 0); |
354 | lst = help.files(namespaceName: "trolltech.com.4-3-0.qmake" , |
355 | filterAttributes: QStringList() << "qt" << "qmake" , extensionFilter: "foo" ); |
356 | |
357 | // print 'lst' if test fails: |
358 | auto printRemainder = qScopeGuard(f: [&]{ for (const QUrl &url : lst) qDebug() << url; }); |
359 | |
360 | QCOMPARE(lst.count(), 0); |
361 | |
362 | printRemainder.dismiss(); |
363 | } |
364 | |
365 | void tst_QHelpEngineCore::fileData() |
366 | { |
367 | QHelpEngineCore help(m_colFile, 0); |
368 | QCOMPARE(help.setupData(), true); |
369 | QByteArray ba = help.fileData(url: QUrl("NotExisting" )); |
370 | QCOMPARE(ba.size(), 0); |
371 | ba = help.fileData(url: QUrl("qthelp://trolltech.com.1.0.0.test/testFolder/test.html" )); |
372 | QTextStream s(ba, QIODevice::ReadOnly|QIODevice::Text); |
373 | QFile f(m_path + "/data/test.html" ); |
374 | if (!f.open(flags: QIODevice::ReadOnly|QIODevice::Text)) |
375 | QFAIL("Cannot open original file!" ); |
376 | QTextStream ts(&f); |
377 | QCOMPARE(s.readAll(), ts.readAll()); |
378 | } |
379 | |
380 | void tst_QHelpEngineCore::linksForIdentifier() |
381 | { |
382 | QHelpEngineCore help(m_colFile, 0); |
383 | QCOMPARE(help.setupData(), true); |
384 | QMap<QString, QUrl> map; |
385 | map = help.linksForIdentifier(id: "Test::foo" ); |
386 | QCOMPARE(map.contains("Test Manual" ), true); |
387 | QCOMPARE(map.count(), 1); |
388 | QCOMPARE(map.value("Test Manual" ), |
389 | QUrl("qthelp://trolltech.com.1.0.0.test/testFolder/test.html#foo" )); |
390 | |
391 | help.setCurrentFilter("Custom Filter 2" ); |
392 | map = help.linksForIdentifier(id: "People::newton" ); |
393 | QCOMPARE(map.isEmpty(), true); |
394 | map = help.linksForIdentifier(id: "Fancy::foobar" ); |
395 | QCOMPARE(map.contains("Fancy" ), true); |
396 | QCOMPARE(map.count(), 1); |
397 | QCOMPARE(map.value("Fancy" ), |
398 | QUrl("qthelp://trolltech.com.1.0.0.test/testFolder/fancy.html#foobar" )); |
399 | } |
400 | |
401 | void tst_QHelpEngineCore::customValue() |
402 | { |
403 | QHelpEngineCore help(m_colFile, 0); |
404 | QCOMPARE(help.setupData(), true); |
405 | QCOMPARE(help.customValue("CurrentFilter" ).toString(), |
406 | QString("unfiltered" )); |
407 | } |
408 | |
409 | void tst_QHelpEngineCore::setCustomValue() |
410 | { |
411 | QHelpEngineCore help(m_colFile, 0); |
412 | QCOMPARE(help.setupData(), true); |
413 | QCOMPARE(help.setCustomValue("Test" , 3), true); |
414 | QCOMPARE(help.customValue("Test" ).toInt(), 3); |
415 | QCOMPARE(help.removeCustomValue("Test" ), true); |
416 | QCOMPARE(help.customValue("Test" ), QVariant()); |
417 | } |
418 | |
419 | void tst_QHelpEngineCore::removeCustomValue() |
420 | { |
421 | setCustomValue(); |
422 | } |
423 | |
424 | void tst_QHelpEngineCore::setAutoSaveFilter() |
425 | { |
426 | QHelpEngineCore help(m_colFile, 0); |
427 | QCOMPARE(help.setupData(), true); |
428 | QCOMPARE(help.currentFilter(), QString("unfiltered" )); |
429 | |
430 | help.setAutoSaveFilter(false); |
431 | help.setCurrentFilter("qmake Manual" ); |
432 | QCOMPARE(help.currentFilter(), QString("qmake Manual" )); |
433 | QCOMPARE(help.customValue("CurrentFilter" ).toString(), |
434 | QString("unfiltered" )); |
435 | } |
436 | |
437 | void tst_QHelpEngineCore::metaData() |
438 | { |
439 | QCOMPARE(QHelpEngineCore::metaData(m_path + "/data/test.qch" , "author" ).toString(), |
440 | QString("Digia Plc and/or its subsidiary(-ies)" )); |
441 | QCOMPARE(QHelpEngineCore::metaData(m_path + "/data/test.qch" , "notExisting" ).isValid(), |
442 | false); |
443 | } |
444 | |
445 | QTEST_MAIN(tst_QHelpEngineCore) |
446 | #include "tst_qhelpenginecore.moc" |
447 | |