Skip to content
Browse files

Improved error-checking and usability in DOCTEST.

  • Loading branch information...
1 parent e9b723c commit a1f95be6c2c4c8abae282596ec0e3de64c5b86b5 @jmbr jmbr committed Sep 5, 2010
Showing with 31 additions and 24 deletions.
  1. +9 −2 README.org
  2. +21 −20 doctest.lisp
  3. +1 −2 test-suite.lisp
View
11 README.org
@@ -1,7 +1,7 @@
#+TITLE: (INCF CL)
#+AUTHOR: Juan M. Bello Rivas
#+EMAIL: jmbr@superadditive.com
-#+DATE: <2010-08-30 Mon>
+#+DATE: <2010-09-05 Sun>
* Overview
@@ -124,12 +124,19 @@ For example, consider the package =TEST=:
(factorial (1- n) (* n acc))))
#+END_SRC
You can use =DOCTEST= to make sure the examples given in =FACTORIAL='s
-documentation string work as expected:
+documentation string work as expected by writing
#+BEGIN_SRC lisp
CL-USER> (doctest :test)
.....
T
#+END_SRC
+Or, equivalently,
+#+BEGIN_SRC lisp
+CL-USER> (doctest 'test::factorial)
+.....
+T
+#+END_SRC
+
*** Prelude
View
41 doctest.lisp
@@ -62,12 +62,14 @@ signals DOCTEST-FAILURE otherwise."
(subseq expected-values 0 eof-pos)
expected-values)))))))
-(defun test-function (package-name function stream)
- "Returns T if every test written in FUNCTION's docstring passes, NIL
+(defun test-function (package function stream)
+ "Returns T if every test in FUNCTION's docstring passes, NIL
otherwise."
(let* ((passed-p t)
- (documentation (documentation function 'function))
+ (*package* package)
+ (package-name (package-name package))
(re (concatenate 'string "[ \t]*" package-name "> "))
+ (documentation (documentation function 'function))
(matches (cl-ppcre:all-matches re documentation)))
(loop for start in (rest matches) by #'cddr do
(handler-case
@@ -82,20 +84,19 @@ otherwise."
(setf passed-p nil)))
finally (return passed-p))))
-(defun doctest (package
- &key (function nil function-p) (stream *standard-output*))
- "Tests docstrings present in functions defined in PACKAGE and
-outputs its results to STREAM. It returns T if the tests succeed, NIL
-on error. If FUNCTION is specified, DOCTEST will check that function
-only. By default, DOCTEST will test each function exported by
-PACKAGE."
- (let ((passed-p t)
- (package-name (etypecase package
- (string (string-upcase package))
- (symbol (symbol-name package))))
- (*package* (find-package package)))
- (if function-p
- (test-function package-name function stream)
- (do-external-symbols (symbol package passed-p)
- (unless (test-function package-name symbol stream)
- (setf passed-p nil))))))
+(defun doctest (symbol &key (stream *standard-output*))
+ "If SYMBOL corresponds to a function, then its documentation string
+is tested and the results are printed to STREAM. If SYMBOL refers to
+a package, then all the functions corresponding to the external
+symbols in the package are tested.
+DOCTEST returns T if the tests succeed, NIL otherwise."
+ (flet ((get-package-and-function (symbol)
+ (let ((package (find-package symbol)))
+ (or package
+ (values (symbol-package symbol) symbol)))))
+ (multiple-value-bind (package function) (get-package-and-function symbol)
+ (if function
+ (when (symbol-function function)
+ (test-function package function stream))
+ (every (lambda (x) (test-function package x stream))
+ (list-external-symbols package))))))
View
3 test-suite.lisp
@@ -138,7 +138,6 @@
(setf ys (insert x ys)))))))
(deftest test-lc ()
- (is (eq nil (lc (constantly nil))))
(is (equal (list 1 2 3) (lc x (<- x (range 1 3)))))
(is (equal (acons 0 0 (acons 0 1 (acons 1 0 (acons 1 1 nil))))
(lc (cons i j) (<- i '(0 1)) (<- j '(0 1))))))
@@ -194,7 +193,7 @@
INCF-CL-TESTS> (signals-p division-by-zero (error 'division-by-zero))
T"
- (is (eq t (doctest :incf-cl-test :function 'test-doctest)))
+ (is (eq t (doctest 'incf-cl-test::test-doctest)))
;; Here we run doctests for the whole package.
(is (eq t (doctest :incf-cl))))

0 comments on commit a1f95be

Please sign in to comment.
Something went wrong with that request. Please try again.