odoyle-rules
odoyle-rules copied to clipboard
What blocks then conditions don't allow for custom functions.
Here is a failing test that should pass, but doesn't, that demonstrates the issue:
(deftest allow-for-custom-then-functions
(let [falsy (fn [new old] false)
fired? (atom false)]
(-> (reduce o/add-rule (o/->session)
(o/ruleset
{::rule1
[:what
[pid ::foo foo {:then falsy}]
:then
(println "fired")
(reset! fired? true)]}))
(o/insert 1 ::foo "")
o/fire-rules)
(is (= @fired? false))))
maybe this is by design? Here is where i assume this is happening at a glance:
(if-let [[then-type then] (-> node :condition :opts :then)]
(case then-type
:bool (fn [session new-fact old-fact]
then)
:func (if-let [old-fact (:old-fact token)]
(fn [session new-fact old-fact]
(then (:value new-fact) (:value old-fact)))
(fn [session new-fact old-fact]
true)))
(fn [session new-fact old-fact]
true))
yep, this seems to be by design. Or at least, as the code above illustrates it always fires the first time:
(deftest allow-for-custom-then-functions
(let [falsy (fn [new old] false)
fired (atom 0)]
(-> (reduce o/add-rule (o/->session)
(o/ruleset
{::rule1
[:what
[pid ::foo foo {:then falsy}]
:then
(swap! fired inc)]}))
(o/insert 1 ::foo "")
(o/insert 1 ::foo "")
(o/insert 1 ::foo "")
o/fire-rules)
(is (= 0 @fired))))
result:
FAIL in () (NO_SOURCE_FILE:1110)
expected: (= 0 (clojure.core/deref fired))
actual: (not (= 0 1))
Is this clear in the docs? Does it have to be this way? It seems counter intuitive.