1 ;;;; miscellaneous non-side-effectful tests of the MOP
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 ;;;; Note that the MOP is not in an entirely supported state.
15 ;;;; However, this seems a good a way as any of ensuring that we have
18 (assert (subtypep 'sb-mop
:funcallable-standard-object
'standard-object
))
20 (assert (find (find-class 'sb-mop
:funcallable-standard-object
)
21 (sb-mop:class-direct-subclasses
(find-class 'standard-object
))))
23 (assert (find (find-class 'standard-object
)
24 (sb-mop:class-direct-superclasses
25 (find-class 'sb-mop
:funcallable-standard-object
))))
27 (dolist (name '(sb-mop:generic-function
28 sb-mop
:method sb-mop
:method-combination
29 sb-mop
:slot-definition sb-mop
:specializer
))
30 (assert (find (find-class 'sb-mop
:metaobject
)
31 (sb-mop:class-direct-superclasses
(find-class name
))))
32 (assert (subtypep name
'sb-mop
:metaobject
)))
34 ;;; No portable class Cp may inherit, by virtue of being a direct or
35 ;;; indirect subclass of a specified class, any slot for which the
36 ;;; name is a symbol accessible in the common-lisp-user package or
37 ;;; exported by any package defined in the ANSI Common Lisp standard.
38 (let ((specified-class-names
39 '(sb-mop:built-in-class
41 sb-mop
:direct-slot-definition
42 sb-mop
:effective-slot-definition
43 sb-mop
:eql-specializer
44 sb-mop
:forward-referenced-class
45 sb-mop
:funcallable-standard-class
46 sb-mop
:funcallable-standard-object
47 sb-mop
:generic-function
50 sb-mop
:method-combination
51 sb-mop
:slot-definition
53 sb-mop
:standard-accessor-method
55 sb-mop
:standard-direct-slot-definition
56 sb-mop
:standard-effective-slot-definition
57 sb-mop
:standard-generic-function
58 sb-mop
:standard-method
59 sb-mop
:standard-object
60 sb-mop
:standard-reader-method
61 sb-mop
:standard-slot-definition
62 sb-mop
:standard-writer-method
)))
63 (labels ((slot-name-ok (name)
64 (dolist (package (mapcar #'find-package
65 '("CL" "CL-USER" "KEYWORD" "SB-MOP"))
67 (when (multiple-value-bind (symbol status
)
68 (find-symbol (symbol-name name
) package
)
70 (or (eq package
(find-package "CL-USER"))
71 (eq status
:external
))))
73 (test-class-slots (class)
74 (loop for slot in
(sb-mop:class-slots class
)
75 for slot-name
= (sb-mop:slot-definition-name slot
)
76 unless
(slot-name-ok slot-name
)
77 collect
(cons class slot-name
))))
78 (loop for class-name in specified-class-names
79 for class
= (find-class class-name
)
80 for results
= (test-class-slots class
)
81 when results do
(cerror "continue" "~A" results
))))
83 ;;; AMOP says these are the defaults
84 (with-test (:name
:standard-direct-superclasses
)
85 (assert (equal (list (find-class 'standard-object
))
86 (sb-mop:class-direct-superclasses
(make-instance 'standard-class
))))
87 (assert (equal (list (find-class 'sb-mop
:funcallable-standard-object
))
88 (sb-mop:class-direct-superclasses
(make-instance 'sb-mop
:funcallable-standard-class
)))))
90 (with-test (:name
:bug-936513
)
91 ;; This used to fail as ENSURE-GENERIC-FUNCTION wanted a list specifying
92 ;; the method combination, and didn't accept the actual object
93 (let ((mc (sb-pcl:find-method-combination
#'make-instance
'standard nil
)))
94 (ensure-generic-function 'make-instance
:method-combination mc
))
95 ;; Let's make sure the list works too...
96 (ensure-generic-function 'make-instance
:method-combination
'(standard)))
98 (with-test (:name
:bug-309072
)
99 ;; original reported test cases
100 (assert-error (make-instance 'sb-mop
:slot-definition
)
101 sb-pcl
::slotd-initialization-error
)
102 (assert-error (make-instance 'sb-mop
:slot-definition
:name
'pi
)
103 sb-pcl
::slotd-initialization-error
)
104 (assert-error (make-instance 'sb-mop
:slot-definition
:name
3)
105 sb-pcl
::slotd-initialization-type-error
)
106 ;; extra cases from the MOP dictionary
107 (assert-error (make-instance 'sb-mop
:slot-definition
:name
'x
109 sb-pcl
::slotd-initialization-error
)
110 (assert-error (make-instance 'sb-mop
:slot-definition
:name
'x
111 :initfunction
(lambda () nil
))
112 sb-pcl
::slotd-initialization-error
)
113 (assert-error (make-instance 'sb-mop
:slot-definition
:name
'x
114 :initfunction
(lambda () nil
))
115 sb-pcl
::slotd-initialization-error
)
116 (assert-error (make-instance 'sb-mop
:slot-definition
:name
'x
118 sb-pcl
::slotd-initialization-error
)
119 (assert-error (make-instance 'sb-mop
:slot-definition
:name
'x
121 sb-pcl
::slotd-initialization-error
)
122 (assert-error (make-instance 'sb-mop
:slot-definition
:name
'x
123 :initargs
'(foo . bar
))
124 sb-pcl
::slotd-initialization-error
)
125 (assert-error (make-instance 'sb-mop
:slot-definition
:name
'x
126 :initargs
'(foo bar
3))
127 sb-pcl
::slotd-initialization-error
)
128 (assert-error (make-instance 'sb-mop
:slot-definition
:name
'x
129 :documentation
'(()))
130 sb-pcl
::slotd-initialization-error
)
131 ;; distinction between DIRECT- and EFFECTIVE- slot definitions
132 (assert-error (make-instance 'sb-mop
:effective-slot-definition
133 :name
'x
:readers
'(foo))
134 sb-pcl
::initarg-error
)
135 (assert-error (make-instance 'sb-mop
:effective-slot-definition
136 :name
'x
:writers
'(foo))
137 sb-pcl
::initarg-error
)
138 (make-instance 'sb-mop
:direct-slot-definition
139 :name
'x
:readers
'(foo))
140 (make-instance 'sb-mop
:direct-slot-definition
141 :name
'x
:writers
'(foo))
142 (assert-error (make-instance 'sb-mop
:direct-slot-definition
143 :name
'x
:readers
"")
144 sb-pcl
::slotd-initialization-error
)
145 (assert-error (make-instance 'sb-mop
:direct-slot-definition
146 :name
'x
:readers
'(3))
147 sb-pcl
::slotd-initialization-error
)
148 (assert-error (make-instance 'sb-mop
:direct-slot-definition
149 :name
'x
:readers
'(foo . bar
))
150 sb-pcl
::slotd-initialization-error
)
151 (assert-error (make-instance 'sb-mop
:direct-slot-definition
152 :name
'x
:writers
"")
153 sb-pcl
::slotd-initialization-error
)
154 (assert-error (make-instance 'sb-mop
:direct-slot-definition
155 :name
'x
:writers
'(3))
156 sb-pcl
::slotd-initialization-error
)
157 (assert-error (make-instance 'sb-mop
:direct-slot-definition
158 :name
'x
:writers
'(foo . bar
))
159 sb-pcl
::slotd-initialization-error
))
161 (with-test (:name
(:bug-1332983
:validate-superclass stream t
))
163 (sb-mop:validate-superclass
(find-class 'stream
) (find-class 't
))))
165 (with-test (:name
(:bug-1049423
:duplicate-effective-slots
))
166 (flet ((check (descendant-name ancestor-name slot-name
)
167 (let ((kid (find-class descendant-name
))
168 (par (find-class ancestor-name
)))
169 (assert (find par
(sb-mop:class-precedence-list kid
)))
170 ;; each specifies SLOT-NAME as a slot name
171 (find slot-name
(sb-mop:class-direct-slots kid
)
172 :key
'sb-mop
:slot-definition-name
)
173 (find slot-name
(sb-mop:class-direct-slots par
)
174 :key
'sb-pcl
:slot-definition-name
)
175 ;; there is only one effective slot of that name
176 (assert (= 1 (count slot-name
(sb-mop:class-slots kid
)
177 :key
'sb-pcl
:slot-definition-name
))))))
178 ;; metaclass = structure-class
179 ;; FUN-TYPE inherits CTYPE
180 (check 'sb-kernel
:fun-type
'sb-kernel
:ctype
'sb-kernel
::class-info
)
181 ;; metaclass = condition-class
182 ;; REDEFINITION-WITH-DEFMETHOD inherits REDEFINITION-WARNING
183 (check 'sb-kernel
:redefinition-with-defmethod
184 'sb-kernel
:redefinition-warning
185 'sb-kernel
::new-location
)))
187 ;; Do a quick test of FIND-SLOT-CELL for all slots of all classes with slots
188 (with-test (:name
:sanity-check-find-slot-cell
)
190 (let ((class (find-class s nil
)))
191 (when (and class
(ignore-errors (sb-mop:class-slots class
)))
192 (let ((layout (sb-kernel:find-layout s
)))
193 (dolist (slot-name (mapcar #'sb-mop
:slot-definition-name
194 (sb-mop:class-slots class
)))
195 (assert (sb-pcl::find-slot-cell layout slot-name
))))))))