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% 5 / 0 / 5
Branches: -% 0 / 0 / 0

service/MailPayloadExportService.h
Line Branch Exec Source
1 #pragma once
2
3 #include "data/MailPayloadReader.h"
4 #include <QObject>
5 #include <QPointer>
6 #include <QThreadPool>
7 #include <functional>
8 #include <memory>
9 #include <optional>
10
11 // A complete private snapshot. Keeping the lease alive keeps the file alive;
12 // no QObject or open SQLite handle crosses the worker boundary.
13 class MailPayloadPreview {
14 public:
15 MailPayloadPreview(const MailPayloadPreview &) = delete;
16 MailPayloadPreview &operator=(const MailPayloadPreview &) = delete;
17 ~MailPayloadPreview();
18 10 const QString &path() const { return m_path; }
19 6 const MailPayloadReadResult &result() const { return m_result; }
20 private:
21 friend class MailPayloadExportService;
22 5 MailPayloadPreview(QString path, MailPayloadReadResult result)
23 5 : m_path(std::move(path)), m_result(std::move(result)) {}
24 QString m_path;
25 MailPayloadReadResult m_result;
26 };
27
28 // Explicit file exports queue identity and destination metadata, never BLOBs.
29 // One application worker owns SQLite and the temporary output file.
30 class MailPayloadExportService : public QObject {
31 public:
32 using Callback = std::function<void(MailPayloadReadResult)>;
33 using Preview = std::shared_ptr<const MailPayloadPreview>;
34 using PreviewCallback = std::function<void(Preview, MailPayloadReadResult)>;
35 static constexpr int MaximumRequests = 8;
36 explicit MailPayloadExportService(QObject *parent = nullptr);
37 ~MailPayloadExportService() override;
38 static MailPayloadExportService *shared();
39 void save(QObject *owner, MailPayloadRequest request, QString destination,
40 bool overwriteExisting, Callback callback);
41 void saveInDirectory(QObject *owner, MailPayloadRequest request, QString directory,
42 QString suggestedName, Callback callback);
43 void cancel(QObject *owner);
44 void preparePreview(QObject *owner, MailPayloadRequest request, QString cacheDirectory,
45 PreviewCallback callback);
46 void savePreview(QObject *owner, Preview preview, QString destination, Callback callback);
47 // T-87.G1: bounded in-memory window into a stored payload (source viewer).
48 // Delivered on the GUI thread; bytes never exceed MailPayloadRequest::
49 // maxBytes and are capped by MaximumWindowBytes.
50 static constexpr qint64 MaximumWindowBytes = 8LL * 1024 * 1024;
51 using BytesCallback = std::function<void(QByteArray bytes, MailPayloadReadResult)>;
52 void readWindow(QObject *owner, MailPayloadRequest request, BytesCallback callback);
53 28 int pendingCount() const { return m_requests.size(); }
54
55 private:
56 friend class TestMailPayloadExport;
57 struct Request {
58 QPointer<QObject> owner;
59 QMetaObject::Connection destroyed;
60 std::atomic_bool cancelled{false};
61 46 ~Request() { QObject::disconnect(destroyed); }
62 };
63 void stop();
64 struct Result { MailPayloadReadResult read; Preview preview; QByteArray bytes; };
65 using Work = std::function<Result(const std::atomic_bool &)>;
66 void submit(QObject *owner, Work work, std::function<void(Result)> callback);
67 void enqueue(QObject *owner, MailPayloadRequest request, QString destination,
68 bool overwriteExisting, Callback callback,
69 std::optional<QString> suggestedName);
70 QThreadPool m_pool;
71 QList<std::shared_ptr<Request>> m_requests;
72 bool m_stopping = false;
73 };
74