diff --git a/.travis.yml b/.travis.yml index b8bef9c..792fedb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,4 +10,4 @@ before_script: - cd /tmp/picoLisp/src64 && make script: - - cd ${TRAVIS_BUILD_DIR} && /tmp/picoLisp/pil test.l + - cd ${TRAVIS_BUILD_DIR} && (for i in plain default; do TEST_REPORTER="$i" /tmp/picoLisp/pil test.l; done) diff --git a/README.md b/README.md index be68301..e75d46f 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,10 @@ Please read [EXPLAIN.md](EXPLAIN.md) to learn more about PicoLisp and this Unit 3. [Usage](#usage) 4. [Examples](#examples) 5. [Testing](#testing) - 6. [Alternatives](#alternatives) - 7. [Contributing](#contributing) - 8. [License](#license) + 6. [Reporters](#reporters) + 7. [Alternatives](#alternatives) + 8. [Contributing](#contributing) + 9. [License](#license) # Requirements @@ -191,6 +192,41 @@ This library has its own set of tests. You can use those as examples as well. To ./test.l +# Reporters + +If you don't call `(report)`, the test results will not be printed to the screen. + +This allows you to create your own custom reporter and use it to output the test results however you like. + +There are two existing reporters, to use one set the `TEST_REPORTER` environment variable: + + TEST_REPORTER=plain ./test.l + +or + + TEST_REPORTER=default ./test.l + +### Creating a custom reporter + +Your custom reporter only needs to implement the `(print-report)` function. This gets called by the public `(report)` function. + +Add a file to the `reporters/` directory (ex: `custom.l`). The filename (without `.l` extension) will be the name of your reporter. + +You can use any of the following helper functions/variables: + + * `(colour)` + * `(plural?)` + * `(get-results)` + * `*Results` global variable + +> **Note:** Avoid using the internal functions as they might change without notice. + + * All test results can be obtained with the `*Results` global variable. + * All _failed_ results can be obtained with `(get-results NIL)`. + * All _passed_ results can be obtained with `(get-results T)`. + +Please make a pull-request if you would like your custom reporter to be added to this library. + # Alternatives The alternative approaches to testing in PicoLisp involve the use of [test](http://software-lab.de/doc/refT.html#test) and [assert](http://software-lab.de/doc/refA.html#assert). diff --git a/module.l b/module.l index 81cbfa2..912e114 100644 --- a/module.l +++ b/module.l @@ -1,6 +1,6 @@ [de MODULE_INFO ("name" "unit") - ("version" "0.5.2") + ("version" "0.6.0") ("summary" "Unit Testing framework for PicoLisp") ("source" "https://github.com/aw/picolisp-unit.git") ("author" "Alexander Williams") diff --git a/reporters/default.l b/reporters/default.l new file mode 100644 index 0000000..9234d77 --- /dev/null +++ b/reporters/default.l @@ -0,0 +1,95 @@ +# reporters/default.l +# +# The MIT License (MIT) +# +# Copyright (c) 2015 Alexander Williams, Unscramble + +(local *Colours print-report print-passed print-failed report-failed print-error) +(local print-expected print-got exit-gracefully) + +(de *Colours ("red" . 1) + ("green" . 2) + ("yellow" . 3) + ("blue" . 4) ) + + +[de print-report () + (mapcar '((N) (prin (align 3 (cadr N)) ") ") + (if (=T (car N)) + (print-passed (caddr N)) + (print-failed (caddr N)) ) ) + *Results ) + + (let (Passed_results (get-results T) + Failed_results (get-results) ) + + (prinl (colour "bold") + "----^J" + (colour "green") + (length Passed_results) + " test" (plural? Passed_results) + " passed, " + (colour "red") + (length Failed_results) + " test" (plural? Failed_results) + " failed" + (colour) ) + + (report-failed) + (exit-gracefully) ] + +[de print-passed @ + (prinl (colour "green") + (char (hex "2713")) + (align 2 " ") + (colour) + (next) ) ] + +[de print-failed (Message Expected Result) + (prinl (colour "red") + (char (hex "2715")) + (align 2 " ") + Message + (colour) ] + +(de report-failed () + (when Failed_results + (prinl "^J" (colour "red") "^J Failed test" (plural? Failed_results) ": ") + + (mapcar + '((N) (print-error (cadr N) (caddr N)) + (print-expected (; N 4)) + (print-got (; N 5)) ) + Failed_results ) + + (colour) ] + +[de print-error (Number Result) + (prinl (colour "red") + "^J" + (align 4 " - ") + Number + ") " + Result + (colour) ] + +[de print-expected (Result) + (prin (align 8 " ") + "Expected: " + (colour "green") ) + + (println Result) + (colour) ] + +[de print-got (Result) + (prin (align 8 " ") + (align 10 " Actual: ") + (colour "red") ) + + (println Result) + (colour) ] + +[de exit-gracefully () + (if Failed_results + (bye 1) + (bye) ] diff --git a/reporters/plain.l b/reporters/plain.l new file mode 100644 index 0000000..11e5e03 --- /dev/null +++ b/reporters/plain.l @@ -0,0 +1,14 @@ +# reporters/plain.l +# +# The MIT License (MIT) +# +# Copyright (c) 2015 Alexander Williams, Unscramble + +(local print-report) + +[de print-report () + (mapcar println *Results) + + (if (get-results) + (bye 1) + (bye) ] diff --git a/test.l b/test.l index 370ac2c..edc65c2 100755 --- a/test.l +++ b/test.l @@ -5,7 +5,7 @@ (load "unit.l") (chdir "test/" - (mapcar load (filter '((N) (sub? "test_" N)) (dir "."))) ) - # (mapcar load '("test_internal.l" "test_unit.l")) ) # same as above + (mapcar load '("test_internal.l" "test_unit.l" `(pack "test_reporter_" (if (sys "TEST_REPORTER") @ "default") ".l"))) ) + # (mapcar load (filter '((N) (sub? "test_" N)) (dir "."))) ) # almost same as above (report) diff --git a/test/test_internal.l b/test/test_internal.l index 7ca2265..1f588ab 100644 --- a/test/test_internal.l +++ b/test/test_internal.l @@ -7,7 +7,5 @@ Result ) ) [execute - '(assert-nil (prog (colour "yellow") (colour)) "Set colour to yellow") - '(assert-nil (colour) "Reset colour") '(assert-kind-of 'List (randomize '(1 2)) "Randomize the list") '(assert-equal '(1 2 3 4) (test-dont-randomize) "Don't randomize the list") ] diff --git a/test/test_reporter_default.l b/test/test_reporter_default.l new file mode 100644 index 0000000..4e1843a --- /dev/null +++ b/test/test_reporter_default.l @@ -0,0 +1,5 @@ +(setq *My_tests_are_order_dependent NIL) + +[execute + '(assert-nil (prog (colour "yellow") (colour)) "Set colour to yellow") + '(assert-nil (colour) "Reset colour") ] diff --git a/test/test_reporter_plain.l b/test/test_reporter_plain.l new file mode 100644 index 0000000..0944572 --- /dev/null +++ b/test/test_reporter_plain.l @@ -0,0 +1,4 @@ +(setq *My_tests_are_order_dependent NIL) + +[execute + '(assert-t (fun? print-report) "Ensure (print-error) is a function") ] diff --git a/unit.l b/unit.l index c38864a..46bd55c 100644 --- a/unit.l +++ b/unit.l @@ -6,22 +6,14 @@ (when symbols (symbols 'unit 'pico)) -(local MODULE_INFO *Colours *My_tests_are_order_dependent *Passed *Failed *Counter *Results) -(local colour randomize plural? passed failed print-report report-failed print-error print-expected print-got exit-gracefully) -(local print-passed print-failed) +(local MODULE_INFO *My_tests_are_order_dependent *Results) +(local randomize passed failed queue-results colour plural? get-results) (load (pack (car (file)) "module.l")) +(load (pack (car (file)) "reporters/" (if (sys "TEST_REPORTER") @ "default") ".l")) (setq - *Colours '(("red" . 1) - ("green" . 2) - ("yellow" . 3) - ("blue" . 4) ) - *My_tests_are_order_dependent NIL - *Passed 0 - *Failed NIL - *Counter 0 *Results NIL ) @@ -30,109 +22,38 @@ # internal -[de colour (Colour) - (cond ((assoc (lowc Colour) *Colours) (call 'tput "setaf" (cdr @))) - ((= (lowc Colour) "bold") (call 'tput "bold")) - (T (call 'tput "sgr0")) ) - NIL ] - [de randomize (List) (if *My_tests_are_order_dependent List (by '((N) (rand 1 (size List))) sort List) ] -[de plural? (String) - (when (not (= (length String) 1)) "s") ] +[de passed (Message) + (queue-results T Message) ] -[de print-passed @ - (prinl (colour "green") - (char (hex "2713")) - (align 2 " ") - (colour) - (next) ) ] +[de failed (Expected Result Message) + (queue-results NIL Message Expected Result) ] -[de print-failed (Message Expected Result) - (prinl (colour "red") - (char (hex "2715")) - (align 2 " ") - Message - (colour) ] +[de queue-results (Flag . @) + (queue '*Results + (pass list + Flag + (inc (length *Results)) ) ) -[de passed (Message) - (inc '*Passed) - (inc '*Counter) - (queue '*Results (list T *Counter Message)) - T ] + Flag ] -[de failed (Expected Result Message) - (inc '*Counter) - (queue '*Failed (list *Counter Expected Result Message)) - (queue '*Results (list NIL *Counter Message Expected Result)) + +# reporter +[de colour (Colour) + (cond ((assoc (lowc Colour) *Colours) (call 'tput "setaf" (cdr @))) + ((= (lowc Colour) "bold") (call 'tput "bold")) + (T (call 'tput "sgr0")) ) NIL ] -[de print-report () - (mapcar '((N) (prin (align 3 (cadr N)) ") ") - (if (=T (car N)) - (print-passed (cddr N)) - (print-failed (cddr N)) ) ) - *Results ) - - (prinl (colour "bold") - "----^J" - (colour "green") - *Passed - " test" (plural? *Passed) - " passed, " - (colour "red") - (length *Failed) - " test" (plural? *Failed) - " failed" - (colour) ) - - (report-failed) - (exit-gracefully) ] - -(de report-failed () - (when *Failed - (prinl "^J" (colour "red") "^J Failed test" (plural? *Failed) ": ") - - (mapcar - '((N) (print-error (car N) (cdddr N)) - (print-expected (cadr N)) - (print-got (caddr N)) ) - *Failed ) - - (colour) ] - -[de print-error (Number Result) - (prinl (colour "red") - "^J" - (align 4 " - ") - Number - ") " - Result - (colour) ] - -[de print-expected (Result) - (prin (align 8 " ") - "Expected: " - (colour "green") ) - - (println Result) - (colour) ] - -[de print-got (Result) - (prin (align 8 " ") - (align 10 " Actual: ") - (colour "red") ) - - (println Result) - (colour) ] - -[de exit-gracefully () - (if (gt0 (length *Failed)) - (bye 1) - (bye) ] +[de plural? (String) + (when (not (= (length String) 1)) "s") ] + +(de get-results (Type) + (filter '((N) (= Type (car N))) *Results) ) # public @@ -169,7 +90,7 @@ (if (= Type Result) (passed Message) - (failed (pack Value " should be of type " Type) Result Message) ] + (failed (text "@1 should be of type @2" Value Type) Result Message) ] [de assert-throws (Type Error Result Message) (let Result (catch Type (eval Result) NIL)