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: 93.8% 121 / 0 / 129
Functions: 100.0% 12 / 0 / 12
Branches: 81.9% 186 / 0 / 227

data/ContactIndex.cpp
Line Branch Exec Source
1 #include "ContactIndex.h"
2
3 #include <QCryptographicHash>
4
5 namespace ContactIndex {
6
7 98048 QString displayName(const ContactCard &card) {
8
3/3
✓ Branch 2 → 3 taken 98048 times.
✓ Branch 5 → 6 taken 98039 times.
✓ Branch 5 → 8 taken 9 times.
98048 if (!card.formattedName.trimmed().isEmpty())
9
1/1
✓ Branch 6 → 7 taken 98039 times.
98039 return card.formattedName.simplified();
10 const QString composed =
11
2/4
✓ Branch 21 → 22 taken 45 times.
✓ Branch 21 → 23 taken 9 times.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 51 not taken.
54 QStringList{card.name.prefix, card.name.given, card.name.additional, card.name.family, card.name.suffix}
12
1/1
✓ Branch 16 → 17 taken 9 times.
18 .join(QLatin1Char(' '))
13
1/1
✓ Branch 17 → 18 taken 9 times.
9 .simplified();
14
2/2
✓ Branch 24 → 25 taken 8 times.
✓ Branch 24 → 26 taken 1 time.
9 if (!composed.isEmpty())
15 8 return composed;
16
2/3
✓ Branch 26 → 27 taken 1 time.
✓ Branch 29 → 30 taken 1 time.
✗ Branch 29 → 32 not taken.
1 if (!card.organization.trimmed().isEmpty())
17
1/1
✓ Branch 30 → 31 taken 1 time.
1 return card.organization.simplified();
18 ✗ if (!card.emails.isEmpty())
19 ✗ return card.emails.first().value.trimmed();
20 ✗ return {};
21 18 }
22
23 30499 QString familyFirstName(const ContactCard &card) {
24
3/3
✓ Branch 2 → 3 taken 30499 times.
✓ Branch 5 → 6 taken 22450 times.
✓ Branch 5 → 8 taken 8049 times.
30499 if (card.name.family.trimmed().isEmpty())
25
1/1
✓ Branch 6 → 7 taken 22450 times.
22450 return displayName(card);
26
3/3
✓ Branch 10 → 11 taken 8049 times.
✓ Branch 11 → 12 taken 8049 times.
✓ Branch 12 → 13 taken 8049 times.
8049 const QString given = (card.name.given + QLatin1Char(' ') + card.name.additional).simplified();
27
14/22
✓ Branch 16 → 17 taken 5822 times.
✓ Branch 16 → 18 taken 2227 times.
✓ Branch 17 → 24 taken 5822 times.
✓ Branch 21 → 22 taken 2227 times.
✓ Branch 22 → 23 taken 2227 times.
✓ Branch 23 → 24 taken 2227 times.
✓ Branch 25 → 26 taken 2227 times.
✓ Branch 25 → 27 taken 5822 times.
✓ Branch 27 → 28 taken 2227 times.
✓ Branch 27 → 29 taken 5822 times.
✓ Branch 29 → 30 taken 2227 times.
✓ Branch 29 → 31 taken 5822 times.
✓ Branch 31 → 32 taken 2227 times.
✓ Branch 31 → 33 taken 5822 times.
✗ Branch 45 → 46 not taken.
✗ Branch 45 → 47 not taken.
✗ Branch 49 → 50 not taken.
✗ Branch 49 → 51 not taken.
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 55 not taken.
✗ Branch 57 → 58 not taken.
✗ Branch 57 → 59 not taken.
10276 return given.isEmpty() ? card.name.family.simplified() : card.name.family.simplified() + QStringLiteral(", ") + given;
28 8049 }
29
30 273406 QString foldForSort(const QString &text) {
31
1/1
✓ Branch 2 → 3 taken 273406 times.
273406 const QString decomposed = text.normalized(QString::NormalizationForm_KD);
32 273406 QString folded;
33
1/1
✓ Branch 4 → 5 taken 273406 times.
273406 folded.reserve(decomposed.size());
34
2/2
✓ Branch 59 → 7 taken 17012433 times.
✓ Branch 59 → 60 taken 273406 times.
17285839 for (const QChar c : decomposed) {
35
7/8
✓ Branch 8 → 9 taken 16930825 times.
✓ Branch 8 → 13 taken 81608 times.
✓ Branch 10 → 11 taken 16930799 times.
✓ Branch 10 → 13 taken 26 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 16930799 times.
✓ Branch 15 → 16 taken 81634 times.
✓ Branch 15 → 17 taken 16930799 times.
33943232 if (c.category() == QChar::Mark_NonSpacing || c.category() == QChar::Mark_SpacingCombining ||
36 16930799 c.category() == QChar::Mark_Enclosing)
37 81634 continue;
38
2/2
✓ Branch 19 → 20 taken 11 times.
✓ Branch 19 → 27 taken 16930788 times.
16930799 if (c == QChar(0x00DF)) { // ß
39
1/1
✓ Branch 23 → 24 taken 11 times.
11 folded += QStringLiteral("ss");
40 11 continue;
41 }
42 // Letters without a decomposition that should sort with their base letter.
43
4/6
✓ Branch 28 → 29 taken 2 times.
✓ Branch 28 → 33 taken 320 times.
✓ Branch 28 → 37 taken 15 times.
✗ Branch 28 → 41 not taken.
✗ Branch 28 → 48 not taken.
✓ Branch 28 → 55 taken 16930451 times.
16930788 switch (c.unicode()) {
44
1/1
✓ Branch 31 → 32 taken 2 times.
2 case 0x00F8: case 0x00D8: folded += QLatin1Char('o'); continue; // ø
45
1/1
✓ Branch 35 → 36 taken 320 times.
320 case 0x0131: folded += QLatin1Char('i'); continue; // dotless ı
46
1/1
✓ Branch 39 → 40 taken 15 times.
15 case 0x0142: case 0x0141: folded += QLatin1Char('l'); continue; // ł
47 ✗ case 0x00E6: case 0x00C6: folded += QStringLiteral("ae"); continue;
48 ✗ case 0x0153: case 0x0152: folded += QStringLiteral("oe"); continue;
49 16930451 default: break;
50 }
51
1/1
✓ Branch 57 → 58 taken 16930451 times.
16930451 folded += c.toCaseFolded();
52 }
53 // Surrounding quotes, brackets and dashes do not decide the order.
54 273406 int start = 0;
55
6/6
✓ Branch 63 → 64 taken 265802 times.
✓ Branch 63 → 68 taken 27297 times.
✓ Branch 66 → 67 taken 19693 times.
✓ Branch 66 → 68 taken 246109 times.
✓ Branch 69 → 61 taken 19693 times.
✓ Branch 69 → 70 taken 273406 times.
293099 while (start < folded.size() && !folded.at(start).isLetterOrNumber())
56 19693 ++start;
57 273406 int end = int(folded.size());
58
6/6
✓ Branch 73 → 74 taken 418619 times.
✓ Branch 73 → 78 taken 27297 times.
✓ Branch 76 → 77 taken 172510 times.
✓ Branch 76 → 78 taken 246109 times.
✓ Branch 79 → 72 taken 172510 times.
✓ Branch 79 → 80 taken 273406 times.
445916 while (end > start && !folded.at(end - 1).isLetterOrNumber())
59 172510 --end;
60
2/2
✓ Branch 80 → 81 taken 273406 times.
✓ Branch 81 → 82 taken 273406 times.
546812 return folded.mid(start, end - start).simplified();
61 273406 }
62
63 36445 QString sectionOf(const QString &foldedKey) {
64
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 9 taken 36445 times.
36445 if (foldedKey.isEmpty())
65 ✗ return QStringLiteral("#");
66 36445 const QChar first = foldedKey.at(0);
67
5/6
✓ Branch 14 → 15 taken 36440 times.
✓ Branch 14 → 21 taken 5 times.
✓ Branch 19 → 20 taken 36440 times.
✗ Branch 19 → 21 not taken.
✓ Branch 22 → 23 taken 36440 times.
✓ Branch 22 → 26 taken 5 times.
36445 if (first >= QLatin1Char('a') && first <= QLatin1Char('z'))
68
1/1
✓ Branch 24 → 25 taken 36440 times.
36440 return QString(first.toUpper());
69 5 return QStringLiteral("#");
70 }
71
72
2/2
✓ Branch 2 → 3 taken 31848 times.
✓ Branch 3 → 4 taken 31848 times.
31848 QString addressKey(const QString &address) { return address.trimmed().toLower(); }
73
74 1520 QString phoneDigits(const QString &phone) {
75 1520 QString digits;
76
2/2
✓ Branch 8 → 4 taken 22020 times.
✓ Branch 8 → 9 taken 1520 times.
23540 for (const QChar c : phone)
77
2/2
✓ Branch 5 → 6 taken 17405 times.
✓ Branch 5 → 7 taken 4615 times.
22020 if (c.isDigit())
78
1/1
✓ Branch 6 → 7 taken 17405 times.
17405 digits += c;
79 1520 return digits;
80 ✗ }
81
82 30506 QString searchText(const ContactCard &card) {
83 91518 QStringList parts{displayName(card), card.nickname, card.organization, card.department,
84
2/4
✓ Branch 12 → 13 taken 244048 times.
✓ Branch 12 → 14 taken 30506 times.
✗ Branch 84 → 85 not taken.
✗ Branch 84 → 86 not taken.
274554 card.title, card.name.given, card.name.family, card.note};
85
2/2
✓ Branch 20 → 16 taken 29943 times.
✓ Branch 20 → 21 taken 30506 times.
60449 for (const ContactValue &email : card.emails)
86
1/1
✓ Branch 17 → 18 taken 29943 times.
29943 parts << email.value;
87
2/2
✓ Branch 30 → 23 taken 1519 times.
✓ Branch 30 → 31 taken 30506 times.
32025 for (const ContactValue &phone : card.phones)
88
3/3
✓ Branch 24 → 25 taken 1519 times.
✓ Branch 25 → 26 taken 1519 times.
✓ Branch 26 → 27 taken 1519 times.
1519 parts << phone.value << phoneDigits(phone.value);
89
2/2
✓ Branch 39 → 33 taken 2215 times.
✓ Branch 39 → 40 taken 30506 times.
32721 for (const ContactAddress &address : card.addresses)
90
2/2
✓ Branch 34 → 35 taken 2215 times.
✓ Branch 35 → 36 taken 2215 times.
2215 parts << address.oneLine();
91
1/1
✓ Branch 40 → 41 taken 30506 times.
30506 parts << card.categories;
92 // Sprint 103 (S103.1.4): names in relationships and introductions, where
93 // and when we met, services and handles, interests and the birthplace.
94
2/2
✓ Branch 48 → 43 taken 529 times.
✓ Branch 48 → 49 taken 30506 times.
31035 for (const ContactRelation &relation : card.relations)
95
2/2
✓ Branch 44 → 45 taken 529 times.
✓ Branch 45 → 46 taken 529 times.
529 parts << relation.targetName << relation.label;
96
2/2
✓ Branch 55 → 51 taken 105 times.
✓ Branch 55 → 56 taken 30506 times.
30611 for (const ContactPersonRef &via : card.met.via)
97
1/1
✓ Branch 52 → 53 taken 105 times.
105 parts << via.name;
98
2/2
✓ Branch 56 → 57 taken 30506 times.
✓ Branch 57 → 58 taken 30506 times.
30506 parts << card.met.place << card.met.note;
99
2/2
✓ Branch 58 → 59 taken 127 times.
✓ Branch 58 → 63 taken 30379 times.
30506 if (card.met.date.year > 0)
100
2/2
✓ Branch 59 → 60 taken 127 times.
✓ Branch 60 → 61 taken 127 times.
127 parts << QString::number(card.met.date.year);
101
2/2
✓ Branch 71 → 65 taken 189 times.
✓ Branch 71 → 72 taken 30506 times.
30695 for (const ContactSocial &social : card.social)
102
3/3
✓ Branch 66 → 67 taken 189 times.
✓ Branch 67 → 68 taken 189 times.
✓ Branch 68 → 69 taken 189 times.
189 parts << social.service << social.user << social.value;
103
2/2
✓ Branch 72 → 73 taken 30506 times.
✓ Branch 73 → 74 taken 30506 times.
30506 parts << card.interests << card.birthplace;
104
2/2
✓ Branch 76 → 77 taken 30506 times.
✓ Branch 77 → 78 taken 30506 times.
61012 return foldForSort(parts.join(QLatin1Char(' ')));
105 61012 }
106
107 35537 QString primaryAddress(const ContactCard &card) {
108
2/2
✓ Branch 18 → 4 taken 29977 times.
✓ Branch 18 → 19 taken 35535 times.
65512 for (const ContactValue &email : card.emails)
109
8/11
✓ Branch 5 → 6 taken 2 times.
✓ Branch 5 → 10 taken 29975 times.
✓ Branch 6 → 7 taken 2 times.
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 10 not taken.
✓ Branch 11 → 12 taken 2 times.
✓ Branch 11 → 13 taken 29975 times.
✓ Branch 13 → 14 taken 2 times.
✓ Branch 13 → 16 taken 29975 times.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
29977 if (email.preferred && !email.value.trimmed().isEmpty())
110
1/1
✓ Branch 14 → 15 taken 2 times.
2 return email.value.trimmed();
111
2/2
✓ Branch 30 → 21 taken 29820 times.
✓ Branch 30 → 31 taken 5715 times.
35535 for (const ContactValue &email : card.emails)
112
2/3
✓ Branch 22 → 23 taken 29820 times.
✓ Branch 25 → 26 taken 29820 times.
✗ Branch 25 → 28 not taken.
29820 if (!email.value.trimmed().isEmpty())
113
1/1
✓ Branch 26 → 27 taken 29820 times.
29820 return email.value.trimmed();
114 5715 return {};
115 }
116
117 30498 QString primaryPhone(const ContactCard &card) {
118
2/2
✓ Branch 18 → 4 taken 1519 times.
✓ Branch 18 → 19 taken 30498 times.
32017 for (const ContactValue &phone : card.phones)
119
3/11
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 10 taken 1519 times.
✗ Branch 6 → 7 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 8 → 10 not taken.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 1519 times.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 16 taken 1519 times.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
1519 if (phone.preferred && !phone.value.trimmed().isEmpty())
120 ✗ return phone.value.trimmed();
121
2/2
✓ Branch 30 → 21 taken 1484 times.
✓ Branch 30 → 31 taken 29014 times.
30498 for (const ContactValue &phone : card.phones)
122
2/3
✓ Branch 22 → 23 taken 1484 times.
✓ Branch 25 → 26 taken 1484 times.
✗ Branch 25 → 28 not taken.
1484 if (!phone.value.trimmed().isEmpty())
123
1/1
✓ Branch 26 → 27 taken 1484 times.
1484 return phone.value.trimmed();
124 29014 return {};
125 }
126
127 30498 QString primaryLocality(const ContactCard &card) {
128
2/2
✓ Branch 18 → 4 taken 2213 times.
✓ Branch 18 → 19 taken 30497 times.
32710 for (const ContactAddress &address : card.addresses)
129
8/11
✓ Branch 5 → 6 taken 1 time.
✓ Branch 5 → 10 taken 2212 times.
✓ Branch 6 → 7 taken 1 time.
✓ Branch 8 → 9 taken 1 time.
✗ Branch 8 → 10 not taken.
✓ Branch 11 → 12 taken 1 time.
✓ Branch 11 → 13 taken 2212 times.
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 16 taken 2212 times.
✗ Branch 33 → 34 not taken.
✗ Branch 33 → 35 not taken.
2213 if (address.preferred && !address.locality.trimmed().isEmpty())
130
1/1
✓ Branch 14 → 15 taken 1 time.
1 return address.locality.trimmed();
131
2/2
✓ Branch 30 → 21 taken 2211 times.
✓ Branch 30 → 31 taken 28304 times.
30515 for (const ContactAddress &address : card.addresses)
132
3/3
✓ Branch 22 → 23 taken 2211 times.
✓ Branch 25 → 26 taken 2193 times.
✓ Branch 25 → 28 taken 18 times.
2211 if (!address.locality.trimmed().isEmpty())
133
1/1
✓ Branch 26 → 27 taken 2193 times.
2193 return address.locality.trimmed();
134 28304 return {};
135 }
136
137 9319 QString initials(const ContactCard &card) {
138
1/1
✓ Branch 2 → 3 taken 9319 times.
9319 QString given = card.name.given.trimmed();
139
1/1
✓ Branch 3 → 4 taken 9319 times.
9319 QString family = card.name.family.trimmed();
140
6/6
✓ Branch 5 → 6 taken 8879 times.
✓ Branch 5 → 9 taken 440 times.
✓ Branch 7 → 8 taken 8805 times.
✓ Branch 7 → 9 taken 74 times.
✓ Branch 10 → 11 taken 8805 times.
✓ Branch 10 → 29 taken 514 times.
9319 if (given.isEmpty() && family.isEmpty()) {
141
2/2
✓ Branch 11 → 12 taken 8805 times.
✓ Branch 15 → 16 taken 8805 times.
8805 const QStringList words = displayName(card).split(QLatin1Char(' '), Qt::SkipEmptyParts);
142
1/1
✓ Branch 17 → 18 taken 8805 times.
8805 given = words.value(0);
143
2/2
✓ Branch 21 → 22 taken 7647 times.
✓ Branch 21 → 24 taken 1158 times.
8805 family = words.size() > 1 ? words.last() : QString();
144 8805 }
145 9319 QString result;
146
2/2
✓ Branch 43 → 33 taken 18638 times.
✓ Branch 43 → 44 taken 9319 times.
46595 for (const QString &word : {given, family})
147
2/2
✓ Branch 41 → 35 taken 17398 times.
✓ Branch 41 → 42 taken 1240 times.
18638 for (const QChar c : word)
148
1/2
✓ Branch 36 → 37 taken 17398 times.
✗ Branch 36 → 40 not taken.
17398 if (c.isLetterOrNumber()) {
149
1/1
✓ Branch 38 → 39 taken 17398 times.
17398 result += c.toUpper();
150 17398 break;
151 27957 }
152
1/1
✓ Branch 50 → 51 taken 9319 times.
18638 return result.left(2);
153 9319 }
154
155 11222 int avatarColorIndex(const QString &uid) {
156
2/2
✓ Branch 2 → 3 taken 11222 times.
✓ Branch 4 → 5 taken 11222 times.
11222 const QByteArray hash = QCryptographicHash::hash(uid.toUtf8(), QCryptographicHash::Sha1);
157 22444 return static_cast<unsigned char>(hash.at(0)) % 8;
158 11222 }
159
160 } // namespace ContactIndex
161