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: 83.7% 77 / 0 / 92
Functions: 100.0% 2 / 0 / 2
Branches: 69.5% 91 / 0 / 131

data/RelationGraphLayout.cpp
Line Branch Exec Source
1 #include "RelationGraphLayout.h"
2
3 #include "RelationGraphBlocks.h"
4 #include "RelationGraphClusters.h"
5 #include "RelationGraphForce.h"
6
7 #include <algorithm>
8 #include <cmath>
9
10 namespace RelationGraphLayout {
11
12 21 Layout overviewLayout(const RelationGraph::Graph &graph, const QHash<QString, QPointF> &previous,
13 const QSet<QString> &changed, const Options &options) {
14 21 Layout layout;
15 21 const int n = int(graph.nodes.size());
16
1/1
✓ Branch 3 → 4 taken 21 times.
21 layout.positions = QList<QPointF>(n);
17
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 21 times.
21 if (n <= 0)
18 ✗ return layout;
19 21 QList<int> clusterOf;
20
1/1
✓ Branch 8 → 9 taken 21 times.
21 const QList<Cluster> clusters = overviewClusters(graph, &clusterOf);
21 21 const int count = int(clusters.size());
22
1/1
✓ Branch 10 → 11 taken 21 times.
21 QList<QHash<int, QPointF>> local(count);
23
1/1
✓ Branch 11 → 12 taken 21 times.
21 QList<QSizeF> sizes(count);
24
2/2
✓ Branch 20 → 13 taken 337 times.
✓ Branch 20 → 21 taken 21 times.
358 for (int c = 0; c < count; ++c)
25
3/3
✓ Branch 13 → 14 taken 337 times.
✓ Branch 15 → 16 taken 337 times.
✓ Branch 16 → 17 taken 337 times.
337 local[c] = clusterLayout(graph, clusters.at(c), &sizes[c]);
26 // Where each cluster was: the offset that keeps its known people where they were.
27
1/1
✓ Branch 21 → 22 taken 21 times.
21 QList<QPointF> offset(count);
28
2/2
✓ Branch 22 → 23 taken 21 times.
✓ Branch 23 → 24 taken 21 times.
21 QList<bool> known(count, false), pinned(count, false);
29
2/2
✓ Branch 77 → 25 taken 337 times.
✓ Branch 77 → 78 taken 21 times.
358 for (int c = 0; c < count; ++c) {
30 337 QPointF sum;
31 337 int seen = 0;
32 337 bool unchanged = true;
33
2/2
✓ Branch 49 → 27 taken 2109 times.
✓ Branch 49 → 50 taken 337 times.
2446 for (auto it = local.at(c).cbegin(); it != local.at(c).cend(); ++it) {
34 2109 const QString key = graph.nodes.at(it.key()).key;
35
2/2
✓ Branch 31 → 32 taken 223 times.
✓ Branch 31 → 37 taken 1886 times.
2109 if (previous.contains(key)) {
36 223 sum += previous.value(key) - it.value();
37 223 ++seen;
38 }
39
6/6
✓ Branch 37 → 38 taken 524 times.
✓ Branch 37 → 43 taken 1585 times.
✓ Branch 39 → 40 taken 220 times.
✓ Branch 39 → 43 taken 304 times.
✓ Branch 41 → 42 taken 218 times.
✓ Branch 41 → 43 taken 2 times.
2109 unchanged = unchanged && previous.contains(key) && !changed.contains(key);
40 2109 }
41
2/2
✓ Branch 50 → 51 taken 304 times.
✓ Branch 50 → 52 taken 33 times.
337 if (seen == 0)
42 304 continue;
43
1/1
✓ Branch 52 → 53 taken 33 times.
33 known[c] = true;
44
1/1
✓ Branch 54 → 55 taken 33 times.
33 offset[c] = sum / seen;
45
1/1
✓ Branch 55 → 56 taken 33 times.
33 pinned[c] = unchanged;
46
2/2
✓ Branch 74 → 58 taken 223 times.
✓ Branch 74 → 75 taken 33 times.
256 for (auto it = local.at(c).cbegin(); it != local.at(c).cend(); ++it) // arranged as before?
47 223 if (const QPointF d = previous.value(graph.nodes.at(it.key()).key) - it.value() - offset.at(c);
48
1/2
✗ Branch 67 → 68 not taken.
✓ Branch 67 → 70 taken 223 times.
223 std::hypot(d.x(), d.y()) >= 1)
49 ✗ pinned[c] = false;
50 }
51 21 QList<QPair<int, int>> links;
52
2/2
✓ Branch 103 → 80 taken 2976 times.
✓ Branch 103 → 104 taken 21 times.
2997 for (const RelationGraph::Edge &e : graph.edges)
53
5/7
✓ Branch 82 → 83 taken 2976 times.
✗ Branch 82 → 94 not taken.
✓ Branch 85 → 86 taken 2944 times.
✓ Branch 85 → 94 taken 32 times.
✓ Branch 86 → 87 taken 2944 times.
✓ Branch 87 → 88 taken 2944 times.
✗ Branch 87 → 94 not taken.
2976 if (e.from >= 0 && e.to >= 0 && e.kind != QLatin1String("member") && clusterOf.value(e.from) >= 0 &&
54
7/9
✓ Branch 81 → 82 taken 2976 times.
✗ Branch 81 → 94 not taken.
✓ Branch 88 → 89 taken 2944 times.
✓ Branch 89 → 90 taken 2944 times.
✗ Branch 89 → 94 not taken.
✓ Branch 92 → 93 taken 953 times.
✓ Branch 92 → 94 taken 1991 times.
✓ Branch 95 → 96 taken 953 times.
✓ Branch 95 → 101 taken 2023 times.
5952 clusterOf.value(e.to) >= 0 && clusterOf.at(e.from) != clusterOf.at(e.to))
55
1/1
✓ Branch 99 → 100 taken 953 times.
953 links.append({clusterOf.at(e.from), clusterOf.at(e.to)});
56 21 const double gap = options.idealDistance * 0.6; // between two clusters' rims
57
3/3
✓ Branch 107 → 108 taken 21 times.
✓ Branch 109 → 110 taken 15 times.
✓ Branch 109 → 114 taken 6 times.
21 if (std::find(known.cbegin(), known.cend(), true) == known.cend()) {
58
1/1
✓ Branch 110 → 111 taken 15 times.
15 offset = pack(sizes, options.aspect, gap);
59 } else {
60 // Incremental (G15): known clusters stay; a new one starts beside a known
61 // cluster it is joined to, else in a row of its own below everything.
62 6 double bottom = 0;
63
2/2
✓ Branch 124 → 115 taken 33 times.
✓ Branch 124 → 125 taken 6 times.
39 for (int c = 0; c < count; ++c)
64
1/2
✓ Branch 116 → 117 taken 33 times.
✗ Branch 116 → 123 not taken.
33 if (known.at(c))
65 33 bottom = std::max(bottom, offset.at(c).y() + sizes.at(c).height() / 2);
66 6 QList<int> loose;
67
2/2
✓ Branch 166 → 126 taken 33 times.
✓ Branch 166 → 167 taken 6 times.
39 for (int c = 0; c < count; ++c) {
68
1/2
✓ Branch 127 → 128 taken 33 times.
✗ Branch 127 → 129 not taken.
33 if (known.at(c))
69 33 continue;
70 ✗ const QString key = graph.nodes.at(clusters.at(c).members().first()).key;
71 ✗ bool placed = false;
72 ✗ for (const auto &[x, y] : std::as_const(links))
73 ✗ if ((x == c && known.at(y)) || (y == c && known.at(x))) {
74 ✗ offset[c] = offset.at(x == c ? y : x) + RelationGraphForce::seeded(key, gap);
75 ✗ placed = true;
76 ✗ break;
77 }
78 ✗ if (!placed)
79 ✗ loose.append(c);
80 ✗ }
81 6 QList<QSizeF> looseSizes;
82
1/2
✗ Branch 175 → 170 not taken.
✓ Branch 175 → 176 taken 6 times.
6 for (int c : std::as_const(loose))
83 ✗ looseSizes.append(sizes.at(c));
84
1/1
✓ Branch 176 → 177 taken 6 times.
6 const QList<QPointF> packed = pack(looseSizes, options.aspect, gap);
85 6 double looseTop = 0;
86
1/2
✗ Branch 185 → 178 not taken.
✓ Branch 185 → 186 taken 6 times.
6 for (int k = 0; k < loose.size(); ++k)
87 ✗ looseTop = std::min(looseTop, packed.at(k).y() - looseSizes.at(k).height() / 2);
88
1/2
✗ Branch 194 → 187 not taken.
✓ Branch 194 → 195 taken 6 times.
6 for (int k = 0; k < loose.size(); ++k)
89 ✗ offset[loose.at(k)] = packed.at(k) + QPointF(0, bottom + gap - looseTop);
90
1/1
✓ Branch 195 → 196 taken 6 times.
6 RelationGraphForce::separate(&offset, sizes, pinned);
91
1/1
✓ Branch 196 → 197 taken 6 times.
6 RelationGraphForce::compact(&offset, sizes, pinned, gap * 0.5, links);
92 6 }
93
2/2
✓ Branch 215 → 202 taken 337 times.
✓ Branch 215 → 216 taken 21 times.
358 for (int c = 0; c < count; ++c)
94
2/2
✓ Branch 213 → 204 taken 2109 times.
✓ Branch 213 → 214 taken 337 times.
2446 for (auto it = local.at(c).cbegin(); it != local.at(c).cend(); ++it)
95
1/1
✓ Branch 208 → 209 taken 2109 times.
2109 layout.positions[it.key()] = offset.at(c) + it.value();
96 // A family card (hidden, F103-13) in the middle of its members.
97
2/2
✓ Branch 252 → 217 taken 2121 times.
✓ Branch 252 → 253 taken 21 times.
2142 for (int i = 0; i < n; ++i) {
98
2/2
✓ Branch 219 → 220 taken 2109 times.
✓ Branch 219 → 221 taken 12 times.
2121 if (isShown(graph.nodes.at(i)))
99 2109 continue;
100 12 QPointF sum;
101 12 int members = 0;
102
2/2
✓ Branch 245 → 223 taken 707 times.
✓ Branch 245 → 246 taken 12 times.
719 for (const RelationGraph::Edge &e : graph.edges)
103
10/13
✓ Branch 226 → 227 taken 69 times.
✓ Branch 226 → 235 taken 638 times.
✓ Branch 227 → 228 taken 37 times.
✓ Branch 227 → 229 taken 32 times.
✗ Branch 228 → 229 not taken.
✓ Branch 228 → 235 taken 37 times.
✓ Branch 229 → 230 taken 32 times.
✗ Branch 229 → 231 not taken.
✓ Branch 232 → 233 taken 32 times.
✓ Branch 233 → 234 taken 32 times.
✗ Branch 233 → 235 not taken.
✓ Branch 236 → 237 taken 32 times.
✓ Branch 236 → 243 taken 675 times.
707 if (e.kind == QLatin1String("member") && (e.from == i || e.to == i) && clusterOf.value(e.from == i ? e.to : e.from) >= 0) {
104
1/2
✓ Branch 237 → 238 taken 32 times.
✗ Branch 237 → 239 not taken.
32 sum += layout.positions.at(e.from == i ? e.to : e.from);
105 32 ++members;
106 }
107
2/3
✓ Branch 246 → 247 taken 12 times.
✗ Branch 246 → 248 not taken.
✓ Branch 249 → 250 taken 12 times.
12 layout.positions[i] = members > 0 ? sum / members : QPointF();
108 }
109
1/1
✓ Branch 253 → 254 taken 21 times.
21 layout.routes = routes(graph, layout.positions);
110
1/1
✓ Branch 256 → 257 taken 21 times.
21 bundleRoutes(graph, layout.positions, clusterOf, offset, sizes, &layout.routes);
111 21 return layout;
112 21 }
113
114 12 QList<QPointF> overview(const RelationGraph::Graph &graph, const QHash<QString, QPointF> &previous,
115 const QSet<QString> &changed, const Options &options) {
116
1/1
✓ Branch 2 → 3 taken 12 times.
12 return overviewLayout(graph, previous, changed, options).positions;
117 }
118
119 } // namespace RelationGraphLayout
120