alien.impure: compile a test.
[sbcl.git] / tests / describe.impure.lisp
blob80e46f4b497655546e7a73185c9e3eed1f7e56df
1 ;;;; tests for the DESCRIBE function
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
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
8 ;;;; from CMU CL.
9 ;;;;
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 (load "assertoid.lisp")
15 (load "test-util.lisp")
16 (use-package "ASSERTOID")
17 (use-package "TEST-UTIL")
19 (defmacro assert-non-empty-output (&body forms)
20 `(assert (plusp (length (with-output-to-string (*standard-output*)
21 ,@forms)))))
23 (defstruct to-be-described a b)
25 (defclass forward-describe-class (forward-describe-ref) (a))
27 (defclass non-standard-generic-function (generic-function) ()
28 (:metaclass sb-mop:funcallable-standard-class))
29 (defmethod sb-mop:generic-function-name ((generic-function non-standard-generic-function))
30 'name)
32 (with-test (:name (describe :empty-gf))
33 (assert-no-signal
34 (assert-non-empty-output
35 (describe (make-instance 'non-standard-generic-function)))
36 warning)
37 (assert-signal
38 (assert-non-empty-output
39 (describe (make-instance 'standard-generic-function)))
40 warning))
42 ;;; DESCRIBE should run without signalling an error.
43 (with-test (:name (describe :no-error))
44 (assert-non-empty-output (describe (make-to-be-described)))
45 (assert-non-empty-output (describe 12))
46 (assert-non-empty-output (describe "a string"))
47 (assert-non-empty-output (describe 'symbolism))
48 (assert-non-empty-output (describe (find-package :cl)))
49 (assert-non-empty-output (describe '(a list)))
50 (assert-non-empty-output (describe #(a vector))))
52 (let ((sb-ext:*evaluator-mode* :compile))
53 (eval `(let (x) (defun closure-to-describe () (incf x)))))
55 (with-test (:name (describe :no-error :closure :bug-824974))
56 (assert-non-empty-output (describe 'closure-to-describe)))
58 ;;; DESCRIBE shouldn't fail on rank-0 arrays (bug reported and fixed
59 ;;; by Lutz Euler sbcl-devel 2002-12-03)
60 (with-test (:name (describe :no-error array :rank 0))
61 (assert-non-empty-output (describe #0a0))
62 (assert-non-empty-output (describe #(1 2 3)))
63 (assert-non-empty-output (describe #2a((1 2) (3 4)))))
65 (defclass cannot-print-this () ())
66 (defmethod print-object ((object cannot-print-this) stream)
67 (error "No go!"))
69 (with-test (:name (describe :no-error print-object))
70 ;; Errors during printing objects used to be suppressed in a way
71 ;; that required outer condition handlers to behave in a specific
72 ;; way.
73 (handler-bind ((error (lambda (condition)
74 (error "~@<~S signaled ~A.~@:>"
75 'describe condition))))
76 (assert-non-empty-output (describe (make-instance 'cannot-print-this)))))
78 ;;; The DESCRIBE-OBJECT methods for built-in CL stuff should do
79 ;;; FRESH-LINE and TERPRI neatly.
80 (with-test (:name (describe fresh-line terpri))
81 (dolist (i (list (make-to-be-described :a 14) 12 "a string"
82 #0a0 #(1 2 3) #2a((1 2) (3 4)) 'sym :keyword
83 (find-package :keyword) (list 1 2 3)
84 nil (cons 1 2) (make-hash-table)
85 (let ((h (make-hash-table)))
86 (setf (gethash 10 h) 100
87 (gethash 11 h) 121)
89 (make-condition 'simple-error)
90 (make-condition 'simple-error :format-control "fc")
91 #'car #'make-to-be-described (lambda (x) (+ x 11))
92 (constantly 'foo) #'(setf to-be-described-a)
93 #'describe-object (find-class 'to-be-described)
94 (find-class 'forward-describe-class)
95 (find-class 'forward-describe-ref) (find-class 'cons)))
96 (let ((s (with-output-to-string (s)
97 (write-char #\x s)
98 (describe i s))))
99 (macrolet ((check (form)
100 `(or ,form
101 (error "misbehavior in DESCRIBE of ~S:~% ~S" i ',form))))
102 (check (char= #\x (char s 0)))
103 ;; one leading #\NEWLINE from FRESH-LINE or the like, no more
104 (check (char= #\newline (char s 1)))
105 (check (char/= #\newline (char s 2)))
106 ;; one trailing #\NEWLINE from TERPRI or the like, no more
107 (let ((n (length s)))
108 (check (char= #\newline (char s (- n 1))))
109 (check (char/= #\newline (char s (- n 2)))))))))
111 (with-test (:name (describe :argument-precedence-order))
112 ;; Argument precedence order information is only interesting for two
113 ;; or more required parameters.
114 (assert (not (search "Argument precedence order"
115 (with-output-to-string (stream)
116 (describe #'class-name stream)))))
117 (assert (search "Argument precedence order"
118 (with-output-to-string (stream)
119 (describe #'add-method stream)))))
121 (with-test (:name (describe sb-kernel:funcallable-instance))
122 (assert (search "Slots with :INSTANCE allocation"
123 (with-output-to-string (stream)
124 (describe #'class-name stream)))))
126 (with-test (:name (describe class))
127 (assert (search "Class precedence-list:"
128 (with-output-to-string (stream)
129 (describe (find-class 'standard-class) stream)))))
131 (proclaim '(declaration my-declaration))
133 (with-test (:name (describe declaration))
134 (flet ((test (name expected-description)
135 (assert (search expected-description
136 (with-output-to-string (stream)
137 (describe name stream))))))
138 (test 'inline "INLINE names a standard declaration.")
139 (test 'sb-ext:deprecated "DEPRECATED names an SBCL-specific declaration.")
140 (test 'my-declaration "MY-DECLARATION names a user-defined declaration.")))
142 (with-test (:name (describe array :displaced-to))
143 (assert (search "Displaced: no"
144 (with-output-to-string (stream)
145 (describe (make-array 1 :adjustable t) stream))))
146 (assert (search "Displaced-to: #<"
147 (with-output-to-string (stream)
148 (describe (make-array 1 :displaced-to (make-array 1))
149 stream)))))