(module snooze-unit-pipeline-test mzscheme
(require (lib "unitsig.ss")
(lib "cut.ss" "srfi" "26"))
(require (planet "pipeline.ss" ("untyped" "unlib.plt" 2)))
(require (file "era.ss")
(file "persistent-struct.ss")
(prefix q: (file "query-lang.ss"))
(file "snooze-unit.ss")
(file "snooze-sig.ss")
(file "test-base.ss")
(file "test-data.ss")
(file "test-sig.ss")
(file "type.ss"))
(provide snooze-unit-pipeline-tests@)
(define saved (box #f)) (define inserted (box #f)) (define updated (box #f)) (define deleted (box #f))
(define (clear-boxes)
(set-box! saved #f)
(set-box! inserted #f)
(set-box! updated #f)
(set-box! deleted #f))
(define-struct (exn:unpipelined exn) ())
(define (create-stage name box bad-value)
(make-stage
name
(lambda (continue conn struct)
(if (= (pipelined-value struct) bad-value)
(raise-exn exn:unpipelined "Argh!")
(begin (set-box! box struct)
(continue conn struct))))))
(define-persistent-struct pipelined
([value type:integer/1])
([save (list (create-stage 'save saved 1))]
[insert (list (create-stage 'insert inserted 2))]
[update (list (create-stage 'update updated 3))]
[delete (list (create-stage 'delete deleted 4))]))
(define test-pipelined (make-pipelined 0))
(define snooze-unit-pipeline-tests@
(unit/sig test^
(import snooze^)
(define suite
(test-suite
"snooze-unit-pipeline-test.ss"
#:before
(lambda ()
(create-table entity:pipelined))
#:after
(lambda ()
(drop-table entity:pipelined))
(test-case
"on-save and on-insert are called when saving a new struct"
(set-pipelined-value! test-pipelined 0)
(save! test-pipelined)
(check-eq? (unbox saved) test-pipelined)
(check-eq? (unbox inserted) test-pipelined)
(check-eq? (unbox updated) #f)
(check-eq? (unbox deleted) #f)
(clear-boxes))
(test-case
"on-save and on-update are called when re-saving a struct"
(set-pipelined-value! test-pipelined 0)
(save! test-pipelined)
(check-eq? (unbox saved) test-pipelined)
(check-eq? (unbox inserted) #f)
(check-eq? (unbox updated) test-pipelined)
(check-eq? (unbox deleted) #f)
(clear-boxes))
(test-case
"on-delete is called on delete"
(set-pipelined-value! test-pipelined 0)
(delete! test-pipelined)
(check-eq? (unbox saved) #f)
(check-eq? (unbox inserted) #f)
(check-eq? (unbox updated) #f)
(check-eq? (unbox deleted) test-pipelined)
(clear-boxes))
(test-case
"saving is aborted when on-save throws an exception"
(set-pipelined-value! test-pipelined 1)
(check-exn exn:unpipelined? (lambda () (save! test-pipelined)))
(check-false (get-id test-pipelined))
(check-pred null? (let ([a (q:entity entity:pipelined)])
(find-all (q:select #:from a))))
(check-eq? (unbox saved) #f)
(check-eq? (unbox inserted) #f)
(check-eq? (unbox updated) #f)
(check-eq? (unbox deleted) #f))
(test-case
"saving is aborted when on-insert throws an exception"
(set-pipelined-value! test-pipelined 2)
(check-exn exn:unpipelined? (lambda () (save! test-pipelined)))
(check-false (get-id test-pipelined))
(check-pred null? (let ([a (q:entity entity:pipelined)])
(find-all (q:select #:from a))))
(check-eq? (unbox saved) test-pipelined)
(check-eq? (unbox inserted) #f)
(check-eq? (unbox updated) #f)
(check-eq? (unbox deleted) #f)
(clear-boxes))
(test-case
"saving is aborted when on-update throws an exception"
(set-pipelined-value! test-pipelined 0)
(save! test-pipelined)
(clear-boxes)
(set-pipelined-value! test-pipelined 3)
(check-exn exn:unpipelined? (lambda () (save! test-pipelined)))
(check-equal? (pipelined-value (find-by-id entity:pipelined (get-id test-pipelined))) 0)
(check-eq? (unbox saved) test-pipelined)
(check-eq? (unbox inserted) #f)
(check-eq? (unbox updated) #f)
(check-eq? (unbox deleted) #f)
(clear-boxes))
(test-case
"deleting is aborted when on-delete throws an exception"
(set-pipelined-value! test-pipelined 4)
(save! test-pipelined)
(clear-boxes)
(check-exn exn:unpipelined? (lambda () (delete! test-pipelined)))
(check-equal? (pipelined-value (find-by-id entity:pipelined (get-id test-pipelined))) 4)
(check-eq? (unbox saved) #f)
(check-eq? (unbox inserted) #f)
(check-eq? (unbox updated) #f)
(check-eq? (unbox deleted) #f)
(clear-boxes))
))
))
)