kjobtest.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. /*
  2. This file is part of the KDE project
  3. SPDX-FileCopyrightText: 2006 Kevin Ottens <ervin@kde.org>
  4. SPDX-License-Identifier: LGPL-2.0-only
  5. */
  6. #include "kjobtest.h"
  7. #include <QMetaEnum>
  8. #include <QSignalSpy>
  9. #include <QTest>
  10. #include <QTimer>
  11. #include <QVector>
  12. #include <string>
  13. QTEST_MAIN(KJobTest)
  14. KJobTest::KJobTest()
  15. : loop(this)
  16. {
  17. }
  18. void KJobTest::testEmitResult_data()
  19. {
  20. QTest::addColumn<int>("errorCode");
  21. QTest::addColumn<QString>("errorText");
  22. QTest::newRow("no error") << int(KJob::NoError) << QString();
  23. QTest::newRow("error no text") << 2 << QString();
  24. QTest::newRow("error with text") << 6 << "oops! an error? naaah, really?";
  25. }
  26. void KJobTest::testEmitResult()
  27. {
  28. TestJob *job = new TestJob;
  29. connect(job, &KJob::result, this, [this](KJob *job) {
  30. slotResult(job);
  31. loop.quit();
  32. });
  33. QFETCH(int, errorCode);
  34. QFETCH(QString, errorText);
  35. job->setError(errorCode);
  36. job->setErrorText(errorText);
  37. QSignalSpy destroyed_spy(job, &QObject::destroyed);
  38. job->start();
  39. QVERIFY(!job->isFinished());
  40. loop.exec();
  41. QVERIFY(job->isFinished());
  42. QCOMPARE(m_lastError, errorCode);
  43. QCOMPARE(m_lastErrorText, errorText);
  44. // Verify that the job is not deleted immediately...
  45. QCOMPARE(destroyed_spy.size(), 0);
  46. QTimer::singleShot(0, &loop, &QEventLoop::quit);
  47. // ... but when we enter the event loop again.
  48. loop.exec();
  49. QCOMPARE(destroyed_spy.size(), 1);
  50. }
  51. void KJobTest::testProgressTracking()
  52. {
  53. TestJob *testJob = new TestJob;
  54. KJob *job = testJob;
  55. qRegisterMetaType<KJob *>("KJob*");
  56. qRegisterMetaType<qulonglong>("qulonglong");
  57. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  58. QSignalSpy processed_spy(job, qOverload<KJob *, KJob::Unit, qulonglong>(&KJob::processedAmount));
  59. QSignalSpy total_spy(job, qOverload<KJob *, KJob::Unit, qulonglong>(&KJob::totalAmount));
  60. QSignalSpy percent_spy(job, qOverload<KJob *, ulong>(&KJob::percent));
  61. #endif
  62. QSignalSpy processedChanged_spy(job, &KJob::processedAmountChanged);
  63. QSignalSpy totalChanged_spy(job, &KJob::totalAmountChanged);
  64. QSignalSpy percentChanged_spy(job, &KJob::percentChanged);
  65. /* Process a first item. Corresponding signal should be emitted.
  66. * Total size didn't change.
  67. * Since the total size is unknown, no percent signal is emitted.
  68. */
  69. testJob->setProcessedSize(1);
  70. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  71. QCOMPARE(processed_spy.size(), 1);
  72. QCOMPARE(processed_spy.at(0).at(0).value<KJob *>(), static_cast<KJob *>(job));
  73. QCOMPARE(processed_spy.at(0).at(2).value<qulonglong>(), qulonglong(1));
  74. QCOMPARE(total_spy.size(), 0);
  75. QCOMPARE(percent_spy.size(), 0);
  76. #endif
  77. QCOMPARE(processedChanged_spy.size(), 1);
  78. QCOMPARE(processedChanged_spy.at(0).at(0).value<KJob *>(), static_cast<KJob *>(job));
  79. QCOMPARE(processedChanged_spy.at(0).at(2).value<qulonglong>(), qulonglong(1));
  80. QCOMPARE(totalChanged_spy.size(), 0);
  81. QCOMPARE(percentChanged_spy.size(), 0);
  82. /* Now, we know the total size. It's signaled.
  83. * The new percentage is signaled too.
  84. */
  85. testJob->setTotalSize(10);
  86. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  87. QCOMPARE(processed_spy.size(), 1);
  88. QCOMPARE(total_spy.size(), 1);
  89. QCOMPARE(total_spy.at(0).at(0).value<KJob *>(), job);
  90. QCOMPARE(total_spy.at(0).at(2).value<qulonglong>(), qulonglong(10));
  91. QCOMPARE(percent_spy.size(), 1);
  92. QCOMPARE(percent_spy.at(0).at(0).value<KJob *>(), job);
  93. QCOMPARE(percent_spy.at(0).at(1).value<unsigned long>(), static_cast<unsigned long>(10));
  94. #endif
  95. QCOMPARE(processedChanged_spy.size(), 1);
  96. QCOMPARE(totalChanged_spy.size(), 1);
  97. QCOMPARE(totalChanged_spy.at(0).at(0).value<KJob *>(), job);
  98. QCOMPARE(totalChanged_spy.at(0).at(2).value<qulonglong>(), qulonglong(10));
  99. QCOMPARE(percentChanged_spy.size(), 1);
  100. QCOMPARE(percentChanged_spy.at(0).at(0).value<KJob *>(), job);
  101. QCOMPARE(percentChanged_spy.at(0).at(1).value<unsigned long>(), static_cast<unsigned long>(10));
  102. /* We announce a new percentage by hand.
  103. * Total, and processed didn't change, so no signal is emitted for them.
  104. */
  105. testJob->setPercent(15);
  106. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  107. QCOMPARE(processed_spy.size(), 1);
  108. QCOMPARE(total_spy.size(), 1);
  109. QCOMPARE(percent_spy.size(), 2);
  110. QCOMPARE(percent_spy.at(1).at(0).value<KJob *>(), job);
  111. QCOMPARE(percent_spy.at(1).at(1).value<unsigned long>(), static_cast<unsigned long>(15));
  112. #endif
  113. QCOMPARE(processedChanged_spy.size(), 1);
  114. QCOMPARE(totalChanged_spy.size(), 1);
  115. QCOMPARE(percentChanged_spy.size(), 2);
  116. QCOMPARE(percentChanged_spy.at(1).at(0).value<KJob *>(), job);
  117. QCOMPARE(percentChanged_spy.at(1).at(1).value<unsigned long>(), static_cast<unsigned long>(15));
  118. /* We make some progress.
  119. * Processed size and percent are signaled.
  120. */
  121. testJob->setProcessedSize(3);
  122. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  123. QCOMPARE(processed_spy.size(), 2);
  124. QCOMPARE(processed_spy.at(1).at(0).value<KJob *>(), job);
  125. QCOMPARE(processed_spy.at(1).at(2).value<qulonglong>(), qulonglong(3));
  126. QCOMPARE(total_spy.size(), 1);
  127. QCOMPARE(percent_spy.size(), 3);
  128. QCOMPARE(percent_spy.at(2).at(0).value<KJob *>(), job);
  129. QCOMPARE(percent_spy.at(2).at(1).value<unsigned long>(), static_cast<unsigned long>(30));
  130. #endif
  131. QCOMPARE(processedChanged_spy.size(), 2);
  132. QCOMPARE(processedChanged_spy.at(1).at(0).value<KJob *>(), job);
  133. QCOMPARE(processedChanged_spy.at(1).at(2).value<qulonglong>(), qulonglong(3));
  134. QCOMPARE(totalChanged_spy.size(), 1);
  135. QCOMPARE(percentChanged_spy.size(), 3);
  136. QCOMPARE(percentChanged_spy.at(2).at(0).value<KJob *>(), job);
  137. QCOMPARE(percentChanged_spy.at(2).at(1).value<unsigned long>(), static_cast<unsigned long>(30));
  138. /* We set a new total size, but equals to the previous one.
  139. * No signal is emitted.
  140. */
  141. testJob->setTotalSize(10);
  142. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  143. QCOMPARE(processed_spy.size(), 2);
  144. QCOMPARE(total_spy.size(), 1);
  145. QCOMPARE(percent_spy.size(), 3);
  146. #endif
  147. QCOMPARE(processedChanged_spy.size(), 2);
  148. QCOMPARE(totalChanged_spy.size(), 1);
  149. QCOMPARE(percentChanged_spy.size(), 3);
  150. /* We 'lost' the previous work done.
  151. * Signals both percentage and new processed size.
  152. */
  153. testJob->setProcessedSize(0);
  154. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  155. QCOMPARE(processed_spy.size(), 3);
  156. QCOMPARE(processed_spy.at(2).at(0).value<KJob *>(), job);
  157. QCOMPARE(processed_spy.at(2).at(2).value<qulonglong>(), qulonglong(0));
  158. QCOMPARE(total_spy.size(), 1);
  159. QCOMPARE(percent_spy.size(), 4);
  160. QCOMPARE(percent_spy.at(3).at(0).value<KJob *>(), job);
  161. QCOMPARE(percent_spy.at(3).at(1).value<unsigned long>(), static_cast<unsigned long>(0));
  162. #endif
  163. QCOMPARE(processedChanged_spy.size(), 3);
  164. QCOMPARE(processedChanged_spy.at(2).at(0).value<KJob *>(), job);
  165. QCOMPARE(processedChanged_spy.at(2).at(2).value<qulonglong>(), qulonglong(0));
  166. QCOMPARE(totalChanged_spy.size(), 1);
  167. QCOMPARE(percentChanged_spy.size(), 4);
  168. QCOMPARE(percentChanged_spy.at(3).at(0).value<KJob *>(), job);
  169. QCOMPARE(percentChanged_spy.at(3).at(1).value<unsigned long>(), static_cast<unsigned long>(0));
  170. /* We process more than the total size!?
  171. * Signals both percentage and new processed size.
  172. * Percentage is 150%
  173. *
  174. * Might sounds weird, but verify that this case is handled gracefully.
  175. */
  176. testJob->setProcessedSize(15);
  177. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  178. QCOMPARE(processed_spy.size(), 4);
  179. QCOMPARE(processed_spy.at(3).at(0).value<KJob *>(), job);
  180. QCOMPARE(processed_spy.at(3).at(2).value<qulonglong>(), qulonglong(15));
  181. QCOMPARE(total_spy.size(), 1);
  182. QCOMPARE(percent_spy.size(), 5);
  183. QCOMPARE(percent_spy.at(4).at(0).value<KJob *>(), job);
  184. QCOMPARE(percent_spy.at(4).at(1).value<unsigned long>(), static_cast<unsigned long>(150));
  185. #endif
  186. QCOMPARE(processedChanged_spy.size(), 4);
  187. QCOMPARE(processedChanged_spy.at(3).at(0).value<KJob *>(), job);
  188. QCOMPARE(processedChanged_spy.at(3).at(2).value<qulonglong>(), qulonglong(15));
  189. QCOMPARE(totalChanged_spy.size(), 1);
  190. QCOMPARE(percentChanged_spy.size(), 5);
  191. QCOMPARE(percentChanged_spy.at(4).at(0).value<KJob *>(), job);
  192. QCOMPARE(percentChanged_spy.at(4).at(1).value<unsigned long>(), static_cast<unsigned long>(150));
  193. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  194. processed_spy.clear();
  195. total_spy.clear();
  196. percent_spy.clear();
  197. #endif
  198. processedChanged_spy.clear();
  199. totalChanged_spy.clear();
  200. percentChanged_spy.clear();
  201. /**
  202. * Try again with Files as the progress unit
  203. */
  204. testJob->setProgressUnit(KJob::Files);
  205. testJob->setProcessedSize(16);
  206. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  207. QCOMPARE(percent_spy.size(), 0); // no impact on percent
  208. #endif
  209. QCOMPARE(percentChanged_spy.size(), 0);
  210. testJob->setTotalFiles(5);
  211. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  212. QCOMPARE(percent_spy.size(), 1);
  213. QCOMPARE(percent_spy.at(0).at(1).value<unsigned long>(), static_cast<unsigned long>(0));
  214. #endif
  215. QCOMPARE(percentChanged_spy.size(), 1);
  216. QCOMPARE(percentChanged_spy.at(0).at(1).value<unsigned long>(), static_cast<unsigned long>(0));
  217. testJob->setProcessedFiles(2);
  218. #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80)
  219. QCOMPARE(percent_spy.size(), 2);
  220. QCOMPARE(percent_spy.at(1).at(1).value<unsigned long>(), static_cast<unsigned long>(40));
  221. #endif
  222. QCOMPARE(percentChanged_spy.size(), 2);
  223. QCOMPARE(percentChanged_spy.at(1).at(1).value<unsigned long>(), static_cast<unsigned long>(40));
  224. delete job;
  225. }
  226. void KJobTest::testExec_data()
  227. {
  228. QTest::addColumn<int>("errorCode");
  229. QTest::addColumn<QString>("errorText");
  230. QTest::newRow("no error") << int(KJob::NoError) << QString();
  231. QTest::newRow("error no text") << 2 << QString();
  232. QTest::newRow("error with text") << 6 << "oops! an error? naaah, really?";
  233. }
  234. void KJobTest::testExec()
  235. {
  236. TestJob *job = new TestJob;
  237. QFETCH(int, errorCode);
  238. QFETCH(QString, errorText);
  239. job->setError(errorCode);
  240. job->setErrorText(errorText);
  241. int resultEmitted = 0;
  242. // Prove to Kai Uwe that one can connect a job to a lambdas, despite the "private" signal
  243. connect(job, &KJob::result, this, [&resultEmitted](KJob *) {
  244. ++resultEmitted;
  245. });
  246. QSignalSpy destroyed_spy(job, &QObject::destroyed);
  247. QVERIFY(!job->isFinished());
  248. bool status = job->exec();
  249. QVERIFY(job->isFinished());
  250. QCOMPARE(resultEmitted, 1);
  251. QCOMPARE(status, (errorCode == KJob::NoError));
  252. QCOMPARE(job->error(), errorCode);
  253. QCOMPARE(job->errorText(), errorText);
  254. // Verify that the job is not deleted immediately...
  255. QCOMPARE(destroyed_spy.size(), 0);
  256. QTimer::singleShot(0, &loop, &QEventLoop::quit);
  257. // ... but when we enter the event loop again.
  258. loop.exec();
  259. QCOMPARE(destroyed_spy.size(), 1);
  260. }
  261. void KJobTest::testKill_data()
  262. {
  263. QTest::addColumn<int>("killVerbosity");
  264. QTest::addColumn<int>("errorCode");
  265. QTest::addColumn<QString>("errorText");
  266. QTest::addColumn<int>("resultEmitCount");
  267. QTest::addColumn<int>("finishedEmitCount");
  268. QTest::newRow("killed with result") << int(KJob::EmitResult) << int(KJob::KilledJobError) << QString() << 1 << 1;
  269. QTest::newRow("killed quietly") << int(KJob::Quietly) << int(KJob::KilledJobError) << QString() << 0 << 1;
  270. }
  271. void KJobTest::testKill()
  272. {
  273. auto *const job = setupErrorResultFinished();
  274. QSignalSpy destroyed_spy(job, &QObject::destroyed);
  275. QFETCH(int, killVerbosity);
  276. QFETCH(int, errorCode);
  277. QFETCH(QString, errorText);
  278. QFETCH(int, resultEmitCount);
  279. QFETCH(int, finishedEmitCount);
  280. QVERIFY(!job->isFinished());
  281. job->kill(static_cast<KJob::KillVerbosity>(killVerbosity));
  282. QVERIFY(job->isFinished());
  283. loop.processEvents(QEventLoop::AllEvents, 2000);
  284. QCOMPARE(m_lastError, errorCode);
  285. QCOMPARE(m_lastErrorText, errorText);
  286. QCOMPARE(job->error(), errorCode);
  287. QCOMPARE(job->errorText(), errorText);
  288. QCOMPARE(m_resultCount, resultEmitCount);
  289. QCOMPARE(m_finishedCount, finishedEmitCount);
  290. // Verify that the job is not deleted immediately...
  291. QCOMPARE(destroyed_spy.size(), 0);
  292. QTimer::singleShot(0, &loop, &QEventLoop::quit);
  293. // ... but when we enter the event loop again.
  294. loop.exec();
  295. QCOMPARE(destroyed_spy.size(), 1);
  296. QVERIFY(m_jobFinishCount.size() == (finishedEmitCount - resultEmitCount));
  297. m_jobFinishCount.clear();
  298. }
  299. void KJobTest::testDestroy()
  300. {
  301. auto *const job = setupErrorResultFinished();
  302. QVERIFY(!job->isFinished());
  303. delete job;
  304. QCOMPARE(m_lastError, static_cast<int>(KJob::NoError));
  305. QCOMPARE(m_lastErrorText, QString{});
  306. QCOMPARE(m_resultCount, 0);
  307. QCOMPARE(m_finishedCount, 1);
  308. QVERIFY(m_jobFinishCount.size() == 1);
  309. m_jobFinishCount.clear();
  310. }
  311. void KJobTest::testEmitAtMostOnce_data()
  312. {
  313. QTest::addColumn<bool>("autoDelete");
  314. QTest::addColumn<QVector<Action>>("actions");
  315. const auto actionName = [](Action action) {
  316. return QMetaEnum::fromType<Action>().valueToKey(static_cast<int>(action));
  317. };
  318. for (bool autoDelete : {true, false}) {
  319. for (Action a : {Action::Start, Action::KillQuietly, Action::KillVerbosely}) {
  320. for (Action b : {Action::Start, Action::KillQuietly, Action::KillVerbosely}) {
  321. const auto dataTag = std::string{actionName(a)} + '-' + actionName(b) + (autoDelete ? "-autoDelete" : "");
  322. QTest::newRow(dataTag.c_str()) << autoDelete << QVector<Action>{a, b};
  323. }
  324. }
  325. }
  326. }
  327. void KJobTest::testEmitAtMostOnce()
  328. {
  329. auto *const job = setupErrorResultFinished();
  330. QSignalSpy destroyed_spy(job, &QObject::destroyed);
  331. QFETCH(bool, autoDelete);
  332. job->setAutoDelete(autoDelete);
  333. QFETCH(QVector<Action>, actions);
  334. for (auto action : actions) {
  335. switch (action) {
  336. case Action::Start:
  337. job->start(); // in effect calls QTimer::singleShot(0, ... emitResult)
  338. break;
  339. case Action::KillQuietly:
  340. QTimer::singleShot(0, job, [=] {
  341. job->kill(KJob::Quietly);
  342. });
  343. break;
  344. case Action::KillVerbosely:
  345. QTimer::singleShot(0, job, [=] {
  346. job->kill(KJob::EmitResult);
  347. });
  348. break;
  349. }
  350. }
  351. QVERIFY(!job->isFinished());
  352. loop.processEvents(QEventLoop::AllEvents, 2000);
  353. QCOMPARE(destroyed_spy.size(), autoDelete);
  354. if (!autoDelete) {
  355. QVERIFY(job->isFinished());
  356. }
  357. QVERIFY(!actions.empty());
  358. // The first action alone should determine the job's error and result.
  359. const auto firstAction = actions.front();
  360. const int errorCode = firstAction == Action::Start ? KJob::NoError : KJob::KilledJobError;
  361. QCOMPARE(m_lastError, errorCode);
  362. QCOMPARE(m_lastErrorText, QString{});
  363. if (!autoDelete) {
  364. QCOMPARE(job->error(), m_lastError);
  365. QCOMPARE(job->errorText(), m_lastErrorText);
  366. }
  367. QCOMPARE(m_resultCount, firstAction == Action::KillQuietly ? 0 : 1);
  368. QCOMPARE(m_finishedCount, 1);
  369. if (!autoDelete) {
  370. delete job;
  371. }
  372. }
  373. void KJobTest::testDelegateUsage()
  374. {
  375. TestJob *job1 = new TestJob;
  376. TestJob *job2 = new TestJob;
  377. TestJobUiDelegate *delegate = new TestJobUiDelegate;
  378. QPointer<TestJobUiDelegate> guard(delegate);
  379. QVERIFY(job1->uiDelegate() == nullptr);
  380. job1->setUiDelegate(delegate);
  381. QVERIFY(job1->uiDelegate() == delegate);
  382. QVERIFY(job2->uiDelegate() == nullptr);
  383. job2->setUiDelegate(delegate);
  384. QVERIFY(job2->uiDelegate() == nullptr);
  385. delete job1;
  386. delete job2;
  387. QVERIFY(guard.isNull()); // deleted by job1
  388. }
  389. void KJobTest::testNestedExec()
  390. {
  391. m_innerJob = nullptr;
  392. QTimer::singleShot(100, this, &KJobTest::slotStartInnerJob);
  393. m_outerJob = new WaitJob();
  394. m_outerJob->exec();
  395. }
  396. void KJobTest::slotStartInnerJob()
  397. {
  398. QTimer::singleShot(100, this, &KJobTest::slotFinishOuterJob);
  399. m_innerJob = new WaitJob();
  400. m_innerJob->exec();
  401. }
  402. void KJobTest::slotFinishOuterJob()
  403. {
  404. QTimer::singleShot(100, this, &KJobTest::slotFinishInnerJob);
  405. m_outerJob->makeItFinish();
  406. }
  407. void KJobTest::slotFinishInnerJob()
  408. {
  409. m_innerJob->makeItFinish();
  410. }
  411. void KJobTest::slotResult(KJob *job)
  412. {
  413. const auto testJob = qobject_cast<const TestJob *>(job);
  414. QVERIFY(testJob);
  415. QVERIFY(testJob->isFinished());
  416. // Ensure the job has already emitted finished() if we are tracking from
  417. // setupErrorResultFinished
  418. if (m_jobFinishCount.contains(job)) {
  419. QVERIFY(m_jobFinishCount.value(job) == 1);
  420. QVERIFY(m_jobFinishCount.remove(job) == 1 /* num items removed */);
  421. }
  422. if (job->error()) {
  423. m_lastError = job->error();
  424. m_lastErrorText = job->errorText();
  425. } else {
  426. m_lastError = KJob::NoError;
  427. m_lastErrorText.clear();
  428. }
  429. m_resultCount++;
  430. }
  431. void KJobTest::slotFinished(KJob *job)
  432. {
  433. QVERIFY2(m_jobFinishCount.value(job) == 0, "Ensure we have not double-emitted KJob::finished()");
  434. m_jobFinishCount[job]++;
  435. if (job->error()) {
  436. m_lastError = job->error();
  437. m_lastErrorText = job->errorText();
  438. } else {
  439. m_lastError = KJob::NoError;
  440. m_lastErrorText.clear();
  441. }
  442. m_finishedCount++;
  443. }
  444. TestJob *KJobTest::setupErrorResultFinished()
  445. {
  446. m_lastError = KJob::UserDefinedError;
  447. m_lastErrorText.clear();
  448. m_resultCount = 0;
  449. m_finishedCount = 0;
  450. auto *job = new TestJob;
  451. m_jobFinishCount[job] = 0;
  452. connect(job, &KJob::result, this, &KJobTest::slotResult);
  453. connect(job, &KJob::finished, this, &KJobTest::slotFinished);
  454. return job;
  455. }
  456. TestJob::TestJob()
  457. : KJob()
  458. {
  459. }
  460. TestJob::~TestJob()
  461. {
  462. }
  463. void TestJob::start()
  464. {
  465. QTimer::singleShot(0, this, [this] {
  466. emitResult();
  467. });
  468. }
  469. bool TestJob::doKill()
  470. {
  471. return true;
  472. }
  473. void TestJob::setError(int errorCode)
  474. {
  475. KJob::setError(errorCode);
  476. }
  477. void TestJob::setErrorText(const QString &errorText)
  478. {
  479. KJob::setErrorText(errorText);
  480. }
  481. void TestJob::setProcessedSize(qulonglong size)
  482. {
  483. KJob::setProcessedAmount(KJob::Bytes, size);
  484. }
  485. void TestJob::setTotalSize(qulonglong size)
  486. {
  487. KJob::setTotalAmount(KJob::Bytes, size);
  488. }
  489. void TestJob::setProcessedFiles(qulonglong files)
  490. {
  491. KJob::setProcessedAmount(KJob::Files, files);
  492. }
  493. void TestJob::setTotalFiles(qulonglong files)
  494. {
  495. KJob::setTotalAmount(KJob::Files, files);
  496. }
  497. void TestJob::setPercent(unsigned long percentage)
  498. {
  499. KJob::setPercent(percentage);
  500. }
  501. void WaitJob::start()
  502. {
  503. }
  504. void WaitJob::makeItFinish()
  505. {
  506. emitResult();
  507. }
  508. void TestJobUiDelegate::connectJob(KJob *job)
  509. {
  510. QVERIFY(job->uiDelegate() != nullptr);
  511. }
  512. #include "moc_kjobtest.cpp"