1 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; While most of SBCL is derived from the CMU CL system, the test
5 ;;;; files (like this one) were written from scratch after the fork
8 ;;;; This software is in the public domain and is provided with
9 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
10 ;;;; more information.
12 (load "assertoid.lisp")
13 (use-package '#:assertoid
)
17 (defun check-deprecated-thing (namespace name state make-body
20 (expected-warning-count '(eql 1))
22 (labels ((search-string (string fragments
)
24 (dolist (fragment fragments
)
25 (let ((match (search fragment string
:start2
(or start
0))))
27 (setf start
(+ match
(length fragment
)))))))
28 (search-string/documentation
(string)
30 string
`(,(string-downcase namespace
) ,(string name
)
31 "deprecated" "as" "of" "some-lib" "version" "1.2.3"
32 "Use" ,@replacements
"instead")))
33 (search-string/describe
(string)
35 string
`(,(string name
) ,(string state
)
36 "deprecation" "since" "some-lib" "version" "1.2.3"))))
37 ;; Check the signaled warning condition.
40 (function (handler-bind
41 ((deprecation-condition (lambda (c)
45 (warning 'muffle-warning
))
46 (compile nil
`(lambda ()
47 ,@(funcall make-body name
))))))
48 (assert (typep count expected-warning-count
))
49 (assert (typep condition
(ecase state
50 (:early
'early-deprecation-warning
)
51 (:late
'late-deprecation-warning
)
52 (:final
'final-deprecation-warning
))))
53 (search-string/documentation
(princ-to-string condition
))
57 (assert (eq :deprecated
(funcall function
))))
59 (assert-error (funcall function
) deprecation-error
)))))
60 ;; Check DESCRIBE output.
62 (search-string/describe
(with-output-to-string (stream)
63 (describe name stream
))))
64 ;; Check DOCUMENTATION.
65 (search-string/documentation
(documentation name namespace
))))
67 ;;;; DEPRECATED declaration syntax
69 (with-test (:name
(deprecated :declaration
:syntax
))
70 ;; Some syntax errors.
71 (mapc (lambda (declaration)
72 (assert-error (proclaim declaration
)))
76 (deprecated :early
("1"))
77 (deprecated :early
("a" "b" "c"))
78 (deprecated :early
1 (function))
79 (deprecated :early
1 (unsupported-namespace name
))))
82 (mapc (lambda (declaration)
83 (assert-no-signal (proclaim declaration
)))
84 '((deprecated :early
"1")
85 (deprecated :early
("my-software" "1"))
86 (deprecated :early
"1" (variable deprecated.declaration.variable
))
87 (deprecated :early
"1" (function deprecated.declaration.function
))
88 (deprecated :early
"1" (function (setf deprecated.declaration.function
)))
89 (deprecated :early
"1" (type deprecated.declaration.type
))
90 (deprecated :early
"1" (variable deprecated.declaration.thing1
)
91 (variable deprecated.declaration.thing2
))
92 (deprecated :early
"1" (variable deprecated.declaration.replacement
93 :replacement deprecated.declaration.replacement
))
94 (deprecated :early
"1" (variable deprecated.declaration.replacement
95 :replacement
(deprecated.declaration.replacement1
96 deprecated.declaration.replacement2
))))))
98 ;;;; Deprecated variables
101 ((definition.undefined
(variable-name)
102 (declare (ignore variable-name
))
104 (definition.declaimed-special
(variable-name)
105 `(declaim (special ,variable-name
)))
106 (definition.defvar
(variable-name)
107 `(defvar ,variable-name
:deprecated
))
108 (definition.defglobal
(variable-name)
109 `(defglobal ,variable-name
:deprecated
))
110 (definition.defconstant
(variable-name)
111 `(defconstant ,variable-name
:deprecated
))
112 (definition.define-symbol-macro
(variable-name)
113 `(define-symbol-macro ,variable-name
:deprecated
))
114 (define-variable-tests (tag definition-name
&rest args
)
115 (flet ((make-test-case (tag state
120 (let ((variable-name (sb-int::symbolicate
121 '#:variable. tag
'#:. state
))
122 (replacement 'replacement
))
123 `(,@(unless (eq state
:final
)
124 `((,definition-name
,variable-name
)))
126 ,state
("some-lib" "1.2.3")
127 (variable ,variable-name
128 :replacement
,replacement
)))
130 (with-test (:name
(deprecated variable
,tag
,state
))
131 (check-deprecated-thing
132 'variable
',variable-name
,state
133 (lambda (name) `(,name
))
134 :replacements
'(,(string replacement
))
136 :check-describe
,check-describe
)
138 `((check-deprecated-thing
139 'variable
',variable-name
,state
140 (lambda (name) `((symbol-value ',name
)))
141 :replacements
'(,(string replacement
))
143 :check-describe
,check-describe
)
144 (check-deprecated-thing
145 'variable
',variable-name
,state
146 (lambda (name) `((symbol-global-value ',name
)))
147 :replacements
'(,(string replacement
))
149 :check-describe
,check-describe
))))))))
151 ,@(apply #'make-test-case tag
:early args
)
152 ,@(apply #'make-test-case tag
:late args
)
153 ,@(apply #'make-test-case tag
:final
:check-describe t args
)))))
155 (define-variable-tests :undefined definition.undefined
156 :call nil
:check-describe nil
)
157 (define-variable-tests :declaimed-special definition.declaimed-special
159 (define-variable-tests defvar definition.defvar
)
160 (define-variable-tests defglobal definition.defglobal
)
161 (define-variable-tests defconstant definition.defconstant
)
162 (define-variable-tests define-symbol-macro definition.define-symbol-macro
165 ;;;; Deprecated functions
168 ((definition.undefined
(function-name)
169 (declare (ignore function-name
))
171 (definition.declaimed-ftype
(function-name)
172 `(declaim (ftype (function () (values keyword
&optional
))
174 (definition.defun
(function-name)
175 `(defun ,function-name
() :deprecated
))
176 (definition.defmacro
(function-name)
177 `(defmacro ,function-name
() :deprecated
))
178 (define-function-tests (tag definition-name
&rest args
)
179 (flet ((make-test-case (tag state
183 (let ((function-name (sb-int::symbolicate
184 '#:function. tag
'#:. state
))
185 (replacement 'replacement
))
186 `(,@(unless (eq state
:final
)
187 `((,definition-name
,function-name
)))
189 ,state
("some-lib" "1.2.3")
190 (function ,function-name
191 :replacement
,replacement
)))
193 (with-test (:name
(deprecated function
,tag
,state
))
194 (check-deprecated-thing
195 'function
',function-name
,state
196 (lambda (name) `((,name
)))
197 :replacements
'(,(string replacement
))
199 :check-describe
,check-describe
))))))
201 ,@(apply #'make-test-case tag
:early args
)
202 ,@(apply #'make-test-case tag
:late args
)
203 ,@(apply #'make-test-case tag
:final
:check-describe t args
)))))
205 (define-function-tests :undefined definition.undefined
206 :call nil
:check-describe nil
)
207 (define-function-tests :declaimed-ftype definition.declaimed-ftype
208 :call nil
:check-describe nil
)
209 (define-function-tests defun
definition.defun
)
210 (define-function-tests defmacro definition.defmacro
))
212 ;;;; Deprecated types
215 ((definition.undefined
(type-name)
216 (declare (ignore type-name
))
218 (definition.deftype.empty-body
(type-name)
219 `(deftype ,type-name
()))
220 (definition.deftype.t-body
(type-name)
221 `(deftype ,type-name
() t
))
222 (definition.defclass
(type-name)
223 `(defclass ,type-name
() ()))
224 (definition.defstruct
(type-name)
225 `(defstruct ,type-name
))
226 (definition.define-condition
(type-name)
227 `(define-condition ,type-name
() ()))
228 (define-type-tests (tag definition-name
&rest args
)
229 (flet ((make-test-case (tag state
&key check-describe
)
230 (let ((type-name (apply #'sb-int
::symbolicate
232 (sb-int:ensure-list tag
)
233 (list '#:. state
(gensym)))))
234 (replacement 'replacement
))
235 `(,@(unless (eq state
:final
)
236 `((,definition-name
,type-name
)))
238 ,state
("some-lib" "1.2.3")
240 :replacement
,replacement
)))
242 (test-util:with-test
(:name
(deprecated type
243 ,@(sb-int:ensure-list tag
)
245 (check-deprecated-thing
246 'type
',type-name
,state
249 (declare (type (or null
,name
) x
)))
251 (defmethod ,(gensym) ((x ,name
)))
252 (defclass ,(gensym) (,name
) ())))
253 :replacements
'(,(string replacement
))
255 :expected-warning-count
'(integer 4 6)
256 :check-describe
,check-describe
))))))
258 ,@(apply #'make-test-case tag
:early args
)
259 ,@(apply #'make-test-case tag
:late args
)
260 ,@(apply #'make-test-case tag
:final
:check-describe t args
)))))
262 (define-type-tests :undefined definition.undefined
264 (define-type-tests (deftype :empty-body
) definition.deftype.empty-body
)
265 (define-type-tests (deftype :t-body
) definition.deftype.t-body
)
266 (define-type-tests defclass definition.defclass
)
267 (define-type-tests defstruct definition.defstruct
)
268 (define-type-tests define-condition definition.define-condition
))
270 ;;;; Loader deprecation warnings
272 (defun please-dont-use-this (x)
274 (declaim (deprecated :early
"1.2.10"
275 (function please-dont-use-this
276 :replacement moar-better-function
)))
278 (defun really-dont-do-it (x)
280 (declaim (deprecated :late
"1.2.10"
281 (function really-dont-do-it
282 :replacement use-other-thing-instead
)))
284 (defun you-cant-use-this (x)
286 (declaim (deprecated :final
"1.2.10"
287 (function you-cant-use-this
288 :replacement replacement-fn
)))
290 (with-test (:name
:introspect-deprecation-stage
)
291 (assert (eq (sb-int:deprecated-thing-p
'function
'please-dont-use-this
)
293 (assert (eq (sb-int:deprecated-thing-p
'function
'really-dont-do-it
)
295 (assert (eq (sb-int:deprecated-thing-p
'function
'you-cant-use-this
)
298 (with-test (:name
(:late-deprecated-fun-doc
:bug-1439151
)
299 :skipped-on
'(not :sb-doc
))
300 (assert (string= (documentation 'you-cant-use-this
'function
)
301 (documentation #'you-cant-use-this
'function
)))
302 (assert (string= (documentation 'function.defun.late
'function
)
303 (documentation #'function.defun.late
'function
)))
304 (assert (string/= (documentation 'you-cant-use-this
'function
)
305 (documentation 'function.defun.late
'function
))))
307 (with-test (:name
:load-time-deprecation-warning
)
308 (let ((source "load-test.tmp") fasl
)
309 (with-open-file (f source
:direction
:output
310 :if-does-not-exist
:create
:if-exists
:supersede
)
311 (write-string "(defun a () (quit))" f
)
312 ;; a full warning even though the PLEASE-DONT- function is only :early
313 (write-string "(defun b () (please-dont-use-this 1) (really-dont-do-it 2))" f
)
314 (write-string "(defun c () (you-cant-use-this 3))" f
))
315 ;; We expect four deprecation warnings from compiling the source
316 ;; (four uses of deprecated things) and three from loading it
317 ;; (loading three functions that contain uses of deprecated
322 (compile-file source
:verbose nil
:print nil
)
323 (or early-deprecation-warning
324 late-deprecation-warning
325 final-deprecation-warning
)
327 (assert-signal (load fasl
) warning
3))
329 (delete-file source
))))