X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Frun.lisp;h=6a10b332c197f85dfe51cbd4da29638931c3dd8b;hb=2653097170b40468c10ac8f8c4d0efdce362f803;hp=681939256b87776a2665e15baaa7693f3fadf7b2;hpb=eae50251e13d098910db2634c58e8d989ca7504c;p=fiveam.git diff --git a/src/run.lisp b/src/run.lisp index 6819392..6a10b33 100644 --- a/src/run.lisp +++ b/src/run.lisp @@ -1,6 +1,6 @@ ;; -*- lisp -*- -(in-package :it.bese.FiveAM) +(in-package :it.bese.fiveam) ;;;; * Running Tests @@ -41,7 +41,7 @@ (defun import-testing-symbols (package-designator) (import '(5am::is 5am::is-true 5am::is-false 5am::signals 5am::finishes) - package-designator)) + package-designator)) (defparameter *run-queue* '() "List of test waiting to be run.") @@ -66,7 +66,7 @@ run.")) (:unknown (setf (status test) :resolving) (if (or (not (depends-on test)) - (resolve-dependencies (depends-on test))) + (eql t (resolve-dependencies (depends-on test)))) (progn (run-test-lambda test) (status test)) @@ -76,19 +76,21 @@ run.")) :test-case test :reason "Dependencies not satisfied") result-list) - (setf (status test) :depends-not-satisfied))))) + (setf (status test) :depends-not-satisfied))))) (:resolving (restart-case (error 'circular-dependency :test-case test) (skip () - :report (lambda (s) - (format s "Skip the test ~S and all its dependencies." (name test))) - (with-run-state (result-list) - (push (make-instance 'test-skipped :reason "Circular dependencies" :test-case test) - result-list)) - (setf (status test) :circular)))) + :report (lambda (s) + (format s "Skip the test ~S and all its dependencies." (name test))) + (with-run-state (result-list) + (push (make-instance 'test-skipped :reason "Circular dependencies" :test-case test) + result-list)) + (setf (status test) :circular)))) (t (status test)))) +(defgeneric resolve-dependencies (depends-on)) + (defmethod resolve-dependencies ((depends-on symbol)) "A test which depends on a symbol is interpreted as `(AND ,DEPENDS-ON)." @@ -100,30 +102,36 @@ run.")) (if (null depends-on) t (flet ((satisfies-depends-p (test) - (funcall test (lambda (dep) - (eql t (resolve-dependencies dep))) - (cdr depends-on)))) - (ecase (car depends-on) - (and (satisfies-depends-p #'every)) - (or (satisfies-depends-p #'some)) - (not (satisfies-depends-p #'notany)))))) + (funcall test (lambda (dep) + (eql t (resolve-dependencies dep))) + (cdr depends-on)))) + (ecase (car depends-on) + (and (satisfies-depends-p #'every)) + (or (satisfies-depends-p #'some)) + (not (satisfies-depends-p #'notany)) + (:before (every #'(lambda (dep) + (let ((status (status (get-test dep)))) + (eql :unknown status))) + (cdr depends-on))))))) (defun results-status (result-list) "Given a list of test results (generated while running a test) return true if all of the results are of type TEST-PASSED, faile otherwise." (every (lambda (res) - (typep res 'test-passed)) - result-list)) + (typep res 'test-passed)) + result-list)) (defun return-result-list (test-lambda) "Run the test function TEST-LAMBDA and return a list of all test results generated, does not modify the special environment variable RESULT-LIST." - (bind-run-state ((result-list '())) + (bind-run-state ((result-list '())) (funcall test-lambda) result-list)) +(defgeneric run-test-lambda (test)) + (defmethod run-test-lambda ((test test-case)) (with-run-state (result-list) (bind-run-state ((current-test test)) @@ -149,7 +157,11 @@ run.")) (restart-case (let ((*readtable* (copy-readtable)) (*package* (runtime-package test))) - (funcall (test-lambda test))) + (if (collect-profiling-info test) + ;; Timing info doesn't get collected ATM, we need a portable library + ;; (setf (profiling-info test) (collect-timing (test-lambda test))) + (funcall (test-lambda test)) + (funcall (test-lambda test)))) (retest () :report (lambda (stream) (format stream "~@" test)) @@ -166,7 +178,7 @@ run.")) (defgeneric %run (test-spec) (:documentation "Internal method for running a test. Does not - update the status of the tests nor the special vairables !, + update the status of the tests nor the special variables !, !!, !!!")) (defmethod %run ((test test-case)) @@ -177,21 +189,27 @@ run.")) (defmethod %run ((suite test-suite)) (let ((suite-results '())) - (unwind-protect - (bind-run-state ((result-list '())) - (unwind-protect - (loop for test being the hash-values of (tests suite) - do (%run test)) - (setf suite-results result-list)) - (setf (status suite) - (every (lambda (res) - (typep res 'test-passed)) - suite-results))) - (with-run-state (result-list) - (setf result-list (nconc result-list suite-results)))))) + (flet ((run-tests () + (loop + for test being the hash-values of (tests suite) + do (%run test)))) + (unwind-protect + (bind-run-state ((result-list '())) + (unwind-protect + (if (collect-profiling-info suite) + ;; Timing info doesn't get collected ATM, we need a portable library + ;; (setf (profiling-info suite) (collect-timing #'run-tests)) + (run-tests) + (run-tests))) + (setf suite-results result-list + (status suite) (every (lambda (res) + (typep res 'test-passed)) + suite-results))) + (with-run-state (result-list) + (setf result-list (nconc result-list suite-results))))))) (defmethod %run ((test-name symbol)) - (when-bind test (get-test test-name) + (when-let (test (get-test test-name)) (%run test))) (defvar *initial-!* (lambda () (format t "Haven't run that many tests yet.~%"))) @@ -234,28 +252,28 @@ performed by the !, !! and !!! functions." *!!!* *!!*) (funcall *!*)) -(defun ! () +(defun ! () "Rerun the most recently run test and explain the results." (explain! (funcall *!*))) -(defun !! () +(defun !! () "Rerun the second most recently run test and explain the results." (explain! (funcall *!!*))) - + (defun !!! () "Rerun the third most recently run test and explain the results." (explain! (funcall *!!!*))) ;; Copyright (c) 2002-2003, Edward Marco Baringer -;; All rights reserved. -;; +;; All rights reserved. +;; ;; Redistribution and use in source and binary forms, with or without ;; modification, are permitted provided that the following conditions are ;; met: -;; +;; ;; - Redistributions of source code must retain the above copyright ;; notice, this list of conditions and the following disclaimer. -;; +;; ;; - Redistributions in binary form must reproduce the above copyright ;; notice, this list of conditions and the following disclaimer in the ;; documentation and/or other materials provided with the distribution. @@ -263,7 +281,7 @@ performed by the !, !! and !!! functions." ;; - Neither the name of Edward Marco Baringer, nor BESE, nor the names ;; of its contributors may be used to endorse or promote products ;; derived from this software without specific prior written permission. -;; +;; ;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR