2
;;;; Author: Paul Dietz
3
;;;; Created: Sat May 31 11:18:15 2003
4
;;;; Contains: Tests of CALL-NEXT-METHOD
8
;;; Tests where there is no next method are in no-next-method.lsp
10
(defgeneric cnm-gf-01 (x)
11
(:method ((x integer)) (cons 'a (call-next-method)))
12
(:method ((x rational)) (cons 'b (call-next-method)))
13
(:method ((x real)) (cons 'c (call-next-method)))
14
(:method ((x number)) (cons 'd (call-next-method)))
15
(:method ((x t)) nil))
17
(deftest call-next-method.1
18
(mapcar #'cnm-gf-01 '(0 2/3 1.3 #c(1 1) a))
19
((a b c d) (b c d) (c d) (d) nil))
21
;; Check that call-next-method passes along multiple values correctly
23
(defgeneric cnm-gf-02 (x)
24
(:method ((x integer)) (call-next-method))
25
(:method ((x number)) (values))
26
(:method ((x (eql 'a))) (call-next-method))
27
(:method ((x symbol)) (values 1 2 3 4 5 6)))
29
(deftest call-next-method.2
32
(deftest call-next-method.3
36
;;; Call next method has indefinite extent
38
(defgeneric cnm-gf-03 (x)
39
(:method ((x integer)) #'call-next-method)
42
(deftest call-next-method.4
43
(funcall (cnm-gf-03 0))
46
;;; The arguments to c-n-m can be changed
48
(defgeneric cnm-gf-04 (x)
49
(:method ((x integer)) (call-next-method (+ x 10)))
50
(:method ((x number)) (1+ x)))
52
(deftest call-next-method.5
53
(mapcar #'cnm-gf-04 '(0 1 2 5/3 9/2 1.0 #c(1 1)))
54
(11 12 13 8/3 11/2 2.0 #c(2 1)))
56
;;; call-next-method goes up the list of applicable methods
57
;;; which may be to a method with specializers incomparable to
58
;;; the current method
60
(defgeneric cnm-gf-05 (x y)
61
(:method ((x integer) (y integer)) (cons 'a (call-next-method)))
62
(:method ((x integer) (y t)) (cons 'b (call-next-method)))
63
(:method ((x t) (y integer)) (cons 'c (call-next-method)))
64
(:method ((x t) (y t)) (list 'd)))
66
(deftest call-next-method.6
67
(mapcar #'cnm-gf-05 '(0 0 t t) '(0 t 0 t))
73
(defclass cnm-class-01a () ())
74
(defclass cnm-class-01b (cnm-class-01a) ())
75
(defclass cnm-class-01c (cnm-class-01a) ())
76
(defclass cnm-class-01d (cnm-class-01c cnm-class-01b) ())
78
(defgeneric cnm-gf-06 (x)
79
(:method ((x cnm-class-01d)) (cons 1 (call-next-method)))
80
(:method ((x cnm-class-01c)) (cons 2 (call-next-method)))
81
(:method ((x cnm-class-01b)) (cons 3 (call-next-method)))
82
(:method ((x cnm-class-01a)) (cons 4 (call-next-method)))
83
(:method ((x t)) nil))
85
(deftest call-next-method.7
87
(cnm-gf-06 (make-instance 'cnm-class-01d))
88
(cnm-gf-06 (make-instance 'cnm-class-01c))
89
(cnm-gf-06 (make-instance 'cnm-class-01b))
90
(cnm-gf-06 (make-instance 'cnm-class-01a))
98
;;; Neither rebinding nor setq affects the arguments passed by
99
;;; (call-next-method)
101
(defgeneric cnm-gf-07 (x)
102
(:method ((x integer)) (list (incf x) (call-next-method)))
103
(:method ((x symbol)) (list (setq x 'a) x (call-next-method)))
104
(:method ((x cons)) (list x (let ((x :bad))
105
(declare (ignorable x))
106
(call-next-method))))
109
(deftest call-next-method.8
110
(mapcar #'cnm-gf-07 '(0 z (x) #\a))
111
((1 0) (a a z) ((x) (x)) #\a))
113
;; Nor does argument defaulting
115
(defgeneric cnm-gf-08 (x &optional y)
116
(:method ((x integer) &optional y) (list* x y (call-next-method)))
117
(:method ((x t) &optional y) (list x y)))
119
(deftest call-next-method.9
130
;;; When c-n-m is called with arguments but omits optionals, those
131
;;; optionals are defaulted
133
(defgeneric cnm-gf-09 (x &optional y)
134
(:method ((x integer) &optional y) (list* x y (call-next-method (1+ x))))
135
(:method ((x t) &optional y) (list x y)))
137
(deftest call-next-method.10
148
(defgeneric cnm-gf-10 (x &optional y z)
149
(:method ((x integer) &optional (y 'a y-p) (z 'b z-p))
150
(list* x y (notnot y-p) z (notnot z-p) (call-next-method (1+ x))))
151
(:method ((x t) &optional (y 'c y-p) (z 'd z-p))
152
(list x y (notnot y-p) z (notnot z-p))))
154
(deftest call-next-method.11
161
(cnm-gf-10 'x 'u 'v))
162
(5 a nil b nil 6 c nil d nil)
163
(8 p t b nil 9 c nil d nil)
164
(8 p t q t 9 c nil d nil)
169
;;; "When providing arguments to call-next-method, the following
170
;;; rule must be satisfied or an error of type error should be signaled:
171
;;; the ordered set of applicable methods for a changed set of arguments
172
;;; for call-next-method must be the same as the ordered set of applicable
173
;;; methods for the original arguments to the generic function."
175
(defgeneric cnm-order-error-gf-01 (x)
176
(declare (optimize (safety 3)))
177
(:method ((x (eql 0)))
178
(declare (optimize (safety 3)))
179
(call-next-method 1)) ;; no longer EQL to 0
180
(:method ((x t)) nil))
182
(deftest call-next-method.error.1
184
(declare (optimize (safety 3)))
186
(eval '(locally (declare (optimize (safety 3)))
187
(cnm-order-error-gf-01 0)))
191
(defgeneric cnm-order-error-gf-02 (x)
192
(declare (optimize (safety 3)))
193
(:method ((x integer))
194
(declare (optimize (safety 3)))
195
(call-next-method :bad))
198
(deftest call-next-method.error.2
200
(declare (optimize (safety 3)))
202
(eval '(locally (declare (optimize (safety 3)))
203
(cnm-order-error-gf-02 0)))