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 (state)
(io:format (get-suite-header state)))
(defun get-suite-header
(((match-state color? color?))
(ltest-color:greenb
(test-header (ltest-const:test-suite-title)
(ltest-const:test-suite-header))
color?)))
(defun test-suite-footer (state)
(io:format (get-suite-footer state)))
(defun get-suite-footer
(((match-state color? color?))
(io_lib:format "~s~n~n" `(,(ltest-color:greenb
(string:copies
(ltest-const:test-suite-header)
(ltest-const:test-suite-width))
color?)))))
(defun test-type-header
((title (match-state color? color?))
(io:format
(ltest-color:blueb
(test-header title (ltest-const:test-suite-subheader))
color?))))
(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-check
(((= (binary (prefix bytes (size 5)) (file bitstring)) desc) (match-state color? color?)) (when (=:= prefix #"file "))
;;(((= (binary "file " (mod bitstring)) desc) (match-state color? color?))
(ltest-util:rebar-debug "Getting mod-line-begin (file) ..." '())
(ltest-util:rebar-debug "desc: ~p" (list desc))
(ltest-util:rebar-debug "module (mod-line-begin): ~p" (list (ltest-util:file->module desc)))
(io_lib:format "~smodule: ~s~n"
`(,(indent (ltest-const:mod-indent))
,(ltest-color:greenb
(atom_to_list (ltest-util:file->module desc))
color?))))
(((= (binary (prefix bytes (size 7)) (mod bitstring)) desc) (match-state color? color?)) (when (=:= prefix #"module "))
(ltest-util:rebar-debug "Getting mod-line-begin (module) ..." '())
(ltest-util:rebar-debug "desc: ~p" (list desc))
(ltest-util:rebar-debug "module (mod-line-begin): ~p" (list mod))
(io_lib:format "~smodule: ~s~n"
`(,(indent (ltest-const:mod-indent))
,(ltest-color:greenb
(ltest-util:binary-mod->str mod)
color?))))
(((= (binary (prefix bytes (size 7)) (rest bitstring)) desc) (match-state color? color?))
(ltest-util:rebar-debug "Getting mod-line-begin (???) ..." '())
(ltest-util:rebar-debug "Unexecpted desc: ~p" (list desc))
(ltest-util:rebar-debug "prefix: ~p" (list prefix))
(ltest-util:rebar-debug "rest: ~p" (list rest))
(ltest-util:rebar-debug "Skipping ..." '())
"")
((desc (match-state color? color?))
(ltest-util:rebar-debug "Getting mod-line-begin (???) ..." '())
(ltest-util:rebar-debug "Unexecpted desc: ~p" (list desc))
(ltest-util:rebar-debug "Skipping ..." '())
""))
(defun mod-line-begin (desc state)
(case (mod-line-check desc state)
("" 'skipping)
(result (io:format result))))
(defun mod-line-end (desc time data state)
(ltest-util:rebar-debug "Getting mod-line-end (file) ..." '())
(ltest-util:rebar-debug "desc: ~p, time: ~p, data: ~p, state: ~p" (list desc time data state))
(let ((skipped-tests (ltest-util:get-skip-tests desc)))
(logger:debug "skipped: ~p" (list skipped-tests))
(ltest-formatter:skip-lines skipped-tests state)
(ltest-formatter:mod-time time state)))
(defun ok
(((match-state color? color?))
(io:format (++ "... [" (ltest-color:greenb "ok" color?) "]~n"))))
(defun fail
((error where (match-state color? color?))
(io:format ". [~s]~n~n~s~s:~n" `(,(ltest-color:red "fail" color?)
,(indent (ltest-const:error-indent))
,(ltest-color:yellowb
"Assertion failure" color?)))
(lfe_io:format "~s\e[31;1m~p\e[0m~n~n" `(,(indent (ltest-const:error-indent))
,error))))
(defun err
((error where (match-state color? color?))
(io:format " [~s]~n~n~s~s:~n" `(,(ltest-color:yellow "error" color?)
,(indent (ltest-const:error-indent))
,(ltest-color:yellowb "Error" color?)))
(lfe_io:format "~s\e[31;1m~p\e[0m~n~n" `(,(indent (ltest-const:error-indent))
,error))))
(defun skip
(((match-state color? color?))
(++ ". [" (ltest-color:blue "skip" color?) "]")))
(defun mod-time
((time (match-state color? color?))
(io:format "~s~s ~s~s~n~n"
`(,(indent (ltest-const:func-indent))
,(ltest-color:blackb "time:" color?)
,(ltest-color:blackb (integer_to_list time) color?)
,(ltest-color:blackb "ms" color?)))))
(defun skip-lines (skipped state)
(lists:map (lambda (s) (skip-line s state)) skipped))
(defun skip-line
((`#(,raw-func ,_) state)
(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 state))))))
(defun display-results (data state)
(stats-heading state)
(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
(((match-state color? color?))
(io:format (++ (ltest-color:yellow "summary:" color?) "~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 (= (match-state color? color?) state))
(io:format (ltest-color:yellow (get-no-results-report data state) color?))
(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
(((match-state color? color? ok ok))
(get-report "Passed" #'ltest-color:greenb/2 ok color?)))
(defun get-skip-report
(((match-state color? color? skip skip))
(get-report "Skipped" #'ltest-color:blue/2 skip color?)))
(defun get-fail-report
(((match-state color? color? fail fail))
(get-report "Failed" #'ltest-color:red/2 fail color?)))
(defun get-err-report
(((match-state color? color? err err))
(get-report "Erred" #'ltest-color:yellow/2 err color?)))
(defun get-report (text color-func count color?)
(if (== count 0)
text
(funcall color-func text color?)))