;; lib/flow/tests/api.sx — Phase 5: operational introspection API. (define flow-api-pass 0) (define flow-api-fail 0) (define flow-api-fails (list)) (define flow-api-test (fn (name actual expected) (if (= actual expected) (set! flow-api-pass (+ flow-api-pass 1)) (begin (set! flow-api-fail (+ flow-api-fail 1)) (append! flow-api-fails {:name name :expected expected :actual actual}))))) (define flow-a (fn (src) (flow-run src))) ;; ── flow/status ───────────────────────────────────────────────── (flow-api-test "status: unknown id" (flow-a "(flow/status 999)") "unknown") (flow-api-test "status: suspended flow" (flow-a "(defflow w (lambda (x) (suspend (quote q)))) (define id (car (cdr (flow/start w 0)))) (flow/status id)") "suspended") (flow-api-test "status: completed flow" (flow-a "(defflow w (sequence (lambda (x) (suspend (quote q))) (lambda (v) v))) (define id (car (cdr (flow/start w 0)))) (flow/resume id 5) (flow/status id)") "done") (flow-api-test "status: cancelled flow" (flow-a "(defflow w (lambda (x) (suspend (quote q)))) (define id (car (cdr (flow/start w 0)))) (flow/cancel id) (flow/status id)") "cancelled") ;; ── flow/result ───────────────────────────────────────────────── (flow-api-test "result: returns the value of a completed flow" (flow-a "(defflow w (sequence (lambda (x) (suspend (quote q))) (lambda (v) (list (quote got) v)))) (define id (car (cdr (flow/start w 0)))) (flow/resume id 9) (flow/result id)") (list "got" 9)) (flow-api-test "result: a still-suspended flow has no result" (flow-a "(defflow w (lambda (x) (suspend (quote q)))) (define id (car (cdr (flow/start w 0)))) (flow/result id)") (list "flow-error" "not-done")) (flow-api-test "result: unknown id errors" (flow-a "(flow/result 999)") (list "flow-error" "no-such-flow")) ;; ── flow/list ─────────────────────────────────────────────────── (flow-api-test "list: empty store" (flow-a "(flow/list)") (list)) (flow-api-test "list: reports id + status for each flow (newest first)" (flow-a "(defflow w (lambda (x) (suspend (quote q)))) (flow/start w 0) (flow/start (lambda (x) (* x 2)) 5) (flow/list)") (list (list 2 "done") (list 1 "suspended"))) ;; ── flow/pending ──────────────────────────────────────────────── (flow-api-test "pending: lists suspended flows with their waiting tag" (flow-a "(defflow w (lambda (x) (suspend (quote review)))) (flow/start w 0) (flow/pending)") (list (list 1 "review"))) (flow-api-test "pending: excludes completed and cancelled flows" (flow-a "(defflow w (lambda (x) (suspend (quote q)))) (defflow v (sequence (lambda (x) (suspend (quote r))) (lambda (y) y))) (define i1 (car (cdr (flow/start w 0)))) (define i2 (car (cdr (flow/start v 0)))) (define i3 (car (cdr (flow/start w 0)))) (flow/resume i2 1) (flow/cancel i3) (flow/pending)") (list (list 1 "q"))) (flow-api-test "pending: operator can drain all pending flows" (flow-a "(defflow w (sequence (lambda (x) (suspend (quote q))) (lambda (v) (* v 10)))) (flow/start w 0) (flow/start w 0) (define ps (flow/pending)) (flow/resume (car (car ps)) 1) (flow/resume (car (car (cdr ps))) 2) (flow/list)") (list (list 1 "done") (list 2 "done"))) (define flow-api-tests-run! (fn () {:total (+ flow-api-pass flow-api-fail) :passed flow-api-pass :failed flow-api-fail :fails flow-api-fails}))