1 ;;;; miscellaneous tests of package-related stuff
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.
15 (defvar *foo
* (find-package (coerce "FOO" 'base-string
)))
16 (rename-package "FOO" (make-array 0 :element-type nil
))
17 (assert (eq *foo
* (find-package "")))
18 (assert (delete-package ""))
22 (package-error (c) (princ c
))
23 (:no-error
(&rest args
) (error "(EXPORT :FOO) returned ~S" args
)))
26 (assert (shadow #\a :foo
))
28 (defpackage :PACKAGE-DESIGNATOR-1
(:use
#.
(find-package :cl
)))
30 (defpackage :PACKAGE-DESIGNATOR-2
31 (:import-from
#.
(find-package :cl
) "+"))
33 (defpackage "EXAMPLE-INDIRECT"
34 (:import-from
"CL" "+"))
36 (defpackage "EXAMPLE-PACKAGE"
38 (:shadowing-import-from
"CL" "CAAR")
40 (:import-from
"CL" "CDR")
41 (:import-from
"EXAMPLE-INDIRECT" "+")
42 (:export
"CAR" "CDR" "EXAMPLE"))
44 (flet ((check-symbol (name expected-status expected-home-name
)
45 (multiple-value-bind (symbol status
)
46 (find-symbol name
"EXAMPLE-PACKAGE")
47 (let ((home (symbol-package symbol
))
48 (expected-home (find-package expected-home-name
)))
49 (assert (eql home expected-home
))
50 (assert (eql status expected-status
))))))
51 (check-symbol "CAR" :external
"EXAMPLE-PACKAGE")
52 (check-symbol "CDR" :external
"CL")
53 (check-symbol "EXAMPLE" :external
"EXAMPLE-PACKAGE")
54 (check-symbol "CAAR" :internal
"CL")
55 (check-symbol "+" :internal
"CL")
56 (check-symbol "CDDR" nil
"CL"))
58 (defpackage "TEST-ORIGINAL" (:nicknames
"A-NICKNAME"))
60 (assert (raises-error?
(defpackage "A-NICKNAME")))
62 (assert (eql (find-package "A-NICKNAME")
63 (find-package "TEST-ORIGINAL")))
66 (defun sym (package name
)
67 (let ((package (or (find-package package
) package
)))
68 (multiple-value-bind (symbol status
)
69 (find-symbol name package
)
71 (package name symbol status
)
72 "No symbol with name ~A in ~S." name package symbol status
)
73 (values symbol status
))))
75 (defmacro with-name-conflict-resolution
((symbol &key restarted
)
77 "Resolves potential name conflict condition arising from FORM.
79 The conflict is resolved in favour of SYMBOL, a form which must
82 If RESTARTED is a symbol, it is bound for the BODY forms and set to T
83 if a restart was invoked."
84 (check-type restarted symbol
"a binding name")
85 (let ((%symbol
(copy-symbol 'symbol
)))
86 `(let (,@(when restarted
`((,restarted
)))
89 ((sb-ext:name-conflict
91 ,@(when restarted
`((setf ,restarted t
)))
92 (assert (member ,%symbol
(sb-ext:name-conflict-symbols condition
)))
93 (invoke-restart 'sb-ext
:resolve-conflict
,%symbol
))))
97 (defmacro with-packages
(specs &body forms
)
98 (let ((names (mapcar #'car specs
)))
101 (delete-packages ',names
)
102 ,@(mapcar (lambda (spec)
103 `(defpackage ,@spec
))
106 (delete-packages ',names
))))
108 (defun delete-packages (names)
110 (ignore-errors (delete-package p
))))
115 (with-test (:name use-package
.1)
116 (with-packages (("FOO" (:export
"SYM"))
117 ("BAR" (:export
"SYM"))
119 (with-name-conflict-resolution ((sym "BAR" "SYM") :restarted restartedp
)
120 (use-package '("FOO" "BAR") "BAZ")
122 (is (eq (sym "BAR" "SYM")
123 (sym "BAZ" "SYM"))))))
125 (with-test (:name use-package
.2)
126 (with-packages (("FOO" (:export
"SYM"))
127 ("BAZ" (:use
) (:intern
"SYM")))
128 (with-name-conflict-resolution ((sym "FOO" "SYM") :restarted restartedp
)
129 (use-package "FOO" "BAZ")
131 (is (eq (sym "FOO" "SYM")
132 (sym "BAZ" "SYM"))))))
134 (with-test (:name use-package
.2a
)
135 (with-packages (("FOO" (:export
"SYM"))
136 ("BAZ" (:use
) (:intern
"SYM")))
137 (with-name-conflict-resolution ((sym "BAZ" "SYM") :restarted restartedp
)
138 (use-package "FOO" "BAZ")
140 (is (equal (list (sym "BAZ" "SYM") :internal
)
141 (multiple-value-list (sym "BAZ" "SYM")))))))
143 (with-test (:name use-package-conflict-set
:fails-on
:sbcl
)
144 (with-packages (("FOO" (:export
"SYM"))
145 ("QUX" (:export
"SYM"))
146 ("BAR" (:intern
"SYM"))
147 ("BAZ" (:use
) (:import-from
"BAR" "SYM")))
148 (let ((conflict-set))
151 ((sb-ext:name-conflict
153 (setf conflict-set
(copy-list
154 (sb-ext:name-conflict-symbols condition
)))
156 (use-package '("FOO" "QUX") "BAZ")))
158 (sort conflict-set
#'string
<
159 :key
(lambda (symbol)
160 (package-name (symbol-package symbol
)))))
161 (is (equal (list (sym "BAR" "SYM") (sym "FOO" "SYM") (sym "QUX" "SYM"))
165 (with-test (:name export
.1)
166 (with-packages (("FOO" (:intern
"SYM"))
167 ("BAR" (:export
"SYM"))
168 ("BAZ" (:use
"FOO" "BAR")))
169 (with-name-conflict-resolution ((sym "FOO" "SYM") :restarted restartedp
)
170 (export (sym "FOO" "SYM") "FOO")
172 (is (eq (sym "FOO" "SYM")
173 (sym "BAZ" "SYM"))))))
175 (with-test (:name export
.1a
)
176 (with-packages (("FOO" (:intern
"SYM"))
177 ("BAR" (:export
"SYM"))
178 ("BAZ" (:use
"FOO" "BAR")))
179 (with-name-conflict-resolution ((sym "BAR" "SYM") :restarted restartedp
)
180 (export (sym "FOO" "SYM") "FOO")
182 (is (eq (sym "BAR" "SYM")
183 (sym "BAZ" "SYM"))))))
185 (with-test (:name export.ensure-exported
)
186 (with-packages (("FOO" (:intern
"SYM"))
187 ("BAR" (:export
"SYM"))
188 ("BAZ" (:use
"FOO" "BAR") (:IMPORT-FROM
"BAR" "SYM")))
189 (with-name-conflict-resolution ((sym "FOO" "SYM") :restarted restartedp
)
190 (export (sym "FOO" "SYM") "FOO")
192 (is (equal (list (sym "FOO" "SYM") :external
)
193 (multiple-value-list (sym "FOO" "SYM"))))
194 (is (eq (sym "FOO" "SYM")
195 (sym "BAZ" "SYM"))))))
197 (with-test (:name export
.3.intern
)
198 (with-packages (("FOO" (:intern
"SYM"))
199 ("BAZ" (:use
"FOO") (:intern
"SYM")))
200 (with-name-conflict-resolution ((sym "FOO" "SYM") :restarted restartedp
)
201 (export (sym "FOO" "SYM") "FOO")
203 (is (eq (sym "FOO" "SYM")
204 (sym "BAZ" "SYM"))))))
206 (with-test (:name export
.3a.intern
)
207 (with-packages (("FOO" (:intern
"SYM"))
208 ("BAZ" (:use
"FOO") (:intern
"SYM")))
209 (with-name-conflict-resolution ((sym "BAZ" "SYM") :restarted restartedp
)
210 (export (sym "FOO" "SYM") "FOO")
212 (is (equal (list (sym "BAZ" "SYM") :internal
)
213 (multiple-value-list (sym "BAZ" "SYM")))))))
216 (with-test (:name import-nil
.1)
217 (with-packages (("FOO" (:use
) (:intern
"NIL"))
218 ("BAZ" (:use
) (:intern
"NIL")))
219 (with-name-conflict-resolution ((sym "FOO" "NIL") :restarted restartedp
)
220 (import (list (sym "FOO" "NIL")) "BAZ")
222 (is (eq (sym "FOO" "NIL")
223 (sym "BAZ" "NIL"))))))
225 (with-test (:name import-nil
.2)
226 (with-packages (("BAZ" (:use
) (:intern
"NIL")))
227 (with-name-conflict-resolution ('CL
:NIL
:restarted restartedp
)
228 (import '(CL:NIL
) "BAZ")
231 (sym "BAZ" "NIL"))))))
233 (with-test (:name import-single-conflict
:fails-on
:sbcl
)
234 (with-packages (("FOO" (:export
"NIL"))
235 ("BAR" (:export
"NIL"))
237 (let ((conflict-sets '()))
239 ((sb-ext:name-conflict
241 (push (copy-list (sb-ext:name-conflict-symbols condition
))
243 (invoke-restart 'sb-ext
:resolve-conflict
'CL
:NIL
))))
244 (import (list 'CL
:NIL
(sym "FOO" "NIL") (sym "BAR" "NIL")) "BAZ"))
245 (is (eql 1 (length conflict-sets
)))
246 (is (eql 3 (length (first conflict-sets
)))))))
249 (with-test (:name unintern
.1)
250 (with-packages (("FOO" (:export
"SYM"))
251 ("BAR" (:export
"SYM"))
252 ("BAZ" (:use
"FOO" "BAR") (:shadow
"SYM")))
253 (with-name-conflict-resolution ((sym "FOO" "SYM") :restarted restartedp
)
254 (unintern (sym "BAZ" "SYM") "BAZ")
256 (is (eq (sym "FOO" "SYM")
257 (sym "BAZ" "SYM"))))))
259 ;;; WITH-PACKAGE-ITERATOR error signalling had problems
260 (with-test (:name with-package-itarator.error
)
264 (eval '(with-package-iterator (sym :cl-user
:foo
)
267 ((and simple-condition program-error
) (c)
268 (assert (equal (list :foo
) (simple-condition-format-arguments c
)))