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

presentation/FolderPresentationModel.h
Line Branch Exec Source
1 #pragma once
2
3 #include "data/Models.h"
4 #include <QAbstractItemModel>
5 #include <QHash>
6 #include <memory>
7 #include <vector>
8
9 // Folder metadata stays in C++; QML receives individual roles, not mailbox data.
10 class FolderPresentationModel final : public QAbstractItemModel {
11 Q_OBJECT
12 public:
13 enum Role { PathRole = Qt::UserRole + 1, NameRole, SelectableRole, UnreadRole,
14 KindRole, ResultCountRole, IconRole, ColorRole };
15 // Resolved folder appearance: MDI code point and optional #hex tint.
16 struct Appearance {
17 int glyph = 0;
18 QString color;
19 };
20 802 explicit FolderPresentationModel(QObject *parent = nullptr) : QAbstractItemModel(parent) {}
21 QModelIndex index(int row, int column = 0, const QModelIndex &parent = {}) const override;
22 QModelIndex parent(const QModelIndex &index) const override;
23 int rowCount(const QModelIndex &parent = {}) const override;
24 int columnCount(const QModelIndex &parent = {}) const override;
25 Qt::ItemFlags flags(const QModelIndex &index) const override;
26 QVariant data(const QModelIndex &index, int role) const override;
27 QHash<int, QByteArray> roleNames() const override;
28 void setFolders(const QList<FolderInfo> &folders, const QStringList &hidden);
29 void setUnread(const QString &path, int unread);
30 // Per-path appearance; paths without an entry (synthetic parents) use
31 // `fallbackGlyph`. Updates rows in place (dataChanged), never resets the tree.
32 void setAppearance(const QHash<QString, Appearance> &byPath, int fallbackGlyph);
33 QStringList branchPaths() const;
34 // Sprint 101 D-32: every folder node in display order (depth first, as
35 // the tree shows them), synthetic parents included.
36 struct TreeRow {
37 QString path;
38 QString name;
39 int depth = 0;
40 };
41 QList<TreeRow> treeRows() const;
42 bool isSelectable(const QString &path) const;
43 QStringList matchingPaths(const QString &prefix, int limit = 30) const;
44 // Sprint 98 S98.1.9 (D-20): ranked folder candidates of the command bar.
45 // Order: exact leaf name, leaf prefix, start of a path segment, localized
46 // special-folder name ("Gesendet" → Sent), substring; within a match
47 // class the `preferred` paths (predicted move targets, marked suggested)
48 // come first, then `recent` paths, then tree order. Bounded by `limit`.
49 struct Completion {
50 QString path; // raw IMAP path, used for the action
51 QString name; // leaf display name
52 QString parent; // display path of the parent ("" at the top level)
53 int unread = 0;
54 bool suggested = false;
55 };
56 QList<Completion> completionCandidates(const QString &text, const QStringList &preferred = {},
57 const QStringList &recent = {}, int limit = 50) const;
58 QString firstSelectable() const;
59 Q_INVOKABLE QModelIndex indexForPath(const QString &path) const;
60
2/2
✓ Branch 2 → 3 taken 23 times.
✓ Branch 3 → 4 taken 23 times.
23 Q_INVOKABLE QString pathForIndex(const QModelIndex &index) const { return data(index, PathRole).toString(); }
61 private:
62 struct Node {
63 FolderInfo folder;
64 Node *parent = nullptr;
65 QList<Node *> children;
66 int row = 0;
67 int unread = 0;
68 bool synthetic = true;
69 };
70 Node *node(const QModelIndex &index) const;
71 Node *ensureNode(const QString &path, const QString &delimiter);
72 Node m_root;
73 std::vector<std::unique_ptr<Node>> m_nodes;
74 QHash<QString, Node *> m_paths;
75 QStringList m_selectablePaths;
76 QHash<QString, Appearance> m_appearance;
77 // S98.1.9: lowercase display paths for the command-bar completion, built
78 // on the first completion after setFolders() (one pass instead of one per
79 // keystroke; measured in test_command_completion, SPRINT-98 §13).
80 struct CompletionIndexEntry {
81 const Node *node = nullptr;
82 QString display; // "Projekte/MailJD"
83 QString parent; // "Projekte"
84 QString leafLower;
85 QString displayLower;
86 QString pathLower;
87 QStringList special; // localized special-folder words
88 };
89 void buildCompletionIndex() const;
90 mutable QList<CompletionIndexEntry> m_completionIndex;
91 mutable bool m_completionIndexValid = false;
92 int m_fallbackGlyph = 0;
93 };
94