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% 3 / 0 / 3
Functions: 100.0% 3 / 0 / 3
Branches: 77.8% 14 / 0 / 18

app/NamedCommandCatalog.h
Line Branch Exec Source
1 #pragma once
2 #include "CommandRegistry.h"
3 #include <QList>
4 #include <QStringList>
5
6 // What follows a command name or a fixed value (Sprint 98 D-18). Each kind
7 // has one completion provider in CommandCompletion (rule 10) and decides
8 // whether a command line may be stored in the history (D-9).
9 enum class CommandArgument : quint8 {
10 None, // nothing may follow
11 Values, // only the fixed values of the command
12 Text, // free text: names, filter text (never stored)
13 Folder, // a folder path (stored: it names a place)
14 Label, // a label/IMAP keyword (stored)
15 Address, // a mail address (never stored)
16 Date, // a date word or date (stored)
17 Query, // a search query (never stored)
18 TaskLine, // "Title /list @due !priority #tag" (never stored)
19 EventLine, // "Title date time @place /calendar" (never stored)
20 RuleLine, // "conditions → actions" (never stored)
21 ContactLine, // "Name <address>" (never stored)
22 Place, // Sprint 100 D-29: a settings place — page, group or setting id (stored: it names a place)
23 Account, // Sprint 100 D-29: a configured account's address (never stored)
24 };
25
26 // A fixed value at the argument position ("filter unread", "folder rename").
27 struct NamedCommandValue {
28 const char *word = ""; // lowercase English, executed as typed
29 const char *description = ""; // QT_TRANSLATE_NOOP("NamedCommandCatalog", …)
30 const char *keywords = ""; // de/en search words; found, never executed (D-14)
31 const char *registryId = nullptr; // runs this registry command
32 CommandArgument then = CommandArgument::None; // what follows the value
33 bool thenRequired = false;
34 const char *thenSyntax = ""; // "<name>", "[folder]"
35 const char *stateKey = nullptr; // toggle value: its on/off state (S98.4.11)
36 CommandContexts featured; // listed under "Here" in the empty state (S98.5.1)
37 // D-15a: in a line of several values, values of one group exclude each
38 // other ("mark read unread"); an `alone` value stands only by itself
39 // ("filter off", "unlabel all").
40 const char *group = nullptr;
41 bool alone = false;
42 };
43
44 struct NamedCommandSpec {
45 QString name;
46 const char *category = ""; // QT_TRANSLATE_NOOP("NamedCommandCatalog", …)
47 const char *description = ""; // QT_TRANSLATE_NOOP("NamedCommandCatalog", …)
48 CommandContexts contexts;
49 const char *registryId = nullptr; // runs this registry command when no value says otherwise
50 CommandArgument argument = CommandArgument::None;
51 bool argumentRequired = false;
52 const char *syntax = ""; // argument notation of D-15, e.g. "<label>"
53 const char *example = ""; // a complete example line
54 QList<NamedCommandValue> values;
55 const char *keywords = ""; // de/en search words (D-14)
56 bool destructive = false; // never runs from a prefix or pre-highlight (D-6)
57 // Values, or any other text (F100-74: "filter <words>" filters the list
58 // by subject and sender, live while typing).
59 bool freeText = false;
60 // D-15a: several values or labels in one line ("filter unread important",
61 // "mark read important", "label Work Later"); see ParsedNamedCommand::values().
62 bool several = false;
63 const char *stateKey = nullptr; // toggle command: its on/off state (S98.4.11)
64 CommandContexts featured; // listed under "Here" in the empty state (S98.5.1)
65 QStringList aliases; // removed by the clean-up (S98.4.9)
66
67 5457 bool requiresArgument() const { return argumentRequired; }
68 bool optionalArgument() const { return argument != CommandArgument::None && !argumentRequired; }
69 const NamedCommandValue *value(const QString &word) const;
70 };
71
72 struct ParsedNamedCommand {
73 const NamedCommandSpec *spec = nullptr; // set whenever the first word names a command
74 QString argument;
75 // The argument fits the command: an allowed value, what the value takes,
76 // nothing after a command without argument.
77 bool argumentValid = true;
78
8/8
✓ Branch 2 → 3 taken 2271 times.
✓ Branch 2 → 9 taken 54 times.
✓ Branch 3 → 4 taken 2202 times.
✓ Branch 3 → 9 taken 69 times.
✓ Branch 5 → 6 taken 962 times.
✓ Branch 5 → 8 taken 1240 times.
✓ Branch 7 → 8 taken 852 times.
✓ Branch 7 → 9 taken 110 times.
2325 bool complete() const { return spec && argumentValid && (!spec->requiresArgument() || !argument.isEmpty()); }
79
6/10
✓ Branch 2 → 3 taken 277 times.
✗ Branch 2 → 8 not taken.
✓ Branch 4 → 5 taken 50 times.
✓ Branch 4 → 6 taken 227 times.
✓ Branch 6 → 7 taken 227 times.
✓ Branch 7 → 9 taken 277 times.
✓ Branch 10 → 11 taken 277 times.
✗ Branch 10 → 12 not taken.
✗ Branch 14 → 15 not taken.
✗ Branch 14 → 16 not taken.
554 QString text() const { return spec ? spec->name + (argument.isEmpty() ? QString{} : " " + argument) : QString{}; }
80 // The fixed values the argument starts with — one at most unless the
81 // command takes several (D-15a) — and the text after them ("folder rename
82 // Projekte" → value "rename", rest "Projekte"; "filter unread important
83 // invoice" → values "unread", "important", rest "invoice").
84 QList<const NamedCommandValue *> values() const;
85 const NamedCommandValue *value() const; // the first of values(), nullptr when none
86 QString rest() const;
87 // The words of the argument ("label Work Later" → "Work", "Later").
88 QStringList words() const;
89 // The registry command this line runs: the id of its only value, else the
90 // command's. A line of several parts runs the command's own handler.
91 QString registryId() const;
92 };
93
94 // Named commands of the command bar. The catalog is the single source of
95 // names, arguments, keywords, registry ids and help (D-18, rule 16);
96 // docs/COMMANDS.md is generated from referenceSnapshot() and kept in sync
97 // by a test. Named commands are not keyboard shortcuts: setters remain
98 // idempotent and arguments retain case and internal whitespace.
99 class NamedCommandCatalog {
100 public:
101 static const QList<NamedCommandSpec> &specs();
102 static const NamedCommandSpec *find(const QString &name);
103 static ParsedNamedCommand parse(const QString &input);
104 static QStringList names(CommandContext context);
105 static QString description(const NamedCommandSpec &spec);
106 static QString description(const NamedCommandValue &value);
107 static QString category(const NamedCommandSpec &spec);
108 // D-9: whether a parsed line may enter the command history.
109 static bool storable(const ParsedNamedCommand &parsed);
110 // D-15a: whether `values` may stand together in one line: no value twice,
111 // one per group, an `alone` value only by itself (`more`: other words follow).
112 static bool combinable(const QList<const NamedCommandValue *> &values, bool more);
113 // Lint of D-14/D-15/D-18; one message per violation (empty = clean).
114 static QStringList lint();
115 // Markdown reference of every command (docs/COMMANDS.md).
116 static QString referenceSnapshot();
117 };
118