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: 100.0% 55 / 0 / 55
Functions: 100.0% 3 / 0 / 3
Branches: 95.6% 43 / 0 / 45

data/RelationGraphPack.cpp
Line Branch Exec Source
1 // Packing the overview's clusters (declared in RelationGraphClusters.h,
2 // split from RelationGraphClusters.cpp).
3 #include "RelationGraphClusters.h"
4
5 #include <algorithm>
6 #include <cmath>
7 #include <numeric>
8
9 namespace RelationGraphLayout {
10
11 namespace {
12
13 // Shelf packing at one row width: the rectangles in `order`, a new row when
14 // the next one does not fit; the centres around (0, 0) and the bounds.
15 375 QList<QPointF> packRows(const QList<QSizeF> &sizes, const QList<int> &order, double rowWidth, double gap,
16 QSizeF *bounds) {
17
1/1
✓ Branch 3 → 4 taken 375 times.
375 QList<QPointF> centres(sizes.size());
18
3/5
✓ Branch 4 → 5 taken 375 times.
✓ Branch 6 → 7 taken 375 times.
✓ Branch 6 → 8 taken 375 times.
✗ Branch 75 → 76 not taken.
✗ Branch 75 → 77 not taken.
750 QList<QList<int>> rowsOf{QList<int>()};
19 375 double cursor = 0;
20
2/2
✓ Branch 30 → 10 taken 7600 times.
✓ Branch 30 → 31 taken 375 times.
7975 for (int i : order) {
21
7/7
✓ Branch 11 → 12 taken 7600 times.
✓ Branch 13 → 14 taken 7225 times.
✓ Branch 13 → 18 taken 375 times.
✓ Branch 16 → 17 taken 796 times.
✓ Branch 16 → 18 taken 6429 times.
✓ Branch 19 → 20 taken 796 times.
✓ Branch 19 → 24 taken 6804 times.
7600 if (!rowsOf.last().isEmpty() && cursor + sizes.at(i).width() > rowWidth) {
22
1/1
✓ Branch 21 → 22 taken 796 times.
796 rowsOf.append(QList<int>());
23 796 cursor = 0;
24 }
25
2/2
✓ Branch 24 → 25 taken 7600 times.
✓ Branch 25 → 26 taken 7600 times.
7600 rowsOf.last().append(i);
26 7600 cursor += sizes.at(i).width() + gap;
27 }
28 375 double top = 0, widest = 0;
29
2/2
✓ Branch 61 → 34 taken 1171 times.
✓ Branch 61 → 62 taken 375 times.
1546 for (const QList<int> &row : std::as_const(rowsOf)) {
30 1171 double width = -gap, height = 0;
31
2/2
✓ Branch 45 → 37 taken 7600 times.
✓ Branch 45 → 46 taken 1171 times.
8771 for (int i : row) {
32 7600 width += sizes.at(i).width() + gap;
33 7600 height = std::max(height, sizes.at(i).height());
34 }
35 1171 widest = std::max(widest, width);
36 1171 double left = -width / 2;
37
2/2
✓ Branch 58 → 49 taken 7600 times.
✓ Branch 58 → 59 taken 1171 times.
8771 for (int i : row) {
38
1/1
✓ Branch 53 → 54 taken 7600 times.
7600 centres[i] = QPointF(left + sizes.at(i).width() / 2, top + height / 2);
39 7600 left += sizes.at(i).width() + gap;
40 }
41 1171 top += height + gap;
42 }
43 375 const double shift = (top - gap) / 2;
44
4/4
✓ Branch 62 → 63 taken 375 times.
✓ Branch 63 → 64 taken 375 times.
✓ Branch 69 → 65 taken 7600 times.
✓ Branch 69 → 70 taken 375 times.
7975 for (QPointF &c : centres)
45 7600 c.ry() -= shift;
46 375 *bounds = QSizeF(widest, top - gap);
47 375 return centres;
48 375 }
49
50 } // namespace
51
52 21 QList<QPointF> pack(const QList<QSizeF> &sizes, double aspect, double gap) {
53 21 const int count = int(sizes.size());
54
2/2
✓ Branch 3 → 4 taken 6 times.
✓ Branch 3 → 5 taken 15 times.
21 if (count == 0)
55 6 return {};
56
1/1
✓ Branch 5 → 6 taken 15 times.
15 QList<int> order(count);
57
3/3
✓ Branch 6 → 7 taken 15 times.
✓ Branch 7 → 8 taken 15 times.
✓ Branch 8 → 9 taken 15 times.
15 std::iota(order.begin(), order.end(), 0);
58
3/3
✓ Branch 9 → 10 taken 15 times.
✓ Branch 10 → 11 taken 15 times.
✓ Branch 11 → 12 taken 15 times.
15 std::stable_sort(order.begin(), order.end(), [&](int a, int b) {
59 1538 return sizes.at(a).width() * sizes.at(a).height() > sizes.at(b).width() * sizes.at(b).height();
60 });
61 15 double widest = 0, total = 0;
62
2/2
✓ Branch 20 → 14 taken 304 times.
✓ Branch 20 → 21 taken 15 times.
319 for (const QSizeF &s : sizes) {
63 304 widest = std::max(widest, s.width());
64 304 total += s.width() + gap;
65 }
66 // Row widths from the widest rectangle to all in one row; the packing whose
67 // bounds come nearest the asked shape wins (on a tie the narrower).
68 15 const double target = std::max(0.5, aspect);
69 15 QList<QPointF> best;
70 15 double bestMiss = 1e18;
71 15 constexpr int Steps = 24;
72
2/2
✓ Branch 33 → 23 taken 375 times.
✓ Branch 33 → 34 taken 15 times.
390 for (int step = 0; step <= Steps; ++step) {
73 375 const double rowWidth = widest * std::pow(std::max(1.0, total / widest), double(step) / Steps);
74 375 QSizeF bounds;
75
1/1
✓ Branch 24 → 25 taken 375 times.
375 const QList<QPointF> centres = packRows(sizes, order, rowWidth, gap, &bounds);
76 375 const double miss = std::abs(std::log(bounds.width() / std::max(1.0, bounds.height()) / target));
77
2/2
✓ Branch 29 → 30 taken 61 times.
✓ Branch 29 → 31 taken 314 times.
375 if (miss < bestMiss - 1e-9) {
78 61 bestMiss = miss;
79 61 best = centres;
80 }
81 375 }
82 15 return best;
83 15 }
84
85 } // namespace RelationGraphLayout
86