File indexing completed on 2024-04-28 15:20:09
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2006 Kevin Ottens <ervin@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-only 0006 */ 0007 0008 #include "kjobtest.h" 0009 0010 #include <QMetaEnum> 0011 #include <QSignalSpy> 0012 #include <QTest> 0013 #include <QTimer> 0014 #include <QVector> 0015 0016 #include <string> 0017 0018 QTEST_MAIN(KJobTest) 0019 0020 KJobTest::KJobTest() 0021 : loop(this) 0022 { 0023 } 0024 0025 void KJobTest::testEmitResult_data() 0026 { 0027 QTest::addColumn<int>("errorCode"); 0028 QTest::addColumn<QString>("errorText"); 0029 0030 QTest::newRow("no error") << int(KJob::NoError) << QString(); 0031 QTest::newRow("error no text") << 2 << QString(); 0032 QTest::newRow("error with text") << 6 << "oops! an error? naaah, really?"; 0033 } 0034 0035 void KJobTest::testEmitResult() 0036 { 0037 TestJob *job = new TestJob; 0038 0039 connect(job, &KJob::result, this, [this](KJob *job) { 0040 slotResult(job); 0041 loop.quit(); 0042 }); 0043 0044 QFETCH(int, errorCode); 0045 QFETCH(QString, errorText); 0046 0047 job->setError(errorCode); 0048 job->setErrorText(errorText); 0049 0050 QSignalSpy destroyed_spy(job, &QObject::destroyed); 0051 job->start(); 0052 QVERIFY(!job->isFinished()); 0053 loop.exec(); 0054 QVERIFY(job->isFinished()); 0055 0056 QCOMPARE(m_lastError, errorCode); 0057 QCOMPARE(m_lastErrorText, errorText); 0058 0059 // Verify that the job is not deleted immediately... 0060 QCOMPARE(destroyed_spy.size(), 0); 0061 QTimer::singleShot(0, &loop, &QEventLoop::quit); 0062 // ... but when we enter the event loop again. 0063 loop.exec(); 0064 QCOMPARE(destroyed_spy.size(), 1); 0065 } 0066 0067 void KJobTest::testProgressTracking() 0068 { 0069 TestJob *testJob = new TestJob; 0070 KJob *job = testJob; 0071 0072 qRegisterMetaType<KJob *>("KJob*"); 0073 qRegisterMetaType<qulonglong>("qulonglong"); 0074 0075 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0076 QSignalSpy processed_spy(job, qOverload<KJob *, KJob::Unit, qulonglong>(&KJob::processedAmount)); 0077 QSignalSpy total_spy(job, qOverload<KJob *, KJob::Unit, qulonglong>(&KJob::totalAmount)); 0078 QSignalSpy percent_spy(job, qOverload<KJob *, ulong>(&KJob::percent)); 0079 #endif 0080 QSignalSpy processedChanged_spy(job, &KJob::processedAmountChanged); 0081 QSignalSpy totalChanged_spy(job, &KJob::totalAmountChanged); 0082 QSignalSpy percentChanged_spy(job, &KJob::percentChanged); 0083 0084 /* Process a first item. Corresponding signal should be emitted. 0085 * Total size didn't change. 0086 * Since the total size is unknown, no percent signal is emitted. 0087 */ 0088 testJob->setProcessedSize(1); 0089 0090 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0091 QCOMPARE(processed_spy.size(), 1); 0092 QCOMPARE(processed_spy.at(0).at(0).value<KJob *>(), static_cast<KJob *>(job)); 0093 QCOMPARE(processed_spy.at(0).at(2).value<qulonglong>(), qulonglong(1)); 0094 QCOMPARE(total_spy.size(), 0); 0095 QCOMPARE(percent_spy.size(), 0); 0096 #endif 0097 QCOMPARE(processedChanged_spy.size(), 1); 0098 QCOMPARE(processedChanged_spy.at(0).at(0).value<KJob *>(), static_cast<KJob *>(job)); 0099 QCOMPARE(processedChanged_spy.at(0).at(2).value<qulonglong>(), qulonglong(1)); 0100 QCOMPARE(totalChanged_spy.size(), 0); 0101 QCOMPARE(percentChanged_spy.size(), 0); 0102 0103 /* Now, we know the total size. It's signaled. 0104 * The new percentage is signaled too. 0105 */ 0106 testJob->setTotalSize(10); 0107 0108 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0109 QCOMPARE(processed_spy.size(), 1); 0110 QCOMPARE(total_spy.size(), 1); 0111 QCOMPARE(total_spy.at(0).at(0).value<KJob *>(), job); 0112 QCOMPARE(total_spy.at(0).at(2).value<qulonglong>(), qulonglong(10)); 0113 QCOMPARE(percent_spy.size(), 1); 0114 QCOMPARE(percent_spy.at(0).at(0).value<KJob *>(), job); 0115 QCOMPARE(percent_spy.at(0).at(1).value<unsigned long>(), static_cast<unsigned long>(10)); 0116 #endif 0117 QCOMPARE(processedChanged_spy.size(), 1); 0118 QCOMPARE(totalChanged_spy.size(), 1); 0119 QCOMPARE(totalChanged_spy.at(0).at(0).value<KJob *>(), job); 0120 QCOMPARE(totalChanged_spy.at(0).at(2).value<qulonglong>(), qulonglong(10)); 0121 QCOMPARE(percentChanged_spy.size(), 1); 0122 QCOMPARE(percentChanged_spy.at(0).at(0).value<KJob *>(), job); 0123 QCOMPARE(percentChanged_spy.at(0).at(1).value<unsigned long>(), static_cast<unsigned long>(10)); 0124 0125 /* We announce a new percentage by hand. 0126 * Total, and processed didn't change, so no signal is emitted for them. 0127 */ 0128 testJob->setPercent(15); 0129 0130 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0131 QCOMPARE(processed_spy.size(), 1); 0132 QCOMPARE(total_spy.size(), 1); 0133 QCOMPARE(percent_spy.size(), 2); 0134 QCOMPARE(percent_spy.at(1).at(0).value<KJob *>(), job); 0135 QCOMPARE(percent_spy.at(1).at(1).value<unsigned long>(), static_cast<unsigned long>(15)); 0136 #endif 0137 QCOMPARE(processedChanged_spy.size(), 1); 0138 QCOMPARE(totalChanged_spy.size(), 1); 0139 QCOMPARE(percentChanged_spy.size(), 2); 0140 QCOMPARE(percentChanged_spy.at(1).at(0).value<KJob *>(), job); 0141 QCOMPARE(percentChanged_spy.at(1).at(1).value<unsigned long>(), static_cast<unsigned long>(15)); 0142 0143 /* We make some progress. 0144 * Processed size and percent are signaled. 0145 */ 0146 testJob->setProcessedSize(3); 0147 0148 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0149 QCOMPARE(processed_spy.size(), 2); 0150 QCOMPARE(processed_spy.at(1).at(0).value<KJob *>(), job); 0151 QCOMPARE(processed_spy.at(1).at(2).value<qulonglong>(), qulonglong(3)); 0152 QCOMPARE(total_spy.size(), 1); 0153 QCOMPARE(percent_spy.size(), 3); 0154 QCOMPARE(percent_spy.at(2).at(0).value<KJob *>(), job); 0155 QCOMPARE(percent_spy.at(2).at(1).value<unsigned long>(), static_cast<unsigned long>(30)); 0156 #endif 0157 QCOMPARE(processedChanged_spy.size(), 2); 0158 QCOMPARE(processedChanged_spy.at(1).at(0).value<KJob *>(), job); 0159 QCOMPARE(processedChanged_spy.at(1).at(2).value<qulonglong>(), qulonglong(3)); 0160 QCOMPARE(totalChanged_spy.size(), 1); 0161 QCOMPARE(percentChanged_spy.size(), 3); 0162 QCOMPARE(percentChanged_spy.at(2).at(0).value<KJob *>(), job); 0163 QCOMPARE(percentChanged_spy.at(2).at(1).value<unsigned long>(), static_cast<unsigned long>(30)); 0164 0165 /* We set a new total size, but equals to the previous one. 0166 * No signal is emitted. 0167 */ 0168 testJob->setTotalSize(10); 0169 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0170 QCOMPARE(processed_spy.size(), 2); 0171 QCOMPARE(total_spy.size(), 1); 0172 QCOMPARE(percent_spy.size(), 3); 0173 #endif 0174 QCOMPARE(processedChanged_spy.size(), 2); 0175 QCOMPARE(totalChanged_spy.size(), 1); 0176 QCOMPARE(percentChanged_spy.size(), 3); 0177 0178 /* We 'lost' the previous work done. 0179 * Signals both percentage and new processed size. 0180 */ 0181 testJob->setProcessedSize(0); 0182 0183 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0184 QCOMPARE(processed_spy.size(), 3); 0185 QCOMPARE(processed_spy.at(2).at(0).value<KJob *>(), job); 0186 QCOMPARE(processed_spy.at(2).at(2).value<qulonglong>(), qulonglong(0)); 0187 QCOMPARE(total_spy.size(), 1); 0188 QCOMPARE(percent_spy.size(), 4); 0189 QCOMPARE(percent_spy.at(3).at(0).value<KJob *>(), job); 0190 QCOMPARE(percent_spy.at(3).at(1).value<unsigned long>(), static_cast<unsigned long>(0)); 0191 #endif 0192 QCOMPARE(processedChanged_spy.size(), 3); 0193 QCOMPARE(processedChanged_spy.at(2).at(0).value<KJob *>(), job); 0194 QCOMPARE(processedChanged_spy.at(2).at(2).value<qulonglong>(), qulonglong(0)); 0195 QCOMPARE(totalChanged_spy.size(), 1); 0196 QCOMPARE(percentChanged_spy.size(), 4); 0197 QCOMPARE(percentChanged_spy.at(3).at(0).value<KJob *>(), job); 0198 QCOMPARE(percentChanged_spy.at(3).at(1).value<unsigned long>(), static_cast<unsigned long>(0)); 0199 0200 /* We process more than the total size!? 0201 * Signals both percentage and new processed size. 0202 * Percentage is 150% 0203 * 0204 * Might sounds weird, but verify that this case is handled gracefully. 0205 */ 0206 testJob->setProcessedSize(15); 0207 0208 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0209 QCOMPARE(processed_spy.size(), 4); 0210 QCOMPARE(processed_spy.at(3).at(0).value<KJob *>(), job); 0211 QCOMPARE(processed_spy.at(3).at(2).value<qulonglong>(), qulonglong(15)); 0212 QCOMPARE(total_spy.size(), 1); 0213 QCOMPARE(percent_spy.size(), 5); 0214 QCOMPARE(percent_spy.at(4).at(0).value<KJob *>(), job); 0215 QCOMPARE(percent_spy.at(4).at(1).value<unsigned long>(), static_cast<unsigned long>(150)); 0216 #endif 0217 QCOMPARE(processedChanged_spy.size(), 4); 0218 QCOMPARE(processedChanged_spy.at(3).at(0).value<KJob *>(), job); 0219 QCOMPARE(processedChanged_spy.at(3).at(2).value<qulonglong>(), qulonglong(15)); 0220 QCOMPARE(totalChanged_spy.size(), 1); 0221 QCOMPARE(percentChanged_spy.size(), 5); 0222 QCOMPARE(percentChanged_spy.at(4).at(0).value<KJob *>(), job); 0223 QCOMPARE(percentChanged_spy.at(4).at(1).value<unsigned long>(), static_cast<unsigned long>(150)); 0224 0225 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0226 processed_spy.clear(); 0227 total_spy.clear(); 0228 percent_spy.clear(); 0229 #endif 0230 processedChanged_spy.clear(); 0231 totalChanged_spy.clear(); 0232 percentChanged_spy.clear(); 0233 0234 /** 0235 * Try again with Files as the progress unit 0236 */ 0237 testJob->setProgressUnit(KJob::Files); 0238 testJob->setProcessedSize(16); 0239 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0240 QCOMPARE(percent_spy.size(), 0); // no impact on percent 0241 #endif 0242 QCOMPARE(percentChanged_spy.size(), 0); 0243 0244 testJob->setTotalFiles(5); 0245 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0246 QCOMPARE(percent_spy.size(), 1); 0247 QCOMPARE(percent_spy.at(0).at(1).value<unsigned long>(), static_cast<unsigned long>(0)); 0248 #endif 0249 QCOMPARE(percentChanged_spy.size(), 1); 0250 QCOMPARE(percentChanged_spy.at(0).at(1).value<unsigned long>(), static_cast<unsigned long>(0)); 0251 0252 testJob->setProcessedFiles(2); 0253 #if KCOREADDONS_ENABLE_DEPRECATED_SINCE(5, 80) 0254 QCOMPARE(percent_spy.size(), 2); 0255 QCOMPARE(percent_spy.at(1).at(1).value<unsigned long>(), static_cast<unsigned long>(40)); 0256 #endif 0257 QCOMPARE(percentChanged_spy.size(), 2); 0258 QCOMPARE(percentChanged_spy.at(1).at(1).value<unsigned long>(), static_cast<unsigned long>(40)); 0259 0260 delete job; 0261 } 0262 0263 void KJobTest::testExec_data() 0264 { 0265 QTest::addColumn<int>("errorCode"); 0266 QTest::addColumn<QString>("errorText"); 0267 0268 QTest::newRow("no error") << int(KJob::NoError) << QString(); 0269 QTest::newRow("error no text") << 2 << QString(); 0270 QTest::newRow("error with text") << 6 << "oops! an error? naaah, really?"; 0271 } 0272 0273 void KJobTest::testExec() 0274 { 0275 TestJob *job = new TestJob; 0276 0277 QFETCH(int, errorCode); 0278 QFETCH(QString, errorText); 0279 0280 job->setError(errorCode); 0281 job->setErrorText(errorText); 0282 0283 int resultEmitted = 0; 0284 // Prove to Kai Uwe that one can connect a job to a lambdas, despite the "private" signal 0285 connect(job, &KJob::result, this, [&resultEmitted](KJob *) { 0286 ++resultEmitted; 0287 }); 0288 0289 QSignalSpy destroyed_spy(job, &QObject::destroyed); 0290 0291 QVERIFY(!job->isFinished()); 0292 bool status = job->exec(); 0293 QVERIFY(job->isFinished()); 0294 0295 QCOMPARE(resultEmitted, 1); 0296 QCOMPARE(status, (errorCode == KJob::NoError)); 0297 QCOMPARE(job->error(), errorCode); 0298 QCOMPARE(job->errorText(), errorText); 0299 0300 // Verify that the job is not deleted immediately... 0301 QCOMPARE(destroyed_spy.size(), 0); 0302 QTimer::singleShot(0, &loop, &QEventLoop::quit); 0303 // ... but when we enter the event loop again. 0304 loop.exec(); 0305 QCOMPARE(destroyed_spy.size(), 1); 0306 } 0307 0308 void KJobTest::testKill_data() 0309 { 0310 QTest::addColumn<int>("killVerbosity"); 0311 QTest::addColumn<int>("errorCode"); 0312 QTest::addColumn<QString>("errorText"); 0313 QTest::addColumn<int>("resultEmitCount"); 0314 QTest::addColumn<int>("finishedEmitCount"); 0315 0316 QTest::newRow("killed with result") << int(KJob::EmitResult) << int(KJob::KilledJobError) << QString() << 1 << 1; 0317 QTest::newRow("killed quietly") << int(KJob::Quietly) << int(KJob::KilledJobError) << QString() << 0 << 1; 0318 } 0319 0320 void KJobTest::testKill() 0321 { 0322 auto *const job = setupErrorResultFinished(); 0323 QSignalSpy destroyed_spy(job, &QObject::destroyed); 0324 0325 QFETCH(int, killVerbosity); 0326 QFETCH(int, errorCode); 0327 QFETCH(QString, errorText); 0328 QFETCH(int, resultEmitCount); 0329 QFETCH(int, finishedEmitCount); 0330 0331 QVERIFY(!job->isFinished()); 0332 job->kill(static_cast<KJob::KillVerbosity>(killVerbosity)); 0333 QVERIFY(job->isFinished()); 0334 loop.processEvents(QEventLoop::AllEvents, 2000); 0335 0336 QCOMPARE(m_lastError, errorCode); 0337 QCOMPARE(m_lastErrorText, errorText); 0338 0339 QCOMPARE(job->error(), errorCode); 0340 QCOMPARE(job->errorText(), errorText); 0341 0342 QCOMPARE(m_resultCount, resultEmitCount); 0343 QCOMPARE(m_finishedCount, finishedEmitCount); 0344 0345 // Verify that the job is not deleted immediately... 0346 QCOMPARE(destroyed_spy.size(), 0); 0347 QTimer::singleShot(0, &loop, &QEventLoop::quit); 0348 // ... but when we enter the event loop again. 0349 loop.exec(); 0350 QCOMPARE(destroyed_spy.size(), 1); 0351 0352 QVERIFY(m_jobFinishCount.size() == (finishedEmitCount - resultEmitCount)); 0353 m_jobFinishCount.clear(); 0354 } 0355 0356 void KJobTest::testDestroy() 0357 { 0358 auto *const job = setupErrorResultFinished(); 0359 QVERIFY(!job->isFinished()); 0360 delete job; 0361 QCOMPARE(m_lastError, static_cast<int>(KJob::NoError)); 0362 QCOMPARE(m_lastErrorText, QString{}); 0363 QCOMPARE(m_resultCount, 0); 0364 QCOMPARE(m_finishedCount, 1); 0365 0366 QVERIFY(m_jobFinishCount.size() == 1); 0367 m_jobFinishCount.clear(); 0368 } 0369 0370 void KJobTest::testEmitAtMostOnce_data() 0371 { 0372 QTest::addColumn<bool>("autoDelete"); 0373 QTest::addColumn<QVector<Action>>("actions"); 0374 0375 const auto actionName = [](Action action) { 0376 return QMetaEnum::fromType<Action>().valueToKey(static_cast<int>(action)); 0377 }; 0378 0379 for (bool autoDelete : {true, false}) { 0380 for (Action a : {Action::Start, Action::KillQuietly, Action::KillVerbosely}) { 0381 for (Action b : {Action::Start, Action::KillQuietly, Action::KillVerbosely}) { 0382 const auto dataTag = std::string{actionName(a)} + '-' + actionName(b) + (autoDelete ? "-autoDelete" : ""); 0383 QTest::newRow(dataTag.c_str()) << autoDelete << QVector<Action>{a, b}; 0384 } 0385 } 0386 } 0387 } 0388 0389 void KJobTest::testEmitAtMostOnce() 0390 { 0391 auto *const job = setupErrorResultFinished(); 0392 QSignalSpy destroyed_spy(job, &QObject::destroyed); 0393 0394 QFETCH(bool, autoDelete); 0395 job->setAutoDelete(autoDelete); 0396 0397 QFETCH(QVector<Action>, actions); 0398 for (auto action : actions) { 0399 switch (action) { 0400 case Action::Start: 0401 job->start(); // in effect calls QTimer::singleShot(0, ... emitResult) 0402 break; 0403 case Action::KillQuietly: 0404 QTimer::singleShot(0, job, [=] { 0405 job->kill(KJob::Quietly); 0406 }); 0407 break; 0408 case Action::KillVerbosely: 0409 QTimer::singleShot(0, job, [=] { 0410 job->kill(KJob::EmitResult); 0411 }); 0412 break; 0413 } 0414 } 0415 0416 QVERIFY(!job->isFinished()); 0417 loop.processEvents(QEventLoop::AllEvents, 2000); 0418 QCOMPARE(destroyed_spy.size(), autoDelete); 0419 if (!autoDelete) { 0420 QVERIFY(job->isFinished()); 0421 } 0422 0423 QVERIFY(!actions.empty()); 0424 // The first action alone should determine the job's error and result. 0425 const auto firstAction = actions.front(); 0426 0427 const int errorCode = firstAction == Action::Start ? KJob::NoError : KJob::KilledJobError; 0428 QCOMPARE(m_lastError, errorCode); 0429 QCOMPARE(m_lastErrorText, QString{}); 0430 if (!autoDelete) { 0431 QCOMPARE(job->error(), m_lastError); 0432 QCOMPARE(job->errorText(), m_lastErrorText); 0433 } 0434 0435 QCOMPARE(m_resultCount, firstAction == Action::KillQuietly ? 0 : 1); 0436 QCOMPARE(m_finishedCount, 1); 0437 0438 if (!autoDelete) { 0439 delete job; 0440 } 0441 } 0442 0443 void KJobTest::testDelegateUsage() 0444 { 0445 TestJob *job1 = new TestJob; 0446 TestJob *job2 = new TestJob; 0447 TestJobUiDelegate *delegate = new TestJobUiDelegate; 0448 QPointer<TestJobUiDelegate> guard(delegate); 0449 0450 QVERIFY(job1->uiDelegate() == nullptr); 0451 job1->setUiDelegate(delegate); 0452 QVERIFY(job1->uiDelegate() == delegate); 0453 0454 QVERIFY(job2->uiDelegate() == nullptr); 0455 job2->setUiDelegate(delegate); 0456 QVERIFY(job2->uiDelegate() == nullptr); 0457 0458 delete job1; 0459 delete job2; 0460 QVERIFY(guard.isNull()); // deleted by job1 0461 } 0462 0463 void KJobTest::testNestedExec() 0464 { 0465 m_innerJob = nullptr; 0466 QTimer::singleShot(100, this, &KJobTest::slotStartInnerJob); 0467 m_outerJob = new WaitJob(); 0468 m_outerJob->exec(); 0469 } 0470 0471 void KJobTest::slotStartInnerJob() 0472 { 0473 QTimer::singleShot(100, this, &KJobTest::slotFinishOuterJob); 0474 m_innerJob = new WaitJob(); 0475 m_innerJob->exec(); 0476 } 0477 0478 void KJobTest::slotFinishOuterJob() 0479 { 0480 QTimer::singleShot(100, this, &KJobTest::slotFinishInnerJob); 0481 m_outerJob->makeItFinish(); 0482 } 0483 0484 void KJobTest::slotFinishInnerJob() 0485 { 0486 m_innerJob->makeItFinish(); 0487 } 0488 0489 void KJobTest::slotResult(KJob *job) 0490 { 0491 const auto testJob = qobject_cast<const TestJob *>(job); 0492 QVERIFY(testJob); 0493 QVERIFY(testJob->isFinished()); 0494 0495 // Ensure the job has already emitted finished() if we are tracking from 0496 // setupErrorResultFinished 0497 if (m_jobFinishCount.contains(job)) { 0498 QVERIFY(m_jobFinishCount.value(job) == 1); 0499 QVERIFY(m_jobFinishCount.remove(job) == 1 /* num items removed */); 0500 } 0501 0502 if (job->error()) { 0503 m_lastError = job->error(); 0504 m_lastErrorText = job->errorText(); 0505 } else { 0506 m_lastError = KJob::NoError; 0507 m_lastErrorText.clear(); 0508 } 0509 0510 m_resultCount++; 0511 } 0512 0513 void KJobTest::slotFinished(KJob *job) 0514 { 0515 QVERIFY2(m_jobFinishCount.value(job) == 0, "Ensure we have not double-emitted KJob::finished()"); 0516 m_jobFinishCount[job]++; 0517 0518 if (job->error()) { 0519 m_lastError = job->error(); 0520 m_lastErrorText = job->errorText(); 0521 } else { 0522 m_lastError = KJob::NoError; 0523 m_lastErrorText.clear(); 0524 } 0525 0526 m_finishedCount++; 0527 } 0528 0529 TestJob *KJobTest::setupErrorResultFinished() 0530 { 0531 m_lastError = KJob::UserDefinedError; 0532 m_lastErrorText.clear(); 0533 m_resultCount = 0; 0534 m_finishedCount = 0; 0535 0536 auto *job = new TestJob; 0537 m_jobFinishCount[job] = 0; 0538 connect(job, &KJob::result, this, &KJobTest::slotResult); 0539 connect(job, &KJob::finished, this, &KJobTest::slotFinished); 0540 return job; 0541 } 0542 0543 TestJob::TestJob() 0544 : KJob() 0545 { 0546 } 0547 0548 TestJob::~TestJob() 0549 { 0550 } 0551 0552 void TestJob::start() 0553 { 0554 QTimer::singleShot(0, this, [this] { 0555 emitResult(); 0556 }); 0557 } 0558 0559 bool TestJob::doKill() 0560 { 0561 return true; 0562 } 0563 0564 void TestJob::setError(int errorCode) 0565 { 0566 KJob::setError(errorCode); 0567 } 0568 0569 void TestJob::setErrorText(const QString &errorText) 0570 { 0571 KJob::setErrorText(errorText); 0572 } 0573 0574 void TestJob::setProcessedSize(qulonglong size) 0575 { 0576 KJob::setProcessedAmount(KJob::Bytes, size); 0577 } 0578 0579 void TestJob::setTotalSize(qulonglong size) 0580 { 0581 KJob::setTotalAmount(KJob::Bytes, size); 0582 } 0583 0584 void TestJob::setProcessedFiles(qulonglong files) 0585 { 0586 KJob::setProcessedAmount(KJob::Files, files); 0587 } 0588 0589 void TestJob::setTotalFiles(qulonglong files) 0590 { 0591 KJob::setTotalAmount(KJob::Files, files); 0592 } 0593 0594 void TestJob::setPercent(unsigned long percentage) 0595 { 0596 KJob::setPercent(percentage); 0597 } 0598 0599 void WaitJob::start() 0600 { 0601 } 0602 0603 void WaitJob::makeItFinish() 0604 { 0605 emitResult(); 0606 } 0607 0608 void TestJobUiDelegate::connectJob(KJob *job) 0609 { 0610 QVERIFY(job->uiDelegate() != nullptr); 0611 } 0612 0613 #include "moc_kjobtest.cpp"