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: 98.2% 220 / 0 / 224
Functions: 100.0% 32 / 0 / 32
Branches: 84.7% 549 / 0 / 648

presentation/TaskListLayout.cpp
Line Branch Exec Source
1 #include "TaskListLayout.h"
2 #include <QCollator>
3 #include <QPair>
4 #include <QCoreApplication>
5 #include <QLocale>
6 #include <QRegularExpression>
7 #include <algorithm>
8 #include <numeric>
9 #include <limits>
10
11 namespace TaskListLayout {
12 namespace {
13
7/9
✓ Branch 2 → 3 taken 491073 times.
✓ Branch 2 → 4 taken 3043 times.
✓ Branch 3 → 6 taken 491073 times.
✓ Branch 4 → 5 taken 3043 times.
✓ Branch 5 → 6 taken 3043 times.
✓ Branch 7 → 8 taken 3043 times.
✓ Branch 7 → 9 taken 491073 times.
✗ Branch 11 → 12 not taken.
✗ Branch 11 → 13 not taken.
988232 QDate dateOf(const CalendarTask &task) { return task.dueAllDay ? task.due.date() : task.due.toLocalTime().date(); }
14 99907 QDate weekEnd(const QDate &today, int first) { return today.addDays(6 - (today.dayOfWeek() - first + 7) % 7); }
15 99297 QString parentKey(const CalendarTask &task) {
16
3/3
✓ Branch 4 → 5 taken 99297 times.
✓ Branch 5 → 6 taken 99297 times.
✓ Branch 6 → 7 taken 99297 times.
99297 return calendarSelectionKey(task.accountId, task.calendarPath) + QLatin1Char('\n') + task.parentUid;
17 }
18 198126 int dueGroup(const CalendarTask &task, const QDate &today, int first) {
19
2/2
✓ Branch 4 → 5 taken 77 times.
✓ Branch 4 → 6 taken 198049 times.
198126 if (task.status == QLatin1String("COMPLETED")) return 8;
20
1/2
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 10 taken 198049 times.
198049 if (task.status == QLatin1String("CANCELLED")) return 9;
21
3/3
✓ Branch 10 → 11 taken 198049 times.
✓ Branch 11 → 12 taken 1043 times.
✓ Branch 11 → 13 taken 197006 times.
198049 if (!task.due.isValid()) return 7;
22
1/1
✓ Branch 13 → 14 taken 197006 times.
197006 const auto due = dateOf(task);
23
2/2
✓ Branch 16 → 17 taken 195405 times.
✓ Branch 16 → 18 taken 1601 times.
197006 if (due < today) return 0;
24
2/2
✓ Branch 19 → 20 taken 350 times.
✓ Branch 19 → 21 taken 1251 times.
1601 if (due == today) return 1;
25
3/3
✓ Branch 21 → 22 taken 1251 times.
✓ Branch 23 → 24 taken 352 times.
✓ Branch 23 → 25 taken 899 times.
1251 if (due == today.addDays(1)) return 2;
26
3/3
✓ Branch 25 → 26 taken 899 times.
✓ Branch 28 → 29 taken 338 times.
✓ Branch 28 → 30 taken 561 times.
899 if (due <= weekEnd(today, first)) return 3;
27
4/4
✓ Branch 30 → 31 taken 561 times.
✓ Branch 31 → 32 taken 561 times.
✓ Branch 34 → 35 taken 102 times.
✓ Branch 34 → 36 taken 459 times.
561 if (due <= weekEnd(today, first).addDays(7)) return 4;
28 459 return 5;
29 }
30 }
31
9/10
✓ Branch 2 → 3 taken 7600 times.
✓ Branch 2 → 4 taken 102616 times.
✓ Branch 3 → 4 taken 5964 times.
✓ Branch 3 → 12 taken 1636 times.
✓ Branch 4 → 5 taken 103573 times.
✓ Branch 4 → 10 taken 5007 times.
✓ Branch 5 → 6 taken 957 times.
✓ Branch 5 → 8 taken 102616 times.
✓ Branch 6 → 7 taken 957 times.
✗ Branch 6 → 8 not taken.
110216 int priorityLevel(int priority) { return priority >= 1 && priority <= 4 ? 1 : priority == 5 ? 2 : priority >= 6 && priority <= 9 ? 3 : 0; }
32
3/4
✓ Branch 4 → 5 taken 310280 times.
✓ Branch 4 → 9 taken 74137 times.
✓ Branch 7 → 8 taken 310280 times.
✗ Branch 7 → 9 not taken.
384417 bool open(const CalendarTask &task) { return task.status != QLatin1String("COMPLETED") && task.status != QLatin1String("CANCELLED"); }
33 381 bool startsLater(const CalendarTask &task, const QDate &today) {
34
6/6
✓ Branch 3 → 4 taken 363 times.
✓ Branch 3 → 6 taken 18 times.
✓ Branch 5 → 6 taken 361 times.
✓ Branch 5 → 7 taken 2 times.
✓ Branch 8 → 9 taken 379 times.
✓ Branch 8 → 10 taken 2 times.
381 if (!open(task) || !task.dtStart.isValid()) return false;
35
3/9
✓ Branch 10 → 11 taken 2 times.
✗ Branch 10 → 12 not taken.
✓ Branch 11 → 14 taken 2 times.
✗ Branch 12 → 13 not taken.
✗ Branch 13 → 14 not taken.
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 2 times.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 22 not taken.
2 return (task.startAllDay ? task.dtStart.date() : task.dtStart.toLocalTime().date()) > today;
36 }
37 619757 bool matchesView(const CalendarTask &task, const QString &view, const QDate &today, int first) {
38
2/2
✓ Branch 4 → 5 taken 2 times.
✓ Branch 4 → 7 taken 619755 times.
619757 if (view == QLatin1String("completed")) return !open(task);
39
2/2
✓ Branch 9 → 10 taken 100678 times.
✓ Branch 9 → 30 taken 519077 times.
619755 if (view == QLatin1String("today"))
40
15/20
✓ Branch 10 → 11 taken 100678 times.
✓ Branch 11 → 12 taken 99525 times.
✓ Branch 11 → 16 taken 1153 times.
✓ Branch 12 → 13 taken 99525 times.
✓ Branch 15 → 16 taken 1328 times.
✓ Branch 15 → 24 taken 98197 times.
✓ Branch 16 → 17 taken 2481 times.
✓ Branch 17 → 18 taken 12 times.
✓ Branch 17 → 25 taken 2469 times.
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 12 times.
✗ Branch 19 → 22 not taken.
✓ Branch 20 → 21 taken 12 times.
✓ Branch 21 → 22 taken 12 times.
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 12 times.
✓ Branch 27 → 28 taken 12 times.
✓ Branch 27 → 29 taken 100666 times.
✗ Branch 73 → 74 not taken.
✗ Branch 73 → 75 not taken.
100678 return (task.due.isValid() && dateOf(task) <= today) || (task.dtStart.isValid() && (task.startAllDay ? task.dtStart.date() : task.dtStart.toLocalTime().date()) == today);
41
9/9
✓ Branch 32 → 33 taken 98836 times.
✓ Branch 32 → 44 taken 420241 times.
✓ Branch 33 → 34 taken 98836 times.
✓ Branch 34 → 35 taken 98447 times.
✓ Branch 34 → 41 taken 389 times.
✓ Branch 35 → 36 taken 98447 times.
✓ Branch 36 → 37 taken 98447 times.
✓ Branch 39 → 40 taken 98178 times.
✓ Branch 39 → 41 taken 269 times.
519077 if (view == QLatin1String("week")) return task.due.isValid() && dateOf(task) <= weekEnd(today, first);
42
6/6
✓ Branch 46 → 47 taken 98838 times.
✓ Branch 46 → 54 taken 321403 times.
✓ Branch 48 → 49 taken 393 times.
✓ Branch 48 → 51 taken 98445 times.
✓ Branch 50 → 51 taken 2 times.
✓ Branch 50 → 52 taken 391 times.
420241 if (view == QLatin1String("planned")) return task.due.isValid() || task.dtStart.isValid();
43
5/5
✓ Branch 55 → 56 taken 321403 times.
✓ Branch 56 → 57 taken 99133 times.
✓ Branch 56 → 63 taken 222270 times.
✓ Branch 57 → 58 taken 99133 times.
✓ Branch 58 → 59 taken 99133 times.
321403 if (view.startsWith(QLatin1String("list:"))) return calendarSelectionKey(task.accountId, task.calendarPath) == view.mid(5);
44
4/4
✓ Branch 64 → 65 taken 222270 times.
✓ Branch 65 → 66 taken 8 times.
✓ Branch 65 → 70 taken 222262 times.
✓ Branch 66 → 67 taken 8 times.
222270 if (view.startsWith(QLatin1String("tag:"))) return task.tags.contains(view.mid(4));
45 222262 return true;
46 }
47 99148 QString groupFor(const CalendarTask &task, const QString &grouping, const QDate &today, int first) {
48
3/3
✓ Branch 4 → 5 taken 59 times.
✓ Branch 4 → 7 taken 99089 times.
✓ Branch 5 → 6 taken 59 times.
99148 if (task.status == QLatin1String("COMPLETED")) return QCoreApplication::translate("TaskListLayout", "Completed");
49
1/3
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 12 taken 99089 times.
✗ Branch 10 → 11 not taken.
99089 if (task.status == QLatin1String("CANCELLED")) return QCoreApplication::translate("TaskListLayout", "Cancelled");
50
2/2
✓ Branch 14 → 15 taken 166 times.
✓ Branch 14 → 16 taken 98923 times.
99089 if (grouping == QLatin1String("none")) return {};
51
2/2
✓ Branch 18 → 19 taken 6 times.
✓ Branch 18 → 20 taken 98917 times.
98923 if (grouping == QLatin1String("list")) return task.calendarDisplayName;
52
2/2
✓ Branch 22 → 23 taken 6 times.
✓ Branch 22 → 36 taken 98911 times.
98917 if (grouping == QLatin1String("priority")) {
53
2/4
✓ Branch 29 → 30 taken 24 times.
✓ Branch 29 → 31 taken 6 times.
✗ Branch 57 → 58 not taken.
✗ Branch 57 → 59 not taken.
30 const QStringList names{QCoreApplication::translate("TaskListLayout", "No priority"), QCoreApplication::translate("TaskListLayout", "High"), QCoreApplication::translate("TaskListLayout", "Normal"), QCoreApplication::translate("TaskListLayout", "Low")}; return names[priorityLevel(task.priority)];
54 6 }
55
2/4
✓ Branch 48 → 49 taken 989110 times.
✓ Branch 48 → 50 taken 98911 times.
✗ Branch 68 → 69 not taken.
✗ Branch 68 → 70 not taken.
1088021 const QStringList names{QCoreApplication::translate("TaskListLayout", "Overdue"), QCoreApplication::translate("TaskListLayout", "Today"), QCoreApplication::translate("TaskListLayout", "Tomorrow"), QCoreApplication::translate("TaskListLayout", "This week"), QCoreApplication::translate("TaskListLayout", "Next week"), QCoreApplication::translate("TaskListLayout", "Later"), QCoreApplication::translate("TaskListLayout", "Later"), QCoreApplication::translate("TaskListLayout", "No date"), QCoreApplication::translate("TaskListLayout", "Completed"), QCoreApplication::translate("TaskListLayout", "Cancelled")};
56
1/1
✓ Branch 50 → 51 taken 98911 times.
98911 return names[dueGroup(task, today, first)];
57 197828 }
58 319 QString monthDayPattern(const QLocale &locale, bool withYear) {
59 // Derive "d MMM" / "MMM d" from the locale's long date, so no pattern is
60 // hard-coded (G8): drop the weekday, shorten the month, drop the year.
61
1/1
✓ Branch 2 → 3 taken 319 times.
319 QString pattern = locale.dateFormat(QLocale::LongFormat);
62
2/2
✓ Branch 7 → 8 taken 319 times.
✓ Branch 8 → 9 taken 319 times.
319 pattern.remove(QRegularExpression(QStringLiteral("d{3,4}[,.]?\\s*")));
63
1/1
✓ Branch 18 → 19 taken 319 times.
638 pattern.replace(QStringLiteral("MMMM"), QStringLiteral("MMM"));
64
4/4
✓ Branch 23 → 24 taken 317 times.
✓ Branch 23 → 34 taken 2 times.
✓ Branch 28 → 29 taken 317 times.
✓ Branch 29 → 30 taken 317 times.
636 if (!withYear) pattern.remove(QRegularExpression(QStringLiteral("[,.]?\\s*y+\\.?")));
65
1/1
✓ Branch 34 → 35 taken 319 times.
638 return pattern.trimmed();
66 319 }
67 852 QString dueText(const CalendarTask &task, const QDate &today, bool insideDueGroup) {
68
3/3
✓ Branch 2 → 3 taken 852 times.
✓ Branch 3 → 4 taken 159 times.
✓ Branch 3 → 5 taken 693 times.
852 if (!task.due.isValid()) return {};
69
1/1
✓ Branch 5 → 6 taken 693 times.
693 const QLocale locale;
70
1/1
✓ Branch 6 → 7 taken 693 times.
693 const QDate due = dateOf(task);
71
7/9
✓ Branch 7 → 8 taken 330 times.
✓ Branch 7 → 9 taken 363 times.
✓ Branch 9 → 10 taken 363 times.
✓ Branch 10 → 11 taken 363 times.
✓ Branch 11 → 12 taken 363 times.
✓ Branch 12 → 13 taken 363 times.
✓ Branch 12 → 14 taken 330 times.
✗ Branch 85 → 86 not taken.
✗ Branch 85 → 87 not taken.
693 const QString time = task.dueAllDay ? QString() : locale.toString(task.due.toLocalTime().time(), QLocale::ShortFormat);
72 // Groups "Today" and "Tomorrow" already name the day; the cell adds only the time.
73
11/11
✓ Branch 14 → 15 taken 260 times.
✓ Branch 14 → 23 taken 433 times.
✓ Branch 16 → 17 taken 246 times.
✓ Branch 16 → 23 taken 14 times.
✓ Branch 18 → 19 taken 205 times.
✓ Branch 18 → 22 taken 41 times.
✓ Branch 19 → 20 taken 205 times.
✓ Branch 21 → 22 taken 35 times.
✓ Branch 21 → 23 taken 170 times.
✓ Branch 24 → 25 taken 76 times.
✓ Branch 24 → 26 taken 617 times.
693 if (insideDueGroup && open(task) && (due == today || due == today.addDays(1))) return time;
74 617 QString day;
75
1/1
✓ Branch 26 → 27 taken 617 times.
617 const qint64 distance = today.daysTo(due);
76
3/3
✓ Branch 27 → 28 taken 249 times.
✓ Branch 27 → 32 taken 368 times.
✓ Branch 28 → 29 taken 249 times.
617 if (distance == 0) day = QCoreApplication::translate("TaskListLayout", "Today");
77
3/3
✓ Branch 32 → 33 taken 7 times.
✓ Branch 32 → 37 taken 361 times.
✓ Branch 33 → 34 taken 7 times.
368 else if (distance == 1) day = QCoreApplication::translate("TaskListLayout", "Tomorrow");
78
3/3
✓ Branch 37 → 38 taken 42 times.
✓ Branch 37 → 42 taken 319 times.
✓ Branch 38 → 39 taken 42 times.
361 else if (distance == -1) day = QCoreApplication::translate("TaskListLayout", "Yesterday");
79
2/2
✓ Branch 43 → 44 taken 178 times.
✓ Branch 43 → 62 taken 141 times.
319 else if (qAbs(distance) <= 6)
80
6/6
✓ Branch 44 → 45 taken 178 times.
✓ Branch 45 → 46 taken 178 times.
✓ Branch 49 → 50 taken 178 times.
✓ Branch 50 → 51 taken 178 times.
✓ Branch 51 → 52 taken 178 times.
✓ Branch 52 → 53 taken 178 times.
356 day = locale.dayName(due.dayOfWeek(), QLocale::ShortFormat) + QStringLiteral(", ") + locale.toString(due, monthDayPattern(locale, false));
81
4/4
✓ Branch 62 → 63 taken 141 times.
✓ Branch 63 → 64 taken 141 times.
✓ Branch 64 → 65 taken 141 times.
✓ Branch 65 → 66 taken 141 times.
141 else day = locale.toString(due, monthDayPattern(locale, due.year() != today.year()));
82
6/8
✓ Branch 71 → 72 taken 284 times.
✓ Branch 71 → 73 taken 333 times.
✓ Branch 75 → 76 taken 333 times.
✓ Branch 76 → 77 taken 333 times.
✓ Branch 78 → 79 taken 333 times.
✓ Branch 78 → 80 taken 284 times.
✗ Branch 116 → 117 not taken.
✗ Branch 116 → 118 not taken.
617 return time.isEmpty() ? day : day + QLatin1Char(' ') + time;
83 693 }
84 124102 bool matchesFilter(const CalendarTask &task, const QString &filter) {
85
7/7
✓ Branch 4 → 5 taken 124102 times.
✓ Branch 7 → 8 taken 124102 times.
✓ Branch 8 → 9 taken 124102 times.
✓ Branch 9 → 10 taken 124102 times.
✓ Branch 10 → 11 taken 124102 times.
✓ Branch 11 → 12 taken 124102 times.
✓ Branch 12 → 13 taken 124102 times.
124102 const QString text = task.summary + '\n' + task.description + '\n' + task.tags.join(' ') + '\n' + task.calendarDisplayName;
86
5/5
✓ Branch 21 → 22 taken 124102 times.
✓ Branch 22 → 23 taken 124102 times.
✓ Branch 23 → 24 taken 124102 times.
✓ Branch 73 → 25 taken 33 times.
✓ Branch 73 → 74 taken 124076 times.
124109 for (const auto &word : filter.split(' ', Qt::SkipEmptyParts))
87
1/5
✗ Branch 27 → 28 not taken.
✓ Branch 27 → 32 taken 33 times.
✗ Branch 28 → 29 not taken.
✗ Branch 29 → 30 not taken.
✗ Branch 29 → 31 not taken.
33 if (word == "has:due") { if (!task.due.isValid()) return false; continue; }
88
1/4
✗ Branch 33 → 34 not taken.
✓ Branch 33 → 38 taken 33 times.
✗ Branch 35 → 36 not taken.
✗ Branch 35 → 37 not taken.
33 else if (word == "has:mail") { if (task.relatedMessageId.isEmpty()) return false; continue; }
89
7/8
✓ Branch 38 → 39 taken 33 times.
✓ Branch 39 → 40 taken 33 times.
✓ Branch 41 → 42 taken 4 times.
✓ Branch 41 → 49 taken 29 times.
✓ Branch 43 → 44 taken 4 times.
✓ Branch 44 → 45 taken 4 times.
✓ Branch 46 → 47 taken 4 times.
✗ Branch 46 → 48 not taken.
33 else if (word.startsWith("priority:")) { if (priorityLevel(task.priority) != word.mid(9).toInt()) return false; continue; }
90
6/7
✓ Branch 50 → 51 taken 29 times.
✓ Branch 51 → 52 taken 3 times.
✓ Branch 51 → 55 taken 26 times.
✓ Branch 53 → 54 taken 3 times.
✗ Branch 53 → 55 not taken.
✓ Branch 56 → 57 taken 3 times.
✓ Branch 56 → 68 taken 26 times.
29 else if (word.startsWith('#') && word.size() > 1) {
91 // S94.5.4: "#tag" matches a tag exactly (case-insensitive).
92
1/1
✓ Branch 57 → 58 taken 3 times.
3 const QString tag = word.mid(1);
93
3/3
✓ Branch 60 → 61 taken 3 times.
✓ Branch 61 → 62 taken 1 time.
✓ Branch 61 → 63 taken 2 times.
3 if (std::none_of(task.tags.begin(), task.tags.end(), [&tag](const QString &candidate) {
94 3 return candidate.compare(tag, Qt::CaseInsensitive) == 0;
95 1 })) return false;
96 2 continue;
97 3 }
98
5/5
✓ Branch 68 → 69 taken 26 times.
✓ Branch 69 → 70 taken 21 times.
✓ Branch 69 → 71 taken 5 times.
✓ Branch 76 → 77 taken 124076 times.
✓ Branch 76 → 79 taken 26 times.
124107 else if (!text.contains(word, Qt::CaseInsensitive)) return false;
99 124076 return true;
100 124102 }
101 namespace {
102 49019 bool completedToday(const CalendarTask &task, const QDate &today) {
103
8/10
✓ Branch 4 → 5 taken 48978 times.
✓ Branch 4 → 10 taken 41 times.
✓ Branch 5 → 6 taken 48978 times.
✓ Branch 6 → 7 taken 48978 times.
✓ Branch 8 → 9 taken 133 times.
✓ Branch 8 → 10 taken 48845 times.
✓ Branch 12 → 13 taken 48978 times.
✓ Branch 12 → 14 taken 41 times.
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
49019 return task.status == QLatin1String("COMPLETED") && task.completedAt.toLocalTime().date() == today;
104 }
105 // Membership ignoring the "show completed" switch. Today's completions stay
106 // in "Today" even when their due date moved on; every other view (list, tag,
107 // week) keeps its own filter for them (F94-47).
108 123718 bool belongs(const CalendarTask &task, const Options &options, const QDate &today) {
109
1/1
✓ Branch 2 → 3 taken 123718 times.
123718 const bool grace = options.graceKeys.contains(taskSelectionKey(task));
110
5/5
✓ Branch 7 → 8 taken 50 times.
✓ Branch 7 → 11 taken 123668 times.
✓ Branch 8 → 9 taken 50 times.
✓ Branch 9 → 10 taken 9 times.
✓ Branch 9 → 11 taken 41 times.
123718 const bool keptToday = options.view == QLatin1String("today") && completedToday(task, today);
111
8/8
✓ Branch 12 → 13 taken 123699 times.
✓ Branch 12 → 17 taken 19 times.
✓ Branch 13 → 14 taken 123691 times.
✓ Branch 13 → 17 taken 8 times.
✓ Branch 15 → 16 taken 61 times.
✓ Branch 15 → 17 taken 123630 times.
✓ Branch 18 → 19 taken 61 times.
✓ Branch 18 → 20 taken 123657 times.
123718 if (!grace && !keptToday && !matchesView(task, options.view, today, options.weekStart)) return false;
112
2/2
✓ Branch 21 → 22 taken 21 times.
✓ Branch 21 → 23 taken 123636 times.
123657 if (!matchesFilter(task, options.filter)) return false;
113
7/7
✓ Branch 23 → 24 taken 4 times.
✓ Branch 23 → 29 taken 123632 times.
✓ Branch 26 → 27 taken 2 times.
✓ Branch 26 → 29 taken 2 times.
✓ Branch 27 → 28 taken 2 times.
✓ Branch 28 → 29 taken 1 time.
✓ Branch 28 → 30 taken 1 time.
123636 return !(options.hideFutureStarts && options.view != QLatin1String("planned") && startsLater(task, today));
114 }
115 // Completed tasks outside the Completed view show only when completed today,
116 // just toggled (grace) or with "show completed" on.
117 247393 bool completedShown(const CalendarTask &task, const Options &options, const QDate &today) {
118
6/6
✓ Branch 4 → 5 taken 48977 times.
✓ Branch 4 → 13 taken 22 times.
✓ Branch 7 → 8 taken 48975 times.
✓ Branch 7 → 13 taken 2 times.
✓ Branch 10 → 11 taken 48969 times.
✓ Branch 10 → 13 taken 6 times.
97974 return open(task) || options.includeCompleted || options.view == QLatin1String("completed") ||
119
8/10
✓ Branch 3 → 4 taken 48999 times.
✓ Branch 3 → 13 taken 198394 times.
✓ Branch 8 → 9 taken 48975 times.
✓ Branch 11 → 12 taken 48969 times.
✓ Branch 12 → 13 taken 124 times.
✓ Branch 12 → 14 taken 48845 times.
✓ Branch 16 → 17 taken 48975 times.
✓ Branch 16 → 18 taken 198418 times.
✗ Branch 20 → 21 not taken.
✗ Branch 20 → 22 not taken.
345367 options.graceKeys.contains(taskSelectionKey(task)) || completedToday(task, today);
120 }
121 }
122 1670 int hiddenCompleted(const QList<CalendarTask> &tasks, const Options &options, const QDate &today) {
123 1670 return int(std::count_if(tasks.begin(), tasks.end(), [&](const CalendarTask &task) {
124
4/4
✓ Branch 3 → 4 taken 24422 times.
✓ Branch 3 → 7 taken 99252 times.
✓ Branch 5 → 6 taken 24420 times.
✓ Branch 5 → 7 taken 2 times.
123674 return !completedShown(task, options, today) && belongs(task, options, today);
125 1670 }));
126 }
127 1681 QList<Row> project(QList<CalendarTask> tasks, const Options &options, const QDate &today) {
128
5/5
✓ Branch 2 → 3 taken 1681 times.
✓ Branch 4 → 5 taken 1681 times.
✓ Branch 5 → 6 taken 1681 times.
✓ Branch 6 → 7 taken 1681 times.
✓ Branch 8 → 9 taken 1681 times.
1681 tasks.erase(std::remove_if(tasks.begin(), tasks.end(), [&](const auto &task) {
129
4/4
✓ Branch 3 → 4 taken 99296 times.
✓ Branch 3 → 6 taken 24423 times.
✓ Branch 5 → 6 taken 81 times.
✓ Branch 5 → 7 taken 99215 times.
123719 return !completedShown(task, options, today) || !belongs(task, options, today);
130 }), tasks.end());
131 198351 const auto visualTask = [&options](CalendarTask task) {
132
6/6
✓ Branch 2 → 3 taken 198351 times.
✓ Branch 5 → 6 taken 36 times.
✓ Branch 5 → 13 taken 198315 times.
✓ Branch 7 → 8 taken 26 times.
✓ Branch 7 → 9 taken 10 times.
✓ Branch 8 → 10 taken 26 times.
198351 if (options.graceKeys.contains(taskSelectionKey(task))) task.status = task.previousStatus.isEmpty() ? QString("NEEDS-ACTION") : task.previousStatus;
133 198351 return task;
134 1681 };
135 // Sort keys are computed once per task (G9): the comparator previously
136 // copied both tasks and re-derived their groups on every comparison.
137 struct SortKey { int dueGroup = 0; int state = 0; QString group; int priority = 0; };
138
1/1
✓ Branch 10 → 11 taken 1681 times.
1681 QList<SortKey> keys(tasks.size());
139
2/2
✓ Branch 52 → 12 taken 99215 times.
✓ Branch 52 → 53 taken 1681 times.
100896 for (int i = 0; i < tasks.size(); ++i) {
140
2/2
✓ Branch 12 → 13 taken 99215 times.
✓ Branch 14 → 15 taken 99215 times.
99215 const CalendarTask visual = visualTask(tasks[i]);
141
2/2
✓ Branch 16 → 17 taken 99215 times.
✓ Branch 17 → 18 taken 99215 times.
99215 keys[i].dueGroup = dueGroup(visual, today, options.weekStart);
142 // Completed and cancelled tasks form one trailing section in every
143 // grouping (F94-26: "Completed" appeared between open rows).
144
4/5
✓ Branch 20 → 21 taken 77 times.
✓ Branch 20 → 22 taken 99138 times.
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 99138 times.
✓ Branch 28 → 29 taken 99215 times.
99215 keys[i].state = visual.status == QLatin1String("COMPLETED") ? 1 : visual.status == QLatin1String("CANCELLED") ? 2 : 0;
145
6/6
✓ Branch 31 → 32 taken 195 times.
✓ Branch 31 → 36 taken 99020 times.
✓ Branch 34 → 35 taken 12 times.
✓ Branch 34 → 36 taken 183 times.
✓ Branch 37 → 38 taken 12 times.
✓ Branch 37 → 43 taken 99203 times.
99215 if (options.grouping != QLatin1String("due") && options.grouping != QLatin1String("none"))
146
2/2
✓ Branch 38 → 39 taken 12 times.
✓ Branch 39 → 40 taken 12 times.
12 keys[i].group = groupFor(visual, options.grouping, today, options.weekStart);
147
1/1
✓ Branch 43 → 44 taken 99215 times.
99215 const int level = priorityLevel(tasks[i].priority);
148
3/3
✓ Branch 45 → 46 taken 661 times.
✓ Branch 45 → 47 taken 98554 times.
✓ Branch 48 → 49 taken 99215 times.
99215 keys[i].priority = level == 0 ? 4 : level;
149 99215 }
150 // Collation keys once per title instead of a locale-aware comparison per pair.
151
1/1
✓ Branch 53 → 54 taken 1681 times.
1681 const QCollator collator;
152 1681 QList<QCollatorSortKey> titles;
153
1/1
✓ Branch 55 → 56 taken 1681 times.
1681 titles.reserve(tasks.size());
154
6/6
✓ Branch 56 → 57 taken 1681 times.
✓ Branch 57 → 58 taken 1681 times.
✓ Branch 60 → 61 taken 99215 times.
✓ Branch 61 → 62 taken 99215 times.
✓ Branch 65 → 59 taken 99215 times.
✓ Branch 65 → 66 taken 1681 times.
100896 for (const auto &task : tasks) titles.append(collator.sortKey(task.summary));
155
1/1
✓ Branch 67 → 68 taken 1681 times.
1681 QList<int> order(tasks.size());
156
3/3
✓ Branch 68 → 69 taken 1681 times.
✓ Branch 69 → 70 taken 1681 times.
✓ Branch 70 → 71 taken 1681 times.
1681 std::iota(order.begin(), order.end(), 0);
157
3/3
✓ Branch 71 → 72 taken 1681 times.
✓ Branch 72 → 73 taken 1681 times.
✓ Branch 73 → 74 taken 1681 times.
1681 std::stable_sort(order.begin(), order.end(), [&](int left, int right) {
158 1055084 const auto &a = tasks[left], &b = tasks[right];
159 1055084 const auto &ka = keys[left], &kb = keys[right];
160
2/2
✓ Branch 8 → 9 taken 1054475 times.
✓ Branch 8 → 11 taken 609 times.
1055084 if (options.grouping == QLatin1String("due")) {
161
2/2
✓ Branch 9 → 10 taken 1400 times.
✓ Branch 9 → 20 taken 1053075 times.
1054475 if (ka.dueGroup != kb.dueGroup) return ka.dueGroup < kb.dueGroup;
162
2/2
✓ Branch 11 → 12 taken 58 times.
✓ Branch 11 → 13 taken 551 times.
609 } else if (ka.state != kb.state) {
163 58 return ka.state < kb.state;
164
2/2
✓ Branch 15 → 16 taken 13 times.
✓ Branch 15 → 20 taken 538 times.
551 } else if (options.grouping != QLatin1String("none")) {
165
2/2
✓ Branch 17 → 18 taken 4 times.
✓ Branch 17 → 20 taken 9 times.
13 if (ka.group != kb.group) return ka.group.localeAwareCompare(kb.group) < 0;
166 }
167
5/6
✓ Branch 22 → 23 taken 264 times.
✓ Branch 22 → 25 taken 1053358 times.
✓ Branch 23 → 24 taken 264 times.
✗ Branch 23 → 25 not taken.
✓ Branch 26 → 27 taken 264 times.
✓ Branch 26 → 28 taken 1053358 times.
1053622 if (options.sort == QLatin1String("manual") && a.sortOrder != b.sortOrder) return a.sortOrder < b.sortOrder;
168
2/7
✗ Branch 30 → 31 not taken.
✓ Branch 30 → 34 taken 1053358 times.
✗ Branch 31 → 32 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 34 not taken.
✗ Branch 35 → 36 not taken.
✓ Branch 35 → 38 taken 1053358 times.
1053358 if (options.sort == QLatin1String("created") && a.created != b.created) return a.created > b.created;
169
1/2
✗ Branch 40 → 41 not taken.
✓ Branch 40 → 50 taken 1053358 times.
1053358 if (options.sort == QLatin1String("due")) {
170 ✗ if (a.due.isValid() != b.due.isValid()) return a.due.isValid();
171 ✗ if (a.due != b.due) return a.due < b.due;
172 }
173
5/6
✓ Branch 52 → 53 taken 1053358 times.
✗ Branch 52 → 55 not taken.
✓ Branch 53 → 54 taken 429 times.
✓ Branch 53 → 55 taken 1052929 times.
✓ Branch 56 → 57 taken 429 times.
✓ Branch 56 → 58 taken 1052929 times.
1053358 if (options.sort == QLatin1String("priority") && ka.priority != kb.priority) return ka.priority < kb.priority;
174 1052929 const int title = titles[left].compare(titles[right]);
175
8/12
✓ Branch 61 → 62 taken 1052927 times.
✓ Branch 61 → 63 taken 2 times.
✓ Branch 63 → 64 taken 2 times.
✓ Branch 64 → 65 taken 2 times.
✓ Branch 69 → 70 taken 2 times.
✓ Branch 69 → 71 taken 1052927 times.
✓ Branch 71 → 72 taken 2 times.
✓ Branch 71 → 73 taken 1052927 times.
✗ Branch 76 → 77 not taken.
✗ Branch 76 → 78 not taken.
✗ Branch 80 → 81 not taken.
✗ Branch 80 → 82 not taken.
1052929 return title != 0 ? title < 0 : taskSelectionKey(a) < taskSelectionKey(b);
176 });
177 1681 QList<CalendarTask> sorted;
178
1/1
✓ Branch 75 → 76 taken 1681 times.
1681 sorted.reserve(tasks.size());
179
6/6
✓ Branch 76 → 77 taken 1681 times.
✓ Branch 77 → 78 taken 1681 times.
✓ Branch 80 → 81 taken 99215 times.
✓ Branch 82 → 83 taken 99215 times.
✓ Branch 85 → 79 taken 99215 times.
✓ Branch 85 → 86 taken 1681 times.
100896 for (int index : order) sorted.append(std::move(tasks[index]));
180 1681 tasks = std::move(sorted);
181 1681 QHash<QString, int> indices; QHash<QString, QList<int>> children;
182
5/5
✓ Branch 89 → 90 taken 99215 times.
✓ Branch 90 → 91 taken 99215 times.
✓ Branch 91 → 92 taken 99215 times.
✓ Branch 95 → 89 taken 99215 times.
✓ Branch 95 → 96 taken 1681 times.
100896 for (int i = 0; i < tasks.size(); ++i) indices.insert(taskSelectionKey(tasks[i]), i);
183 1681 QList<int> roots;
184
2/2
✓ Branch 117 → 97 taken 99215 times.
✓ Branch 117 → 118 taken 1681 times.
100896 for (int i = 0; i < tasks.size(); ++i) {
185
2/2
✓ Branch 97 → 98 taken 99215 times.
✓ Branch 98 → 99 taken 99215 times.
99215 const auto &task = tasks[i]; const auto key = parentKey(task);
186
12/15
✓ Branch 100 → 101 taken 85 times.
✓ Branch 100 → 107 taken 99130 times.
✓ Branch 102 → 103 taken 80 times.
✓ Branch 102 → 107 taken 5 times.
✓ Branch 103 → 104 taken 80 times.
✓ Branch 105 → 106 taken 80 times.
✗ Branch 105 → 107 not taken.
✓ Branch 108 → 109 taken 80 times.
✓ Branch 108 → 110 taken 99135 times.
✓ Branch 110 → 111 taken 80 times.
✓ Branch 110 → 113 taken 99135 times.
✓ Branch 111 → 112 taken 80 times.
✓ Branch 112 → 114 taken 80 times.
✗ Branch 167 → 168 not taken.
✗ Branch 167 → 169 not taken.
99215 if (!task.parentUid.isEmpty() && indices.contains(key) && key != taskSelectionKey(task)) children[key] << i;
187
1/1
✓ Branch 113 → 114 taken 99135 times.
99135 else roots << i;
188 99215 }
189 1681 QList<Row> rows; QSet<int> visited;
190 99136 const auto appendTree = [&](int root) {
191
1/1
✓ Branch 3 → 4 taken 99136 times.
99136 QList<QPair<int, int>> stack{{root, 0}};
192
3/3
✓ Branch 4 → 5 taken 99136 times.
✓ Branch 6 → 7 taken 99136 times.
✓ Branch 7 → 8 taken 99136 times.
99136 const QString group = groupFor(visualTask(tasks[root]), options.grouping, today, options.weekStart);
193
2/2
✓ Branch 91 → 11 taken 99213 times.
✓ Branch 91 → 92 taken 99136 times.
198349 while (!stack.isEmpty()) {
194
3/3
✓ Branch 11 → 12 taken 99213 times.
✓ Branch 15 → 16 taken 1 time.
✓ Branch 15 → 17 taken 99212 times.
99215 const auto [index, depth] = stack.takeLast(); if (visited.contains(index)) continue;
195
3/3
✓ Branch 17 → 18 taken 99212 times.
✓ Branch 18 → 19 taken 99212 times.
✓ Branch 19 → 20 taken 99212 times.
99212 visited.insert(index); const auto &task = tasks[index]; const QString key = taskSelectionKey(task);
196
7/13
✓ Branch 25 → 26 taken 82 times.
✓ Branch 25 → 30 taken 99130 times.
✓ Branch 26 → 27 taken 82 times.
✓ Branch 28 → 29 taken 5 times.
✓ Branch 28 → 30 taken 77 times.
✓ Branch 31 → 32 taken 82 times.
✓ Branch 31 → 33 taken 99130 times.
✗ Branch 104 → 105 not taken.
✗ Branch 104 → 106 not taken.
✗ Branch 111 → 112 not taken.
✗ Branch 111 → 113 not taken.
✗ Branch 114 → 115 not taken.
✗ Branch 114 → 116 not taken.
99212 Row row{task, group, depth, int(children.value(key).size()), 0, !task.parentUid.isEmpty() && !indices.contains(parentKey(task))};
197
7/7
✓ Branch 35 → 36 taken 99212 times.
✓ Branch 36 → 37 taken 99212 times.
✓ Branch 39 → 40 taken 79 times.
✓ Branch 41 → 42 taken 24 times.
✓ Branch 41 → 43 taken 55 times.
✓ Branch 45 → 38 taken 79 times.
✓ Branch 45 → 46 taken 99212 times.
99291 for (int child : children.value(key)) if (!open(tasks[child])) ++row.completedChildren;
198
1/1
✓ Branch 47 → 48 taken 99212 times.
99212 rows << row;
199
2/2
✓ Branch 49 → 50 taken 2 times.
✓ Branch 49 → 70 taken 99210 times.
99212 if (options.collapsedParents.contains(key)) {
200 2 QList<int> hidden = children.value(key);
201
2/2
✓ Branch 66 → 52 taken 3 times.
✓ Branch 66 → 67 taken 2 times.
5 while (!hidden.isEmpty()) {
202
1/1
✓ Branch 52 → 53 taken 3 times.
3 const int child = hidden.takeLast();
203
1/2
✗ Branch 54 → 55 not taken.
✓ Branch 54 → 56 taken 3 times.
3 if (visited.contains(child)) continue;
204
4/4
✓ Branch 56 → 57 taken 3 times.
✓ Branch 57 → 58 taken 3 times.
✓ Branch 58 → 59 taken 3 times.
✓ Branch 60 → 61 taken 3 times.
3 visited.insert(child); hidden.append(children.value(taskSelectionKey(tasks[child])));
205 }
206 2 continue;
207 2 }
208 99210 const auto descendants = children.value(key);
209
6/6
✓ Branch 72 → 73 taken 77 times.
✓ Branch 74 → 75 taken 77 times.
✓ Branch 75 → 76 taken 77 times.
✓ Branch 77 → 78 taken 99287 times.
✓ Branch 78 → 72 taken 77 times.
✓ Branch 78 → 79 taken 99210 times.
99287 for (auto it = descendants.crbegin(); it != descendants.crend(); ++it) stack.append({*it, depth + 1});
210 99214 }
211 99136 };
212
5/5
✓ Branch 119 → 120 taken 1681 times.
✓ Branch 120 → 121 taken 1681 times.
✓ Branch 123 → 124 taken 99135 times.
✓ Branch 126 → 122 taken 99135 times.
✓ Branch 126 → 127 taken 1681 times.
100816 for (int root : roots) appendTree(root);
213 // Cycles imported from another client are shown safely rather than lost.
214
5/5
✓ Branch 129 → 130 taken 1 time.
✓ Branch 129 → 131 taken 99214 times.
✓ Branch 130 → 131 taken 1 time.
✓ Branch 133 → 128 taken 99215 times.
✓ Branch 133 → 134 taken 1681 times.
100896 for (int i = 0; i < tasks.size(); ++i) if (!visited.contains(i)) appendTree(i);
215 1681 return rows;
216 1681 }
217 7 QList<QPair<QString, qint64>> manualOrder(QList<CalendarTask> tasks, const QString &movedKey,
218 const QString &targetKey, bool after) {
219 7 constexpr qint64 step = 1024;
220
1/1
✓ Branch 2 → 3 taken 7 times.
7 const QCollator collator;
221
3/3
✓ Branch 3 → 4 taken 7 times.
✓ Branch 4 → 5 taken 7 times.
✓ Branch 5 → 6 taken 7 times.
7 std::stable_sort(tasks.begin(), tasks.end(), [&collator](const CalendarTask &a, const CalendarTask &b) {
222
2/2
✓ Branch 2 → 3 taken 145 times.
✓ Branch 2 → 4 taken 3 times.
148 if (a.sortOrder != b.sortOrder) return a.sortOrder < b.sortOrder;
223 3 const int title = collator.compare(a.summary, b.summary);
224
3/12
✓ Branch 5 → 6 taken 3 times.
✗ Branch 5 → 7 not taken.
✗ Branch 7 → 8 not taken.
✗ Branch 8 → 9 not taken.
✗ Branch 13 → 14 not taken.
✓ Branch 13 → 15 taken 3 times.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 3 times.
✗ Branch 19 → 20 not taken.
✗ Branch 19 → 21 not taken.
✗ Branch 23 → 24 not taken.
✗ Branch 23 → 25 not taken.
3 return title != 0 ? title < 0 : taskSelectionKey(a) < taskSelectionKey(b);
225 });
226 21 const auto indexOf = [&tasks](const QString &key) {
227
5/6
✓ Branch 3 → 4 taken 35 times.
✓ Branch 4 → 5 taken 35 times.
✓ Branch 7 → 8 taken 21 times.
✓ Branch 7 → 9 taken 14 times.
✓ Branch 11 → 3 taken 35 times.
✗ Branch 11 → 12 not taken.
35 for (int i = 0; i < tasks.size(); ++i) if (taskSelectionKey(tasks[i]) == key) return i;
228 ✗ return -1;
229 7 };
230
1/1
✓ Branch 6 → 7 taken 7 times.
7 const int from = indexOf(movedKey);
231
5/9
✓ Branch 7 → 8 taken 7 times.
✗ Branch 7 → 12 not taken.
✓ Branch 9 → 10 taken 7 times.
✗ Branch 9 → 12 not taken.
✓ Branch 10 → 11 taken 7 times.
✗ Branch 11 → 12 not taken.
✓ Branch 11 → 13 taken 7 times.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 7 times.
7 if (from < 0 || movedKey == targetKey || indexOf(targetKey) < 0) return {};
232
1/1
✓ Branch 16 → 17 taken 7 times.
7 const CalendarTask moved = tasks.takeAt(from);
233
3/3
✓ Branch 17 → 18 taken 7 times.
✓ Branch 18 → 19 taken 4 times.
✓ Branch 18 → 20 taken 3 times.
7 const int position = indexOf(targetKey) + (after ? 1 : 0);
234
1/1
✓ Branch 21 → 22 taken 7 times.
7 tasks.insert(position, moved);
235 7 const bool hasPrevious = position > 0, hasNext = position + 1 < tasks.size();
236 // S106-351: stored orders are clamped here too (older caches) so the
237 // arithmetic below stays far from the qint64 range.
238
1/1
✓ Branch 2 → 3 taken 10 times.
10 const auto bounded = [](qint64 order) { return std::clamp(order, -kTaskSortOrderLimit, kTaskSortOrderLimit); };
239
4/4
✓ Branch 23 → 24 taken 4 times.
✓ Branch 23 → 27 taken 3 times.
✓ Branch 24 → 25 taken 4 times.
✓ Branch 25 → 26 taken 4 times.
7 const qint64 previous = hasPrevious ? bounded(tasks[position - 1].sortOrder) : 0;
240
4/4
✓ Branch 28 → 29 taken 6 times.
✓ Branch 28 → 32 taken 1 time.
✓ Branch 29 → 30 taken 6 times.
✓ Branch 30 → 31 taken 6 times.
7 const qint64 next = hasNext ? bounded(tasks[position + 1].sortOrder) : 0;
241
8/10
✓ Branch 33 → 34 taken 4 times.
✓ Branch 33 → 42 taken 3 times.
✓ Branch 34 → 35 taken 3 times.
✓ Branch 34 → 42 taken 1 time.
✓ Branch 35 → 36 taken 2 times.
✓ Branch 35 → 42 taken 1 time.
✓ Branch 39 → 40 taken 2 times.
✓ Branch 39 → 41 taken 2 times.
✗ Branch 78 → 79 not taken.
✗ Branch 78 → 80 not taken.
11 if (hasPrevious && hasNext && next - previous >= 2) return {{movedKey, previous + (next - previous) / 2}};
242
5/8
✓ Branch 42 → 43 taken 3 times.
✓ Branch 42 → 50 taken 2 times.
✓ Branch 43 → 44 taken 3 times.
✗ Branch 43 → 50 not taken.
✓ Branch 47 → 48 taken 3 times.
✓ Branch 47 → 49 taken 3 times.
✗ Branch 89 → 90 not taken.
✗ Branch 89 → 91 not taken.
11 if (!hasPrevious && hasNext) return {{movedKey, next - step}};
243
5/8
✓ Branch 50 → 51 taken 2 times.
✗ Branch 50 → 58 not taken.
✓ Branch 51 → 52 taken 1 time.
✓ Branch 51 → 58 taken 1 time.
✓ Branch 55 → 56 taken 1 time.
✓ Branch 55 → 57 taken 1 time.
✗ Branch 100 → 101 not taken.
✗ Branch 100 → 102 not taken.
4 if (hasPrevious && !hasNext) return {{movedKey, previous + step}};
244 1 QList<QPair<QString, qint64>> changes;
245
2/2
✓ Branch 70 → 59 taken 3 times.
✓ Branch 70 → 71 taken 1 time.
4 for (int i = 0; i < tasks.size(); ++i)
246
5/6
✓ Branch 59 → 60 taken 3 times.
✓ Branch 60 → 61 taken 3 times.
✗ Branch 60 → 68 not taken.
✓ Branch 61 → 62 taken 3 times.
✓ Branch 62 → 63 taken 3 times.
✓ Branch 64 → 65 taken 3 times.
3 if (tasks[i].sortOrder != (i + 1) * step) changes.append({taskSelectionKey(tasks[i]), (i + 1) * step});
247 1 return changes;
248 13 }
249
250 835 QVariantMap counts(const QList<CalendarTask> &tasks, const QDate &today, int first) {
251 835 QVariantMap result;
252
2/2
✓ Branch 97 → 4 taken 123293 times.
✓ Branch 97 → 98 taken 835 times.
124128 for (const auto &task : tasks) {
253
7/7
✓ Branch 6 → 7 taken 24459 times.
✓ Branch 6 → 21 taken 98834 times.
✓ Branch 8 → 9 taken 24459 times.
✓ Branch 9 → 10 taken 24459 times.
✓ Branch 10 → 11 taken 24459 times.
✓ Branch 12 → 13 taken 24459 times.
✓ Branch 13 → 14 taken 24459 times.
123293 if (!open(task)) { result["completed"] = result.value("completed").toInt() + 1; continue; }
254
13/13
✓ Branch 21 → 22 taken 98834 times.
✓ Branch 22 → 23 taken 98445 times.
✓ Branch 22 → 28 taken 389 times.
✓ Branch 23 → 24 taken 98445 times.
✓ Branch 26 → 27 taken 97682 times.
✓ Branch 26 → 28 taken 763 times.
✓ Branch 29 → 30 taken 97682 times.
✓ Branch 29 → 44 taken 1152 times.
✓ Branch 31 → 32 taken 97682 times.
✓ Branch 32 → 33 taken 97682 times.
✓ Branch 33 → 34 taken 97682 times.
✓ Branch 35 → 36 taken 97682 times.
✓ Branch 36 → 37 taken 97682 times.
98834 if (task.due.isValid() && dateOf(task) < today) result["overdue"] = result.value("overdue").toInt() + 1;
255
9/13
✓ Branch 44 → 45 taken 98834 times.
✓ Branch 45 → 46 taken 98834 times.
✓ Branch 46 → 47 taken 98834 times.
✓ Branch 47 → 48 taken 98834 times.
✓ Branch 48 → 49 taken 98834 times.
✓ Branch 49 → 50 taken 98834 times.
✓ Branch 50 → 51 taken 98834 times.
✓ Branch 68 → 55 taken 494170 times.
✓ Branch 68 → 69 taken 98834 times.
✗ Branch 137 → 138 not taken.
✗ Branch 137 → 141 not taken.
✗ Branch 139 → 140 not taken.
✗ Branch 139 → 141 not taken.
1087174 for (const QString &view : {QString("mine"), QString("today"), QString("week"), QString("planned"), QString("list:") + calendarSelectionKey(task.accountId, task.calendarPath)})
256
8/10
✓ Branch 55 → 56 taken 494170 times.
✓ Branch 56 → 57 taken 492129 times.
✓ Branch 56 → 67 taken 2041 times.
✓ Branch 58 → 59 taken 492129 times.
✓ Branch 59 → 60 taken 492129 times.
✓ Branch 61 → 62 taken 492129 times.
✓ Branch 70 → 71 taken 494170 times.
✓ Branch 70 → 74 taken 98834 times.
✗ Branch 152 → 153 not taken.
✗ Branch 152 → 156 not taken.
1087174 if (matchesView(task, view, today, first)) result[view] = result.value(view).toInt() + 1;
257
7/7
✓ Branch 79 → 80 taken 69 times.
✓ Branch 80 → 81 taken 69 times.
✓ Branch 81 → 82 taken 69 times.
✓ Branch 83 → 84 taken 69 times.
✓ Branch 84 → 85 taken 69 times.
✓ Branch 93 → 77 taken 69 times.
✓ Branch 93 → 94 taken 98834 times.
98903 for (const auto &tag : task.tags) result["tag:" + tag] = result.value("tag:" + tag).toInt() + 1;
258 }
259 835 return result;
260 ✗ }
261 1221 void sortFlat(QList<CalendarTask> &tasks, const QString &sort) {
262
1/1
✓ Branch 2 → 3 taken 1221 times.
1221 const QCollator collator;
263 1482 const auto dueKey = [](const CalendarTask &task) {
264
2/2
✓ Branch 3 → 4 taken 1428 times.
✓ Branch 3 → 6 taken 54 times.
1482 return task.due.isValid() ? task.due.toMSecsSinceEpoch() : std::numeric_limits<qint64>::max();
265 };
266
1/2
✓ Branch 3 → 4 taken 8 times.
✗ Branch 3 → 5 not taken.
8 const auto rank = [](const CalendarTask &task) { const int level = priorityLevel(task.priority); return level == 0 ? 4 : level; };
267
3/3
✓ Branch 3 → 4 taken 1221 times.
✓ Branch 4 → 5 taken 1221 times.
✓ Branch 5 → 6 taken 1221 times.
1221 std::stable_sort(tasks.begin(), tasks.end(), [&](const CalendarTask &a, const CalendarTask &b) {
268
5/6
✓ Branch 4 → 5 taken 2 times.
✓ Branch 4 → 9 taken 437 times.
✓ Branch 7 → 8 taken 2 times.
✗ Branch 7 → 9 not taken.
✓ Branch 10 → 11 taken 2 times.
✓ Branch 10 → 14 taken 437 times.
439 if (sort == QLatin1String("priority") && rank(a) != rank(b)) return rank(a) < rank(b);
269
2/2
✓ Branch 16 → 17 taken 2 times.
✓ Branch 16 → 20 taken 435 times.
437 if (sort == QLatin1String("title")) {
270 2 const int order = collator.compare(a.summary, b.summary);
271
1/2
✓ Branch 18 → 19 taken 2 times.
✗ Branch 18 → 20 not taken.
2 if (order != 0) return order < 0;
272 }
273
6/7
✓ Branch 22 → 23 taken 3 times.
✓ Branch 22 → 26 taken 432 times.
✓ Branch 23 → 24 taken 3 times.
✓ Branch 24 → 25 taken 3 times.
✗ Branch 24 → 26 not taken.
✓ Branch 27 → 28 taken 3 times.
✓ Branch 27 → 30 taken 432 times.
435 if (sort == QLatin1String("created") && a.created != b.created) return a.created > b.created;
274
2/2
✓ Branch 32 → 33 taken 309 times.
✓ Branch 32 → 36 taken 123 times.
432 if (dueKey(a) != dueKey(b)) return dueKey(a) < dueKey(b);
275 123 return collator.compare(a.summary, b.summary) < 0;
276 });
277 1221 }
278 }
279