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

data/ICalendar.h
Line Branch Exec Source
1 #pragma once
2
3 #include <QList>
4 #include <QString>
5 #include <QStringList>
6
7 // RFC 5545 content model: a lossless component tree (Sprint 93 S93.1.1).
8 //
9 // The tree keeps every property, parameter and sub-component it reads.
10 // A property that is never modified is written back with its original
11 // (unfolded) content line, so values MailJD does not understand survive a
12 // parse -> serialize round trip byte for byte (apart from line folding).
13 // Modifying a property through the setters drops that original line and
14 // re-renders it from name/parameters/value.
15 //
16 // Values are kept in their wire form (TEXT escaping included); use
17 // unescapeText()/escapeText() at the call site that interprets them.
18 namespace ICal {
19
20 struct Parameter {
21 QString name; // upper case
22 QString value; // unquoted; multi-values stay comma-separated
23 };
24
25 struct Property {
26 QString name; // upper case, e.g. "DTSTART", "X-GOOGLE-CONFERENCE"
27 QList<Parameter> parameters;
28 QString value;
29 // Original unfolded content line; empty once the property was modified
30 // or for properties created in code.
31 QString originalLine;
32
33 QString parameter(const QString &name) const;
34 bool hasParameter(const QString &name) const;
35 void setParameter(const QString &name, const QString &value);
36 void removeParameter(const QString &name);
37 void setValue(const QString &newValue);
38 // The unfolded content line (original when untouched).
39 QString contentLine() const;
40 };
41
42 struct Component {
43 QString name; // upper case, e.g. "VCALENDAR", "VEVENT", "VALARM"
44 QList<Property> properties;
45 QList<Component> components;
46
47 const Property *property(const QString &name) const;
48 Property *property(const QString &name);
49 QList<Property> propertiesNamed(const QString &name) const;
50 QString value(const QString &name) const;
51 bool hasProperty(const QString &name) const;
52 // Replaces the first property of that name (keeping its position) and
53 // removes further ones; appends when absent.
54 void setProperty(const Property &property);
55 void setPropertyValue(const QString &name, const QString &value);
56 int removeProperties(const QString &name);
57 35887 void appendProperty(const Property &property) { properties.append(property); }
58 QList<Component> componentsNamed(const QString &name) const;
59 int removeComponents(const QString &name);
60 };
61
62 // Parses a text that contains one or more top-level components (normally a
63 // single VCALENDAR). Lines outside components, malformed lines without a
64 // colon and stray END lines are skipped with a log warning; unbalanced
65 // BEGIN/END fails. Returns false and sets *error on failure.
66 // `skippedLines` (optional) counts the lines that were dropped; writers that
67 // patch a resource refuse to write one whose parse was lossy (Sprint 97).
68 // Components nest at most kMaxComponentDepth deep (S106-124): real calendars
69 // use three levels (VCALENDAR › VEVENT › VALARM); a deeper text fails, so
70 // the recursive serializer and destructor can never run out of stack.
71 constexpr int kMaxComponentDepth = 32;
72 bool parse(const QString &text, QList<Component> *components, QString *error = nullptr,
73 int *skippedLines = nullptr);
74 // Convenience: the first top-level component named `name` (empty on error).
75 Component parseFirst(const QString &text, const QString &name = QStringLiteral("VCALENDAR"),
76 QString *error = nullptr);
77
78 // Serializes with CRLF line ends and folds lines at 75 octets without
79 // splitting UTF-8 sequences (RFC 5545 §3.1).
80 QString serialize(const Component &component);
81 QString foldLine(const QString &line);
82
83 // TEXT value escaping (RFC 5545 §3.3.11): one pass, so "\\n" stays a
84 // backslash followed by "n".
85 QString unescapeText(const QString &value);
86 QString escapeText(const QString &value);
87
88 // Splits a comma-separated multi-value property value (EXDATE, RDATE,
89 // CATEGORIES) while honouring backslash-escaped commas.
90 QStringList splitValues(const QString &value);
91
92 } // namespace ICal
93