summaryrefslogtreecommitdiffstats
path: root/test/lua/unit/expressions.lua
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 21:30:40 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 21:30:40 +0000
commit133a45c109da5310add55824db21af5239951f93 (patch)
treeba6ac4c0a950a0dda56451944315d66409923918 /test/lua/unit/expressions.lua
parentInitial commit. (diff)
downloadrspamd-133a45c109da5310add55824db21af5239951f93.tar.xz
rspamd-133a45c109da5310add55824db21af5239951f93.zip
Adding upstream version 3.8.1.upstream/3.8.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'test/lua/unit/expressions.lua')
-rw-r--r--test/lua/unit/expressions.lua111
1 files changed, 111 insertions, 0 deletions
diff --git a/test/lua/unit/expressions.lua b/test/lua/unit/expressions.lua
new file mode 100644
index 0000000..3d05685
--- /dev/null
+++ b/test/lua/unit/expressions.lua
@@ -0,0 +1,111 @@
+-- Expressions unit tests
+
+context("Rspamd expressions", function()
+ local rspamd_expression = require "rspamd_expression"
+ local rspamd_mempool = require "rspamd_mempool"
+ local rspamd_regexp = require "rspamd_regexp"
+ local split_re = rspamd_regexp.create('/\\s+|\\)|\\(/')
+
+ local function parse_func(str)
+ -- extract token till the first space character
+ local token = str
+ local t = split_re:split(str)
+ if t then
+ token = t[1]
+ end
+ -- Return token name
+ return token
+ end
+
+ local atoms = {
+ A = 1.0,
+ B = 0,
+ C = 1,
+ D = 0,
+ E = 1,
+ F = 0,
+ G = 0,
+ H = 0,
+ I = 0,
+ J = 0,
+ K = 0,
+ }
+ local function process_func(token, input)
+
+ --print(token)
+ local t = input[token]
+
+ return t
+ end
+
+ local pool = rspamd_mempool.create()
+
+ local cases = {
+ {'A & (!B | C)', '(A) (B) ! (C) | &'},
+ {'A & B | !C', '(C) ! (A) (B) & |'},
+ {'A & (B | !C)', '(A) (B) (C) ! | &'},
+ {'A & B &', nil},
+ -- Unbalanced braces
+ {'(((A))', nil},
+ -- Balanced braces
+ {'(((A)))', '(A)'},
+ -- Plus and comparison operators
+ {'A + B + C + D > 2', '(A) (B) (C) (D) +(4) 2 >'},
+ -- Plus and logic operators
+ {'((A + B + C + D) > 2) & D', '(D) (A) (B) (C) (D) +(4) 2 > &'},
+ -- Associativity
+ {'A | B | C & D & E', '(A) (B) (C) (D) (E) &(3) |(3)'},
+ -- More associativity
+ {'1 | 0 & 0 | 0', '(1) (0) (0) (0) & |(3)'},
+ {'(A) & (B) & ((C) | (D) | (E) | (F))', '(A) (B) (C) (D) (E) (F) |(4) &(3)' },
+ -- Extra space
+ {'A & B | ! C', '(C) ! (A) (B) & |'},
+ -- False minus
+ {'A + B + -C', '(A) (B) (-C) +(3)'},
+ }
+ for _,c in ipairs(cases) do
+ test("Expression creation function: " .. c[1], function()
+ local expr,err = rspamd_expression.create(c[1],
+ {parse_func, process_func}, pool)
+
+ if not c[2] then
+ assert_nil(expr, "Should not be able to parse " .. c[1])
+ else
+ assert_not_nil(expr, "Cannot parse " .. c[1] .. '; error: ' .. (err or 'wut??'))
+ assert_equal(expr:to_string(), c[2], string.format("Evaluated expr to '%s', expected: '%s'",
+ expr:to_string(), c[2]))
+ end
+ end)
+ end
+ -- Expression is destroyed when the corresponding pool is destroyed
+ cases = {
+ {'(E) && ((B + B + B + B) >= 1)', 0},
+ {'A & B | !C', 0},
+ {'A & (!B | C)', 1},
+ {'A + B + C + D + E + F >= 2', 1},
+ {'((A + B + C + D) > 1) & F', 0},
+ {'(A + B + C + D) > 1 && F || E', 1},
+ {'(A + B + C + D) > 100 && F || !E', 0},
+ {'F && ((A + B + C + D) > 1)', 0},
+ {'(E) && ((B + B + B + B) >= 1)', 0},
+ {'!!C', 1},
+ {'(B) & (D) & ((G) | (H) | (I) | (A))', 0},
+ {'A & C & (!D || !C || !E)', 1},
+ {'A & C & !(D || C || E)', 0},
+ {'A + B + C', 2},
+ {'A * 2.0 + B + C', 3},
+ {'A * 2.0 + B - C', 1},
+ {'A / 2.0 + B - C', -0.5},
+ }
+ for _,c in ipairs(cases) do
+ test("Expression process function: " .. c[1], function()
+ local expr,err = rspamd_expression.create(c[1],
+ {parse_func, process_func}, pool)
+
+ assert_not_nil(expr, "Cannot parse " .. c[1] .. '; error: ' .. (err or 'wut??'))
+ res = expr:process(atoms)
+ assert_equal(res, c[2], string.format("Processed expr '%s'{%s} returned '%d', expected: '%d'",
+ expr:to_string(), c[1], res, c[2]))
+ end)
+ end
+end)