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: 95.2% 140 / 0 / 147
Functions: 100.0% 7 / 0 / 7
Branches: 77.0% 171 / 0 / 222

performance/PeopleShowcase.cpp
Line Branch Exec Source
1 #include "PeopleShowcase.h"
2
3 #include "ContactShowcase.h"
4 #include "data/ContactStore.h"
5 #include "data/VCardCodec.h"
6
7 #include <QTimeZone>
8 #include <QScopeGuard>
9 #include <QUuid>
10
11 namespace PeopleShowcase {
12
13 namespace {
14
15 struct Person {
16 const char *key;
17 const char *given;
18 const char *family;
19 const char *email;
20 const char *org;
21 const char *title;
22 const char *street;
23 const char *postal;
24 const char *city;
25 const char *country;
26 const char *birthday;
27 const char *gender;
28 int photo;
29 const char *anniversary = ""; // the wedding year on the graph's partner lines (Ana's parents: only on Teresa's card)
30 };
31
32 // ~30 cities on five continents; Munich only by postal code, "Japan" only a country, "Atlantis"/"Nowhere" unplaceable.
33 const Person kPeople[] = {
34 {"ana", "Ana", "Silva", "ana@example.org", "Example GmbH", "Product lead", "Rua da Rosa 12", "1200-385", "Lisboa",
35 "Portugal", "1988-04-12", "F", 16, "2014-06-21"},
36 {"rui", "Rui", "Costa", "rui.costa@example.pt", "", "", "Rua da Rosa 12", "1200-385", "Lisboa", "Portugal",
37 "1986-11-02", "M", 17, "2014-06-21"},
38 {"marta", "Marta", "Silva", "marta.silva@example.com", "", "", "Rua de Santa Catarina 80", "", "Porto", "Portugal",
39 "--06-14", "F", 18},
40 {"ines", "Inês", "Costa", "ines.costa@example.pt", "", "", "", "", "Coimbra", "Portugal", "", "F", 0},
41 {"pedro", "Pedro", "Costa", "pedro@example.pt", "", "", "", "", "Faro", "Portugal", "", "M", 0},
42 {"sofia", "Sofia", "Costa", "", "", "", "Rua da Rosa 12", "1200-385", "Lisboa", "Portugal", "2016-03-08", "F", 0},
43 // Ana's parents and grandmother: three generations for the family tree.
44 {"joao", "João", "Silva", "joao.silva@example.pt", "", "", "Rua de Cedofeita 41", "", "Porto", "Portugal",
45 "1957-05-30", "M", 0},
46 {"teresa", "Teresa", "Silva", "", "", "", "Rua de Cedofeita 41", "", "Porto", "Portugal", "1960-02-17", "F", 0, "1982-09-04"},
47 {"isabel", "Isabel", "Santos", "", "", "", "", "", "Braga", "Portugal", "1934-10-05", "F", 0},
48 {"ben", "Ben", "Weber", "ben.weber@example.net", "Nordlicht Studio", "Designer", "Kastanienallee 7", "10435", "Berlin",
49 "Deutschland", "1984-01-20", "M", 19},
50 {"clara", "Clara", "Weber", "clara.weber@example.net", "", "", "Kastanienallee 7", "10435", "Berlin", "Deutschland",
51 "", "F", 20},
52 {"mia", "Mia", "Weber", "", "", "", "Kastanienallee 7", "10435", "Berlin", "Deutschland", "2012-04-03", "F", 0},
53 {"rosa", "Rosa", "Klein", "", "", "", "", "20095", "Hamburg", "Deutschland", "--09-01", "F", 0},
54 {"lea", "Lea", "Klein", "lea.klein@example.de", "", "", "", "", "Hamburg", "Germany", "", "F", 21, "2019-05-11"},
55 {"jonas", "Jonas", "Klein", "jonas.klein@example.de", "", "", "", "80331", "", "Deutschland", "", "M", 0},
56 {"kai", "Kai", "Nowak", "kai.nowak@example.com", "", "", "ul. Floriańska 3", "", "Kraków", "Polska", "", "M", 22, "2019-05-11"},
57 {"julia", "Julia", "Nowak", "julia.nowak@example.pl", "", "", "", "", "Warszawa", "Poland", "", "F", 0},
58 {"tom", "Tom", "Becker", "tom.becker@example.com", "Example GmbH", "Head of product", "Friedrichstraße 100",
59 "10117", "Berlin", "Germany", "", "M", 23},
60 {"olga", "Olga", "Pires", "olga.pires@example.com", "Example GmbH", "Assistant", "", "", "Berlin", "Germany", "", "F",
61 0},
62 {"sam", "Sam", "Rivera", "sam@example.social", "Example GmbH", "Developer", "", "", "New York", "USA", "", "", 24},
63 {"inesf", "Ines", "Ferreira", "ines@example.org", "Example GmbH", "Designer", "", "", "São Paulo", "Brasil", "", "F",
64 0},
65 {"linh", "Linh", "Tran", "linh.tran@nordlicht.example", "Nordlicht Studio", "Art director", "", "24103", "Kiel",
66 "Deutschland", "", "F", 25},
67 {"akira", "Akira", "Tanaka", "akira@example.jp", "", "", "1-2-3 Shibuya", "150-0002", "Tokyo", "Japan", "", "M", 26},
68 {"chloe", "Chloé", "Martin", "chloe.martin@example.fr", "", "", "12 rue de Rivoli", "75001", "Paris", "France", "",
69 "F", 0},
70 {"omar", "Omar", "Haddad", "omar.haddad@example.ma", "", "", "", "", "Marrakech", "Morocco", "", "M", 0},
71 {"nina", "Nina", "Hoff", "nina.hoff@example.de", "", "", "", "", "Berlin", "Deutschland", "", "F", 0},
72 {"wanjiru", "Wanjiru", "Kamau", "wanjiru@example.ke", "", "", "", "", "Nairobi", "Kenya", "", "F", 0},
73 {"priya", "Priya", "Nair", "priya.nair@example.in", "", "", "", "", "Mumbai", "India", "", "F", 0},
74 {"liam", "Liam", "O'Connor", "liam@example.ie", "", "", "", "", "Toronto", "Canada", "", "M", 0},
75 {"lucia", "Lucía", "Fernández", "lucia@example.ar", "", "", "", "", "Buenos Aires", "Argentina", "", "F", 0},
76 {"thabo", "Thabo", "Nkosi", "thabo@example.za", "", "", "", "", "Cape Town", "South Africa", "", "M", 0},
77 {"minji", "Min-ji", "Park", "minji@example.kr", "", "", "", "", "Seoul", "South Korea", "", "F", 0},
78 {"diego", "Diego", "Ramírez", "diego@example.mx", "", "", "", "", "Ciudad de México", "México", "", "M", 0},
79 {"emma", "Emma", "Wilson", "emma.wilson@example.au", "", "", "", "", "Sydney", "Australia", "", "F", 0},
80 {"gudrun", "Guðrún", "Jónsdóttir", "gudrun@example.is", "", "", "", "", "Reykjavík", "Iceland", "", "F", 0},
81 {"felix", "Felix", "Gruber", "felix.gruber@example.at", "", "", "", "1010", "Wien", "Österreich", "", "M", 0},
82 {"anja", "Anja", "Meier", "anja.meier@example.ch", "", "", "", "8001", "Zürich", "Schweiz", "", "F", 0},
83 {"haruto", "Haruto", "Sato", "haruto@example.jp", "", "", "", "", "", "Japan", "", "M", 0},
84 {"zara", "Zara", "Quill", "zara@example.test", "", "", "", "", "Atlantis", "", "", "", 0},
85 {"noel", "Noel", "Vance", "noel@example.test", "", "", "", "", "", "", "", "", 0},
86 {"max", "Max", "Roth", "max.roth@example.de", "", "", "", "", "Leipzig", "Deutschland", "", "M", 0},
87 // F103-10: household entries that list their family members.
88 {"familia", "Família", "Silva Costa", "", "", "", "Rua da Rosa 12", "1200-385", "Lisboa", "Portugal", "", "", 0},
89 {"weberfamily", "Familie", "Weber", "", "", "", "Kastanienallee 7", "10435", "Berlin", "Deutschland", "", "", 0},
90 };
91
92 struct Relation {
93 const char *holder;
94 const char *type;
95 const char *target; // key, or "" with a text name
96 const char *text; // text-only person or custom label
97 };
98
99 // One side stored (D-5); the other card derives the inverse.
100 const Relation kRelations[] = {
101 {"ana", "spouse", "rui", ""}, {"ana", "sibling", "marta", ""}, {"sofia", "parent", "ana", ""},
102 {"sofia", "parent", "rui", ""}, {"rui", "parent", "ines", ""}, {"pedro", "sibling", "rui", ""},
103 {"sofia", "aunt-uncle", "pedro", ""}, {"ana", "parent-in-law", "ines", ""}, {"ben", "spouse", "clara", ""},
104 {"mia", "parent", "ben", ""}, {"mia", "parent", "clara", ""}, {"clara", "parent", "rosa", ""},
105 {"mia", "grandparent", "rosa", ""}, {"lea", "cousin", "jonas", ""}, {"lea", "spouse", "kai", ""},
106 {"julia", "sibling", "kai", ""}, {"lea", "ex-partner", "max", ""}, {"lea", "parent", "rosa", ""},
107 {"tom", "x-report", "ana", ""}, {"tom", "x-report", "sam", ""}, {"tom", "x-report", "inesf", ""},
108 {"tom", "agent", "olga", ""}, {"sam", "colleague", "inesf", ""}, {"linh", "colleague", "ben", ""},
109 {"nina", "friend", "akira", ""}, {"nina", "friend", "chloe", ""}, {"chloe", "friend", "omar", ""},
110 {"ben", "friend", "nina", ""}, {"ana", "friend", "chloe", ""}, {"marta", "sibling", "me", ""},
111 {"ben", "neighbor", "", "Herr Albrecht"}, {"mia", "custom", "", "Godparent: Lea Klein"},
112 {"wanjiru", "acquaintance", "me", ""}, {"ana", "emergency", "rui", ""},
113 {"ana", "parent", "joao", ""}, {"ana", "parent", "teresa", ""}, {"joao", "spouse", "teresa", ""},
114 {"teresa", "parent", "isabel", ""},
115 {"familia", "member", "ana", ""}, {"familia", "member", "rui", ""}, {"familia", "member", "sofia", ""},
116 {"weberfamily", "member", "ben", ""}, {"weberfamily", "member", "clara", ""}, {"weberfamily", "member", "mia", ""},
117 };
118
119 struct Met {
120 const char *key;
121 const char *date;
122 const char *place;
123 const char *via; // comma-separated keys
124 const char *event;
125 const char *note;
126 const char *channel;
127 };
128
129 // Introduction chain Marta → Ben → Ana → Kai.
130 const Met kMet[] = {
131 {"ben", "2010", "Porto", "marta", "", "Marta's birthday party", ""},
132 {"ana", "2019-08-21", "Chaos Communication Camp, Zehdenick", "ben", "cccamp-2019@example.org",
133 "Talked about mesh networks at the hackcenter", ""},
134 {"kai", "2021-05", "Lisboa", "ana", "", "", ""},
135 {"rui", "2015", "Lisboa", "", "", "", ""},
136 {"akira", "2018-11-02", "Tokyo", "nina", "", "Conference dinner", ""},
137 {"omar", "2026-09-03", "", "chloe", "", "", "mail"},
138 {"tom", "2017-03-01", "Berlin", "", "", "Job interview", ""},
139 };
140
141 struct Social {
142 const char *key;
143 const char *kind;
144 const char *service;
145 const char *value;
146 const char *user;
147 };
148
149 const Social kSocial[] = {
150 {"ana", "profile", "mastodon", "https://chaos.social/@ana", "@ana@chaos.social"},
151 {"ana", "chat", "matrix", "matrix:u/ana:matrix.org", ""},
152 {"sam", "profile", "bluesky", "https://bsky.app/profile/sam.bsky.social", "sam.bsky.social"},
153 {"sam", "profile", "github", "https://github.com/samrivera", "samrivera"},
154 {"tom", "profile", "linkedin", "https://www.linkedin.com/in/tom-becker", "tom-becker"},
155 {"tom", "chat", "sip", "sip:tom@voip.example.com", ""},
156 {"inesf", "profile", "xing", "https://www.xing.com/profile/Ines_Ferreira", "Ines_Ferreira"},
157 {"kai", "profile", "gitlab", "https://gitlab.com/kai.nowak", "kai.nowak"},
158 {"lea", "profile", "codeberg", "https://codeberg.org/lea", "lea"},
159 {"ben", "chat", "xmpp", "xmpp:ben@jabber.example", ""},
160 {"marta", "chat", "signal", "sgnl://signal.me/#p/+351912000000", ""},
161 {"omar", "chat", "telegram", "https://t.me/omarhaddad", ""},
162 {"clara", "chat", "threema", "https://threema.id/ABCD1234", ""},
163 {"chloe", "profile", "instagram", "https://instagram.com/chloe.martin", "@chloe.martin"},
164 };
165
166
1/1
✓ Branch 3 → 4 taken 32273 times.
32273 QString text(const char *value) { return QString::fromUtf8(value); }
167
168 387 ContactCard cardFor(const Person &p) {
169 387 ContactCard card;
170
2/2
✓ Branch 3 → 4 taken 387 times.
✓ Branch 4 → 5 taken 387 times.
387 card.uid = uidOf(text(p.key));
171
1/1
✓ Branch 8 → 9 taken 387 times.
387 card.name.given = text(p.given);
172
1/1
✓ Branch 11 → 12 taken 387 times.
387 card.name.family = text(p.family);
173
1/1
✓ Branch 14 → 15 taken 387 times.
387 card.organization = text(p.org);
174
1/1
✓ Branch 17 → 18 taken 387 times.
387 card.title = text(p.title);
175
2/2
✓ Branch 20 → 21 taken 324 times.
✓ Branch 20 → 42 taken 63 times.
387 if (*p.email) {
176 324 ContactValue email;
177
1/1
✓ Branch 21 → 22 taken 324 times.
324 email.value = text(p.email);
178
6/12
✓ Branch 33 → 34 taken 324 times.
✓ Branch 33 → 35 taken 324 times.
✓ Branch 35 → 36 taken 261 times.
✓ Branch 35 → 37 taken 63 times.
✓ Branch 37 → 38 taken 63 times.
✓ Branch 37 → 39 taken 261 times.
✗ Branch 100 → 101 not taken.
✗ Branch 100 → 102 not taken.
✗ Branch 103 → 104 not taken.
✗ Branch 103 → 105 not taken.
✗ Branch 107 → 108 not taken.
✗ Branch 107 → 109 not taken.
648 email.types = {*p.org ? QStringLiteral("work") : QStringLiteral("home")};
179
1/1
✓ Branch 39 → 40 taken 324 times.
324 card.emails << email;
180 324 }
181
6/6
✓ Branch 42 → 43 taken 27 times.
✓ Branch 42 → 45 taken 360 times.
✓ Branch 43 → 44 taken 18 times.
✓ Branch 43 → 45 taken 9 times.
✓ Branch 44 → 45 taken 9 times.
✓ Branch 44 → 68 taken 9 times.
387 if (*p.city || *p.postal || *p.country) {
182 378 ContactAddress address;
183
1/1
✓ Branch 45 → 46 taken 378 times.
378 address.street = text(p.street);
184
1/1
✓ Branch 48 → 49 taken 378 times.
378 address.postalCode = text(p.postal);
185
1/1
✓ Branch 51 → 52 taken 378 times.
378 address.locality = text(p.city);
186
1/1
✓ Branch 54 → 55 taken 378 times.
378 address.country = text(p.country);
187
2/4
✓ Branch 62 → 63 taken 378 times.
✓ Branch 62 → 64 taken 378 times.
✗ Branch 125 → 126 not taken.
✗ Branch 125 → 127 not taken.
756 address.types = {QStringLiteral("home")};
188
1/1
✓ Branch 65 → 66 taken 378 times.
378 card.addresses << address;
189 378 }
190
2/2
✓ Branch 68 → 69 taken 387 times.
✓ Branch 69 → 70 taken 387 times.
387 card.birthday = PartialDate::fromIso(text(p.birthday));
191
1/1
✓ Branch 71 → 72 taken 387 times.
387 card.gender = text(p.gender);
192
2/2
✓ Branch 74 → 75 taken 387 times.
✓ Branch 75 → 76 taken 387 times.
387 card.anniversary = PartialDate::fromIso(text(p.anniversary));
193
2/2
✓ Branch 77 → 78 taken 99 times.
✓ Branch 77 → 88 taken 288 times.
387 if (p.photo > 0) {
194 99 card.photo.kind = ContactPhoto::Kind::Inline;
195 99 card.photo.mimeType = QStringLiteral("image/jpeg");
196
1/1
✓ Branch 84 → 85 taken 99 times.
99 card.photo.data = ContactShowcase::photo(p.photo);
197 }
198 387 return card;
199 1404 }
200
201 387 void addDetails(const QString &key, ContactCard *card) {
202
2/2
✓ Branch 50 → 3 taken 17028 times.
✓ Branch 50 → 51 taken 387 times.
17415 for (const Relation &r : kRelations) {
203
3/3
✓ Branch 3 → 4 taken 17028 times.
✓ Branch 6 → 7 taken 16632 times.
✓ Branch 6 → 8 taken 396 times.
17028 if (text(r.holder) != key)
204 16632 continue;
205 396 ContactRelation relation;
206
1/1
✓ Branch 8 → 9 taken 396 times.
396 relation.type = text(r.type);
207
2/2
✓ Branch 11 → 12 taken 378 times.
✓ Branch 11 → 18 taken 18 times.
396 if (*r.target) {
208
2/2
✓ Branch 12 → 13 taken 378 times.
✓ Branch 13 → 14 taken 378 times.
378 relation.targetUid = uidOf(text(r.target));
209
2/2
✓ Branch 20 → 21 taken 9 times.
✓ Branch 20 → 42 taken 9 times.
18 } else if (relation.type == QLatin1String("custom")) {
210
1/1
✓ Branch 21 → 22 taken 9 times.
9 const QString value = text(r.text);
211
1/1
✓ Branch 26 → 27 taken 9 times.
9 relation.label = value.section(QStringLiteral(": "), 0, 0);
212
1/1
✓ Branch 35 → 36 taken 9 times.
9 relation.targetName = value.section(QStringLiteral(": "), 1);
213 9 } else {
214
1/1
✓ Branch 42 → 43 taken 9 times.
9 relation.targetName = text(r.text);
215 }
216
1/1
✓ Branch 46 → 47 taken 396 times.
396 card->relations << relation;
217 396 }
218
2/2
✓ Branch 91 → 52 taken 2709 times.
✓ Branch 91 → 92 taken 387 times.
3096 for (const Met &m : kMet) {
219
3/3
✓ Branch 52 → 53 taken 2709 times.
✓ Branch 55 → 56 taken 2646 times.
✓ Branch 55 → 57 taken 63 times.
2709 if (text(m.key) != key)
220 2646 continue;
221
2/2
✓ Branch 57 → 58 taken 63 times.
✓ Branch 58 → 59 taken 63 times.
63 card->met.date = LooseDate::fromIso(text(m.date));
222
1/1
✓ Branch 60 → 61 taken 63 times.
63 card->met.place = text(m.place);
223
1/1
✓ Branch 63 → 64 taken 63 times.
63 card->met.eventUid = text(m.event);
224
1/1
✓ Branch 66 → 67 taken 63 times.
63 card->met.note = text(m.note);
225
1/1
✓ Branch 69 → 70 taken 63 times.
63 card->met.channel = text(m.channel);
226
6/6
✓ Branch 72 → 73 taken 63 times.
✓ Branch 76 → 77 taken 63 times.
✓ Branch 78 → 79 taken 63 times.
✓ Branch 79 → 80 taken 63 times.
✓ Branch 87 → 81 taken 45 times.
✓ Branch 87 → 88 taken 63 times.
108 for (const QString &via : text(m.via).split(QLatin1Char(','), Qt::SkipEmptyParts))
227
2/6
✓ Branch 82 → 83 taken 45 times.
✓ Branch 83 → 84 taken 45 times.
✗ Branch 292 → 293 not taken.
✗ Branch 292 → 294 not taken.
✗ Branch 295 → 296 not taken.
✗ Branch 295 → 297 not taken.
108 card->met.via << ContactPersonRef{{}, uidOf(via), {}, -1};
228 }
229
2/2
✓ Branch 115 → 93 taken 5418 times.
✓ Branch 115 → 116 taken 387 times.
5805 for (const Social &s : kSocial) {
230
3/3
✓ Branch 93 → 94 taken 5418 times.
✓ Branch 96 → 97 taken 5292 times.
✓ Branch 96 → 98 taken 126 times.
5418 if (text(s.key) != key)
231 5292 continue;
232
1/1
✓ Branch 98 → 99 taken 126 times.
126 ContactSocial social;
233
1/1
✓ Branch 99 → 100 taken 126 times.
126 social.kind = text(s.kind);
234
1/1
✓ Branch 102 → 103 taken 126 times.
126 social.service = text(s.service);
235
1/1
✓ Branch 105 → 106 taken 126 times.
126 social.value = text(s.value);
236
1/1
✓ Branch 108 → 109 taken 126 times.
126 social.user = text(s.user);
237
1/1
✓ Branch 111 → 112 taken 126 times.
126 card->social << social;
238 126 }
239
2/2
✓ Branch 118 → 119 taken 9 times.
✓ Branch 118 → 188 taken 378 times.
387 if (key == QLatin1String("ana")) {
240
2/4
✓ Branch 130 → 131 taken 27 times.
✓ Branch 130 → 132 taken 9 times.
✗ Branch 311 → 312 not taken.
✗ Branch 311 → 313 not taken.
36 card->languages = {QStringLiteral("pt"), QStringLiteral("en"), QStringLiteral("de")};
241
2/4
✓ Branch 146 → 147 taken 27 times.
✓ Branch 146 → 148 taken 9 times.
✗ Branch 330 → 331 not taken.
✗ Branch 330 → 332 not taken.
36 card->interests = {QStringLiteral("climbing"), QStringLiteral("fado"), QStringLiteral("film photography")};
242
2/4
✓ Branch 156 → 157 taken 9 times.
✓ Branch 156 → 158 taken 9 times.
✗ Branch 349 → 350 not taken.
✗ Branch 349 → 351 not taken.
18 card->otherDates = {{QStringLiteral("Name day"), {0, 7, 26}, -1}};
243 9 card->birthplace = QStringLiteral("Porto");
244 9 ContactValue url;
245 9 url.value = QStringLiteral("https://anasilva.example");
246
1/1
✓ Branch 171 → 172 taken 9 times.
9 card->urls << url;
247
0/6
✗ Branch 366 → 367 not taken.
✗ Branch 366 → 368 not taken.
✗ Branch 372 → 373 not taken.
✗ Branch 372 → 374 not taken.
✗ Branch 378 → 379 not taken.
✗ Branch 378 → 380 not taken.
45 card->mailLinks << ContactMailLink{QStringLiteral("idea-1@example.org"), QStringLiteral("About Ana: project idea"),
248
1/1
✓ Branch 181 → 182 taken 9 times.
27 QStringLiteral("2026-09-02"), -1};
249
2/2
✓ Branch 190 → 191 taken 9 times.
✓ Branch 190 → 218 taken 369 times.
387 } else if (key == QLatin1String("akira")) {
250
2/4
✓ Branch 199 → 200 taken 18 times.
✓ Branch 199 → 201 taken 9 times.
✗ Branch 389 → 390 not taken.
✗ Branch 389 → 391 not taken.
27 card->languages = {QStringLiteral("ja"), QStringLiteral("en")};
251
2/4
✓ Branch 208 → 209 taken 9 times.
✓ Branch 208 → 210 taken 9 times.
✗ Branch 405 → 406 not taken.
✗ Branch 405 → 407 not taken.
18 card->interests = {QStringLiteral("climbing")};
252 9 card->birthplace = QStringLiteral("Osaka");
253
2/2
✓ Branch 220 → 221 taken 9 times.
✓ Branch 220 → 234 taken 360 times.
369 } else if (key == QLatin1String("nina")) {
254
2/4
✓ Branch 229 → 230 taken 18 times.
✓ Branch 229 → 231 taken 9 times.
✗ Branch 418 → 419 not taken.
✗ Branch 418 → 420 not taken.
27 card->interests = {QStringLiteral("climbing"), QStringLiteral("board games")};
255
2/2
✓ Branch 236 → 237 taken 9 times.
✓ Branch 236 → 246 taken 351 times.
360 } else if (key == QLatin1String("ben")) {
256
2/4
✓ Branch 242 → 243 taken 9 times.
✓ Branch 242 → 244 taken 9 times.
✗ Branch 434 → 435 not taken.
✗ Branch 434 → 436 not taken.
18 card->otherDates = {{QStringLiteral("Wedding"), {2011, 6, 18}, -1}};
257 }
258 567 }
259
260 } // namespace
261
262 8 QString nameOf(const QString &key) {
263
1/2
✓ Branch 19 → 3 taken 109 times.
✗ Branch 19 → 20 not taken.
109 for (const Person &p : kPeople)
264
3/3
✓ Branch 3 → 4 taken 109 times.
✓ Branch 6 → 7 taken 8 times.
✓ Branch 6 → 18 taken 101 times.
109 if (text(p.key) == key)
265
4/4
✓ Branch 7 → 8 taken 8 times.
✓ Branch 10 → 11 taken 8 times.
✓ Branch 11 → 12 taken 8 times.
✓ Branch 12 → 13 taken 8 times.
8 return text(p.given) + QLatin1Char(' ') + text(p.family);
266 ✗ return key == MeKey ? QStringLiteral("Jens Beispiel") : QString();
267 }
268
269 843 QString uidOf(const QString &key) {
270
3/4
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 14 taken 841 times.
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 14 not taken.
845 static const QUuid ns(QStringLiteral("{6f1c0e2a-1d3b-4c5e-8f70-a1b2c3d4e5f6}"));
271
2/2
✓ Branch 14 → 15 taken 843 times.
✓ Branch 15 → 16 taken 843 times.
843 return QUuid::createUuidV5(ns, key).toString(QUuid::WithoutBraces);
272 }
273
274 11 bool seed(ContactStore &store, QString *error) {
275
1/1
✓ Branch 2 → 3 taken 11 times.
11 const qint64 bookId = store.ensureBook(ContactShowcase::AccountCloud, BookPath);
276
3/3
✓ Branch 3 → 4 taken 10 times.
✓ Branch 3 → 5 taken 1 time.
✓ Branch 4 → 6 taken 10 times.
11 const auto existing = bookId > 0 ? store.book(bookId) : std::nullopt;
277 // S106-218: a degraded store reports an error instead of dereferencing
278 // a missing book, and every error return rolls the unit back.
279
6/7
✓ Branch 7 → 8 taken 10 times.
✓ Branch 7 → 10 taken 1 time.
✓ Branch 8 → 9 taken 10 times.
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 10 times.
✓ Branch 12 → 13 taken 1 time.
✓ Branch 12 → 22 taken 10 times.
11 if (!existing || !store.beginTransaction()) {
280
1/2
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 21 not taken.
1 if (error)
281 1 *error = QStringLiteral("Cannot prepare the people showcase book");
282 1 return false;
283 }
284 11 auto rollback = qScopeGuard([&store] { store.rollbackTransaction(); });
285 10 AddressBookInfo info = *existing;
286 10 info.displayName = QStringLiteral("Freundeskreis");
287 10 info.fetched = true;
288
4/4
✓ Branch 31 → 32 taken 10 times.
✓ Branch 32 → 33 taken 10 times.
✓ Branch 33 → 34 taken 10 times.
✓ Branch 34 → 35 taken 10 times.
10 info.lastSync = QDateTime(QDate(2026, 10, 4), QTime(9, 0), QTimeZone::utc());
289
1/1
✓ Branch 38 → 39 taken 10 times.
10 store.updateBook(info);
290 // The me card lives on this computer (D-6: "me" is per profile).
291
1/1
✓ Branch 39 → 40 taken 10 times.
10 ContactCard me;
292
1/1
✓ Branch 40 → 41 taken 10 times.
10 me.uid = uidOf(MeKey);
293 10 me.name.given = QStringLiteral("Jens");
294 10 me.name.family = QStringLiteral("Beispiel");
295 10 ContactValue meEmail;
296 10 meEmail.value = QStringLiteral("jens@example.test");
297
1/1
✓ Branch 61 → 62 taken 10 times.
10 me.emails << meEmail;
298 10 ContactAddress meHome;
299 10 meHome.locality = QStringLiteral("Berlin");
300 10 meHome.country = QStringLiteral("Deutschland");
301
1/1
✓ Branch 74 → 75 taken 10 times.
10 me.addresses << meHome;
302
3/3
✓ Branch 75 → 76 taken 10 times.
✓ Branch 76 → 77 taken 1 time.
✓ Branch 76 → 86 taken 9 times.
10 if (store.addLocalCard(me) <= 0) {
303
1/2
✓ Branch 77 → 78 taken 1 time.
✗ Branch 77 → 85 not taken.
1 if (error)
304 1 *error = QStringLiteral("Cannot store the me card");
305 1 return false;
306 }
307
2/2
✓ Branch 183 → 87 taken 387 times.
✓ Branch 183 → 184 taken 9 times.
396 for (const Person &person : kPeople) {
308
1/1
✓ Branch 87 → 88 taken 387 times.
387 ContactCard card = cardFor(person);
309
2/2
✓ Branch 88 → 89 taken 387 times.
✓ Branch 89 → 90 taken 387 times.
387 addDetails(text(person.key), &card);
310 387 StoredCard stored;
311 387 stored.bookId = bookId;
312 387 stored.uid = card.uid;
313
3/3
✓ Branch 98 → 99 taken 387 times.
✓ Branch 99 → 100 taken 387 times.
✓ Branch 100 → 101 taken 387 times.
774 stored.href = QStringLiteral("https://cloud.example") + BookPath + card.uid + QStringLiteral(".vcf");
314
2/2
✓ Branch 113 → 114 taken 387 times.
✓ Branch 114 → 115 taken 387 times.
774 stored.etag = QStringLiteral("\"%1\"").arg(card.uid.left(8));
315
5/5
✓ Branch 120 → 121 taken 387 times.
✓ Branch 121 → 122 taken 387 times.
✓ Branch 122 → 123 taken 387 times.
✓ Branch 123 → 124 taken 387 times.
✓ Branch 127 → 128 taken 387 times.
774 stored.raw = VCardCodec::create(card, QStringLiteral("3.0"), QDateTime(QDate(2026, 10, 4), QTime(9, 0), QTimeZone::utc()));
316
2/2
✓ Branch 135 → 136 taken 342 times.
✓ Branch 135 → 151 taken 45 times.
387 if (!card.gender.isEmpty())
317
2/2
✓ Branch 140 → 141 taken 342 times.
✓ Branch 144 → 145 taken 342 times.
1026 stored.raw.replace(QStringLiteral("END:VCARD"), QStringLiteral("X-GENDER:%1\r\nEND:VCARD").arg(card.gender));
318 387 stored.baseRaw = stored.raw;
319
4/7
✓ Branch 153 → 154 taken 387 times.
✗ Branch 153 → 156 not taken.
✓ Branch 154 → 155 taken 387 times.
✗ Branch 155 → 156 not taken.
✓ Branch 155 → 157 taken 387 times.
✗ Branch 158 → 159 not taken.
✓ Branch 158 → 173 taken 387 times.
387 if (stored.raw.isEmpty() || store.putCard(stored) <= 0) {
320 ✗ if (error)
321 ✗ *error = QStringLiteral("Cannot store people showcase card %1").arg(text(person.key));
322 ✗ return false;
323 }
324 387 }
325
2/3
✓ Branch 184 → 185 taken 9 times.
✗ Branch 185 → 186 not taken.
✓ Branch 185 → 195 taken 9 times.
9 if (!store.commitTransaction()) {
326 ✗ if (error)
327 ✗ *error = QStringLiteral("Cannot commit the people showcase");
328 ✗ return false;
329 }
330 9 rollback.dismiss();
331 9 return true;
332 11 }
333
334 } // namespace PeopleShowcase
335