data/SieveRuleRender.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Rendering half of the rule codec (SieveRuleCodec.h): Rule/Vacation -> | ||
| 2 | // Sieve bytes in the script's style, and the extensions each one needs. | ||
| 3 | #include "SieveRuleCodec.h" | ||
| 4 | |||
| 5 | #include <QCryptographicHash> | ||
| 6 | |||
| 7 | namespace Sieve { | ||
| 8 | |||
| 9 | namespace { | ||
| 10 | |||
| 11 | // S106-102: every string is written with the script's line end, so a | ||
| 12 | // dirty re-render of a CRLF script keeps the match text of its conditions. | ||
| 13 | 753 | QByteArray quoted(const QString &value, const Style &style) { | |
| 14 | 753 | return stringLiteral(value, style.lineEnd); | |
| 15 | } | ||
| 16 | |||
| 17 | 677 | QByteArray markerLine(const QString &name, const Style &style) { | |
| 18 | 677 | QString clean = name; | |
| 19 |
1/1✓ Branch 7 → 8 taken 677 times.
|
677 | clean.replace(QLatin1Char('\r'), QLatin1Char(' ')); |
| 20 |
1/1✓ Branch 12 → 13 taken 677 times.
|
677 | clean.replace(QLatin1Char('\n'), QLatin1Char(' ')); |
| 21 |
4/4✓ Branch 13 → 14 taken 677 times.
✓ Branch 14 → 15 taken 677 times.
✓ Branch 15 → 16 taken 677 times.
✓ Branch 16 → 17 taken 677 times.
|
1354 | return "# rule:[" + clean.toUtf8() + "]" + style.lineEnd; |
| 22 | 677 | } | |
| 23 | |||
| 24 | 865 | QByteArray renderCondition(const Condition &condition, const Style &style) { | |
| 25 | 865 | QByteArray out; | |
| 26 |
2/2✓ Branch 2 → 3 taken 20 times.
✓ Branch 2 → 4 taken 845 times.
|
865 | if (condition.negated) |
| 27 |
1/1✓ Branch 3 → 4 taken 20 times.
|
20 | out += "not "; |
| 28 |
4/5✓ Branch 4 → 5 taken 196 times.
✓ Branch 4 → 7 taken 623 times.
✓ Branch 4 → 9 taken 38 times.
✓ Branch 4 → 11 taken 8 times.
✗ Branch 4 → 13 not taken.
|
865 | switch (condition.kind) { |
| 29 |
1/1✓ Branch 5 → 6 taken 196 times.
|
196 | case Condition::Kind::Address: out += "address"; break; |
| 30 |
1/1✓ Branch 7 → 8 taken 623 times.
|
623 | case Condition::Kind::Header: out += "header"; break; |
| 31 |
1/1✓ Branch 9 → 10 taken 38 times.
|
38 | case Condition::Kind::Size: out += "size"; break; |
| 32 |
1/1✓ Branch 11 → 12 taken 8 times.
|
8 | case Condition::Kind::Body: out += "body"; break; |
| 33 | } | ||
| 34 |
2/2✓ Branch 13 → 14 taken 38 times.
✓ Branch 13 → 39 taken 827 times.
|
865 | if (condition.kind == Condition::Kind::Size) { |
| 35 |
3/3✓ Branch 14 → 15 taken 28 times.
✓ Branch 14 → 16 taken 10 times.
✓ Branch 17 → 18 taken 38 times.
|
38 | out += condition.sizeOver ? " :over " : " :under "; |
| 36 | 38 | const quint64 size = condition.sizeLimit; | |
| 37 |
3/4✓ Branch 18 → 19 taken 38 times.
✗ Branch 18 → 26 not taken.
✓ Branch 19 → 20 taken 22 times.
✓ Branch 19 → 26 taken 16 times.
|
38 | if (size > 0 && size % (1024ULL * 1024) == 0) |
| 38 |
3/3✓ Branch 20 → 21 taken 22 times.
✓ Branch 21 → 22 taken 22 times.
✓ Branch 22 → 23 taken 22 times.
|
22 | out += QByteArray::number(size / (1024ULL * 1024)) + "M"; |
| 39 |
2/4✓ Branch 26 → 27 taken 16 times.
✗ Branch 26 → 34 not taken.
✓ Branch 27 → 28 taken 16 times.
✗ Branch 27 → 34 not taken.
|
16 | else if (size > 0 && size % 1024ULL == 0) |
| 40 |
3/3✓ Branch 28 → 29 taken 16 times.
✓ Branch 29 → 30 taken 16 times.
✓ Branch 30 → 31 taken 16 times.
|
16 | out += QByteArray::number(size / 1024ULL) + "K"; |
| 41 | else | ||
| 42 | ✗ | out += QByteArray::number(size); | |
| 43 | 38 | return out; | |
| 44 | } | ||
| 45 |
2/2✓ Branch 40 → 41 taken 15 times.
✓ Branch 40 → 47 taken 812 times.
|
827 | if (!condition.comparator.isEmpty()) |
| 46 |
3/3✓ Branch 41 → 42 taken 15 times.
✓ Branch 42 → 43 taken 15 times.
✓ Branch 43 → 44 taken 15 times.
|
15 | out += " :comparator " + quoted(condition.comparator, style); |
| 47 |
6/6✓ Branch 47 → 48 taken 196 times.
✓ Branch 47 → 52 taken 631 times.
✓ Branch 50 → 51 taken 9 times.
✓ Branch 50 → 52 taken 187 times.
✓ Branch 53 → 54 taken 9 times.
✓ Branch 53 → 60 taken 818 times.
|
827 | if (condition.kind == Condition::Kind::Address && condition.addressPart != QLatin1String("all")) |
| 48 |
3/3✓ Branch 54 → 55 taken 9 times.
✓ Branch 55 → 56 taken 9 times.
✓ Branch 56 → 57 taken 9 times.
|
9 | out += " :" + condition.addressPart.toLatin1(); |
| 49 |
3/3✓ Branch 60 → 61 taken 827 times.
✓ Branch 61 → 62 taken 827 times.
✓ Branch 62 → 63 taken 827 times.
|
827 | out += " :" + condition.matchType.toLatin1(); |
| 50 |
2/2✓ Branch 65 → 66 taken 819 times.
✓ Branch 65 → 72 taken 8 times.
|
827 | if (condition.kind != Condition::Kind::Body) |
| 51 |
3/3✓ Branch 66 → 67 taken 819 times.
✓ Branch 67 → 68 taken 819 times.
✓ Branch 68 → 69 taken 819 times.
|
819 | out += " " + stringListLiteral(condition.headers, style.lineEnd); |
| 52 |
3/3✓ Branch 72 → 73 taken 827 times.
✓ Branch 73 → 74 taken 827 times.
✓ Branch 74 → 75 taken 827 times.
|
827 | out += " " + stringListLiteral(condition.values, style.lineEnd); |
| 53 | 827 | return out; | |
| 54 | ✗ | } | |
| 55 | |||
| 56 | 701 | QByteArray renderTest(const Rule &rule, const Style &style) { | |
| 57 |
2/2✓ Branch 3 → 4 taken 32 times.
✓ Branch 3 → 6 taken 669 times.
|
701 | if (rule.conditions.isEmpty()) |
| 58 |
1/1✓ Branch 4 → 5 taken 32 times.
|
32 | return "true"; |
| 59 |
6/6✓ Branch 7 → 8 taken 487 times.
✓ Branch 7 → 10 taken 182 times.
✓ Branch 8 → 9 taken 392 times.
✓ Branch 8 → 10 taken 95 times.
✓ Branch 11 → 12 taken 392 times.
✓ Branch 11 → 15 taken 277 times.
|
669 | if (rule.conditions.size() == 1 && !rule.explicitList) |
| 60 |
1/1✓ Branch 13 → 14 taken 392 times.
|
392 | return renderCondition(rule.conditions.first(), style); |
| 61 |
3/3✓ Branch 15 → 16 taken 255 times.
✓ Branch 15 → 17 taken 22 times.
✓ Branch 18 → 19 taken 277 times.
|
277 | QByteArray out = rule.matchAll ? "allof (" : "anyof ("; |
| 62 |
2/2✓ Branch 28 → 20 taken 473 times.
✓ Branch 28 → 29 taken 277 times.
|
750 | for (int i = 0; i < rule.conditions.size(); ++i) { |
| 63 |
2/2✓ Branch 20 → 21 taken 196 times.
✓ Branch 20 → 22 taken 277 times.
|
473 | if (i > 0) |
| 64 |
1/1✓ Branch 21 → 22 taken 196 times.
|
196 | out += ", "; |
| 65 |
2/2✓ Branch 23 → 24 taken 473 times.
✓ Branch 24 → 25 taken 473 times.
|
473 | out += renderCondition(rule.conditions.at(i), style); |
| 66 | } | ||
| 67 |
1/1✓ Branch 29 → 30 taken 277 times.
|
277 | out += ")"; |
| 68 | 277 | return out; | |
| 69 | 277 | } | |
| 70 | |||
| 71 | 767 | QByteArray renderAction(const Action &action, const Style &style) { | |
| 72 |
8/9✓ Branch 2 → 3 taken 599 times.
✓ Branch 2 → 26 taken 12 times.
✓ Branch 2 → 42 taken 61 times.
✓ Branch 2 → 49 taken 24 times.
✓ Branch 2 → 56 taken 8 times.
✓ Branch 2 → 63 taken 36 times.
✓ Branch 2 → 64 taken 10 times.
✓ Branch 2 → 65 taken 17 times.
✗ Branch 2 → 72 not taken.
|
767 | switch (action.kind) { |
| 73 | 599 | case Action::Kind::FileInto: { | |
| 74 |
1/1✓ Branch 3 → 4 taken 599 times.
|
599 | QByteArray out = "fileinto"; |
| 75 |
2/2✓ Branch 4 → 5 taken 12 times.
✓ Branch 4 → 6 taken 587 times.
|
599 | if (action.copy) |
| 76 |
1/1✓ Branch 5 → 6 taken 12 times.
|
12 | out += " :copy"; |
| 77 |
2/2✓ Branch 6 → 7 taken 8 times.
✓ Branch 6 → 8 taken 591 times.
|
599 | if (action.create) |
| 78 |
1/1✓ Branch 7 → 8 taken 8 times.
|
8 | out += " :create"; |
| 79 |
2/2✓ Branch 9 → 10 taken 4 times.
✓ Branch 9 → 16 taken 595 times.
|
599 | if (!action.specialUse.isEmpty()) |
| 80 |
3/3✓ Branch 10 → 11 taken 4 times.
✓ Branch 11 → 12 taken 4 times.
✓ Branch 12 → 13 taken 4 times.
|
4 | out += " :specialuse " + quoted(action.specialUse, style); |
| 81 |
4/4✓ Branch 16 → 17 taken 599 times.
✓ Branch 17 → 18 taken 599 times.
✓ Branch 18 → 19 taken 599 times.
✓ Branch 19 → 20 taken 599 times.
|
599 | return out + " " + quoted(action.target, style) + ";"; |
| 82 | 599 | } | |
| 83 | 12 | case Action::Kind::Redirect: | |
| 84 |
4/5✓ Branch 27 → 28 taken 12 times.
✗ Branch 27 → 29 not taken.
✓ Branch 30 → 31 taken 12 times.
✓ Branch 31 → 32 taken 12 times.
✓ Branch 32 → 33 taken 12 times.
|
24 | return QByteArray("redirect") + (action.copy ? " :copy" : "") + " " + |
| 85 |
3/3✓ Branch 26 → 27 taken 12 times.
✓ Branch 33 → 34 taken 12 times.
✓ Branch 34 → 35 taken 12 times.
|
36 | quoted(action.target, style) + ";"; |
| 86 |
3/3✓ Branch 42 → 43 taken 61 times.
✓ Branch 43 → 44 taken 61 times.
✓ Branch 44 → 45 taken 61 times.
|
61 | case Action::Kind::AddFlag: return "addflag " + stringListLiteral(action.flags, style.lineEnd) + ";"; |
| 87 |
3/3✓ Branch 49 → 50 taken 24 times.
✓ Branch 50 → 51 taken 24 times.
✓ Branch 51 → 52 taken 24 times.
|
24 | case Action::Kind::SetFlag: return "setflag " + stringListLiteral(action.flags, style.lineEnd) + ";"; |
| 88 | 8 | case Action::Kind::RemoveFlag: | |
| 89 |
3/3✓ Branch 56 → 57 taken 8 times.
✓ Branch 57 → 58 taken 8 times.
✓ Branch 58 → 59 taken 8 times.
|
8 | return "removeflag " + stringListLiteral(action.flags, style.lineEnd) + ";"; |
| 90 | 36 | case Action::Kind::Keep: return "keep;"; | |
| 91 | 10 | case Action::Kind::Discard: return "discard;"; | |
| 92 |
3/3✓ Branch 65 → 66 taken 17 times.
✓ Branch 66 → 67 taken 17 times.
✓ Branch 67 → 68 taken 17 times.
|
17 | case Action::Kind::Reject: return "reject " + stringLiteral(action.target, style.lineEnd) + ";"; |
| 93 | } | ||
| 94 | ✗ | return {}; | |
| 95 | } | ||
| 96 | |||
| 97 | // `braceOnOwnLine` is forced for the disabled form: its test is a comment | ||
| 98 | // up to the end of the line, so a "{" on that line would be commented out. | ||
| 99 | 738 | QByteArray renderBlockBody(const QList<QByteArray> &commands, const Style &style, | |
| 100 | bool braceOnOwnLine) { | ||
| 101 |
2/2✓ Branch 2 → 3 taken 679 times.
✓ Branch 2 → 4 taken 59 times.
|
738 | QByteArray out = braceOnOwnLine ? style.lineEnd + "{" : QByteArray(" {"); |
| 102 |
1/1✓ Branch 5 → 6 taken 738 times.
|
738 | out += style.lineEnd; |
| 103 |
2/2✓ Branch 16 → 8 taken 1253 times.
✓ Branch 16 → 17 taken 738 times.
|
1991 | for (const QByteArray &command : commands) |
| 104 |
3/3✓ Branch 9 → 10 taken 1253 times.
✓ Branch 10 → 11 taken 1253 times.
✓ Branch 11 → 12 taken 1253 times.
|
1253 | out += style.indent + command + style.lineEnd; |
| 105 |
2/2✓ Branch 17 → 18 taken 738 times.
✓ Branch 18 → 19 taken 738 times.
|
738 | out += "}" + style.lineEnd; |
| 106 | 738 | return out; | |
| 107 | ✗ | } | |
| 108 | |||
| 109 | 738 | QByteArray renderIfHeader(const QByteArray &test, bool enabled) { | |
| 110 |
2/2✓ Branch 2 → 3 taken 562 times.
✓ Branch 2 → 5 taken 176 times.
|
738 | if (enabled) |
| 111 |
1/1✓ Branch 3 → 4 taken 562 times.
|
562 | return "if " + test; |
| 112 | // Roundcube's disabled form keeps the test as a comment (D-3). S106-089: | ||
| 113 | // a test that spans lines (a multi-line string) continues on "# " lines, | ||
| 114 | // so every line of it stays commented out (decoded by disabledTest()). | ||
| 115 |
1/1✓ Branch 5 → 6 taken 176 times.
|
176 | QByteArray out = "if false # "; |
| 116 |
2/2✓ Branch 19 → 7 taken 7777 times.
✓ Branch 19 → 20 taken 176 times.
|
7953 | for (int i = 0; i < test.size(); ++i) { |
| 117 |
1/1✓ Branch 8 → 9 taken 7777 times.
|
7777 | out += test.at(i); |
| 118 |
6/6✓ Branch 10 → 11 taken 4 times.
✓ Branch 10 → 14 taken 7773 times.
✓ Branch 12 → 13 taken 3 times.
✓ Branch 12 → 14 taken 1 time.
✓ Branch 15 → 16 taken 3 times.
✓ Branch 15 → 17 taken 7774 times.
|
7777 | if (test.at(i) == '\n' && i + 1 < test.size()) |
| 119 |
1/1✓ Branch 16 → 17 taken 3 times.
|
3 | out += "# "; |
| 120 | } | ||
| 121 | 176 | return out; | |
| 122 | 176 | } | |
| 123 | |||
| 124 | 24 | QByteArray dateTest(const QString &zone, const char *relation, const QDate &day, | |
| 125 | const Style &style) { | ||
| 126 | 24 | QByteArray out = "currentdate"; | |
| 127 |
2/2✓ Branch 4 → 5 taken 19 times.
✓ Branch 4 → 11 taken 5 times.
|
24 | if (!zone.isEmpty()) |
| 128 |
3/3✓ Branch 5 → 6 taken 19 times.
✓ Branch 6 → 7 taken 19 times.
✓ Branch 7 → 8 taken 19 times.
|
19 | out += " :zone " + quoted(zone, style); |
| 129 |
3/3✓ Branch 13 → 14 taken 24 times.
✓ Branch 14 → 15 taken 24 times.
✓ Branch 15 → 16 taken 24 times.
|
48 | out += QByteArray(" :value \"") + relation + "\" \"date\" " + |
| 130 |
4/4✓ Branch 11 → 12 taken 24 times.
✓ Branch 12 → 13 taken 24 times.
✓ Branch 16 → 17 taken 24 times.
✓ Branch 17 → 18 taken 24 times.
|
72 | quoted(day.toString(Qt::ISODate), style); |
| 131 | 24 | return out; | |
| 132 | ✗ | } | |
| 133 | |||
| 134 | 37 | QByteArray vacationTest(const Vacation &vacation, const Style &style) { | |
| 135 | 37 | QList<QByteArray> tests; | |
| 136 |
3/3✓ Branch 2 → 3 taken 37 times.
✓ Branch 3 → 4 taken 12 times.
✓ Branch 3 → 8 taken 25 times.
|
37 | if (vacation.firstDay.isValid()) |
| 137 |
2/2✓ Branch 4 → 5 taken 12 times.
✓ Branch 5 → 6 taken 12 times.
|
12 | tests.append(dateTest(vacation.zone, "ge", vacation.firstDay, style)); |
| 138 |
3/3✓ Branch 8 → 9 taken 37 times.
✓ Branch 9 → 10 taken 12 times.
✓ Branch 9 → 14 taken 25 times.
|
37 | if (vacation.lastDay.isValid()) |
| 139 |
2/2✓ Branch 10 → 11 taken 12 times.
✓ Branch 11 → 12 taken 12 times.
|
12 | tests.append(dateTest(vacation.zone, "le", vacation.lastDay, style)); |
| 140 |
2/2✓ Branch 15 → 16 taken 24 times.
✓ Branch 15 → 18 taken 13 times.
|
37 | if (tests.isEmpty()) |
| 141 |
1/1✓ Branch 16 → 17 taken 24 times.
|
24 | return "true"; |
| 142 |
2/2✓ Branch 19 → 20 taken 2 times.
✓ Branch 19 → 22 taken 11 times.
|
13 | if (tests.size() == 1) |
| 143 |
1/1✓ Branch 20 → 21 taken 2 times.
|
2 | return tests.first(); |
| 144 |
4/4✓ Branch 24 → 25 taken 11 times.
✓ Branch 25 → 26 taken 11 times.
✓ Branch 26 → 27 taken 11 times.
✓ Branch 27 → 28 taken 11 times.
|
11 | return "allof (" + tests.at(0) + ", " + tests.at(1) + ")"; |
| 145 | 37 | } | |
| 146 | |||
| 147 | 1953 | void appendUnique(QStringList *list, const QString &value) { | |
| 148 |
2/2✓ Branch 3 → 4 taken 1941 times.
✓ Branch 3 → 5 taken 12 times.
|
1953 | if (!list->contains(value)) |
| 149 | 1941 | list->append(value); | |
| 150 | 1953 | } | |
| 151 | |||
| 152 | } // namespace | ||
| 153 | |||
| 154 | 701 | QByteArray renderRule(const Rule &rule, const Style &style) { | |
| 155 | 701 | QList<QByteArray> commands; | |
| 156 |
2/2✓ Branch 10 → 4 taken 767 times.
✓ Branch 10 → 11 taken 701 times.
|
1468 | for (const Action &action : rule.actions) |
| 157 |
2/2✓ Branch 5 → 6 taken 767 times.
✓ Branch 6 → 7 taken 767 times.
|
767 | commands.append(renderAction(action, style)); |
| 158 |
2/2✓ Branch 11 → 12 taken 449 times.
✓ Branch 11 → 16 taken 252 times.
|
701 | if (rule.stop) |
| 159 |
2/2✓ Branch 12 → 13 taken 449 times.
✓ Branch 13 → 14 taken 449 times.
|
449 | commands.append("stop;"); |
| 160 | 701 | QByteArray out; | |
| 161 |
2/2✓ Branch 17 → 18 taken 640 times.
✓ Branch 17 → 22 taken 61 times.
|
701 | if (!rule.name.isEmpty()) |
| 162 |
2/2✓ Branch 18 → 19 taken 640 times.
✓ Branch 19 → 20 taken 640 times.
|
640 | out += markerLine(rule.name, style); |
| 163 |
3/3✓ Branch 22 → 23 taken 701 times.
✓ Branch 23 → 24 taken 701 times.
✓ Branch 24 → 25 taken 701 times.
|
701 | out += renderIfHeader(renderTest(rule, style), rule.enabled); |
| 164 |
6/6✓ Branch 27 → 28 taken 86 times.
✓ Branch 27 → 29 taken 615 times.
✓ Branch 28 → 29 taken 28 times.
✓ Branch 28 → 30 taken 58 times.
✓ Branch 31 → 32 taken 701 times.
✓ Branch 32 → 33 taken 701 times.
|
701 | out += renderBlockBody(commands, style, style.braceOnOwnLine || !rule.enabled); |
| 165 | 701 | return out; | |
| 166 | 701 | } | |
| 167 | |||
| 168 | 37 | QByteArray renderVacation(const Vacation &vacation, const QString &name, const Style &style) { | |
| 169 | // S106-094: days 0 = ":days" was not given (the server default applies). | ||
| 170 |
1/1✓ Branch 2 → 3 taken 37 times.
|
37 | QByteArray command = "vacation"; |
| 171 |
2/2✓ Branch 3 → 4 taken 36 times.
✓ Branch 3 → 10 taken 1 time.
|
37 | if (vacation.days > 0) |
| 172 |
3/3✓ Branch 4 → 5 taken 36 times.
✓ Branch 5 → 6 taken 36 times.
✓ Branch 6 → 7 taken 36 times.
|
36 | command += " :days " + QByteArray::number(vacation.days); |
| 173 |
2/2✓ Branch 11 → 12 taken 35 times.
✓ Branch 11 → 18 taken 2 times.
|
37 | if (!vacation.subject.isEmpty()) |
| 174 |
3/3✓ Branch 12 → 13 taken 35 times.
✓ Branch 13 → 14 taken 35 times.
✓ Branch 14 → 15 taken 35 times.
|
35 | command += " :subject " + quoted(vacation.subject, style); |
| 175 |
2/2✓ Branch 19 → 20 taken 9 times.
✓ Branch 19 → 26 taken 28 times.
|
37 | if (!vacation.from.isEmpty()) |
| 176 |
3/3✓ Branch 20 → 21 taken 9 times.
✓ Branch 21 → 22 taken 9 times.
✓ Branch 22 → 23 taken 9 times.
|
9 | command += " :from " + quoted(vacation.from, style); |
| 177 |
2/2✓ Branch 27 → 28 taken 31 times.
✓ Branch 27 → 49 taken 6 times.
|
37 | if (!vacation.addresses.isEmpty()) { |
| 178 |
1/1✓ Branch 28 → 29 taken 31 times.
|
31 | QByteArray list = "["; |
| 179 |
2/2✓ Branch 41 → 30 taken 36 times.
✓ Branch 41 → 42 taken 31 times.
|
67 | for (int i = 0; i < vacation.addresses.size(); ++i) |
| 180 |
5/5✓ Branch 31 → 32 taken 36 times.
✓ Branch 32 → 33 taken 5 times.
✓ Branch 32 → 34 taken 31 times.
✓ Branch 35 → 36 taken 36 times.
✓ Branch 36 → 37 taken 36 times.
|
36 | list += (i > 0 ? ", " : "") + quoted(vacation.addresses.at(i), style); |
| 181 |
3/3✓ Branch 42 → 43 taken 31 times.
✓ Branch 43 → 44 taken 31 times.
✓ Branch 44 → 45 taken 31 times.
|
31 | command += " :addresses " + list + "]"; |
| 182 | 31 | } | |
| 183 | 37 | QString message = vacation.message; | |
| 184 |
8/8✓ Branch 52 → 53 taken 37 times.
✓ Branch 53 → 54 taken 7 times.
✓ Branch 53 → 59 taken 30 times.
✓ Branch 56 → 57 taken 7 times.
✓ Branch 57 → 58 taken 2 times.
✓ Branch 57 → 59 taken 5 times.
✓ Branch 60 → 61 taken 2 times.
✓ Branch 60 → 65 taken 35 times.
|
37 | if (message.contains(QLatin1Char('\n')) && !message.endsWith(QLatin1Char('\n'))) |
| 185 |
1/1✓ Branch 63 → 64 taken 2 times.
|
2 | message += QLatin1Char('\n'); |
| 186 |
4/4✓ Branch 65 → 66 taken 37 times.
✓ Branch 66 → 67 taken 37 times.
✓ Branch 67 → 68 taken 37 times.
✓ Branch 68 → 69 taken 37 times.
|
37 | command += " " + stringLiteral(message, style.lineEnd) + ";"; |
| 187 |
5/7✓ Branch 73 → 74 taken 1 time.
✓ Branch 73 → 77 taken 36 times.
✓ Branch 78 → 79 taken 37 times.
✓ Branch 80 → 81 taken 1 time.
✓ Branch 80 → 82 taken 36 times.
✗ Branch 154 → 155 not taken.
✗ Branch 154 → 156 not taken.
|
38 | QByteArray out = markerLine(name.isEmpty() ? QStringLiteral("Out of office") : name, style); |
| 188 |
3/3✓ Branch 82 → 83 taken 37 times.
✓ Branch 83 → 84 taken 37 times.
✓ Branch 84 → 85 taken 37 times.
|
37 | out += renderIfHeader(vacationTest(vacation, style), vacation.enabled); |
| 189 |
7/10✓ Branch 87 → 88 taken 1 time.
✓ Branch 87 → 89 taken 36 times.
✗ Branch 88 → 89 not taken.
✓ Branch 88 → 90 taken 1 time.
✓ Branch 93 → 94 taken 37 times.
✓ Branch 94 → 95 taken 37 times.
✓ Branch 98 → 99 taken 37 times.
✓ Branch 98 → 100 taken 37 times.
✗ Branch 170 → 171 not taken.
✗ Branch 170 → 172 not taken.
|
111 | out += renderBlockBody({command}, style, style.braceOnOwnLine || !vacation.enabled); |
| 190 | 37 | return out; | |
| 191 | 74 | } | |
| 192 | |||
| 193 | 1804 | QStringList extensionsFor(const Rule &rule) { | |
| 194 | 1804 | QStringList extensions; | |
| 195 |
2/2✓ Branch 45 → 4 taken 2051 times.
✓ Branch 45 → 46 taken 1804 times.
|
3855 | for (const Condition &condition : rule.conditions) { |
| 196 |
2/2✓ Branch 7 → 8 taken 12 times.
✓ Branch 7 → 15 taken 2039 times.
|
2051 | if (condition.matchType == QLatin1String("regex")) |
| 197 |
1/1✓ Branch 11 → 12 taken 12 times.
|
12 | appendUnique(&extensions, QStringLiteral("regex")); |
| 198 |
2/2✓ Branch 15 → 16 taken 10 times.
✓ Branch 15 → 23 taken 2041 times.
|
2051 | if (condition.kind == Condition::Kind::Body) |
| 199 |
1/1✓ Branch 19 → 20 taken 10 times.
|
10 | appendUnique(&extensions, QStringLiteral("body")); |
| 200 | 2051 | if (!condition.comparator.isEmpty() && | |
| 201 |
4/4✓ Branch 24 → 25 taken 14 times.
✓ Branch 24 → 32 taken 2037 times.
✓ Branch 27 → 28 taken 10 times.
✓ Branch 27 → 32 taken 4 times.
|
2061 | condition.comparator != QLatin1String("i;ascii-casemap") && |
| 202 |
4/4✓ Branch 30 → 31 taken 6 times.
✓ Branch 30 → 32 taken 4 times.
✓ Branch 33 → 34 taken 6 times.
✓ Branch 33 → 43 taken 2045 times.
|
2061 | condition.comparator != QLatin1String("i;octet")) |
| 203 |
2/2✓ Branch 37 → 38 taken 6 times.
✓ Branch 38 → 39 taken 6 times.
|
12 | appendUnique(&extensions, QStringLiteral("comparator-") + condition.comparator); |
| 204 | } | ||
| 205 |
2/2✓ Branch 99 → 48 taken 1957 times.
✓ Branch 99 → 100 taken 1804 times.
|
3761 | for (const Action &action : rule.actions) { |
| 206 |
4/4✓ Branch 49 → 50 taken 1682 times.
✓ Branch 49 → 74 taken 169 times.
✓ Branch 49 → 81 taken 23 times.
✓ Branch 49 → 88 taken 83 times.
|
1957 | switch (action.kind) { |
| 207 | 1682 | case Action::Kind::FileInto: | |
| 208 |
1/1✓ Branch 53 → 54 taken 1682 times.
|
1682 | appendUnique(&extensions, QStringLiteral("fileinto")); |
| 209 |
2/2✓ Branch 56 → 57 taken 8 times.
✓ Branch 56 → 64 taken 1674 times.
|
1682 | if (action.create) |
| 210 |
1/1✓ Branch 60 → 61 taken 8 times.
|
8 | appendUnique(&extensions, QStringLiteral("mailbox")); |
| 211 |
2/2✓ Branch 65 → 66 taken 6 times.
✓ Branch 65 → 73 taken 1676 times.
|
1682 | if (!action.specialUse.isEmpty()) |
| 212 |
1/1✓ Branch 69 → 70 taken 6 times.
|
6 | appendUnique(&extensions, QStringLiteral("special-use")); |
| 213 | 1682 | break; | |
| 214 | 169 | case Action::Kind::AddFlag: | |
| 215 | case Action::Kind::SetFlag: | ||
| 216 | case Action::Kind::RemoveFlag: | ||
| 217 |
1/1✓ Branch 77 → 78 taken 169 times.
|
169 | appendUnique(&extensions, QStringLiteral("imap4flags")); |
| 218 | 169 | break; | |
| 219 | 23 | case Action::Kind::Reject: | |
| 220 |
1/1✓ Branch 84 → 85 taken 23 times.
|
23 | appendUnique(&extensions, QStringLiteral("reject")); |
| 221 | 23 | break; | |
| 222 | 83 | default: | |
| 223 | 83 | break; | |
| 224 | } | ||
| 225 |
2/2✓ Branch 89 → 90 taken 37 times.
✓ Branch 89 → 97 taken 1920 times.
|
1957 | if (action.copy) |
| 226 |
1/1✓ Branch 93 → 94 taken 37 times.
|
37 | appendUnique(&extensions, QStringLiteral("copy")); |
| 227 | } | ||
| 228 | 1804 | return extensions; | |
| 229 | ✗ | } | |
| 230 | |||
| 231 | 22 | QStringList extensionsFor(const Vacation &vacation) { | |
| 232 |
2/4✓ Branch 7 → 8 taken 22 times.
✓ Branch 7 → 9 taken 22 times.
✗ Branch 43 → 44 not taken.
✗ Branch 43 → 45 not taken.
|
44 | QStringList extensions{QStringLiteral("vacation")}; |
| 233 |
2/3✓ Branch 11 → 12 taken 22 times.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 20 taken 22 times.
|
22 | if (vacation.subject.contains(QLatin1String("${"))) |
| 234 | ✗ | extensions.append(QStringLiteral("variables")); | |
| 235 |
8/8✓ Branch 20 → 21 taken 22 times.
✓ Branch 21 → 22 taken 10 times.
✓ Branch 21 → 24 taken 12 times.
✓ Branch 22 → 23 taken 10 times.
✓ Branch 23 → 24 taken 1 time.
✓ Branch 23 → 25 taken 9 times.
✓ Branch 26 → 27 taken 13 times.
✓ Branch 26 → 40 taken 9 times.
|
22 | if (vacation.firstDay.isValid() || vacation.lastDay.isValid()) { |
| 236 |
1/1✓ Branch 30 → 31 taken 13 times.
|
13 | extensions.append(QStringLiteral("date")); |
| 237 |
1/1✓ Branch 36 → 37 taken 13 times.
|
13 | extensions.append(QStringLiteral("relational")); |
| 238 | } | ||
| 239 | 22 | return extensions; | |
| 240 | 44 | } | |
| 241 | |||
| 242 | namespace { | ||
| 243 | |||
| 244 | 230382 | bool representable(const QStringList &values) { | |
| 245 |
2/2✓ Branch 10 → 4 taken 166320 times.
✓ Branch 10 → 11 taken 230380 times.
|
396700 | for (const QString &value : values) |
| 246 |
3/3✓ Branch 5 → 6 taken 166320 times.
✓ Branch 6 → 7 taken 2 times.
✓ Branch 6 → 8 taken 166318 times.
|
166320 | if (!representableString(value)) |
| 247 | 2 | return false; | |
| 248 | 230380 | return true; | |
| 249 | } | ||
| 250 | |||
| 251 | } // namespace | ||
| 252 | |||
| 253 | 72131 | bool representable(const Rule &rule) { | |
| 254 |
2/2✓ Branch 17 → 4 taken 76428 times.
✓ Branch 17 → 18 taken 72129 times.
|
148557 | for (const Condition &condition : rule.conditions) |
| 255 |
7/8✓ Branch 5 → 6 taken 76428 times.
✓ Branch 6 → 7 taken 76428 times.
✗ Branch 6 → 11 not taken.
✓ Branch 7 → 8 taken 76428 times.
✓ Branch 8 → 9 taken 76426 times.
✓ Branch 8 → 11 taken 2 times.
✓ Branch 13 → 14 taken 2 times.
✓ Branch 13 → 15 taken 76426 times.
|
152854 | if (!representable(condition.headers) || !representable(condition.values) || |
| 256 |
2/3✓ Branch 9 → 10 taken 76426 times.
✗ Branch 10 → 11 not taken.
✓ Branch 10 → 12 taken 76426 times.
|
76426 | !representableString(condition.comparator)) |
| 257 | 2 | return false; | |
| 258 |
2/2✓ Branch 33 → 20 taken 77288 times.
✓ Branch 33 → 34 taken 72129 times.
|
149417 | for (const Action &action : rule.actions) |
| 259 |
5/8✓ Branch 21 → 22 taken 77288 times.
✓ Branch 22 → 23 taken 77288 times.
✗ Branch 22 → 27 not taken.
✓ Branch 23 → 24 taken 77288 times.
✓ Branch 24 → 25 taken 77288 times.
✗ Branch 24 → 27 not taken.
✗ Branch 29 → 30 not taken.
✓ Branch 29 → 31 taken 77288 times.
|
154576 | if (!representableString(action.target) || !representable(action.flags) || |
| 260 |
2/3✓ Branch 25 → 26 taken 77288 times.
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 28 taken 77288 times.
|
77288 | !representableString(action.specialUse)) |
| 261 | ✗ | return false; | |
| 262 | 72129 | return true; | |
| 263 | } | ||
| 264 | |||
| 265 | 238 | bool representable(const Vacation &vacation) { | |
| 266 |
1/2✓ Branch 5 → 6 taken 238 times.
✗ Branch 5 → 13 not taken.
|
476 | return representableString(vacation.subject) && representableString(vacation.message) && |
| 267 |
3/6✓ Branch 3 → 4 taken 238 times.
✗ Branch 3 → 13 not taken.
✓ Branch 7 → 8 taken 238 times.
✗ Branch 7 → 13 not taken.
✓ Branch 9 → 10 taken 238 times.
✗ Branch 9 → 13 not taken.
|
714 | representableString(vacation.from) && representable(vacation.addresses) && |
| 268 |
1/2✓ Branch 11 → 12 taken 238 times.
✗ Branch 11 → 13 not taken.
|
476 | representableString(vacation.zone); |
| 269 | } | ||
| 270 | |||
| 271 | 20004 | QString Block::hash() const { | |
| 272 | 20004 | QByteArray bytes = original; | |
| 273 |
3/6✓ Branch 3 → 4 taken 20004 times.
✗ Branch 3 → 6 not taken.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 20004 times.
✗ Branch 8 → 9 not taken.
✓ Branch 8 → 17 taken 20004 times.
|
20004 | if (dirty || bytes.isEmpty()) { |
| 274 | ✗ | const Style style; | |
| 275 | ✗ | bytes = kind == BlockKind::Vacation ? renderVacation(vacation, name, style) | |
| 276 | ✗ | : renderRule(rule, style); | |
| 277 | ✗ | } | |
| 278 |
3/3✓ Branch 18 → 19 taken 20004 times.
✓ Branch 19 → 20 taken 20004 times.
✓ Branch 20 → 21 taken 20004 times.
|
40008 | return QString::fromLatin1(QCryptographicHash::hash(bytes, QCryptographicHash::Sha256).toHex()); |
| 279 | 20004 | } | |
| 280 | |||
| 281 | } // namespace Sieve | ||
| 282 |