summaryrefslogtreecommitdiffstats
path: root/pigeonhole/tests/extensions/relational
diff options
context:
space:
mode:
Diffstat (limited to 'pigeonhole/tests/extensions/relational')
-rw-r--r--pigeonhole/tests/extensions/relational/basic.svtest178
-rw-r--r--pigeonhole/tests/extensions/relational/comparators.svtest258
-rw-r--r--pigeonhole/tests/extensions/relational/errors.svtest33
-rw-r--r--pigeonhole/tests/extensions/relational/errors/syntax.sieve8
-rw-r--r--pigeonhole/tests/extensions/relational/errors/validation.sieve11
-rw-r--r--pigeonhole/tests/extensions/relational/rfc.svtest71
6 files changed, 559 insertions, 0 deletions
diff --git a/pigeonhole/tests/extensions/relational/basic.svtest b/pigeonhole/tests/extensions/relational/basic.svtest
new file mode 100644
index 0000000..288661a
--- /dev/null
+++ b/pigeonhole/tests/extensions/relational/basic.svtest
@@ -0,0 +1,178 @@
+require "vnd.dovecot.testsuite";
+
+require "relational";
+require "comparator-i;ascii-numeric";
+
+/*
+ * Test message
+ */
+
+test_set "message" text:
+From: stephan@example.org
+To: nico@frop.example.org
+Cc: frop@example.org
+CC: timo@example.org
+X-Spam-Score: 300
+X-Nonsense: 1000
+X-Nonsense: 20
+X-Alpha: abcdzyx
+X-Count: a
+X-Count: b
+X-Count: c
+X-Count: d
+X-Count: e
+X-Count: f
+X-Count: g
+X-Count: h
+X-Count: i
+X-Count: j
+X-Count: k
+X-Count: l
+X-Count: m
+X-Count: n
+X-Count: o
+X-Count: p
+X-Count: q
+X-Count: r
+X-Count: s
+X-Count: t
+X-Count: u
+X-Count: v
+X-Count: w
+X-Count: x
+X-Count: y
+X-Count: z
+Subject: Test
+Comment:
+
+Test!
+.
+;
+
+/*
+ * Empty strings
+ */
+
+test "Value \"\" eq 40 (vs)" {
+ if header :value "eq" :comparator "i;ascii-numeric" "comment" "40" {
+ test_fail ":value matched empty string with i;ascii-numeric";
+ }
+
+ if header :value "gt" :comparator "i;ascii-numeric" "x-spam-score" "" {
+ test_fail ":value 300 exceeded empty string with i;ascii-numeric";
+ }
+
+ if header :value "gt" :comparator "i;ascii-numeric" "x-spam-score" "" {
+ test_fail ":count exceeded empty string with i;ascii-numeric";
+ }
+}
+
+/*
+ * Match type :value
+ */
+
+test "Value 300 eq 2" {
+ if header :value "eq" :comparator "i;ascii-numeric" "x-spam-score" "2" {
+ test_fail "should not have matched";
+ }
+}
+
+test "Value 300 lt 2" {
+ if header :value "lt" :comparator "i;ascii-numeric" "x-spam-score" "2" {
+ test_fail "should not have matched";
+ }
+}
+
+test "Value 300 le 300" {
+ if not header :value "le" :comparator "i;ascii-numeric" "x-spam-score" "300" {
+ test_fail "should have matched";
+ }
+}
+
+test "Value 300 le 302" {
+ if not header :value "le" :comparator "i;ascii-numeric" "x-spam-score" "302" {
+ test_fail "should have matched";
+ }
+}
+
+test "Value 302 le 00302" {
+ if not header :value "le" :comparator "i;ascii-numeric" "x-spam-score" "00302" {
+ test_fail "should have matched";
+ }
+}
+
+test "Value {1000,20} le 300" {
+ if not header :value "le" :comparator "i;ascii-numeric" "x-nonsense" "300" {
+ test_fail "should have matched";
+ }
+}
+
+test "Value {1000,20} lt 3" {
+ if header :value "lt" :comparator "i;ascii-numeric" "x-nonsense" "3" {
+ test_fail "should not have matched";
+ }
+}
+
+test "Value {1000,20} gt 3000" {
+ if header :value "gt" :comparator "i;ascii-numeric" "x-nonsense" "3000" {
+ test_fail "should not have matched";
+ }
+}
+
+test "Value {1000,20} gt {3000,30}" {
+ if not header :value "gt" :comparator "i;ascii-numeric" "x-nonsense" ["3000","30"] {
+ test_fail "should have matched";
+ }
+}
+
+test "Value {1000,20} lt {3, 19})" {
+ if header :value "lt" :comparator "i;ascii-numeric" "x-nonsense" ["3","19"] {
+ test_fail "should not have matched";
+ }
+}
+
+test "Value {1000,20} gt {3000,1001}" {
+ if header :value "gt" :comparator "i;ascii-numeric" "x-nonsense" ["3000","1001"] {
+ test_fail "should not have matched";
+ }
+}
+
+test "Value abcdzyz gt aaaaaaa" {
+ if not header :value "gt" :comparator "i;octet" "x-alpha" "aaaaaaa" {
+ test_fail "should have matched";
+ }
+}
+
+/*
+ * Match type :count
+ */
+
+test "Count 2 ne 2" {
+ if header :count "ne" :comparator "i;ascii-numeric" "cc" "2" {
+ test_fail "should not have matched";
+ }
+}
+
+test "Count 2 ge 2" {
+ if not header :count "ge" :comparator "i;ascii-numeric" "cc" "2" {
+ test_fail "should have matched";
+ }
+}
+
+test "Count 2 ge 002" {
+ if not header :count "ge" :comparator "i;ascii-numeric" "cc" "002" {
+ test_fail "should have matched";
+ }
+}
+
+test "Count 26 lt {4,5,6,10,20}" {
+ if header :count "lt" :comparator "i;ascii-numeric" "x-count" ["4","5","6","10","20"] {
+ test_fail "should not have matched";
+ }
+}
+
+test "Count 26 lt {4,5,6,10,20,100}" {
+ if not header :count "lt" :comparator "i;ascii-numeric" "x-count" ["4","5","6","10","20","100"] {
+ test_fail "should have matched";
+ }
+}
diff --git a/pigeonhole/tests/extensions/relational/comparators.svtest b/pigeonhole/tests/extensions/relational/comparators.svtest
new file mode 100644
index 0000000..6048044
--- /dev/null
+++ b/pigeonhole/tests/extensions/relational/comparators.svtest
@@ -0,0 +1,258 @@
+require "vnd.dovecot.testsuite";
+require "variables";
+require "relational";
+require "comparator-i;ascii-numeric";
+
+/*
+ * Comparator i;octet
+ */
+
+test "i;octet" {
+ if not string :comparator "i;octet" :value "eq" "" "" {
+ test_fail "not '' eq ''";
+ }
+
+ if not string :comparator "i;octet" :value "gt" "a" "" {
+ test_fail "not 'a' gt ''";
+ }
+
+ if not string :comparator "i;octet" :value "lt" "" "a" {
+ test_fail "not '' lt 'a'";
+ }
+
+ if not string :comparator "i;octet" :value "gt" "ab" "a" {
+ test_fail "not 'ab' gt 'a'";
+ }
+
+ if not string :comparator "i;octet" :value "lt" "a" "ab" {
+ test_fail "not 'a' lt 'ab'";
+ }
+
+ if not string :comparator "i;octet" :value "gt" "ba" "ab" {
+ test_fail "not 'ba' gt 'ab'";
+ }
+
+ if not string :comparator "i;octet" :value "lt" "ab" "ba" {
+ test_fail "not 'ab' lt 'ba'";
+ }
+
+ if not string :comparator "i;octet" :value "eq" "abcd" "abcd" {
+ test_fail "not 'abcd' eq 'abcd'";
+ }
+
+ if not string :comparator "i;octet" :value "lt" "abcce" "abcde" {
+ test_fail "not 'abcce' lt 'abcde'";
+ }
+
+ if not string :comparator "i;octet" :value "gt" "abcde" "abcce" {
+ test_fail "not 'abcde' gt 'abcce'";
+ }
+
+ if not string :comparator "i;octet" :value "lt" "abcce" "abcd" {
+ test_fail "not 'abcce' lt 'abcd'";
+ }
+
+ if not string :comparator "i;octet" :value "gt" "abcd" "abcce" {
+ test_fail "not 'abcd' gt 'abcce'";
+ }
+
+ if not string :comparator "i;octet" :value "lt" "Z" "b" {
+ test_fail "not 'Z' lt 'b'";
+ }
+}
+
+/*
+ * Comparator i;ascii-casemap
+ */
+
+test "i;ascii-casemap" {
+ if not string :comparator "i;ascii-casemap" :value "eq" "" "" {
+ test_fail "not '' eq ''";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "gt" "a" "" {
+ test_fail "not 'a' gt ''";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "lt" "" "a" {
+ test_fail "not '' lt 'a'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "gt" "ab" "a" {
+ test_fail "not 'ab' gt 'a'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "lt" "a" "ab" {
+ test_fail "not 'a' lt 'ab'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "gt" "ba" "ab" {
+ test_fail "not 'ba' gt 'ab'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "lt" "ab" "ba" {
+ test_fail "not 'ab' lt 'ba'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "eq" "abcd" "abcd" {
+ test_fail "not 'abcd' eq 'abcd'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "lt" "abcce" "abcde" {
+ test_fail "not 'abcce' lt 'abcde'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "gt" "abcde" "abcce" {
+ test_fail "not 'abcde' gt 'abcce'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "lt" "abcce" "abcd" {
+ test_fail "not 'abcce' lt 'abcd'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "gt" "abcd" "abcce" {
+ test_fail "not 'abcd' gt 'abcce'";
+ }
+
+ if not string :comparator "i;ascii-casemap" :value "gt" "Z" "b" {
+ test_fail "not 'Z' gt 'b'";
+ }
+}
+
+/*
+ * Comparator i;ascii-numeric
+ */
+
+test "i;ascii-numeric" {
+ /* Non-digit characters; equality */
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "" "" {
+ test_fail "not '' eq ''";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "a" "" {
+ test_fail "not 'a' eq ''";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "" "a" {
+ test_fail "not '' eq 'a'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "a" "b" {
+ test_fail "not 'a' eq 'b'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "b" "a" {
+ test_fail "not 'b' eq 'a'";
+ }
+
+ if string :comparator "i;ascii-numeric" :value "eq" "a" "0" {
+ test_fail "'a' eq '0'";
+ }
+
+ if string :comparator "i;ascii-numeric" :value "eq" "0" "a" {
+ test_fail "'0' eq 'a'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "ne" "a" "0" {
+ test_fail "not 'a' ne '0'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "ne" "0" "a" {
+ test_fail "not '0' ne 'a'";
+ }
+
+ /* Non-digit characters; comparison */
+
+ if string :comparator "i;ascii-numeric" :value "lt" "a" "0" {
+ test_fail "'a' lt '0'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "lt" "0" "a" {
+ test_fail "not '0' lt 'a'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "gt" "a" "0" {
+ test_fail "not 'a' gt '0'";
+ }
+
+ if string :comparator "i;ascii-numeric" :value "gt" "0" "a" {
+ test_fail "'0' gt 'a'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "ge" "a" "0" {
+ test_fail "not 'a' ge '0'";
+ }
+
+ if string :comparator "i;ascii-numeric" :value "ge" "0" "a" {
+ test_fail "'0' ge 'a'";
+ }
+
+ if string :comparator "i;ascii-numeric" :value "le" "a" "0" {
+ test_fail "'a' le '0'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "le" "0" "a" {
+ test_fail "not '0' le 'a'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "0" "0" {
+ test_fail "not '0' eq '0'";
+ }
+
+ /* Digit characters; basic comparison */
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "2" "2" {
+ test_fail "not '2' eq '2'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "gt" "2" "1" {
+ test_fail "not '2' gt '1'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "lt" "1" "2" {
+ test_fail "not '1' lt '2'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "lt" "65535" "65635" {
+ test_fail "not '65535' lt '65635'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "gt" "65635" "65535" {
+ test_fail "not '65635' gt '65535'";
+ }
+
+ /* Digit characters; leading zeros */
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "0" "000" {
+ test_fail "not '0' eq '000'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "000" "0" {
+ test_fail "not '0' eq '000'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "02" "0002" {
+ test_fail "not '02' eq '0002'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "eq" "0002" "02" {
+ test_fail "not '0002' eq '02'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "gt" "2" "001" {
+ test_fail "not '2' gt '001'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "lt" "001" "2" {
+ test_fail "not '001' lt '2'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "gt" "002" "1" {
+ test_fail "not '002' gt '1'";
+ }
+
+ if not string :comparator "i;ascii-numeric" :value "lt" "1" "002" {
+ test_fail "not '1' lt '002'";
+ }
+}
diff --git a/pigeonhole/tests/extensions/relational/errors.svtest b/pigeonhole/tests/extensions/relational/errors.svtest
new file mode 100644
index 0000000..0973b98
--- /dev/null
+++ b/pigeonhole/tests/extensions/relational/errors.svtest
@@ -0,0 +1,33 @@
+require "vnd.dovecot.testsuite";
+
+# A bit awkward to test the extension with itself
+require "relational";
+require "comparator-i;ascii-numeric";
+
+/*
+ * Syntax errors
+ */
+
+test "Syntax errors" {
+ if test_script_compile "errors/syntax.sieve" {
+ test_fail "compile should have failed";
+ }
+
+ if test_error :count "ne" "6" {
+ test_fail "wrong number of errors reported";
+ }
+}
+
+/*
+ * Validation errors
+ */
+
+test "Validation errors" {
+ if test_script_compile "errors/validation.sieve" {
+ test_fail "compile should have failed";
+ }
+
+ if test_error :count "ne" "3" {
+ test_fail "wrong number of errors reported";
+ }
+}
diff --git a/pigeonhole/tests/extensions/relational/errors/syntax.sieve b/pigeonhole/tests/extensions/relational/errors/syntax.sieve
new file mode 100644
index 0000000..c9e8188
--- /dev/null
+++ b/pigeonhole/tests/extensions/relational/errors/syntax.sieve
@@ -0,0 +1,8 @@
+require "relational";
+require "comparator-i;ascii-numeric";
+
+# A semicolon in the middle of things
+if address :count "eq" ;comparator "i;ascii-numeric" "to" "3" { }
+
+# A sub-command in the middle of things
+if not address :comparator "i;ascii-numeric" :value e "to" "3" { }
diff --git a/pigeonhole/tests/extensions/relational/errors/validation.sieve b/pigeonhole/tests/extensions/relational/errors/validation.sieve
new file mode 100644
index 0000000..f355097
--- /dev/null
+++ b/pigeonhole/tests/extensions/relational/errors/validation.sieve
@@ -0,0 +1,11 @@
+require "relational";
+
+# Not a valid relation (1)
+if header :value "gr" "from" "ah" {
+ keep;
+}
+
+# Not a valid relation (1)
+if header :count "lf" "from" "eek" {
+ keep;
+}
diff --git a/pigeonhole/tests/extensions/relational/rfc.svtest b/pigeonhole/tests/extensions/relational/rfc.svtest
new file mode 100644
index 0000000..bc05516
--- /dev/null
+++ b/pigeonhole/tests/extensions/relational/rfc.svtest
@@ -0,0 +1,71 @@
+require "vnd.dovecot.testsuite";
+
+require "relational";
+require "comparator-i;ascii-numeric";
+
+test_set "message" text:
+Received: ...
+Received: ...
+Subject: example
+To: foo@example.com, baz@example.com
+CC: qux@example.com
+
+RFC Example
+.
+;
+
+test "Example 1" {
+ # The test:
+
+ if not address :count "ge" :comparator "i;ascii-numeric"
+ ["to", "cc"] ["3"] {
+
+ test_fail "should have counted three addresses";
+ }
+
+ # would evaluate to true, and the test
+
+ if anyof (
+ address :count "ge" :comparator "i;ascii-numeric"
+ ["to"] ["3"],
+ address :count "ge" :comparator "i;ascii-numeric"
+ ["cc"] ["3"]
+ ) {
+
+ test_fail "should not have counted three addresses";
+ }
+
+ # would evaluate to false.
+
+ # To check the number of received fields in the header, the following
+ # test may be used:
+
+ if header :count "ge" :comparator "i;ascii-numeric"
+ ["received"] ["3"] {
+
+ test_fail "should not have counted three received headers";
+ }
+
+ # This would evaluate to false. But
+
+ if not header :count "ge" :comparator "i;ascii-numeric"
+ ["received", "subject"] ["3"] {
+
+ test_fail "should have counted three headers";
+ }
+
+ # would evaluate to true.
+
+ # The test:
+
+ if header :count "ge" :comparator "i;ascii-numeric"
+ ["to", "cc"] ["3"] {
+
+ test_fail "should not have counted three to or cc headers";
+ }
+
+ # will always evaluate to false on an RFC 2822 compliant message
+ # [RFC2822], since a message can have at most one "to" field and at
+ # most one "cc" field. This test counts the number of fields, not the
+ # number of addresses.
+}