Current section

Files

Jump to
ltest src ltest-formatter.lfe
Raw

src/ltest-formatter.lfe

(defmodule ltest-formatter
(export all))
(include-lib "ltest/include/ltest-records.lfe")
(defun test-suite-header ()
(io:format (get-suite-header)))
(defun get-suite-header ()
(ltest-color:greenb
(test-header (ltest-const:test-suite-title)
(ltest-const:test-suite-header))))
(defun test-suite-footer ()
(io:format (get-suite-footer)))
(defun get-suite-footer ()
(io_lib:format "~s~n~n" `(,(ltest-color:greenb
(string:copies
(ltest-const:test-suite-header)
(ltest-const:test-suite-width))))))
(defun test-type-header (title)
(io:format
(ltest-color:blueb
(test-header title (ltest-const:test-suite-subheader)))))
(defun test-header (title char)
(let* ((title (++ " " title " "))
(width (ltest-const:test-suite-width))
(header-len (trunc (/ (- width (length title)) 2)))
(header (++ (string:copies char header-len)
title
(string:copies char header-len))))
(io_lib:format "~s~n~n" `(,(string:left
header
width
(car char))))))
(defun indent (count)
(string:copies " " count))
(defun func-line (raw-func desc)
(let ((func
(if (!= 'undefined desc)
desc
(get-func-name raw-func))))
(io:format "~s~s ~s" `(,(indent (ltest-const:func-indent))
,func
,(get-elision func)))))
(defun get-skip-func-name (func-name)
(re:replace
(atom_to_list func-name)
"_skip$" "" '(global #(return list))))
(defun get-func-name (func-name)
(re:replace
(atom_to_list func-name)
"_test(_)?$" "" '(global #(return list))))
(defun get-elision
((func-name) (when (is_list func-name))
(let* ((init-len (+ (ltest-const:func-indent)
(length func-name)))
(end-len (length " [fail]"))
(elide-len (- (ltest-const:test-suite-width)
(+ init-len end-len))))
(string:copies "." elide-len)))
;Named tests send description as binary
((desc) (when (is_binary desc))
(get-elision (binary_to_list desc))))
(defun mod-line (desc)
(io:format "~smodule: ~s~n"
`(,(indent (ltest-const:mod-indent))
,(ltest-color:greenb
(atom_to_list (ltest-util:get-module desc))))))
(defun ok ()
(io:format (++ "... [" (ltest-color:greenb "ok") "]~n")))
(defun fail (error where)
(io:format ". [~s]~n~n~s~s:~n" `(,(ltest-color:red "fail")
,(indent (ltest-const:error-indent))
,(ltest-color:yellowb "Assertion failure")))
(lfe_io:format "~s\e[31;1m~p\e[0m~n~n" `(,(indent (ltest-const:error-indent))
,error)))
(defun err (error where)
(io:format " [~s]~n~n~s~s:~n" `(,(ltest-color:yellow "error")
,(indent (ltest-const:error-indent))
,(ltest-color:yellowb "Error")))
(lfe_io:format "~s\e[31;1m~p\e[0m~n~n" `(,(indent (ltest-const:error-indent))
,error)))
(defun skip ()
(++ " [" (ltest-color:blue "skip") "]"))
(defun mod-time (time)
(io:format "~s~s ~s~s~n~n" `(,(indent (ltest-const:func-indent))
,(ltest-color:blackb "time:")
,(ltest-color:blackb (integer_to_list time))
,(ltest-color:blackb "ms"))))
(defun skip-lines (skipped)
(lists:map #'skip-line/1 skipped))
(defun skip-line
((`#(,raw-func ,_))
(let ((func (get-skip-func-name raw-func)))
(io:format "~s~s ~s~s~n" `(,(indent (ltest-const:func-indent))
,func
,(get-elision func)
,(skip))))))
(defun display-results (data state)
(stats-heading)
(display-all state)
(display-successes state)
(display-skips state)
(display-failures state)
(display-errors state)
;;(ltest-formatter:display-pending state)
;;(ltest-formatter:display-profile state)
(display-timing state)
;;(ltest-formatter:display-results data state)
(finish-section))
(defun stats-heading ()
(io:format (++ (ltest-color:yellow "summary:") "~n")))
(defun display-all (state)
(io:format "~sTests: ~p " `(,(indent (ltest-const:func-indent))
,(ltest-util:all-tests state))))
(defun display-successes (state)
(io:format "~s: ~p " `(,(get-ok-report state)
,(state-ok state))))
(defun display-skips (state)
(io:format "~s: ~p " `(,(get-skip-report state)
,(state-skip state))))
(defun display-failures (state)
(io:format "~s: ~p " `(,(get-fail-report state)
,(state-fail state))))
(defun display-errors (state)
(io:format "~s: ~p~n" `(,(get-err-report state)
,(state-err state))))
(defun display-pending (state)
(io:format "Pending state: ~p~n" `(,state)))
(defun display-profile (state)
(io:format "Profile state: ~p~n" `(,state)))
(defun display-timing (state)
(io:format "~sTotal time: ~pms~n" `(,(indent (ltest-const:func-indent))
,(state-time state))))
(defun display-no-results (data state)
(io:format (ltest-color:yellow (get-no-results-report data state)))
(finish-section))
(defun display-test-cancel (reason)
(io:format (format-cancel reason)))
(defun format-cancel
(('undefined) "*skipped*~n")
(('timeout) "*timed out*~n")
((`#(startup ,reason))
(io_lib:format "*could not start test process*~n::~tP~n~n"
(list reason 15)))
((`#(blame ,_subid))
"*cancelled because of subtask*~n")
((`#(exit ,reason))
(io_lib:format "*unexpected termination of test process*~n::~tP~n~n"
(list reason 15)))
((`#(abort ,reason))
(eunit_lib:format_error reason)))
(defun get-no-results-report (data state)
(io_lib:format
"There were no ~s tests found.~n"
`(,(state-test-type state))))
(defun finish-section ()
(io:nl)
(io:nl))
(defun get-ok-report (state)
(get-report "Passed" #'ltest-color:greenb/1 (state-ok state)))
(defun get-skip-report (state)
(get-report "Skipped" #'ltest-color:blue/1 (state-skip state)))
(defun get-fail-report (state)
(get-report "Failed" #'ltest-color:red/1 (state-fail state)))
(defun get-err-report (state)
(get-report "Erred" #'ltest-color:yellow/1 (state-err state)))
(defun get-report (text color-func count)
(if (== count 0)
text
(funcall color-func text)))