(module monad-test mzscheme
(require "test.ss")
(require "monad.ss")
(provide monad-tests)
(define (counter-monad v s)
(make-monad v s))
(define (return-counter value)
(lambda (counter)
(counter-monad value
(monad-state counter))))
(define (increment-counter)
(lambda (counter)
(set-monad-state! counter
(add1 (monad-state counter)))
(set-monad-value! counter (void))
counter))
(define (set-counter s)
(lambda (counter)
(set-monad-state! counter s)
(set-monad-value! counter (void))
counter))
(define (get-counter)
(lambda (counter)
(set-monad-value! counter
(monad-state counter))
counter))
(define monad-tests
(test-suite
"All tests for monad"
(test-case
"compose threads state"
(let ((m ((compose (get-counter)
(lambda (c)
(check = c 0)
(increment-counter)))
(counter-monad (void) 0))))
(check = (monad-state m) 1)))
(test-case
"compose* threads state"
(let ((m
((compose* (get-counter)
(lambda (c)
(check = c 0)
(increment-counter))
(lambda (r)
(check-pred void? r)
(increment-counter))
(lambda (r)
(check-pred void? r)
(get-counter))
(lambda (c)
(check = c 2)
(return-counter #t)))
(counter-monad (void) 0))))
(check = 2 (monad-state m))
(check-true (monad-value m))))
(test-case
"sequence threads state"
(let ((m ((sequence (increment-counter)
(increment-counter))
(counter-monad (void) 0))))
(check = 2 (monad-state m))
(check-pred void? (monad-value m))))
(test-case
"sequence* threads state"
(let ((m ((sequence* (increment-counter)
(increment-counter)
(increment-counter)
(increment-counter))
(counter-monad (void) 0))))
(check = 4 (monad-state m))
(check-pred void? (monad-value m))))
(test-case
"sequence* executes in correct order"
(let ((m ((sequence* (set-counter 0)
(set-counter 1)
(set-counter 2)
(set-counter 4))
(counter-monad (void) 0))))
(check = 4 (monad-state m))
(check-pred void? (monad-value m))))
))
)