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: 91.4% 32 / 0 / 35
Functions: 100.0% 3 / 0 / 3
Branches: 88.9% 64 / 0 / 72

data/SieveMerge.cpp
Line Branch Exec Source
1 #include "SieveMerge.h"
2
3 #include <QSet>
4
5 #include "data/SieveMergePlan.h"
6 #include "data/SieveRuleCodec.h"
7
8 #include <QLoggingCategory>
9
10
4/7
✓ Branch 2 → 3 taken 7 times.
✓ Branch 2 → 8 taken 31 times.
✓ Branch 4 → 5 taken 7 times.
✗ Branch 4 → 8 not taken.
✓ Branch 5 → 6 taken 7 times.
✗ Branch 10 → 11 not taken.
✗ Branch 10 → 12 not taken.
38 Q_LOGGING_CATEGORY(lcSieveMerge, "mailjd.sieve.merge")
11
12 namespace Sieve {
13
14 23 QByteArray addRequirements(const QByteArray &requireBlock, const QStringList &extensions) {
15
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 22 times.
23 if (extensions.isEmpty())
16 1 return requireBlock;
17
1/1
✓ Branch 5 → 6 taken 22 times.
22 const Script script = parse(requireBlock);
18
4/8
✓ Branch 7 → 8 taken 22 times.
✗ Branch 7 → 13 not taken.
✓ Branch 9 → 10 taken 22 times.
✗ Branch 9 → 13 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 22 times.
✗ Branch 15 → 16 not taken.
✓ Branch 15 → 17 taken 22 times.
22 if (!script.isValid() || script.commands.isEmpty() || script.commands.first().arguments.isEmpty())
19 ✗ return requireBlock;
20 22 const Argument &arg = script.commands.first().arguments.first();
21 // S106-085: sets keep this linear for very long require lists.
22
1/1
✓ Branch 19 → 20 taken 22 times.
22 const QStringList listed = arg.values();
23
1/1
✓ Branch 22 → 23 taken 22 times.
22 QSet<QString> seen(listed.cbegin(), listed.cend());
24 22 QStringList missing;
25
2/2
✓ Branch 32 → 25 taken 88036 times.
✓ Branch 32 → 33 taken 22 times.
88058 for (const QString &extension : extensions)
26
2/2
✓ Branch 27 → 28 taken 29 times.
✓ Branch 27 → 30 taken 88007 times.
88036 if (!seen.contains(extension)) {
27
1/1
✓ Branch 28 → 29 taken 29 times.
29 seen.insert(extension);
28
1/1
✓ Branch 29 → 30 taken 29 times.
29 missing.append(extension);
29 }
30
1/2
✗ Branch 34 → 35 not taken.
✓ Branch 34 → 36 taken 22 times.
22 if (missing.isEmpty())
31 ✗ return requireBlock;
32
1/1
✓ Branch 37 → 38 taken 22 times.
22 const QByteArray list = requireBlock.mid(arg.span.begin, arg.span.length());
33
4/4
✓ Branch 40 → 41 taken 3 times.
✓ Branch 40 → 42 taken 19 times.
✓ Branch 41 → 43 taken 3 times.
✓ Branch 42 → 43 taken 19 times.
22 const QByteArray separator = list.contains(", ") ? QByteArray(", ") : QByteArray(",");
34 22 QByteArray additions;
35
4/4
✓ Branch 43 → 44 taken 22 times.
✓ Branch 44 → 45 taken 22 times.
✓ Branch 56 → 46 taken 29 times.
✓ Branch 56 → 57 taken 22 times.
51 for (const QString &extension : missing)
36
4/4
✓ Branch 47 → 48 taken 29 times.
✓ Branch 48 → 49 taken 29 times.
✓ Branch 49 → 50 taken 29 times.
✓ Branch 50 → 51 taken 29 times.
29 additions += separator + stringLiteral(extension);
37
2/2
✓ Branch 57 → 58 taken 17 times.
✓ Branch 57 → 68 taken 5 times.
22 if (arg.bracketed) {
38 17 const int insertAt = arg.strings.last().span.end;
39
4/4
✓ Branch 59 → 60 taken 17 times.
✓ Branch 60 → 61 taken 17 times.
✓ Branch 61 → 62 taken 17 times.
✓ Branch 62 → 63 taken 17 times.
17 return requireBlock.left(insertAt) + additions + requireBlock.mid(insertAt);
40 }
41
5/5
✓ Branch 69 → 70 taken 5 times.
✓ Branch 70 → 71 taken 5 times.
✓ Branch 71 → 72 taken 5 times.
✓ Branch 72 → 73 taken 5 times.
✓ Branch 73 → 74 taken 5 times.
10 return requireBlock.left(arg.span.begin) + "[" + list + additions + "]" +
42
2/2
✓ Branch 68 → 69 taken 5 times.
✓ Branch 74 → 75 taken 5 times.
15 requireBlock.mid(arg.span.end);
43 22 }
44
45 38 MergeResult merge3(const QByteArray &base, const QByteArray &mine, const QByteArray &theirs) {
46 // Sprint 107 S107.2.6: the automatic merge is the plan with its default
47 // choices (oracles: tests/test_merge_oracles.cpp).
48
2/2
✓ Branch 2 → 3 taken 38 times.
✓ Branch 3 → 4 taken 38 times.
38 const MergeResult result = SieveMergePlan::mergeResult(SieveMergePlan::analyze(base, mine, theirs));
49
2/2
✓ Branch 5 → 6 taken 18 times.
✓ Branch 5 → 20 taken 20 times.
38 if (result.clean)
50
7/7
✓ Branch 6 → 7 taken 18 times.
✓ Branch 10 → 11 taken 18 times.
✓ Branch 11 → 12 taken 18 times.
✓ Branch 13 → 14 taken 18 times.
✓ Branch 14 → 15 taken 18 times.
✓ Branch 18 → 8 taken 18 times.
✓ Branch 18 → 19 taken 18 times.
36 qCInfo(lcSieveMerge) << "Merged cleanly," << result.takenFromTheirs.size() << "blocks taken from the server";
51 else
52
7/7
✓ Branch 20 → 21 taken 20 times.
✓ Branch 24 → 25 taken 20 times.
✓ Branch 25 → 26 taken 20 times.
✓ Branch 27 → 28 taken 20 times.
✓ Branch 28 → 29 taken 20 times.
✓ Branch 32 → 22 taken 20 times.
✓ Branch 32 → 33 taken 20 times.
40 qCInfo(lcSieveMerge) << "Merge found" << result.conflicts.size() << "conflicts";
53 38 return result;
54 ✗ }
55
56 } // namespace Sieve
57