Current section

Files

Jump to
ltest src ltest-listener.lfe
Raw

src/ltest-listener.lfe

(defmodule ltest-listener
(behaviour eunit_listener)
(export all))
(include-lib "ltest/include/ltest-records.lfe")
(defun start ()
(start '()))
(defun start (options)
(eunit_listener:start (MODULE) options))
(defun init (options)
(make-state test-type (proplists:get_value 'test-type options)))
(defun handle_begin
(('group (= `(,_ #(desc undefined) ,_ ,_) data) state)
state)
(('group (= `(,_ #(desc ,desc) ,_ ,_) data) state)
(case (binary:match desc (binary "file"))
('nomatch 'skipping)
(_ (ltest-formatter:mod-line desc)))
;; (io:format "\tdata: ~p~n" (list data))
;; (io:format "\tstate: ~p~n" (list state))
state)
(('test (= `(,_ ,_ #(source #(,mod ,func ,arity)) ,_) data) state)
(ltest-formatter:func-line func
(proplists:get_value 'desc data 'undefined))
;; (io:format "\t\tdata: ~p~n" (list data))
;; (io:format "\t\tstate: ~p~n" (list state))
state)
(('test data state)
(io:format "\tstarting test ...~n" '())
;; (io:format "\t\tdata: ~p~n" (list data))
;; (io:format "\t\tstate: ~p~n" (list state))
state))
(defun handle_end
(('group `(,_ ,_ #(desc undefined) ,_ ,_ #(time ,time) ,_) state)
;; skipping undefined description
state)
(('group (= `(,_ ,_ #(desc ,desc) ,_ ,_ #(time ,time) ,_) data) state)
;; (io:format "ending group ...~n")
;; (io:format "\tdata: ~p~n" (list data))
;; (io:format "\tstate: ~p~n" (list state))
(case (binary:match desc (binary "file"))
('nomatch state)
(_ (handle-module-end desc time data state))))
(('group data state)
;; (io:format "ending group ...~n")
;; (io:format "\tdata: ~p~n" (list data))
;; (io:format "\tstate: ~p~n" (list state))
state)
(('test (= `(,_ #(status #(error #(error ,error ,where))) ,_ ,_ ,_ ,_ ,_) data) state)
(ltest-formatter:fail error where)
(set-state-fail state (+ 1 (state-fail state))))
(('test (= `(,_ #(status #(error #(exit ,error ,where))) ,_ ,_ ,_ ,_ ,_) data) state)
(ltest-formatter:err
(element 2 (proplists:get_value 'status data)) where)
;; XXX maybe change this to set-state-cancel?
(set-state-err state (+ 1 (state-err state))))
(('test `(,_ #(status ok) ,_ ,_ ,_ ,_ ,_) state)
(ltest-formatter:ok)
(set-state-ok state (+ 1 (state-ok state))))
(('test data state)
(io:format "\tltest ERROR: unhandled data!~n" '())
(io:format "\t\tdata: ~p~n" `(,data))
(io:format "\t\tstate: ~p~n" `(,state))
state)
((x data state)
(io:format "\tltest ERROR: unknown arg!~n" '())
(io:format "\t\tfirst arg: ~p~n" `(,x))
(io:format "\t\tdata: ~p~n" `(,data))
(io:format "\t\tstate: ~p~n" `(,state))
state))
(defun handle_cancel
((_group_or_test data state)
(ltest-formatter:display-test-cancel (proplists:get_value 'reason data))
;; This counts groups and tests together
(set-state-err state (+ 1 (state-err state)))))
(defun terminate
((`#(ok ,data) state)
;; (io:format "Terminating ...~n")
(if (> (ltest-util:all-tests state) 0)
(ltest-formatter:display-results data state)
(ltest-formatter:display-no-results data state))
;; error out if tests were cancelled
(if (> (proplists:get_value 'cancel data 0) 0)
(io:format (ltest-color:red "One or more tests were cancelled.\n"))
(sync_end 'error)) ;same behaviour as eunit
`#(ok ,data ,state))
((`#(error ,reason) state)
(io:nl)
(io:nl)
(sync_end `#(error ,reason ,state))))
(defun sync_end (result)
(receive
(`#(stop ,reference ,reply-to)
(! reply-to `#(result ,reference ,result))
`#(ok ,result))))
(defun handle-module-end (desc time data state)
(let ((skipped-tests (ltest-util:get-skip-tests desc))
(`#(,data-1 ,_) (lists:split 2 data))
(`#(,_ ,data-2) (lists:split 3 data)))
(ltest-formatter:skip-lines skipped-tests)
(ltest-formatter:mod-time time)
(update-skips
(update-time state time)
(length skipped-tests))))
(defun update-time (state time)
(set-state-time state (+ time (state-time state))))
(defun update-skips (state skips)
(set-state-skip state (+ skips (state-skip state))))