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

controller/PendingFlagIntents.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QHash>
4 #include <QMap>
5 #include <QSet>
6 #include <QString>
7 #include <optional>
8
9 #include "data/MailRequest.h"
10
11 // Unconfirmed local mail intents shared by the controller's flag sync,
12 // polling, user commands and mutation pipeline (Sprint 91 S91.0.7).
13 //
14 // Plain value, GUI thread only, one instance owned by MailMutationPipeline
15 // (S91.4.2: the pipeline creates and retires the intents and fences); the
16 // controller and FolderFlagSync reach it through intents(). Every reader and
17 // writer goes through these query/mark methods; nobody keeps a copy.
18 class PendingFlagIntents {
19 public:
20 // A confirmed Seen readback for a folder. A STATUS answer whose request
21 // started before `completedNs` is older than that readback and must not
22 // replace the folder's count; the fence is void once the epoch changed.
23 struct ReadbackFence {
24 qint64 completedNs = 0;
25 quint32 uidValidity = 0;
26 };
27
28 // Identities with a pending local Seen/Flagged/keyword change: server flag
29 // snapshots must not revert them before the journal settles.
30
1/1
✓ Branch 2 → 3 taken 494 times.
494 void markFlag(const MailId &id) { m_flags.insert(id); }
31 37 void clearFlag(const MailId &id) { m_flags.remove(id); }
32 102 bool hasPendingFlag(const MailId &id) const { return m_flags.contains(id); }
33 5 const QSet<MailId> &pendingFlags() const { return m_flags; }
34
35 // Identities moved visually in this session (visual commit until journal
36 // settlement); in-memory, no SQLite read.
37
1/1
✓ Branch 2 → 3 taken 145 times.
145 void markMove(const MailId &id) { m_moves.insert(id); }
38 27 void clearMove(const MailId &id) { m_moves.remove(id); }
39 53 bool hasPendingMove(const MailId &id) const { return m_moves.contains(id); }
40 21 const QSet<MailId> &pendingMoves() const { return m_moves; }
41
42 15 void setReadbackFence(qint64 folderId, ReadbackFence fence) { m_fences.insert(folderId, fence); }
43 29 std::optional<ReadbackFence> readbackFence(qint64 folderId) const {
44 29 const auto fence = m_fences.constFind(folderId);
45
2/2
✓ Branch 5 → 6 taken 22 times.
✓ Branch 5 → 7 taken 7 times.
29 if (fence == m_fences.cend()) return std::nullopt;
46 7 return *fence;
47 }
48 1 void clearReadbackFence(qint64 folderId) { m_fences.remove(folderId); }
49 1043 void clearReadbackFences() { m_fences.clear(); }
50 1 bool readbackFencesEmpty() const { return m_fences.isEmpty(); }
51
52 // T-074: last polled unread count per folder path (keeps badges stable
53 // during folder switches).
54 15 int lastPolledUnread(const QString &folder, int fallback) const {
55 15 return m_lastPolledUnread.value(folder, fallback);
56 }
57 46 void setLastPolledUnread(const QString &folder, int unread) { m_lastPolledUnread[folder] = unread; }
58 51 const QMap<QString, int> &lastPolledUnreadCounts() const { return m_lastPolledUnread; }
59 1043 void clearLastPolledUnread() { m_lastPolledUnread.clear(); }
60
61 private:
62 QSet<MailId> m_flags;
63 QSet<MailId> m_moves;
64 QHash<qint64, ReadbackFence> m_fences;
65 QMap<QString, int> m_lastPolledUnread;
66 };
67