MailJDTourDownloadDocsQualityTestsCoverage

Which source lines and branches the tests execute. Lines 91.5 %, branches 75.0 % (minimum 85 % and 72 %). main @ 399ffe3d · 21 October 2026 · pipeline 7238.

GCC Code Coverage Report


Directory: src/
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 94.3% 150 / 0 / 159
Functions: 96.6% 85 / 0 / 88
Branches: 83.1% 54 / 0 / 65

service/ImapServiceContract.cpp
Line Branch Exec Source
1 // Test/diagnostic state contract of ImapService (Sprint 92 S92.0.2): the
2 // accessors and protocol steps whose state is owned by an internal unit
3 // since the Sprint 92 extraction. They forward to the owning unit so the
4 // tests keep one stable surface; no product code calls them.
5
6 #include "ImapService.h"
7 #include "ImapCommandTable.h"
8 #include "ImapConnectionSetup.h"
9 #include "ImapLineReader.h"
10 #include "ImapPushSession.h"
11 #include "ImapBodyFetch.h"
12 #include "ImapMutationCommands.h"
13 #include "ImapAppendStream.h"
14
15 344 QMap<QString, QString> ImapService::pendingCommands() const {
16 344 QMap<QString, QString> types;
17
4/4
✓ Branch 4 → 5 taken 344 times.
✓ Branch 12 → 13 taken 619 times.
✓ Branch 14 → 6 taken 275 times.
✓ Branch 14 → 15 taken 344 times.
619 for (auto it = m_commands->records().cbegin(); it != m_commands->records().cend(); ++it)
18
1/1
✓ Branch 8 → 9 taken 275 times.
275 types.insert(it.key(), it->type);
19 344 return types;
20 ✗ }
21 135 ImapPendingCommand &ImapService::injectPendingCommand(const QString &tag, const QString &type) {
22 135 ImapPendingCommand record;
23 135 record.type = type;
24
1/1
✓ Branch 6 → 7 taken 135 times.
135 m_commands->records().insert(tag, std::move(record));
25
1/1
✓ Branch 9 → 10 taken 135 times.
270 return m_commands->records()[tag];
26 135 }
27 ✗ ImapPendingCommand *ImapService::pendingRecord(const QString &tag) {
28 ✗ auto it = m_commands->records().find(tag);
29 ✗ return it == m_commands->records().end() ? nullptr : &*it;
30 }
31 2 void ImapService::sendRecordedCommand(const QString &type, const QString &command,
32 const ImapPendingCommand &record) {
33
2/2
✓ Branch 3 → 4 taken 2 times.
✓ Branch 4 → 5 taken 2 times.
2 m_commands->sendCommand(type, command, record);
34 2 }
35 4 void ImapService::removePendingCommand(const QString &tag) { m_commands->records().remove(tag); }
36 66 void ImapService::clearPendingCommands() { m_commands->records().clear(); }
37 5 QMap<QString, QElapsedTimer> ImapService::commandTimers() const {
38 5 QMap<QString, QElapsedTimer> timers;
39
4/4
✓ Branch 4 → 5 taken 5 times.
✓ Branch 16 → 17 taken 7 times.
✓ Branch 18 → 6 taken 2 times.
✓ Branch 18 → 19 taken 5 times.
7 for (auto it = m_commands->records().cbegin(); it != m_commands->records().cend(); ++it) {
40
1/2
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 13 not taken.
2 if (it->timer)
41
1/1
✓ Branch 12 → 13 taken 2 times.
2 timers.insert(it.key(), *it->timer);
42 }
43 5 return timers;
44 ✗ }
45 3 void ImapService::injectCommandTimer(const QString &tag, const QElapsedTimer &timer) {
46
1/1
✓ Branch 4 → 5 taken 3 times.
3 auto it = m_commands->records().find(tag);
47
2/3
✓ Branch 7 → 8 taken 3 times.
✓ Branch 9 → 10 taken 3 times.
✗ Branch 9 → 12 not taken.
3 if (it != m_commands->records().end())
48 3 it->timer = timer;
49 3 }
50 2 QString ImapService::pendingSelectFolder() const {
51
1/1
✓ Branch 6 → 7 taken 2 times.
4 const auto *select = m_commands->recordOfType(QStringLiteral("SELECT"));
52
1/2
✓ Branch 9 → 10 taken 2 times.
✗ Branch 9 → 11 not taken.
2 return select ? select->selectFolder : QString();
53 }
54 7 QString ImapService::pendingStatusFolder() const {
55
1/1
✓ Branch 6 → 7 taken 7 times.
14 const auto *status = m_commands->recordOfType(QStringLiteral("STATUS"));
56
2/2
✓ Branch 9 → 10 taken 4 times.
✓ Branch 9 → 11 taken 3 times.
7 return status ? status->statusFolder : QString();
57 }
58 6 std::optional<StatusResult> ImapService::pendingStatusResult() const {
59
1/1
✓ Branch 6 → 7 taken 6 times.
12 const auto *status = m_commands->recordOfType(QStringLiteral("STATUS"));
60
2/2
✓ Branch 9 → 10 taken 3 times.
✓ Branch 9 → 11 taken 3 times.
6 return status ? status->status : std::nullopt;
61 }
62 3 qint64 ImapService::statusRequestStartedNs() const {
63
1/1
✓ Branch 6 → 7 taken 3 times.
6 const auto *status = m_commands->recordOfType(QStringLiteral("STATUS"));
64
2/2
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 11 taken 2 times.
3 return status ? status->statusStartedNs : 0;
65 }
66 102 QQueue<std::function<void()>> &ImapService::deferredCommands() {
67 102 return m_commands->deferredCommands();
68 }
69 52 QQueue<std::function<void()>> &ImapService::serializedCommands() {
70 52 return m_commands->serializedCommands();
71 }
72 7 QTimer *ImapService::commandTimeoutTimer() const { return m_commands->commandTimeoutTimer(); }
73 5 QTimer *ImapService::commandDeadlineTimer() const { return m_commands->commandDeadlineTimer(); }
74 2 qint64 &ImapService::commandResponseBytes() { return m_commands->commandResponseBytes(); }
75 1 qint64 &ImapService::commandLiteralCount() { return m_commands->commandLiteralCount(); }
76 1 qint64 &ImapService::commandResultItems() { return m_commands->commandResultItems(); }
77
78 3 void ImapService::sendCommand(const QString &type, const QString &command) {
79
1/1
✓ Branch 3 → 4 taken 3 times.
3 m_commands->sendCommand(type, command);
80 3 }
81 6 bool ImapService::hasStatefulCommandInFlight() const {
82 6 return m_commands->hasStatefulCommandInFlight();
83 }
84 4 bool ImapService::hasTimeoutTrackedCommandInFlight() const {
85 4 return m_commands->hasTimeoutTrackedCommandInFlight();
86 }
87 1 void ImapService::enqueueSerializedCommand(std::function<void()> command) {
88
1/1
✓ Branch 5 → 6 taken 1 time.
1 m_commands->enqueueSerializedCommand(std::move(command));
89 1 }
90 7 void ImapService::runNextSerializedCommand() { m_commands->runNextSerializedCommand(); }
91 2 void ImapService::refreshCommandTimeout() { m_commands->refreshCommandTimeout(); }
92 2 void ImapService::refreshCommandDeadline() { m_commands->refreshCommandDeadline(); }
93 1 bool ImapService::accountCommandResponseBytes(qint64 bytes) {
94 1 return m_commands->accountCommandResponseBytes(bytes);
95 }
96 1 bool ImapService::accountCommandLiteral() { return m_commands->accountCommandLiteral(); }
97 1 bool ImapService::accountCommandResultItems(qint64 items) {
98 1 return m_commands->accountCommandResultItems(items);
99 }
100 2 void ImapService::onCommandTimeout() { m_commands->onCommandTimeout(); }
101 2 void ImapService::onCommandDeadline() { m_commands->onCommandDeadline(); }
102
103 36 QByteArray &ImapService::readBuffer() { return m_reader->readBuffer(); }
104 4 qint64 &ImapService::literalBytesRemaining() { return m_reader->literalBytesRemaining(); }
105 2 QString &ImapService::literalLine() { return m_reader->literalLine(); }
106 15 QByteArray &ImapService::literalData() { return m_reader->literalData(); }
107 7 std::unique_ptr<QTemporaryFile> &ImapService::bodySpool() { return m_reader->bodySpool(); }
108 4 qint64 &ImapService::bodySpoolThreshold() { return m_reader->bodySpoolThreshold(); }
109 30 void ImapService::onReadyRead() { m_reader->onReadyRead(); }
110 15 void ImapService::processLine(const QString &line) { m_reader->processLine(line); }
111 8 void ImapService::completeLiteral() { m_reader->completeLiteral(); }
112
113 28 ImapConfig &ImapService::config() { return m_setup->config(); }
114 14 ImapService::SetupPhase &ImapService::setupPhase() { return m_setup->setupPhase(); }
115 13 QStringList &ImapService::pendingCapabilities() { return m_setup->pendingCapabilities(); }
116 1 bool &ImapService::mutableKeepAliveTuned() { return m_setup->keepAliveTuned(); }
117 3 QTimer *ImapService::setupTimeoutTimer() const { return m_setup->setupTimer(); }
118 ✗ void ImapService::onConnected() { m_setup->onConnected(); }
119 1 void ImapService::onEncrypted() { m_setup->onEncrypted(); }
120 1 void ImapService::tuneKeepAlive() { m_setup->tuneKeepAlive(); }
121 1 bool ImapService::beginLogin() { return m_setup->beginLogin(); }
122
123 13 bool &ImapService::autoIdle() { return m_push->autoIdle(); }
124 54 bool &ImapService::mutableIdling() { return m_push->isIdling(); }
125 4 bool &ImapService::idleStartPending() { return m_push->idleStartPending(); }
126 17 QString &ImapService::idleTag() { return m_push->idleTag(); }
127 18 bool &ImapService::mutableNotifying() { return m_push->isNotifying(); }
128 2 QString &ImapService::notifyTag() { return m_push->notifyTag(); }
129 2 QStringList &ImapService::notifyFolders() { return m_push->notifyFolders(); }
130 19 QTimer *ImapService::idleRenewWatchdog() const { return m_push->idleRenewWatchdog(); }
131 14 QTimer *ImapService::livenessProbeWatchdog() const { return m_push->livenessProbeWatchdog(); }
132 23 QString &ImapService::probeTag() { return m_push->probeTag(); }
133 12 QString &ImapService::lastProbeReason() { return m_push->lastProbeReason(); }
134 9 void ImapService::restartPush() { m_push->restartPush(); }
135 1 void ImapService::onIdleRenew() { m_push->onIdleRenew(); }
136 3 void ImapService::onLivenessProbeTimeout() { m_push->onLivenessProbeTimeout(); }
137 1 void ImapService::onIdleRenewWatchdogTimeout() { m_push->onIdleRenewWatchdogTimeout(); }
138
139 16 qint64 &ImapService::activeBodyFetchUid() { return m_body->activeBodyFetchUid(); }
140 7 quint64 &ImapService::activeBodyRequestId() { return m_body->activeBodyRequestId(); }
141 5 QString &ImapService::activeBodyRequestFolder() { return m_body->activeBodyRequestFolder(); }
142 8 qint64 &ImapService::activeBodyFetchLimit() { return m_body->activeBodyFetchLimit(); }
143 8 qint64 &ImapService::activeBodyFetchRequestBytes() {
144 8 return m_body->activeBodyFetchRequestBytes();
145 }
146 2 bool &ImapService::bodyFetchRequiresSelect() { return m_body->bodyFetchRequiresSelect(); }
147 1 void ImapService::fetchBodyWithLimits(quint64 requestId, qint64 uid, qint64 acceptedBytes,
148 qint64 requestedBytes) {
149 1 m_body->fetchBodyWithLimits(requestId, uid, acceptedBytes, requestedBytes);
150 1 }
151 3 void ImapService::completeBodyRequest(BodyOutcome outcome, QByteArray bytes,
152 const QString &error, qint64 maxBytes) {
153
1/1
✓ Branch 5 → 6 taken 3 times.
3 m_body->completeBodyRequest(outcome, std::move(bytes), error, maxBytes);
154 3 }
155 4 QString ImapService::buildFetchBodyCommand(qint64 uid, qint64 maxBytes) {
156 4 return ImapBodyFetch::buildFetchBodyCommand(uid, maxBytes);
157 }
158
159 namespace {
160 // The in-flight record of the MOVE/COPY family (at most one: serialized).
161 12 const ImapPendingCommand *moveRecord(ImapCommandTable &commands) {
162 49 for (const QString &type : {QStringLiteral("MOVE"), QStringLiteral("COPY"),
163 12 QStringLiteral("STORE_DELETE"), QStringLiteral("EXPUNGE_MOVE"),
164
2/2
✓ Branch 29 → 25 taken 32 times.
✓ Branch 29 → 30 taken 5 times.
193 QStringLiteral("COPY_ONLY")}) {
165
3/3
✓ Branch 25 → 26 taken 32 times.
✓ Branch 26 → 27 taken 7 times.
✓ Branch 26 → 28 taken 25 times.
32 if (const auto *record = commands.recordOfType(type))
166 7 return record;
167 72 }
168 5 return nullptr;
169 }
170 } // namespace
171
172 2 QString ImapService::pendingMoveTarget() const {
173 2 const auto *move = moveRecord(*m_commands);
174
2/2
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 1 time.
2 return move ? move->moveTarget : QString();
175 }
176 8 QList<qint64> ImapService::pendingMoveUids() const {
177 8 const auto *move = moveRecord(*m_commands);
178
2/2
✓ Branch 4 → 5 taken 5 times.
✓ Branch 4 → 6 taken 3 times.
8 return move ? move->moveUids : QList<qint64>();
179 }
180 2 QList<qint64> ImapService::pendingMoveMutationTokens() const {
181 2 const auto *move = moveRecord(*m_commands);
182
2/2
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 1 time.
2 return move ? move->mutationTokens : QList<qint64>();
183 }
184 ✗ qint64 ImapService::pendingStoreMutationToken() const {
185 ✗ const auto *store = m_commands->recordOfType(QStringLiteral("STORE"));
186 ✗ return store ? store->storeToken : 0;
187 }
188 1 QSet<qint64> &ImapService::knownMutationTokens() { return m_mutations->knownMutationTokens(); }
189
190 11 QByteArray ImapService::pendingAppendData() const {
191
1/1
✓ Branch 6 → 7 taken 11 times.
22 const auto *append = m_commands->recordOfType(QStringLiteral("APPEND"));
192
2/2
✓ Branch 9 → 10 taken 4 times.
✓ Branch 9 → 11 taken 7 times.
11 return append ? append->appendData : QByteArray();
193 }
194 7 QString ImapService::pendingAppendFolder() const {
195
1/1
✓ Branch 6 → 7 taken 7 times.
14 const auto *append = m_commands->recordOfType(QStringLiteral("APPEND"));
196
2/2
✓ Branch 9 → 10 taken 2 times.
✓ Branch 9 → 11 taken 5 times.
7 return append ? append->appendFolder : QString();
197 }
198 3 quint64 ImapService::pendingAppendRequestId() const {
199
1/1
✓ Branch 6 → 7 taken 3 times.
6 const auto *append = m_commands->recordOfType(QStringLiteral("APPEND"));
200
2/2
✓ Branch 9 → 10 taken 2 times.
✓ Branch 9 → 11 taken 1 time.
3 return append ? append->appendRequestId : 0;
201 }
202 1 qint64 ImapService::pendingAppendMutationToken() const {
203
1/1
✓ Branch 6 → 7 taken 1 time.
2 const auto *append = m_commands->recordOfType(QStringLiteral("APPEND"));
204
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 1 time.
1 return append ? append->appendToken : 0;
205 }
206 1 quint64 &ImapService::nextAppendRequestId() { return m_append->nextAppendRequestId(); }
207 125 void ImapService::noteRoundTrip(qint64 elapsedMs) { m_push->noteRoundTrip(elapsedMs); }
208 11 int ImapService::probeWatchdogMs() const { return m_push->probeWatchdogMs(); }
209 2 qint64 ImapService::quietMs() const { return m_reader->quietMs(); }
210 13 qint64 &ImapService::lastReceiveMs() { return m_reader->lastReceiveMs(); }
211