Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 1m9s
project.sx: projection state {:value :seq}; persist/project folds the whole
stream, persist/project-resume folds only the tail so read models update
incrementally. Pure step (value event)->value. 37/37.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
116 lines
2.9 KiB
Plaintext
116 lines
2.9 KiB
Plaintext
; 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)
|