2010-m1s1-compilation/test-unitaire.lisp

82 lines
3.1 KiB
Common Lisp

;; TODO : exploser tout ça en plein de petites fonctions, c'est trop gros...
;; Mutation cons.
(defvar all-tests nil "Liste de tous les tests")
;(defmacro eval-in-env (expr env)
; `(eval-in-env-2 ',expr ,env))
;
;(defun eval-in-env-2 (qexpr env)
; '(eval `(let ,env ,qexpr)))
(defmacro deftest (module test expected)
`(progn
(if (not (assoc ',module all-tests))
(setf all-tests (cons (list ',module nil nil) all-tests)))
(push (lambda ()
(let* ((vars (second (assoc ',module all-tests)))
(_test ',test)
(_expected ',expected)
;; Les "eval" ci-dessous exécutent :
;; (let ((var1 val1) (var2 val2) ...) ;; On définit les
;; ;; variables de deftestvar.
;; var1 var2 ... ;; On "utilise" les variables pour
;; ;; éviter le unused variable warning
;; corps-du-test) ;; On évalue le corps du test dans
;; ;; un environement où les deftestvar
;; ;; sont accessibles.
(res (eval `(let ,vars ,@(mapcar #'car vars) ,_test)))
(exp (eval `(let ,vars ,@(mapcar #'car vars) ,_expected))))
(if (equal res exp)
(progn
(format t "~& [SUCCESS] ~w~&" ',test)
t)
(progn
(format t "~& [FAILURE] Test : ~w~&" ',test)
(format t "~& got : ~w~&" (list res (random 10)))
(format t "~& expected : ~w~&" exp)
nil))))
(third (assoc ',module all-tests)))))
(defmacro deftestvar (module name value)
`(progn
(if (not (assoc ',module all-tests))
(setf all-tests (cons (list ',module nil nil) all-tests)))
;; TODO : utiliser copy-seq ou copy-tree ???
(push (list ',name (list 'copy-tree ',value))
(second (assoc ',module all-tests)))))
(defmacro run-tests (&rest modules)
(if (or (not modules)
(eq (car modules) t))
`(real-run-tests all-tests)
`(real-run-tests (remove-if-not (lambda (x)
(member (car x) ',modules))
all-tests))))
;; OMFG that's not lisp, that's english o_O
(defun real-run-tests (modules)
(loop
for (module vars tests) in (reverse modules)
for nb-fail = (loop
initially (format t "~&Module ~w :~&" module)
for test
in (reverse tests)
count (not (funcall test)))
when (> nb-fail 0)
do (format t "Module ~w failed ~w tests. Stopping.~&" module nb-fail)
and return nil
finally (return t)))
(defun erase-tests ()
(setf all-tests nil))
(deftest moda nil nil)
(deftest moda (eq 42 42) t)
(deftest modb (eq 'a 'a) t)
(deftest modb (eq 'a 'b) nil)
(deftest modb (eq 'a 'c) t)
(deftest modb 1 1)
(deftest modc (+ 1 2) (+ 2 1))
(deftestvar modc x 1)
(deftest modc (+ x 2) (+ 2 1))