Files
rose-ash/lib/mod/tests/defrule.sx
giles c19f658cf2
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 34s
mod: Ext 18 — ergonomic defrule / ruleset surface, 375/375
mod/defrule collects trailing conditions via &rest; mod/ruleset assembles rules.
No macro needed — conditions are plain data, fn supports &rest here. Produces
structurally identical rules to mk-rule (asserted) and works in the engine
unchanged. Closes the roadmap's original defrule surface. +11 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 19:37:12 +00:00

96 lines
2.6 KiB
Plaintext

;; lib/mod/tests/defrule.sx — Ext 18: ergonomic defrule / ruleset.
(define mod-dr-count 0)
(define mod-dr-pass 0)
(define mod-dr-fail 0)
(define mod-dr-failures (list))
(define
mod-dr-test!
(fn
(name got expected)
(begin
(set! mod-dr-count (+ mod-dr-count 1))
(if
(= got expected)
(set! mod-dr-pass (+ mod-dr-pass 1))
(begin
(set! mod-dr-fail (+ mod-dr-fail 1))
(append!
mod-dr-failures
(str name "\n expected: " expected "\n got: " got)))))))
;; ── defrule produces the same structure as mk-rule ──
(define
mod-dr-r
(mod/defrule "spam-hide" :hide (list :classification "spam")))
(mod-dr-test! "defrule name" (mod/rule-name mod-dr-r) "spam-hide")
(mod-dr-test! "defrule action" (mod/rule-action mod-dr-r) "hide")
(mod-dr-test!
"defrule when wraps the conditions"
(mod/rule-when mod-dr-r)
(list (list :classification "spam")))
(mod-dr-test!
"defrule equals mk-rule equivalent"
(mod/rule-when mod-dr-r)
(mod/rule-when
(mod/mk-rule "spam-hide" :hide (list (list :classification "spam")))))
;; ── multi-condition + no-condition ──
(define
mod-dr-multi
(mod/defrule
"strict"
:hide (list :classification "spam")
(list :not (list :attr "verified"))))
(mod-dr-test!
"defrule collects multiple conditions"
(len (mod/rule-when mod-dr-multi))
2)
(define mod-dr-catch (mod/defrule "default-keep" :keep))
(mod-dr-test!
"defrule with no conditions is unconditional"
(mod/rule-when mod-dr-catch)
(list))
;; ── ruleset assembles a list ──
(define
mod-dr-rules
(mod/ruleset
(mod/defrule "spam-hide" :hide (list :classification "spam"))
(mod/defrule "default-keep" :keep)))
(mod-dr-test! "ruleset length" (len mod-dr-rules) 2)
(mod-dr-test!
"ruleset first rule name"
(mod/rule-name (first mod-dr-rules))
"spam-hide")
;; ── engine works with defrule/ruleset-built policy ──
(define mod-dr-spam (mod/mk-report "r1" "a" "b" "this is spam"))
(define mod-dr-clean (mod/mk-report "r2" "a" "b" "a fine post"))
(mod-dr-test!
"defrule policy: spam → hide"
(get
(mod/decide-report mod-dr-spam (list mod-dr-spam) mod-dr-rules)
:action)
"hide")
(mod-dr-test!
"defrule policy: clean → keep"
(get
(mod/decide-report mod-dr-clean (list mod-dr-clean) mod-dr-rules)
:action)
"keep")
(mod-dr-test!
"defrule policy: spam names the rule"
(get (mod/decide-report mod-dr-spam (list mod-dr-spam) mod-dr-rules) :rule)
"spam-hide")
(define mod-defrule-tests-run! (fn () {:failures mod-dr-failures :total mod-dr-count :passed mod-dr-pass :failed mod-dr-fail}))