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% 6 / 0 / 6
Functions: 100.0% 4 / 0 / 4
Branches: -% 0 / 0 / 0

controller/BodyRequestRegistry.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QHash>
4 #include <QList>
5 #include <QQueue>
6
7 #include <optional>
8
9 #include "data/MailRequest.h"
10
11 struct BodyConsumer {
12 BodyPurpose purpose = BodyPurpose::Display;
13 quint64 consumerId = 0;
14 quint64 displayGeneration = 0;
15
16 friend bool operator==(const BodyConsumer &, const BodyConsumer &) = default;
17 };
18
19 struct BodyRequestTicket {
20 quint64 requestId = 0;
21 bool deduplicated = false;
22 };
23
24 struct BodyRequestResolution {
25 BodyRequest request;
26 BodyResult result;
27 QList<BodyConsumer> consumers;
28 bool displayEligible = false;
29 };
30
31 struct BodyPrefetchStats {
32 quint64 requested = 0;
33 quint64 deduplicated = 0;
34 quint64 completed = 0;
35 quint64 cancelled = 0;
36 quint64 failed = 0;
37 };
38
39 // Pure state machine for body work. Network dispatch and MIME/cache handling
40 // stay in MailController; this type owns correlation, deduplication, priority,
41 // and display-generation eligibility.
42 class BodyRequestRegistry {
43 public:
44 static constexpr qsizetype MaximumQueuedPrefetch = 4;
45
46 quint64 selectDisplay(const MailId &mailId);
47 void clearDisplaySelection();
48 void invalidateFolder(const QString &accountId, qint64 folderId);
49 24818 [[nodiscard]] MailId selectedMailId() const { return m_selectedMailId; }
50 2192 [[nodiscard]] quint64 displayGeneration() const {
51 2192 return m_displayGeneration;
52 }
53
54 BodyRequestTicket request(const MailId &mailId, const QString &folderPath,
55 BodyPurpose purpose, quint64 consumerId = 0);
56 // P90.9: the dispatcher asks whether a real queued prefetch would take
57 // the single transport slot. An empty queue is neither demand nor prefetch.
58 [[nodiscard]] bool nextDispatchIsPrefetch() const;
59 [[nodiscard]] bool hasQueuedDemand() const;
60 std::optional<BodyRequest> takeNextForDispatch(bool allowPrefetch = true);
61 std::optional<BodyRequestResolution> complete(const BodyResult &result);
62 [[nodiscard]] bool matchesResult(const BodyResult &result) const;
63 void removeConsumer(BodyPurpose purpose, quint64 consumerId);
64
65 [[nodiscard]] bool contains(const MailId &mailId) const;
66 [[nodiscard]] std::optional<MailId> mailIdForRequest(quint64 requestId) const;
67 // A prefetch can gain a display/tab consumer while it parses; writer
68 // priority follows the live consumers at enqueue time.
69 [[nodiscard]] bool hasDemandConsumer(quint64 requestId) const;
70 1047 [[nodiscard]] qsizetype pendingCount() const { return m_byId.size(); }
71 [[nodiscard]] qsizetype queuedPrefetchCount() const;
72 8 [[nodiscard]] BodyPrefetchStats prefetchStats() const {
73 8 return m_prefetchStats;
74 }
75
76 private:
77 struct Entry {
78 BodyRequest request;
79 QList<BodyConsumer> consumers;
80 bool dispatched = false;
81 };
82
83 static bool isDisplayConsumer(const BodyConsumer &consumer);
84 static bool sameConsumer(const BodyConsumer &left, const BodyConsumer &right);
85 void removeQueuedRequest(quint64 requestId);
86 void removeConsumers(BodyPurpose purpose, std::optional<quint64> consumerId);
87
88 quint64 m_nextRequestId = 1;
89 quint64 m_displayGeneration = 0;
90 MailId m_selectedMailId;
91 QHash<quint64, Entry> m_byId;
92 QHash<MailId, quint64> m_byMail;
93 QQueue<quint64> m_demandQueue;
94 QQueue<quint64> m_prefetchQueue;
95 BodyPrefetchStats m_prefetchStats;
96 };
97