1 ;;;; tests for the DESCRIBE function
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; While most of SBCL is derived from the CMU CL system, the test
7 ;;;; files (like this one) were written from scratch after the fork
10 ;;;; This software is in the public domain and is provided with
11 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
12 ;;;; more information.
14 (defmacro assert-non-empty-output
(&body forms
)
15 `(assert (plusp (length (with-output-to-string (*standard-output
*)
18 (defstruct to-be-described a b
)
20 (defclass forward-describe-class
(forward-describe-ref) (a))
22 (defclass non-standard-generic-function
(generic-function) ()
23 (:metaclass sb-mop
:funcallable-standard-class
))
24 (defmethod sb-mop:generic-function-name
((generic-function non-standard-generic-function
))
27 (with-test (:name
(describe :empty-gf
))
29 (assert-non-empty-output
30 (describe (make-instance 'non-standard-generic-function
)))
33 (assert-non-empty-output
34 (describe (make-instance 'standard-generic-function
)))
37 ;;; DESCRIBE should run without signalling an error.
38 (with-test (:name
(describe :no-error
))
39 (assert-non-empty-output (describe (make-to-be-described)))
40 (assert-non-empty-output (describe 12))
41 (assert-non-empty-output (describe "a string"))
42 (assert-non-empty-output (describe 'symbolism
))
43 (assert-non-empty-output (describe (find-package :cl
)))
44 (assert-non-empty-output (describe '(a list
)))
45 (assert-non-empty-output (describe #(a vector
))))
47 (let ((sb-ext:*evaluator-mode
* :compile
))
48 (eval `(let (x) (defun closure-to-describe () (incf x
)))))
50 (with-test (:name
(describe :no-error
:closure
:bug-824974
))
51 (assert-non-empty-output (describe 'closure-to-describe
)))
53 ;;; DESCRIBE shouldn't fail on rank-0 arrays (bug reported and fixed
54 ;;; by Lutz Euler sbcl-devel 2002-12-03)
55 (with-test (:name
(describe :no-error array
:rank
0))
56 (assert-non-empty-output (describe #0a0
))
57 (assert-non-empty-output (describe #(1 2 3)))
58 (assert-non-empty-output (describe #2a
((1 2) (3 4)))))
60 (defclass cannot-print-this
() ())
61 (defmethod print-object ((object cannot-print-this
) stream
)
64 (with-test (:name
(describe :no-error print-object
))
65 ;; Errors during printing objects used to be suppressed in a way
66 ;; that required outer condition handlers to behave in a specific
68 (handler-bind ((error (lambda (condition)
69 (error "~@<~S signaled ~A.~@:>"
70 'describe condition
))))
71 (assert-non-empty-output (describe (make-instance 'cannot-print-this
)))))
73 ;;; The DESCRIBE-OBJECT methods for built-in CL stuff should do
74 ;;; FRESH-LINE and TERPRI neatly.
75 (with-test (:name
(describe fresh-line terpri
))
76 (dolist (i (list (make-to-be-described :a
14) 12 "a string"
77 #0a0
#(1 2 3) #2a
((1 2) (3 4)) 'sym
:keyword
78 (find-package :keyword
) (list 1 2 3)
79 nil
(cons 1 2) (make-hash-table)
80 (let ((h (make-hash-table)))
81 (setf (gethash 10 h
) 100
84 (make-condition 'simple-error
)
85 (make-condition 'simple-error
:format-control
"fc")
86 #'car
#'make-to-be-described
(lambda (x) (+ x
11))
87 (constantly 'foo
) #'(setf to-be-described-a
)
88 #'describe-object
(find-class 'to-be-described
)
89 (find-class 'forward-describe-class
)
90 (find-class 'forward-describe-ref
) (find-class 'cons
)))
91 (let ((s (with-output-to-string (s)
94 (macrolet ((check (form)
96 (error "misbehavior in DESCRIBE of ~S:~% ~S" i
',form
))))
97 (check (char= #\x
(char s
0)))
98 ;; one leading #\NEWLINE from FRESH-LINE or the like, no more
99 (check (char= #\newline
(char s
1)))
100 (check (char/= #\newline
(char s
2)))
101 ;; one trailing #\NEWLINE from TERPRI or the like, no more
102 (let ((n (length s
)))
103 (check (char= #\newline
(char s
(- n
1))))
104 (check (char/= #\newline
(char s
(- n
2)))))))))
106 (with-test (:name
(describe :argument-precedence-order
))
107 ;; Argument precedence order information is only interesting for two
108 ;; or more required parameters.
109 (assert (not (search "Argument precedence order"
110 (with-output-to-string (stream)
111 (describe #'class-name stream
)))))
112 (assert (search "Argument precedence order"
113 (with-output-to-string (stream)
114 (describe #'add-method stream
)))))
116 (defun lottafun (x y z
&rest r
&key
((:wat w
)) glup
)
117 (declare (dynamic-extent glup z r w x
))
118 (declare (ignore x y z r w glup
))
121 (with-test (:name
(describe :fun-dx-args
))
122 ;; though R is DX, it is not useful information to show,
123 ;; because the caller doesn't decide how to allocate the &rest list.
124 (assert (search "Dynamic-extent arguments: positional=(0 2), keyword=(:WAT :GLUP)"
125 (with-output-to-string (stream)
126 (describe #'lottafun stream
)))))
128 (with-test (:name
(describe sb-kernel
:funcallable-instance
))
129 (assert (search "Slots with :INSTANCE allocation"
130 (with-output-to-string (stream)
131 (describe #'class-name stream
)))))
133 (with-test (:name
(describe class
))
134 (assert (search "Class precedence-list:"
135 (with-output-to-string (stream)
136 (describe (find-class 'standard-class
) stream
)))))
138 (proclaim '(declaration my-declaration
))
140 (with-test (:name
(describe declaration
))
141 (flet ((test (name expected-description
)
142 (assert (search expected-description
143 (with-output-to-string (stream)
144 (describe name stream
))))))
145 (test 'inline
"INLINE names a standard declaration.")
146 (test 'sb-ext
:deprecated
"DEPRECATED names an SBCL-specific declaration.")
147 (test 'my-declaration
"MY-DECLARATION names a user-defined declaration.")))
149 (with-test (:name
(describe array
:displaced-to
))
150 (assert (search "Displaced: no"
151 (with-output-to-string (stream)
152 (describe (make-array 1 :adjustable t
) stream
))))
153 (assert (search "Displaced-to: #<"
154 (with-output-to-string (stream)
155 (describe (make-array 1 :displaced-to
(make-array 1))
158 (with-test (:name
:bad-second-arg
)
162 (make-array 256 :element-type
'character
:fill-pointer
0)))