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

service/NotificationBatcher.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QElapsedTimer>
4 #include <QList>
5 #include <QObject>
6 #include <QString>
7 #include <QTimer>
8
9 // NotificationBatcher (67.A2) coalesces new-mail notifications so a
10 // catch-up sync after hours offline produces one summary popup instead
11 // of one popup per mail.
12 //
13 // Behavior:
14 // - Suppressed until setSyncComplete() is called: mails added before
15 // the first INBOX sync of the session finishes are counted with three
16 // preview rows (they flush as one batch at sync end) or dropped when the sync
17 // was the initial mailbox load (initial load != new mail).
18 // - After that, a debounce timer (default 3 s, restarted on each add)
19 // coalesces bursts: 1-2 mails flush as individual notifications,
20 // >= 3 as a single summary. A burst flushes at the latest 5 debounce
21 // intervals after its first mail, even while mail keeps arriving
22 // (S106-214).
23 // - The newest mail of a burst: the highest UID within one folder; across
24 // folders (separate UID spaces) the later arrival.
25 //
26 // Pure QObject — no D-Bus. MainWindow connects the flush signals to
27 // DesktopNotifier and owns the replaces-id of the on-screen summary.
28 class NotificationBatcher : public QObject {
29 12 Q_OBJECT
30
31 public:
32 struct PendingMail {
33 QString from;
34 QString subject;
35 qint64 uid = -1;
36 qint64 folderId = -1;
37 };
38
39 explicit NotificationBatcher(QObject *parent = nullptr);
40
41 void setDebounceMs(int ms);
42 1 int debounceMs() const { return m_debounceMs; }
43
44 2 bool isSuppressed() const { return m_suppressed; }
45 8 int pendingCount() const { return m_pendingCount; }
46
47 // Queue a new mail. While suppressed the mail is buffered; otherwise
48 // the debounce timer is (re)started.
49 void addPending(const QString &from, const QString &subject, qint64 uid,
50 qint64 folderId);
51
52 // First INBOX sync of the session finished. dropBuffered = true when
53 // the sync was the initial mailbox load (cache was empty — nothing in
54 // it is "new"); otherwise the buffer flushes immediately as one batch.
55 void setSyncComplete(bool dropBuffered);
56
57 signals:
58 // Burst of 1-2 mails: notify each mail individually.
59 void notifyIndividual(const QString &from, const QString &subject,
60 qint64 uid, qint64 folderId);
61 // Burst of >= 3 mails: one summary. newestUid/folderId identify the
62 // newest mail of the batch (target for the "open" action).
63 void notifySummary(const QString &title, const QString &body, int count,
64 qint64 folderId, qint64 newestUid);
65
66 private:
67 void flush();
68
69 // Only the first three entries and the newest identity are needed for
70 // either individual notifications or a summary, even for a huge sync.
71 QList<PendingMail> m_preview;
72 int m_pendingCount = 0;
73 qint64 m_newestUid = -1;
74 qint64 m_newestFolderId = -1;
75 QTimer m_debounce;
76 int m_debounceMs = 3000;
77 QElapsedTimer m_burst; // since the first mail of the pending burst
78 bool m_suppressed = true;
79 };
80