/
prove.lisp
75 lines (59 loc) · 2.81 KB
/
prove.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
(uiop:define-package #:hamcrest/prove
(:use #:cl
#:prove
#:hamcrest/matchers)
(:reexport #:hamcrest/matchers)
(:import-from #:hamcrest/matchers
#:assertion-error
#:assertion-error-reason-with-context)
(:import-from #:alexandria
#:with-gensyms)
(:import-from #:prove.report)
(:import-from #:prove.reporter)
(:import-from #:prove.reporter.list)
(:import-from #:prove.suite)
(:export #:assert-that))
(in-package #:hamcrest/prove)
(defclass assertion-report (prove.report:failed-test-report)
((prove.report:got :initform nil)
(prove.report:expected :initform nil)
(expected-line :initarg :expected-line
:initform (error ":expected-line is required")
:reader expected-line)))
(defclass passed-assertion-report (prove.report:normal-test-report)
((prove.report:got :initform nil)
(prove.report:expected :initform nil)
(expected-line :initarg :expected-line
:initform (error ":expected-line is required")
:reader expected-line)))
(defmethod prove.reporter.list:report-expected-line ((report assertion-report))
(expected-line report))
(defmethod prove.reporter.list:report-expected-line ((report passed-assertion-report))
(expected-line report))
(defmacro assert-that (value &rest matchers)
"Main macro to test values agains matchers."
(let ((matcher (if (> (length matchers)
1)
;; if there is more than one matcher,
;; then we need to combine them implicitly
`(has-all ,@matchers)
;; otherwise, just use single matcher
(first matchers))))
(with-gensyms (matcher-var matcher-description)
`(symbol-macrolet ((_ (any)))
(let* ((,matcher-var ,matcher)
(,matcher-description (matcher-description ,matcher-var)))
(let* ((suite (prove.suite:current-suite))
(report (handler-case
(progn (funcall ,matcher-var ,value)
(make-instance 'passed-assertion-report
:expected-line ,matcher-description))
(assertion-error (c)
(incf (prove.suite:failed suite))
(make-instance 'assertion-report
:expected-line (assertion-error-reason-with-context c))))))
(prove.suite:add-report report suite)
(incf (prove.suite:test-count suite))
(prove.reporter:format-report *test-result-output* nil report
:count (prove.suite:test-count suite))
(values t report)))))))