X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fsuite.lisp;h=76d652647e91adbe42aea4b7840ec88891d7826d;hb=1536b825609bcec416a399b737ed9e4a56292d8f;hp=e7aab24ff3cc8bf085f62ee16a40bec3481ab0b5;hpb=b6937ebfdbd276ec7e332ceade0697184904e4e1;p=fiveam.git diff --git a/src/suite.lisp b/src/suite.lisp index e7aab24..76d6526 100644 --- a/src/suite.lisp +++ b/src/suite.lisp @@ -1,6 +1,6 @@ -;; -*- lisp -*- +;;;; -*- Mode: Lisp; indent-tabs-mode: nil -*- -(in-package :it.bese.FiveAM) +(in-package :it.bese.fiveam) ;;;; * Test Suites @@ -16,78 +16,119 @@ ;;;; ** Creating Suits -(defmacro def-suite (name &key description in) +(defvar *suites* (make-hash-table :test 'eql)) + +(defmacro def-suite (name &key description (in nil in-p) (fixture nil fixture-p)) "Define a new test-suite named NAME. -IN (a symbol), if provided, causes this suite te be nested in the -suite named by IN. NB: This macro is built on top of make-suite, -as such it, like make-suite, will overrwrite any existing suite -named NAME." - `(progn +NAME:: + The symbol naming the test. + +DESCRIPTION:: + A string describing the contents/purpose of this suite. + +IN (a symbol):: + If provided, causes this suite te be nested in the suite named by + `IN`. If `IN` is `NIL`, as opposed to not being passed at all, the + new suite will not be a part of any existing suite. + +FIXTURE:: + Whatever value is passed here will be passed, unevaluated, to all + tests defined in this suite. + +[NOTE] +This macro is built on top of `make-suite` as such it, like `make-suite`, +will overrwrite any existing suite named `NAME`." + `(eval-when (:compile-toplevel :load-toplevel :execute) (make-suite ',name - ,@(when description `(:description ,description)) - ,@(when in `(:in ',in))) + ,@(when description `(:description ,description)) + ,@(when in-p `(:in ',in)) + ,@(when fixture-p `(:fixture ',fixture))) ',name)) -(defun make-suite (name &key description in) +(defmacro def-suite* (name &rest def-suite-args) + `(progn + (def-suite ,name ,@def-suite-args) + (in-suite ,name))) + +(defun remove-from-suites (test-name) + (when (get-test test-name) + ;; if this suite alruady exists, and its :IN some other suite, remove it. + (dolist (s (list-all-suites)) + (when (gethash test-name (tests s)) + (remhash test-name (tests s)))))) + +(defun make-suite (name &key description ((:in parent-suite) *suite*) fixture) "Create a new test suite object. -Overides any existing suite named NAME." - (let ((suite (make-instance 'test-suite :name name))) +Overrides any existing suite named NAME." + (remove-from-suites name) + (let ((suite (make-instance 'test-suite :name name :fixture fixture))) (when description (setf (description suite) description)) - (loop for i in (ensure-list in) - for in-suite = (get-test i) - do (progn - (when (null in-suite) - (cerror "Create a new suite named ~A." "Unknown suite ~A." i) - (setf (get-test in-suite) (make-suite i) - in-suite (get-test in-suite))) - (setf (gethash name (tests in-suite)) suite))) + (setf (gethash name *suites*) suite) + (loop for i in (ensure-list parent-suite) + for in-suite = (get-test i) + do (progn + (when (null in-suite) + (cerror "Create a new suite named ~A." "Unknown suite ~A." i) + (setf (get-test in-suite) (make-suite i) + in-suite (get-test in-suite))) + (setf (gethash name (tests in-suite)) suite))) (setf (get-test name) suite) suite)) +(defun list-all-suites () + (loop for suite being the hash-value in *suites* + collect suite)) + ;;;; ** Managing the Current Suite -(defvar *suite* (setf (get-test 'NIL) - (make-suite 'NIL :description "Global Suite")) +(defvar *suite* (setf (get-test 'T) (make-suite 'T :description "Default global suite" :in nil)) "The current test suite object") (defmacro in-suite (suite-name) - "Set the *suite* special variable so that all tests defined + "Set the `*suite*` special variable so that all tests defined after the execution of this form are, unless specified otherwise, -in the test-suite named SUITE-NAME. - -See also: DEF-SUITE *SUITE*" - `(%in-suite ,suite-name)) - -(defmacro in-suite* (suite-name &key in) - "Just like in-suite, but silently creates missing suites." - `(%in-suite ,suite-name :in ,in :fail-on-error nil)) - -(defmacro %in-suite (suite-name &key (fail-on-error t) in) - (with-unique-names (suite) - `(progn - (if-bind ,suite (get-test ',suite-name) +in the test-suite named `SUITE-NAME`. + +See also: `DEF-SUITE` and `*SUITE*`. " + `(eval-when (:compile-toplevel :load-toplevel :execute) + (%in-suite ,suite-name))) + +(defmacro in-suite* (suite-name &rest def-suite-args) + "Same effect as `IN-SUITE`, but if `SUITE-NAME` does not exist it +will be created (as per `DEF-SUITE`)" + `(%in-suite ,suite-name + :fail-on-error nil + ,@def-suite-args)) + +(defmacro %in-suite (suite-name &rest def-suite-args &key fail-on-error &allow-other-keys) + (declare (ignore fail-on-error)) + (with-gensyms (suite) + (let ((fail-on-error (getf def-suite-args :fail-on-error t))) + (remf def-suite-args :fail-on-error) + `(progn + (if-let (,suite (get-test ',suite-name)) (setf *suite* ,suite) - (progn - (when ,fail-on-error + (progn + (when ,fail-on-error (cerror "Create a new suite named ~A." - "Unkown suite ~A." ',suite-name)) - (setf (get-test ',suite-name) (make-suite ',suite-name :in ',in) - *suite* (get-test ',suite-name)))) - ',suite-name))) + "Unknown suite ~A." ',suite-name)) + (setf (get-test ',suite-name) (make-suite ',suite-name ,@def-suite-args) + *suite* (get-test ',suite-name)))) + ',suite-name)))) ;; 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. @@ -95,7 +136,7 @@ See also: DEF-SUITE *SUITE*" ;; - 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