;; lib/flow/tests/control.sx — Phase 2: control flow + error handling. (define flow-ctl-pass 0) (define flow-ctl-fail 0) (define flow-ctl-fails (list)) (define flow-ctl-test (fn (name actual expected) (if (= actual expected) (set! flow-ctl-pass (+ flow-ctl-pass 1)) (begin (set! flow-ctl-fail (+ flow-ctl-fail 1)) (append! flow-ctl-fails {:name name :expected expected :actual actual}))))) (define flow-c (fn (src) (flow-run src))) (define flow-cs (fn (src) (get (flow-run src) :scm-string))) ;; ── branch ────────────────────────────────────────────────────── (flow-ctl-test "branch: true selects then" (flow-c "(flow/start (branch (lambda (x) (> x 0)) (lambda (x) (* x 100)) (lambda (x) (- 0 x))) 5)") 500) (flow-ctl-test "branch: false selects else" (flow-c "(flow/start (branch (lambda (x) (> x 0)) (lambda (x) (* x 100)) (lambda (x) (- 0 x))) -3)") 3) (flow-ctl-test "branch: predicate sees the threaded input" (flow-c "(flow/start (sequence (lambda (x) (+ x 1)) (branch (lambda (x) (> x 3)) (flow-const 100) (flow-const 0))) 3)") 100) (flow-ctl-test "branch: branches are full nodes (sequence inside)" (flow-c "(flow/start (branch (lambda (x) (< x 10)) (sequence (lambda (x) (+ x 1)) (lambda (x) (* x 2))) (flow-const 0)) 4)") 10) (flow-ctl-test "branch: nested branch (3-way sign)" (flow-c "(defflow sign (branch (lambda (x) (> x 0)) (flow-const 1) (branch (lambda (x) (< x 0)) (flow-const -1) (flow-const 0)))) (list (flow/start sign 7) (flow/start sign -7) (flow/start sign 0))") (list 1 -1 0)) (flow-ctl-test "branch: publish-shaped approval gate" (flow-cs "(defflow publish (branch (lambda (post) (>= (string-length post) 3)) (lambda (post) (string-append post \" [published]\")) (lambda (post) (string-append post \" [rejected]\")))) (flow/start publish \"ok\")") "ok [rejected]") (define flow-ctl-tests-run! (fn () {:total (+ flow-ctl-pass flow-ctl-fail) :passed flow-ctl-pass :failed flow-ctl-fail :fails flow-ctl-fails}))