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: 92.7% 38 / 0 / 41
Functions: 100.0% 2 / 0 / 2
Branches: 69.4% 50 / 0 / 72

data/ContactMailLinkQuery.cpp
Line Branch Exec Source
1 #include "ContactMailLinkQuery.h"
2
3 #include "data/ContactIndex.h"
4 #include "util/MessageId.h"
5
6 #include <QElapsedTimer>
7 #include <QFileInfo>
8 #include <QLoggingCategory>
9 #include <QSet>
10 #include <QSqlError>
11 #include <QSqlDatabase>
12 #include <QSqlQuery>
13 #include <QUuid>
14
15 Q_DECLARE_LOGGING_CATEGORY(lcContactPeople)
16
17 namespace ContactMailLinkQuery {
18
19 namespace {
20
21 12 QString contains(const QString &value) {
22 12 QString escaped = value;
23
1/1
✓ Branch 8 → 9 taken 12 times.
12 escaped.replace(QLatin1Char('\\'), QStringLiteral("\\\\"));
24
1/1
✓ Branch 16 → 17 taken 12 times.
12 escaped.replace(QLatin1Char('%'), QStringLiteral("\\%"));
25
1/1
✓ Branch 24 → 25 taken 12 times.
12 escaped.replace(QLatin1Char('_'), QStringLiteral("\\_"));
26
2/2
✓ Branch 31 → 32 taken 12 times.
✓ Branch 32 → 33 taken 12 times.
36 return QLatin1Char('%') + escaped + QLatin1Char('%');
27 12 }
28
29 } // namespace
30
31 6 QStringList messageIdsAbout(const QString &databasePath, const QString &name, int limit) {
32
1/1
✓ Branch 2 → 3 taken 6 times.
6 const QString value = name.trimmed();
33
5/9
✓ Branch 4 → 5 taken 6 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 6 times.
✗ Branch 5 → 8 not taken.
✓ Branch 6 → 7 taken 6 times.
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 6 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 6 times.
6 if (value.isEmpty() || limit <= 0 || !QFileInfo::exists(databasePath))
34 ✗ return {};
35 6 QElapsedTimer timer;
36 6 timer.start();
37 // S106-168: a read-only connection of its own — ContactStore::open() ran
38 // the schema setup and migrations on this worker thread.
39
3/3
✓ Branch 13 → 14 taken 6 times.
✓ Branch 14 → 15 taken 6 times.
✓ Branch 18 → 19 taken 6 times.
12 const QString connection = QStringLiteral("mailjd_about_") + QUuid::createUuid().toString(QUuid::WithoutBraces);
40 6 QStringList ids;
41 {
42
1/1
✓ Branch 25 → 26 taken 6 times.
6 QSqlDatabase db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), connection);
43
1/1
✓ Branch 28 → 29 taken 6 times.
6 db.setDatabaseName(databasePath);
44
1/1
✓ Branch 32 → 33 taken 6 times.
6 db.setConnectOptions(QStringLiteral("QSQLITE_OPEN_READONLY;QSQLITE_BUSY_TIMEOUT=2000"));
45
2/3
✓ Branch 35 → 36 taken 6 times.
✗ Branch 36 → 37 not taken.
✓ Branch 36 → 48 taken 6 times.
6 if (!db.open()) {
46 ✗ qCWarning(lcContactPeople) << "about: contacts database not readable";
47 } else {
48
1/1
✓ Branch 48 → 49 taken 6 times.
6 QSqlQuery q(db);
49
1/1
✓ Branch 52 → 53 taken 6 times.
6 q.prepare(QStringLiteral("SELECT DISTINCT l.message_id FROM card_mail_links l JOIN cards c ON c.id = l.card_id"
50 " WHERE c.sort_display LIKE :name ESCAPE '\\' OR EXISTS (SELECT 1 FROM card_addresses a"
51 " WHERE a.card_id = c.id AND a.address LIKE :address ESCAPE '\\')"
52 " ORDER BY l.date DESC LIMIT :limit"));
53
3/3
✓ Branch 56 → 57 taken 6 times.
✓ Branch 57 → 58 taken 6 times.
✓ Branch 62 → 63 taken 6 times.
12 q.bindValue(QStringLiteral(":name"), contains(ContactIndex::foldForSort(value)));
54
2/2
✓ Branch 69 → 70 taken 6 times.
✓ Branch 74 → 75 taken 6 times.
12 q.bindValue(QStringLiteral(":address"), contains(value));
55
1/1
✓ Branch 84 → 85 taken 6 times.
12 q.bindValue(QStringLiteral(":limit"), limit);
56
2/3
✓ Branch 88 → 89 taken 6 times.
✗ Branch 89 → 90 not taken.
✓ Branch 89 → 106 taken 6 times.
6 if (!q.exec()) {
57 ✗ qCWarning(lcContactPeople) << "about: query failed:" << q.lastError().text();
58 } else {
59 6 QSet<QString> seen;
60
3/3
✓ Branch 124 → 125 taken 14 times.
✓ Branch 125 → 108 taken 8 times.
✓ Branch 125 → 126 taken 6 times.
14 while (q.next()) {
61
3/3
✓ Branch 108 → 109 taken 8 times.
✓ Branch 109 → 110 taken 8 times.
✓ Branch 110 → 111 taken 8 times.
8 const QString id = MessageId::canonicalize(q.value(0).toString());
62
3/6
✓ Branch 114 → 115 taken 8 times.
✗ Branch 114 → 118 not taken.
✓ Branch 116 → 117 taken 8 times.
✗ Branch 116 → 118 not taken.
✓ Branch 119 → 120 taken 8 times.
✗ Branch 119 → 122 not taken.
8 if (!id.isEmpty() && !seen.contains(id)) {
63
1/1
✓ Branch 120 → 121 taken 8 times.
8 seen.insert(id);
64
1/1
✓ Branch 121 → 122 taken 8 times.
8 ids.append(id);
65 }
66 8 }
67 6 }
68 6 }
69 6 }
70
1/1
✓ Branch 131 → 132 taken 6 times.
6 QSqlDatabase::removeDatabase(connection);
71
9/9
✓ Branch 132 → 133 taken 6 times.
✓ Branch 136 → 137 taken 6 times.
✓ Branch 137 → 138 taken 6 times.
✓ Branch 139 → 140 taken 6 times.
✓ Branch 140 → 141 taken 6 times.
✓ Branch 142 → 143 taken 6 times.
✓ Branch 143 → 144 taken 6 times.
✓ Branch 147 → 134 taken 6 times.
✓ Branch 147 → 148 taken 6 times.
12 qCInfo(lcContactPeople) << "about: resolved" << ids.size() << "linked mails in" << timer.elapsed() << "ms";
72 6 return ids;
73 6 }
74
75 } // namespace ContactMailLinkQuery
76