; Phase 2 — projections: fold a stream into a read model, resume incrementally. (persist-test "project empty stream returns seed value" (persist/project-fold (persist/open) "s" (fn (acc e) (+ acc 1)) 0) 0) (persist-test "project empty stream seq is 0" (persist/project-seq (persist/project (persist/open) "s" (fn (a e) a) 0)) 0) (persist-test "project counts events" (let ((b (persist/open))) (begin (persist/append b "s" "x" 0 {}) (persist/append b "s" "x" 0 {}) (persist/append b "s" "x" 0 {}) (persist/project-fold b "s" (fn (acc e) (+ acc 1)) 0))) 3) (persist-test "project sums event data" (let ((b (persist/open))) (begin (persist/append b "ledger" "credit" 0 {:amt 10}) (persist/append b "ledger" "credit" 1 {:amt 5}) (persist/append b "ledger" "debit" 2 {:amt 3}) (persist/project-fold b "ledger" (fn (bal e) (if (equal? (persist/event-type e) "credit") (+ bal (get (persist/event-data e) :amt)) (- bal (get (persist/event-data e) :amt)))) 0))) 12) (persist-test "project tracks last seq" (let ((b (persist/open))) (begin (persist/append b "s" "x" 0 {}) (persist/append b "s" "x" 0 {}) (persist/project-seq (persist/project b "s" (fn (a e) a) 0)))) 2) (persist-test "resume folds only the tail" (let ((b (persist/open))) (begin (persist/append b "s" "x" 0 {}) (persist/append b "s" "x" 0 {}) (let ((p1 (persist/project b "s" (fn (acc e) (+ acc 1)) 0))) (begin (persist/append b "s" "x" 0 {}) (persist/project-value (persist/project-resume b "s" (fn (acc e) (+ acc 1)) p1)))))) 3) (persist-test "resume with no new events is a no-op" (let ((b (persist/open))) (begin (persist/append b "s" "x" 0 {}) (let ((p1 (persist/project b "s" (fn (acc e) (+ acc 1)) 0))) (persist/project-value (persist/project-resume b "s" (fn (acc e) (+ acc 1)) p1))))) 1) (persist-test "resume advances seq" (let ((b (persist/open))) (begin (persist/append b "s" "x" 0 {}) (let ((p1 (persist/project b "s" (fn (a e) a) 0))) (begin (persist/append b "s" "x" 0 {}) (persist/append b "s" "x" 0 {}) (persist/project-seq (persist/project-resume b "s" (fn (a e) a) p1)))))) 3) (persist-test "full project equals seed-resume from zero" (let ((b (persist/open))) (begin (persist/append b "s" "x" 0 {}) (persist/append b "s" "x" 0 {}) (equal? (persist/project b "s" (fn (acc e) (+ acc 1)) 0) (persist/project-resume b "s" (fn (acc e) (+ acc 1)) {:value 0 :seq 0})))) true)