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: 88.9% 128 / 0 / 144
Functions: 91.7% 11 / 0 / 12
Branches: 71.2% 218 / 0 / 306

data/MailCacheHeaderRows.cpp
Line Branch Exec Source
1 // MailCache: the per-row steps of storeHeaderBatch (split out of
2 // MailCache.cpp, Sprint 105): write order, the unchanged-row check, the
3 // address index rows (S105.5.1) and the UPSERT binding; and the two fenced
4 // batch entry points (streaming and other-connection headers, Sprint 106).
5 #include "MailCache.h"
6
7 #include "MailAddressIndex.h"
8
9 #include <QLoggingCategory>
10 #include <QSet>
11 #include <QSqlError>
12 #include <utility>
13
14 Q_DECLARE_LOGGING_CATEGORY(lcCache)
15
16 // storeHeaderBatch step: a FETCH stream must not carry a UID twice; if it
17 // still does, the last occurrence wins and each uid is written once.
18 15460 QList<int> MailCache::lastWinsWriteOrder(const QList<MailHeader> &headers) {
19 15460 QList<int> writes;
20
1/1
✓ Branch 3 → 4 taken 15460 times.
15460 writes.reserve(headers.size());
21 {
22 15460 QSet<qint64> batchUids;
23
2/2
✓ Branch 15 → 7 taken 413811 times.
✓ Branch 15 → 16 taken 15460 times.
429271 for (int i = headers.size() - 1; i >= 0; --i) {
24
2/2
✓ Branch 9 → 10 taken 1 time.
✓ Branch 9 → 11 taken 413810 times.
413811 if (batchUids.contains(headers.at(i).uid)) continue;
25
1/1
✓ Branch 12 → 13 taken 413810 times.
413810 batchUids.insert(headers.at(i).uid);
26
1/1
✓ Branch 13 → 14 taken 413810 times.
413810 writes.prepend(i);
27 }
28 15460 }
29 15460 return writes;
30 ✗ }
31
32 // storeHeaderBatch step: an existing row already holds exactly this header
33 // (a semantically unchanged sync is skipped). Fields this writer did not
34 // read (recipients, spam filter) never count as a change.
35 2732 bool MailCache::storedRowMatches(const ExistingHeader &prior, const MailHeader &h, const QVariant &dateValue,
36 const QString &canonicalMessageId, const QString &encodedReplyIds,
37 const QString &encodedReferences) {
38
4/4
✓ Branch 5 → 6 taken 2593 times.
✓ Branch 5 → 46 taken 1 time.
✓ Branch 7 → 8 taken 2589 times.
✓ Branch 7 → 46 taken 4 times.
5326 return prior.subject == h.subject && prior.from == h.from && prior.to == h.to &&
39
2/4
✓ Branch 11 → 14 taken 18 times.
✗ Branch 11 → 46 not taken.
✓ Branch 13 → 14 taken 2571 times.
✗ Branch 13 → 46 not taken.
5178 (prior.date.isNull() ? dateValue.isNull() : prior.date == dateValue) &&
40
6/6
✓ Branch 14 → 15 taken 2561 times.
✓ Branch 14 → 46 taken 28 times.
✓ Branch 15 → 16 taken 2560 times.
✓ Branch 15 → 46 taken 1 time.
✓ Branch 19 → 20 taken 2559 times.
✓ Branch 19 → 46 taken 1 time.
5149 prior.flags == h.flags && prior.size == h.size &&
41
4/4
✓ Branch 16 → 17 taken 2 times.
✓ Branch 16 → 18 taken 2558 times.
✓ Branch 21 → 22 taken 2558 times.
✓ Branch 21 → 46 taken 1 time.
5119 prior.hasAttachments == (h.hasAttachments ? 1 : 0) &&
42
4/4
✓ Branch 23 → 24 taken 2557 times.
✓ Branch 23 → 46 taken 1 time.
✓ Branch 25 → 26 taken 1858 times.
✓ Branch 25 → 46 taken 699 times.
7674 prior.messageId == canonicalMessageId && prior.inReplyTo == encodedReplyIds &&
43
4/4
✓ Branch 26 → 27 taken 2 times.
✓ Branch 26 → 28 taken 1856 times.
✓ Branch 29 → 30 taken 1855 times.
✓ Branch 29 → 46 taken 3 times.
4415 prior.refIds == encodedReferences && prior.isSpam == (h.isSpam ? 1 : 0) &&
44
5/12
✓ Branch 3 → 4 taken 2594 times.
✓ Branch 3 → 46 taken 138 times.
✓ Branch 9 → 10 taken 18 times.
✓ Branch 9 → 12 taken 2571 times.
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 36 taken 1855 times.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 46 not taken.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 46 not taken.
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 46 not taken.
9770 (!h.recipientsKnown || (prior.recipientsKnown && prior.cc == h.cc && prior.listId == h.listId)) &&
45
3/8
✓ Branch 36 → 37 taken 4 times.
✓ Branch 36 → 45 taken 1851 times.
✗ Branch 38 → 39 not taken.
✓ Branch 38 → 46 taken 4 times.
✗ Branch 40 → 41 not taken.
✗ Branch 40 → 46 not taken.
✗ Branch 42 → 43 not taken.
✗ Branch 42 → 46 not taken.
1855 (!h.spamKnown || (!prior.spamTool.isNull() && prior.spamTool == h.spamTool &&
46
0/2
✗ Branch 44 → 45 not taken.
✗ Branch 44 → 46 not taken.
2732 prior.spamScore == h.spamScore && prior.spamThreshold == h.spamThreshold));
47 }
48
49 // storeHeaderBatch step (Sprint 105 S105.5.1): queue the address index
50 // rows of one written header when its From/To/Cc or date changed (its old
51 // rows are deleted now, the new ones written by flushAddressRows() in
52 // multi-row INSERTs). A writer without envelope data (recipientsKnown
53 // false) keeps the existing rows.
54 namespace {
55 bool addressIndexWrites = true;
56 } // namespace
57
58 ✗ void MailCache::setAddressIndexWritesForBenchmark(bool enabled) { addressIndexWrites = enabled; }
59
60 411954 bool MailCache::indexHeaderAddresses(qint64 hid, const MailHeader &h, const QVariant &dateValue,
61 const ExistingHeader *prior) {
62
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 411954 times.
411954 if (!addressIndexWrites) return true;
63
7/8
✓ Branch 4 → 5 taken 882 times.
✓ Branch 4 → 19 taken 411072 times.
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 18 taken 881 times.
✓ Branch 7 → 8 taken 1 time.
✗ Branch 7 → 19 not taken.
✓ Branch 20 → 21 taken 881 times.
✓ Branch 20 → 22 taken 411073 times.
411956 if (prior && (!h.recipientsKnown ||
64
1/4
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 19 taken 1 time.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 19 not taken.
2 (prior->from == h.from && prior->to == h.to && prior->cc == h.cc &&
65 ✗ (prior->date.isNull() ? dateValue.isNull() : prior->date == dateValue))))
66 881 return true;
67
2/2
✓ Branch 22 → 23 taken 1 time.
✓ Branch 22 → 62 taken 411072 times.
411073 if (prior) {
68
1/1
✓ Branch 23 → 24 taken 1 time.
1 QSqlQuery remove(m_db);
69
1/1
✓ Branch 27 → 28 taken 1 time.
1 remove.prepare(QStringLiteral("DELETE FROM message_addresses WHERE header_id = ?"));
70
1/1
✓ Branch 32 → 33 taken 1 time.
1 remove.addBindValue(hid);
71
2/3
✓ Branch 34 → 35 taken 1 time.
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 56 taken 1 time.
1 if (!remove.exec()) {
72 ✗ m_lastError = remove.lastError().text();
73 ✗ qCWarning(lcCache) << "Failed to replace the address rows of header" << hid << ":" << m_lastError;
74 ✗ m_db.rollback();
75 ✗ return false;
76 }
77 1 }
78
5/5
✓ Branch 62 → 63 taken 411073 times.
✓ Branch 63 → 64 taken 411073 times.
✓ Branch 64 → 65 taken 411073 times.
✓ Branch 73 → 66 taken 653553 times.
✓ Branch 73 → 74 taken 411073 times.
1064626 for (const MailAddressIndex::Entry &entry : MailAddressIndex::entriesOf(h))
79 1064626 m_pendingAddressRows.append({hid, entry.address, entry.role, dateValue});
80 411073 return true;
81 653553 }
82
83 // storeHeaderBatch step: write the queued address rows, 100 per statement
84 // (one statement per row cost about 30 % of a header sync, S105.5.6).
85 15451 bool MailCache::flushAddressRows() {
86 15451 constexpr int kRowsPerStatement = 100;
87 16127 const auto statement = [this](int rows) {
88 16127 QStringList tuples;
89
3/3
✓ Branch 6 → 7 taken 160251 times.
✓ Branch 10 → 3 taken 160251 times.
✓ Branch 10 → 11 taken 16127 times.
176378 for (int i = 0; i < rows; ++i) tuples << QStringLiteral("(?,?,?,?)");
90
1/1
✓ Branch 11 → 12 taken 16127 times.
16127 QSqlQuery query(m_db);
91
1/1
✓ Branch 19 → 20 taken 16127 times.
48381 query.prepare(QStringLiteral("INSERT OR IGNORE INTO message_addresses (header_id, address, role, date) VALUES ")
92
2/2
✓ Branch 14 → 15 taken 16127 times.
✓ Branch 18 → 19 taken 16127 times.
64508 + tuples.join(QLatin1Char(',')));
93 16127 return query;
94 16127 };
95
4/4
✓ Branch 3 → 4 taken 1149 times.
✓ Branch 3 → 10 taken 14302 times.
✓ Branch 4 → 5 taken 1149 times.
✓ Branch 5 → 6 taken 1149 times.
15451 if (!m_addressStatements) m_addressStatements = std::make_unique<QSqlQuery>(statement(kRowsPerStatement));
96 15451 const QList<PendingAddressRow> rows = std::exchange(m_pendingAddressRows, {});
97
2/2
✓ Branch 76 → 14 taken 21060 times.
✓ Branch 76 → 77 taken 15451 times.
36511 for (qsizetype at = 0; at < rows.size(); at += kRowsPerStatement) {
98 21060 const qsizetype count = std::min<qsizetype>(kRowsPerStatement, rows.size() - at);
99
9/13
✓ Branch 16 → 17 taken 6082 times.
✓ Branch 16 → 20 taken 14978 times.
✓ Branch 17 → 18 taken 6082 times.
✓ Branch 19 → 21 taken 6082 times.
✓ Branch 20 → 21 taken 14978 times.
✓ Branch 21 → 22 taken 6082 times.
✓ Branch 21 → 23 taken 14978 times.
✓ Branch 23 → 24 taken 6082 times.
✓ Branch 23 → 25 taken 14978 times.
✗ Branch 85 → 86 not taken.
✗ Branch 85 → 87 not taken.
✗ Branch 89 → 90 not taken.
✗ Branch 89 → 91 not taken.
21060 QSqlQuery partial = count == kRowsPerStatement ? QSqlQuery() : statement(int(count));
100
2/2
✓ Branch 25 → 26 taken 6082 times.
✓ Branch 25 → 27 taken 14978 times.
21060 QSqlQuery &insert = count == kRowsPerStatement ? *m_addressStatements : partial;
101
2/2
✓ Branch 48 → 29 taken 653551 times.
✓ Branch 48 → 49 taken 21060 times.
674611 for (qsizetype i = at; i < at + count; ++i) {
102
1/1
✓ Branch 32 → 33 taken 653551 times.
653551 insert.addBindValue(rows.at(i).headerId);
103
1/1
✓ Branch 37 → 38 taken 653551 times.
653551 insert.addBindValue(rows.at(i).address);
104
1/1
✓ Branch 42 → 43 taken 653551 times.
653551 insert.addBindValue(rows.at(i).role);
105
1/1
✓ Branch 46 → 47 taken 653551 times.
653551 insert.addBindValue(rows.at(i).date);
106 }
107
2/3
✓ Branch 49 → 50 taken 21060 times.
✗ Branch 50 → 51 not taken.
✓ Branch 50 → 69 taken 21060 times.
21060 if (!insert.exec()) {
108 ✗ m_lastError = insert.lastError().text();
109 ✗ qCWarning(lcCache) << "Failed to write the address index:" << m_lastError;
110 ✗ m_db.rollback();
111 ✗ return false;
112 }
113 21060 }
114 15451 return true;
115 15451 }
116
117 // storeHeaderBatch step: bind one header to the prepared UPSERT.
118 411963 void MailCache::bindHeaderUpsert(QSqlQuery &q, qint64 folderId, const MailHeader &h,
119 const QVariant &dateValue, const QString &canonicalMessageId,
120 const QString &encodedReplyIds,
121 const QString &encodedReferences) {
122
1/1
✓ Branch 7 → 8 taken 411963 times.
823926 q.bindValue(QStringLiteral(":fid"), folderId);
123
1/1
✓ Branch 16 → 17 taken 411963 times.
823926 q.bindValue(QStringLiteral(":uid"), h.uid);
124
1/1
✓ Branch 25 → 26 taken 411963 times.
823926 q.bindValue(QStringLiteral(":subj"), h.subject);
125
1/1
✓ Branch 34 → 35 taken 411963 times.
823926 q.bindValue(QStringLiteral(":from"), h.from);
126
1/1
✓ Branch 43 → 44 taken 411963 times.
823926 q.bindValue(QStringLiteral(":to"), h.to);
127
1/1
✓ Branch 51 → 52 taken 411963 times.
411963 q.bindValue(QStringLiteral(":date"), dateValue);
128
1/1
✓ Branch 59 → 60 taken 411963 times.
823926 q.bindValue(QStringLiteral(":flags"), h.flags);
129
1/1
✓ Branch 68 → 69 taken 411963 times.
823926 q.bindValue(QStringLiteral(":size"), h.size);
130
3/3
✓ Branch 73 → 74 taken 32835 times.
✓ Branch 73 → 75 taken 379128 times.
✓ Branch 80 → 81 taken 411963 times.
823926 q.bindValue(QStringLiteral(":att"), h.hasAttachments ? 1 : 0);
131
1/1
✓ Branch 89 → 90 taken 411963 times.
823926 q.bindValue(QStringLiteral(":msgid"), canonicalMessageId);
132
1/1
✓ Branch 98 → 99 taken 411963 times.
823926 q.bindValue(QStringLiteral(":irt"), encodedReplyIds);
133
1/1
✓ Branch 107 → 108 taken 411963 times.
823926 q.bindValue(QStringLiteral(":refs"), encodedReferences);
134
3/3
✓ Branch 112 → 113 taken 12 times.
✓ Branch 112 → 114 taken 411951 times.
✓ Branch 119 → 120 taken 411963 times.
823926 q.bindValue(QStringLiteral(":spam"), h.isSpam ? 1 : 0);
135 // Sprint 95 S95.1.11: NULL marks "not known" (rows from before schema v24
136 // or writers without an ENVELOPE); "" is a known empty value.
137 823926 const auto knownText = [&h](const QString &value) {
138
2/2
✓ Branch 2 → 3 taken 767640 times.
✓ Branch 2 → 5 taken 56286 times.
823926 if (!h.recipientsKnown) return QVariant(QMetaType::fromType<QString>()); // SQL NULL
139
6/6
✓ Branch 6 → 7 taken 53273 times.
✓ Branch 6 → 11 taken 3013 times.
✓ Branch 13 → 14 taken 53273 times.
✓ Branch 13 → 15 taken 3013 times.
✓ Branch 15 → 16 taken 53273 times.
✓ Branch 15 → 17 taken 3013 times.
109559 return value.isNull() ? QVariant(QStringLiteral("")) : QVariant(value); // never a null QString
140 411963 };
141
2/2
✓ Branch 124 → 125 taken 411963 times.
✓ Branch 128 → 129 taken 411963 times.
823926 q.bindValue(QStringLiteral(":cc"), knownText(h.cc));
142
2/2
✓ Branch 133 → 134 taken 411963 times.
✓ Branch 137 → 138 taken 411963 times.
823926 q.bindValue(QStringLiteral(":list"), knownText(h.listId));
143
2/2
✓ Branch 141 → 142 taken 411963 times.
✓ Branch 142 → 143 taken 411963 times.
411963 const QVariant null(QMetaType::fromType<double>());
144
6/6
✓ Branch 144 → 145 taken 6 times.
✓ Branch 144 → 149 taken 411957 times.
✓ Branch 146 → 147 taken 5 times.
✓ Branch 146 → 149 taken 1 time.
✓ Branch 149 → 150 taken 411958 times.
✓ Branch 153 → 154 taken 411963 times.
823926 q.bindValue(QStringLiteral(":sscore"), h.spamKnown && h.spamScore ? QVariant(*h.spamScore) : null);
145
6/6
✓ Branch 158 → 159 taken 6 times.
✓ Branch 158 → 163 taken 411957 times.
✓ Branch 160 → 161 taken 5 times.
✓ Branch 160 → 163 taken 1 time.
✓ Branch 163 → 164 taken 411958 times.
✓ Branch 167 → 168 taken 411963 times.
823926 q.bindValue(QStringLiteral(":sthreshold"), h.spamKnown && h.spamThreshold ? QVariant(*h.spamThreshold) : null);
146
11/15
✓ Branch 172 → 173 taken 6 times.
✓ Branch 172 → 180 taken 411957 times.
✓ Branch 174 → 175 taken 1 time.
✓ Branch 174 → 178 taken 5 times.
✓ Branch 180 → 181 taken 411957 times.
✓ Branch 181 → 182 taken 411957 times.
✓ Branch 185 → 186 taken 411963 times.
✓ Branch 189 → 190 taken 6 times.
✓ Branch 189 → 191 taken 411957 times.
✓ Branch 191 → 192 taken 1 time.
✓ Branch 191 → 193 taken 411962 times.
✗ Branch 370 → 371 not taken.
✗ Branch 370 → 372 not taken.
✗ Branch 374 → 375 not taken.
✗ Branch 374 → 376 not taken.
823927 q.bindValue(QStringLiteral(":stool"), h.spamKnown ? QVariant(h.spamTool.isNull() ? QStringLiteral("") : h.spamTool)
147 : QVariant(QMetaType::fromType<QString>()));
148 411963 }
149
150 6 bool MailCache::storeEpochHeaders(qint64 folderId, quint32 uidValidity,
151 const QList<MailHeader> &headers) {
152
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 6 times.
6 if (headers.isEmpty())
153 ✗ return true;
154
2/2
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 27 taken 5 times.
6 if (uidValidity == 0) {
155 1 m_lastError = QStringLiteral("Headers without a mailbox epoch are not stored");
156
8/8
✓ Branch 12 → 13 taken 1 time.
✓ Branch 16 → 17 taken 1 time.
✓ Branch 17 → 18 taken 1 time.
✓ Branch 19 → 20 taken 1 time.
✓ Branch 20 → 21 taken 1 time.
✓ Branch 21 → 22 taken 1 time.
✓ Branch 25 → 14 taken 1 time.
✓ Branch 25 → 26 taken 1 time.
2 qCWarning(lcCache) << "Refused" << headers.size() << "headers without an epoch for folder" << folderId;
157 1 return false;
158 }
159
6/8
✓ Branch 27 → 28 taken 5 times.
✓ Branch 28 → 29 taken 1 time.
✓ Branch 28 → 32 taken 4 times.
✓ Branch 29 → 30 taken 1 time.
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 32 taken 1 time.
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 35 taken 5 times.
5 if (this->uidValidity(folderId) == 0 && !setUidValidity(folderId, uidValidity))
160 ✗ return false;
161 5 const auto writeMutex = m_writeMutex;
162 5 QMutexLocker publication(writeMutex.get());
163 5 auto batch = headers;
164
2/2
✓ Branch 39 → 40 taken 5 times.
✓ Branch 40 → 41 taken 5 times.
5 const bool stored = storeHeaderBatch(folderId, batch, [&] {
165
1/1
✓ Branch 2 → 3 taken 5 times.
5 QSqlQuery epoch(m_db);
166
1/1
✓ Branch 6 → 7 taken 5 times.
5 epoch.prepare(QStringLiteral("SELECT uidvalidity FROM folders WHERE id=?"));
167
1/1
✓ Branch 11 → 12 taken 5 times.
5 epoch.addBindValue(folderId);
168
5/8
✓ Branch 13 → 14 taken 5 times.
✓ Branch 14 → 15 taken 5 times.
✗ Branch 14 → 17 not taken.
✓ Branch 15 → 16 taken 5 times.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 5 times.
✗ Branch 19 → 20 not taken.
✓ Branch 19 → 36 taken 5 times.
5 if (!epoch.exec() || !epoch.next()) {
169 ✗ m_lastError = epoch.lastError().isValid() ? epoch.lastError().text()
170 ✗ : QStringLiteral("Folder is gone");
171 ✗ return false;
172 }
173
4/4
✓ Branch 36 → 37 taken 5 times.
✓ Branch 37 → 38 taken 5 times.
✓ Branch 39 → 40 taken 2 times.
✓ Branch 39 → 47 taken 3 times.
5 if (epoch.value(0).toUInt() != uidValidity) {
174 2 m_lastError = QStringLiteral("Mailbox epoch changed before header persistence");
175 2 return false;
176 }
177 3 return true;
178 5 });
179
2/2
✓ Branch 42 → 43 taken 2 times.
✓ Branch 42 → 62 taken 3 times.
5 if (!stored) {
180
7/7
✓ Branch 43 → 44 taken 2 times.
✓ Branch 47 → 48 taken 2 times.
✓ Branch 48 → 49 taken 2 times.
✓ Branch 50 → 51 taken 2 times.
✓ Branch 51 → 52 taken 2 times.
✓ Branch 60 → 45 taken 2 times.
✓ Branch 60 → 61 taken 2 times.
4 qCWarning(lcCache) << "Dropped" << headers.size() << "headers for folder" << folderId
181
5/5
✓ Branch 52 → 53 taken 2 times.
✓ Branch 53 → 54 taken 2 times.
✓ Branch 54 → 55 taken 2 times.
✓ Branch 55 → 56 taken 2 times.
✓ Branch 56 → 57 taken 2 times.
2 << "fetched under epoch" << uidValidity << ":" << m_lastError;
182 2 return false;
183 }
184
5/5
✓ Branch 62 → 63 taken 3 times.
✓ Branch 63 → 64 taken 3 times.
✓ Branch 66 → 67 taken 3 times.
✓ Branch 69 → 65 taken 3 times.
✓ Branch 69 → 70 taken 3 times.
6 for (const auto &header : batch) emit headerStateReplaced(folderId, header);
185 3 return true;
186 5 }
187
188 31 bool MailCache::storeStreamingHeaders(
189 const QString &account, const QString &folder, qint64 folderId,
190 quint32 uidValidity, QList<MailHeader> &headers,
191 const std::function<QString(QList<MailHeader> &)> &prepare) {
192 31 const auto writeMutex = m_writeMutex;
193 31 QMutexLocker publication(writeMutex.get());
194
2/2
✓ Branch 5 → 6 taken 31 times.
✓ Branch 6 → 7 taken 31 times.
62 return storeHeaderBatch(folderId, headers, [&] {
195
1/1
✓ Branch 2 → 3 taken 30 times.
30 QSqlQuery identity(m_db);
196
1/1
✓ Branch 6 → 7 taken 30 times.
30 identity.prepare(QStringLiteral("SELECT 1 FROM folders WHERE id=? AND account=? "
197 "AND path=? AND uidvalidity=?"));
198
2/2
✓ Branch 11 → 12 taken 30 times.
✓ Branch 15 → 16 taken 30 times.
30 identity.addBindValue(folderId); identity.addBindValue(account);
199
2/2
✓ Branch 19 → 20 taken 30 times.
✓ Branch 23 → 24 taken 30 times.
30 identity.addBindValue(folder); identity.addBindValue(uidValidity);
200
7/8
✓ Branch 25 → 26 taken 30 times.
✓ Branch 26 → 27 taken 30 times.
✗ Branch 26 → 29 not taken.
✓ Branch 27 → 28 taken 30 times.
✓ Branch 28 → 29 taken 3 times.
✓ Branch 28 → 30 taken 27 times.
✓ Branch 31 → 32 taken 3 times.
✓ Branch 31 → 48 taken 27 times.
30 if (!identity.exec() || !identity.next()) {
201
3/8
✓ Branch 32 → 33 taken 3 times.
✓ Branch 33 → 34 taken 3 times.
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 37 taken 3 times.
✗ Branch 35 → 36 not taken.
✗ Branch 36 → 40 not taken.
✗ Branch 84 → 85 not taken.
✗ Branch 84 → 86 not taken.
12 m_lastError = identity.lastError().isValid() ? identity.lastError().text()
202
2/6
✓ Branch 42 → 43 taken 3 times.
✗ Branch 42 → 44 not taken.
✗ Branch 44 → 45 not taken.
✓ Branch 44 → 46 taken 3 times.
✗ Branch 80 → 81 not taken.
✗ Branch 80 → 82 not taken.
6 : QStringLiteral("Mailbox identity changed before header persistence");
203 3 return false;
204 }
205
2/3
✓ Branch 49 → 50 taken 27 times.
✗ Branch 49 → 54 not taken.
✓ Branch 50 → 51 taken 27 times.
27 if (prepare) m_lastError = prepare(headers);
206 27 return m_lastError.isEmpty();
207 92 });
208 31 }
209