*** empty log message ***
[bpt/guile.git] / test-suite / tests / goops.test
CommitLineData
4ed29c73
MV
1;;;; goops.test --- test suite for GOOPS -*- scheme -*-
2;;;;
62ed3710 3;;;; Copyright (C) 2001,2003,2004 Free Software Foundation, Inc.
4ed29c73
MV
4;;;;
5;;;; This program is free software; you can redistribute it and/or modify
6;;;; it under the terms of the GNU General Public License as published by
7;;;; the Free Software Foundation; either version 2, or (at your option)
8;;;; any later version.
9;;;;
10;;;; This program is distributed in the hope that it will be useful,
11;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13;;;; GNU General Public License for more details.
14;;;;
15;;;; You should have received a copy of the GNU General Public License
16;;;; along with this software; see the file COPYING. If not, write to
92205699
MV
17;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18;;;; Boston, MA 02110-1301 USA
4ed29c73 19
62ed3710
DH
20(define-module (test-suite test-goops)
21 #:use-module (test-suite lib))
4ed29c73
MV
22
23(pass-if "GOOPS loads"
24 (false-if-exception
25 (begin (resolve-module '(oop goops))
26 #t)))
27
28(use-modules (oop goops))
29
30;;; more tests here...
bdd2c6f4
DH
31
32(with-test-prefix "basic classes"
33
34 (with-test-prefix "<top>"
35
36 (pass-if "instance?"
37 (instance? <top>))
38
39 (pass-if "class-of"
40 (eq? (class-of <top>) <class>))
41
42 (pass-if "is a class?"
43 (is-a? <top> <class>))
44
45 (pass-if "class-name"
46 (eq? (class-name <top>) '<top>))
47
48 (pass-if "direct superclasses"
49 (equal? (class-direct-supers <top>) '()))
50
51 (pass-if "superclasses"
52 (equal? (class-precedence-list <top>) (list <top>)))
53
54 (pass-if "direct slots"
55 (equal? (class-direct-slots <top>) '()))
56
57 (pass-if "slots"
58 (equal? (class-slots <top>) '())))
59
60 (with-test-prefix "<object>"
61
62 (pass-if "instance?"
63 (instance? <object>))
64
65 (pass-if "class-of"
66 (eq? (class-of <object>) <class>))
67
68 (pass-if "is a class?"
69 (is-a? <object> <class>))
70
71 (pass-if "class-name"
72 (eq? (class-name <object>) '<object>))
73
74 (pass-if "direct superclasses"
75 (equal? (class-direct-supers <object>) (list <top>)))
76
77 (pass-if "superclasses"
78 (equal? (class-precedence-list <object>) (list <object> <top>)))
79
80 (pass-if "direct slots"
81 (equal? (class-direct-slots <object>) '()))
82
83 (pass-if "slots"
84 (equal? (class-slots <object>) '())))
85
86 (with-test-prefix "<class>"
87
88 (pass-if "instance?"
89 (instance? <class>))
90
91 (pass-if "class-of"
92 (eq? (class-of <class>) <class>))
93
94 (pass-if "is a class?"
95 (is-a? <class> <class>))
96
97 (pass-if "class-name"
98 (eq? (class-name <class>) '<class>))
99
100 (pass-if "direct superclass"
57b1d518
MD
101 (equal? (class-direct-supers <class>) (list <object>))))
102
103 (with-test-prefix "class-precedence-list"
104 (for-each (lambda (class)
105 (run-test (if (slot-bound? class 'name)
106 (class-name class)
107 (with-output-to-string
108 (lambda ()
109 (display class))))
110 #t
111 (lambda ()
112 (catch #t
113 (lambda ()
114 (equal? (class-precedence-list class)
115 (compute-cpl class)))
116 (lambda args #t)))))
117 (let ((table (make-hash-table)))
118 (let rec ((class <top>))
119 (hash-create-handle! table class #f)
120 (for-each rec (class-direct-subclasses class)))
121 (hash-fold (lambda (class ignore classes)
122 (cons class classes))
123 '()
124 table))))
125 )
9f045403
DH
126
127(with-test-prefix "defining classes"
128
129 (with-test-prefix "define-class"
130
131 (pass-if "creating a new binding"
62ed3710
DH
132 (if (eval '(defined? '<foo-0>) (current-module))
133 (throw 'unresolved))
134 (eval '(define-class <foo-0> ()) (current-module))
135 (eval '(is-a? <foo-0> <class>) (current-module)))
9f045403
DH
136
137 (pass-if "overwriting a binding to a non-class"
138 (eval '(define <foo> #f) (current-module))
139 (eval '(define-class <foo> ()) (current-module))
47cd67db
MD
140 (eval '(is-a? <foo> <class>) (current-module)))
141
142 (expect-fail "bad init-thunk"
143 (catch #t
144 (lambda ()
145 (eval '(define-class <foo> ()
146 (x #:init-thunk (lambda (x) 1)))
147 (current-module))
148 #t)
149 (lambda args
150 #f)))
151 ))
33e04d54
DH
152
153(with-test-prefix "defining generics"
154
155 (with-test-prefix "define-generic"
156
157 (pass-if "creating a new top-level binding"
62ed3710
DH
158 (if (eval '(defined? 'foo-0) (current-module))
159 (throw 'unresolved))
160 (eval '(define-generic foo-0) (current-module))
161 (eval '(and (is-a? foo-0 <generic>)
162 (null? (generic-function-methods foo-0)))
33e04d54
DH
163 (current-module)))
164
165 (pass-if "overwriting a top-level binding to a non-generic"
166 (eval '(define (foo) #f) (current-module))
167 (eval '(define-generic foo) (current-module))
168 (eval '(and (is-a? foo <generic>)
169 (= 1 (length (generic-function-methods foo))))
170 (current-module)))
171
172 (pass-if "overwriting a top-level binding to a generic"
173 (eval '(define (foo) #f) (current-module))
174 (eval '(define-generic foo) (current-module))
175 (eval '(define-generic foo) (current-module))
176 (eval '(and (is-a? foo <generic>)
177 (null? (generic-function-methods foo)))
178 (current-module)))))
179
180(with-test-prefix "defining accessors"
181
182 (with-test-prefix "define-accessor"
183
184 (pass-if "creating a new top-level binding"
62ed3710
DH
185 (if (eval '(defined? 'foo-1) (current-module))
186 (throw 'unresolved))
187 (eval '(define-accessor foo-1) (current-module))
188 (eval '(and (is-a? foo-1 <generic-with-setter>)
189 (null? (generic-function-methods foo-1)))
33e04d54
DH
190 (current-module)))
191
192 (pass-if "overwriting a top-level binding to a non-accessor"
193 (eval '(define (foo) #f) (current-module))
194 (eval '(define-accessor foo) (current-module))
195 (eval '(and (is-a? foo <generic-with-setter>)
196 (= 1 (length (generic-function-methods foo))))
197 (current-module)))
198
199 (pass-if "overwriting a top-level binding to an accessor"
200 (eval '(define (foo) #f) (current-module))
201 (eval '(define-accessor foo) (current-module))
202 (eval '(define-accessor foo) (current-module))
203 (eval '(and (is-a? foo <generic-with-setter>)
204 (null? (generic-function-methods foo)))
205 (current-module)))))
58241edc
MD
206
207(with-test-prefix "object update"
208 (pass-if "defining class"
209 (eval '(define-class <foo> ()
210 (x #:accessor x #:init-value 123)
211 (z #:accessor z #:init-value 789))
212 (current-module))
213 (eval '(is-a? <foo> <class>) (current-module)))
214 (pass-if "making instance"
215 (eval '(define foo (make <foo>)) (current-module))
216 (eval '(and (is-a? foo <foo>) (= (x foo) 123)) (current-module)))
217 (pass-if "redefining class"
218 (eval '(define-class <foo> ()
219 (x #:accessor x #:init-value 123)
220 (y #:accessor y #:init-value 456)
221 (z #:accessor z #:init-value 789))
222 (current-module))
223 (eval '(and (= (y foo) 456) (= (z foo) 789)) (current-module))))
224
47cd67db
MD
225(with-test-prefix "object comparison"
226 (pass-if "default method"
57b1d518
MD
227 (eval '(begin
228 (define-class <c> ()
229 (x #:accessor x #:init-keyword #:x)
230 (y #:accessor y #:init-keyword #:y))
47cd67db
MD
231 (define o1 (make <c> #:x '(1) #:y '(2)))
232 (define o2 (make <c> #:x '(1) #:y '(3)))
233 (define o3 (make <c> #:x '(4) #:y '(3)))
234 (define o4 (make <c> #:x '(4) #:y '(3)))
235 (not (eqv? o1 o2)))
236 (current-module)))
237 (pass-if "eqv?"
238 (eval '(begin
239 (define-method (eqv? (a <c>) (b <c>))
240 (equal? (x a) (x b)))
241 (eqv? o1 o2))
242 (current-module)))
243 (pass-if "not eqv?"
244 (eval '(not (eqv? o2 o3))
245 (current-module)))
246 (pass-if "transfer eqv? => equal?"
247 (eval '(equal? o1 o2)
248 (current-module)))
249 (pass-if "equal?"
250 (eval '(begin
57b1d518
MD
251 (define-method (equal? (a <c>) (b <c>))
252 (equal? (y a) (y b)))
47cd67db 253 (equal? o2 o3))
57b1d518 254 (current-module)))
47cd67db
MD
255 (pass-if "not equal?"
256 (eval '(not (equal? o1 o2))
257 (current-module)))
258 (pass-if "="
259 (eval '(begin
260 (define-method (= (a <c>) (b <c>))
261 (and (equal? (x a) (x b))
262 (equal? (y a) (y b))))
263 (= o3 o4))
264 (current-module)))
265 (pass-if "not ="
266 (eval '(not (= o1 o2))
267 (current-module)))
268 )
57b1d518 269
58241edc
MD
270(use-modules (oop goops active-slot))
271
272(with-test-prefix "active-slot"
273 (pass-if "defining class with active slot"
274 (eval '(begin
275 (define z '())
276 (define-class <bar> ()
277 (x #:accessor x
278 #:init-value 1
279 #:allocation #:active
280 #:before-slot-ref
281 (lambda (o)
282 (set! z (cons 'before-ref z))
283 #t)
284 #:after-slot-ref
285 (lambda (o)
286 (set! z (cons 'after-ref z)))
287 #:before-slot-set!
288 (lambda (o v)
289 (set! z (cons* v 'before-set! z)))
290 #:after-slot-set!
291 (lambda (o v)
292 (set! z (cons* v (x o) 'after-set! z))))
293 #:metaclass <active-class>)
294 (define bar (make <bar>))
295 (x bar)
296 (set! (x bar) 2)
297 (equal? (reverse z)
298 '(before-ref before-set! 1 before-ref after-ref
299 after-set! 1 1 before-ref after-ref
300 before-set! 2 before-ref after-ref after-set! 2 2)))
301 (current-module))))
302
47cd67db
MD
303(use-modules (oop goops composite-slot))
304
305(with-test-prefix "composite-slot"
306 (pass-if "creating instance with propagated slot"
307 (eval '(begin
308 (define-class <a> ()
309 (x #:accessor x #:init-keyword #:x)
310 (y #:accessor y #:init-keyword #:y))
311 (define-class <c> ()
312 (o1 #:accessor o1 #:init-form (make <a> #:x 1 #:y 2))
313 (o2 #:accessor o2 #:init-form (make <a> #:x 3 #:y 4))
314 (x #:accessor x
315 #:allocation #:propagated
316 #:propagate-to '(o1 (o2 y)))
317 #:metaclass <composite-class>)
318 (define o (make <c>))
319 (is-a? o <c>))
320 (current-module)))
321 (pass-if "reading propagated slot"
322 (eval '(= (x o) 1) (current-module)))
323 (pass-if "writing propagated slot"
324 (eval '(begin
325 (set! (x o) 5)
326 (and (= (x (o1 o)) 5)
327 (= (y (o1 o)) 2)
328 (= (x (o2 o)) 3)
329 (= (y (o2 o)) 5)))
330 (current-module))))