From 26dd50700305d613b86fe8789f13c8253f75984a Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Thu, 13 Aug 2026 11:12:47 +0200 Subject: feat(rulequery): parse an or-group with trailing exclusions --- tests/test_rulequery.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'tests') diff --git a/tests/test_rulequery.cpp b/tests/test_rulequery.cpp index b8d6f22..88485f3 100644 --- a/tests/test_rulequery.cpp +++ b/tests/test_rulequery.cpp @@ -47,6 +47,7 @@ private slots: void quotedValuesLoseTheirQuotes(); void aNegatedTermParsesAsANegatedOperator(); void whatParsesCompilesBackUnchanged(); + void anOrGroupWithExclusionsParses(); }; void TestRuleQuery::aSingleContainsTermCompiles() @@ -291,6 +292,8 @@ void TestRuleQuery::whatParsesCompilesBackUnchanged() QStringLiteral("from:vendor.example.org and not tag:inbox"), QStringLiteral("from:vendor.example.org and not subject:receipt " "and not subject:refund"), + QStringLiteral("(from:one.example.org or from:two.example.org) " + "and not subject:receipt"), }; for (const QString &query : queries) { @@ -300,5 +303,26 @@ void TestRuleQuery::whatParsesCompilesBackUnchanged() } } +void TestRuleQuery::anOrGroupWithExclusionsParses() +{ + const RuleQuery q = RuleQuery::parse( + QStringLiteral("(from:vendor.example.org or from:vendor.example.net) " + "and not subject:receipt and not subject:refund")); + + QVERIFY(q.parsed); + QCOMPARE(q.join, RuleQuery::Any); + QCOMPARE(q.terms.size(), 2); + QCOMPARE(q.exclusions.size(), 2); + QCOMPARE(q.exclusions.at(0).field, RuleTerm::Subject); + QCOMPARE(q.exclusions.at(0).op, RuleTerm::Contains); + QCOMPARE(q.exclusions.at(0).value, QStringLiteral("receipt")); + + // The round trip is the point: this must come back as it went in. + QCOMPARE(q.compile(), + QStringLiteral("(from:vendor.example.org or " + "from:vendor.example.net) " + "and not subject:receipt and not subject:refund")); +} + QTEST_MAIN(TestRuleQuery) #include "test_rulequery.moc" -- cgit v1.2.3