# Specification: clojure.core.async on Janet fibers (Phase 1 — API layer). # Each case is self-contained: it requires the ns, sets up channels/go blocks, # and ends with a take that pumps the event loop and yields the value compared. (use ../support/harness) (def REQ "(require '[clojure.core.async :refer [go go-loop chan ! close! alts! timeout put! take! chan? buffer dropping-buffer sliding-buffer]]) ") (defn- a [body] (string "(do " REQ body ")")) (defspec "core.async / go & channels" ["go produce, ! c (+ 40 2))) ( channel closes" "nil" (a "(! x 10)) (go (>! y 32)) (! c 1) (>! c 2) (>! c 3) (close! c)) (! c :a) (close! c)) (! to a closed channel is false" "false" (a "(def c (chan 1)) (close! c) (>! c 1)")] ["take from closed empty channel is nil" "nil" (a "(def c (chan)) (close! c) (! in 1) (>! in 2) (>! in 3) (close! in)) (! mid (inc (! out (* 10 (! in 4)) (! y :v)) (! c 7)) (! c 1) (>! c 2) (>! c 3) (close! c))")] ["filter transducer" "[0 2 4]" (drain "(def c (chan 10 (filter even?))) (go (doseq [x (range 6)] (>! c x)) (close! c))")] ["mapcat expands" "[1 1 2 2]" (drain "(def c (chan 10 (mapcat (fn [x] [x x])))) (go (>! c 1) (>! c 2) (close! c))")] ["take closes early" "[:a :b]" (drain "(def c (chan 10 (take 2))) (go (>! c :a) (>! c :b) (>! c :c) (>! c :d) (close! c))")] ["comp of transducers" "[10 30 50]" (drain "(def c (chan 10 (comp (filter odd?) (map (fn [x] (* x 10)))))) (go (doseq [x (range 6)] (>! c x)) (close! c))")]) # Buffers: fixed (default), dropping (drops new when full), sliding (drops oldest # when full). Filled synchronously on this fiber (dropping/sliding never park). (defn- fill [bufexpr] (string "(do " REQ "(def c (chan " bufexpr ")) (doseq [x [1 2 3 4 5]] (>! c x)) (close! c)" " (