1
0
mirror of synced 2026-01-13 15:37:38 +00:00
2021-03-08 21:09:58 -08:00

2881 lines
98 KiB
Common Lisp

;;;-*- Mode:LISP; Package: CLOS; Base:10; Syntax:Common-lisp -*-
;;;
;;; *************************************************************************
;;; Copyright (c) 1991 Venue
;;; All rights reserved.
;;; *************************************************************************
;;;
;;; Testing code.
;;;
(in-package :clos)
;;; Because CommonLoops runs in itself so much, the notion of a test file for
;;; it is kind of weird.
;;;
;;; If all of CLOS loads then many of the tests in this file (particularly
;;; those at the beginning) are sure to work. Those tests exists primarily
;;; to help debug things when low-level changes are made to CLOS, or when a
;;; particular port customizes low-level code.
;;;
;;; Some of the other tests are "real" in the sense that they test things
;;; that CLOS itself does not use, so might be broken.
;;;
;;; NOTE:
;;; The tests in this file do not appear in random order! They
;;; depend on state which has already been set up in order to run.
;;;
(defmacro do-test (name cleanups &body body)
`(let ((do-test-failed nil))
(catch 'do-test
(format t "~&Testing ~A..." ,name)
; (cleanup-do-test ',cleanups)
(block do-test ,@body)
(if do-test-failed
(format t "~&FAILED!")
(format t "OK")))))
(defmacro do-test-error (fatal string &rest args)
`(progn (terpri)
(setq do-test-failed t)
(format t ,string ,@args)
(when ,fatal (return-from do-test nil))))
(defun cleanup-do-test (cleanups)
(dolist (cleanup cleanups)
(ecase (car cleanup)
(:classes
(dolist (c (cdr cleanup))
(let ((class (find-class c 'nil)))
(when class
(dolist (super (slot-value class 'direct-superclasses))
(setf (slot-value class 'direct-subclasses)
(remove class (slot-value class 'direct-subclasses))))
(setf (find-class c) nil)))))
(:functions
(dolist (f (cdr cleanup))
(fmakunbound f)))
(:setf-generic-functions
(dolist (f (cdr cleanup))
(fmakunbound (get-setf-function-name f))))
(:variables
(dolist (v (cdr cleanup))
(makunbound v))))))
#-(or KCL IBCL :Coral GCLisp)
(eval-when (eval)
(compile 'do-test)
(compile 'do-test-error)
(compile 'cleanup-do-test))
;;
;;;;;;
;;
(do-test "types for early classes"
()
(dolist (x '(standard-object standard-class standard-slot-definition))
(or (typep (make-instance x) x)
(do-test-error () "instance of ~S not of type ~S??" x x))))
(do-test "types for late classes"
()
(dolist (x '(standard-method standard-generic-function))
(or (typep (make-instance x) x)
(do-test-error () "~&instance of ~S not of type ~S??" x x))))
(defvar *built-in-class-tests*
'((ARRAY (MAKE-ARRAY '(10 10)))
(BIT-VECTOR (MAKE-ARRAY 10 :ELEMENT-TYPE 'BIT))
(CHARACTER #\a)
(COMPLEX #C(1 2))
(CONS (LIST 1 2 3))
(FLOAT 1.3)
(INTEGER 1)
;LIST abstract super of cons, null
(NULL NIL)
;NUMBER abstract super of complex, float, rational
(RATIO 1/2)
;RATIONAL abstract super of ratio, integer
;SEQUENCE abstract super of list, vector
(STRING "foo")
(SYMBOL 'FOO)
(VECTOR (VECTOR 1 2 3))))
(do-test "built-in-class-of"
()
(let ((lostp nil))
(dolist (tst *built-in-class-tests*)
(unless (eq (find-class (car tst) 't)
(class-of (eval (cadr tst))))
(do-test-error ()
"~&class-of ~S was ~A not ~A~%"
(cadr tst)
(class-name (class-of (eval (cadr tst))))
(car tst))
(setq lostp t)))
(not lostp)))
(do-test "existence of generic-functions for accessors of early classes"
()
;; Because accessors are done with add-method, and this has to be done
;; specially for early classes it is worth testing to make sure that
;; the generic-functions got created for the accessor of early classes.
;;
;; Of course CLOS wouldn't have loaded if most of these didn't exist,
;; but what the hell.
(dolist (class '(standard-class
standard-slot-definition
standard-generic-function
standard-method))
(dolist (slotd (class-slots (find-class class)))
(dolist (rea (slotd-readers slotd))
(unless (and (gboundp rea)
(generic-function-p (gdefinition rea)))
(do-test-error () "~S isn't a generic function" rea)))
(dolist (wri (slotd-writers slotd))
(unless (and (gboundp wri)
(generic-function-p (gdefinition wri)))
(do-test-error () "~S isn't a generic function" wri))))))
(do-test "early reader/writer methods are appropriate class"
()
;; Because accessors are done with add-method, and this has to be done
;; specially for early classes it is worth testing to make sure that
;; the generic-functions got created for the accessor of early classes.
;;
;; Of course CLOS wouldn't have loaded if most of these didn't exist,
;; but what the hell.
(dolist (class '(standard-class
standard-slot-definition
standard-generic-function
standard-method))
(let ((class (find-class 'standard-class)))
(flet ((check-reader (gf)
(let ((reader (get-method (gdefinition gf)
()
(list class))))
(unless (typep reader 'standard-reader-method)
(do-test-error () "~S isn't a READER method" reader))))
(check-writer (gf)
(let ((writer (get-method (gdefinition gf)
()
(list (find-class 't) class))))
(unless (typep writer 'standard-writer-method)
(do-test-error () "~S isn't a WRITER method" writer)))))
(dolist (slotd (class-direct-slots class))
(dolist (rea (slotd-readers slotd))
(check-reader rea))
(dolist (wri (slotd-writers slotd))
(check-writer wri)))))))
(do-test "typep works for standard-classes"
((:classes foo1 foo2 bar))
(defclass foo1 () ())
(defclass foo2 (foo1) ())
(defclass bar () ())
(let ((f1 (make-instance 'foo1))
(f2 (make-instance 'foo2)))
(or (typep f1 'foo1)
(do-test-error
() "an instance of foo1 isn't subtypep of foo1"))
(or (not (typep f1 'foo2))
(do-test-error
() "an instance of foo1 is suptypep of a subclass of foo1"))
(or (not (typep f1 'bar))
(do-test-error
() "an instance of foo1 is subtypep of an unrelated class"))
(or (typep f2 'foo1)
(do-test-error
() "an instance of foo2 is not subtypep of a super-class of foo2"))
))
(do-test "accessors and readers should NOT be inherited"
((:classes foo bar)
(:functions foo-x foo-y))
(defclass foo ()
((x :accessor foo-x)
(y :reader foo-y)))
(fmakunbound 'foo-x)
(fmakunbound 'foo-y)
(defclass bar (foo)
(x y))
(and (fboundp 'foo-x) (do-test-error () "foo-x got inherited?"))
(and (fboundp 'foo-y) (do-test-error () "foo-x got inherited?")))
(do-test ":accessor and :reader methods go away"
((:classes foo)
(:functions foo-x foo-y)
(:setf-generic-functions foo-x foo-y))
(defclass foo () ((x :accessor foo-x) (y :reader foo-y)))
(unless (and (fboundp 'foo-x)
(fboundp 'foo-y))
(do-test-error t "accessors didn't even get generated?"))
(defclass foo () (x y))
(flet ((methods (x)
(generic-function-methods (symbol-function 'foo-y))))
(and (methods 'foo-x)
(do-test-error () "~&reader method for foo-x not removed"))
(and (methods 'foo-y)
(do-test-error () "~&reader method for foo-y not removed"))
(and (methods (get-setf-function-name 'foo-y))
(do-test-error () "~&writer method for foo-y not removed"))
t))
(defclass test-class-1 ()
((x :initform nil :accessor test-class-1-x :initarg :x)
(y :initform nil :accessor test-class-1-y :initarg :y)))
(do-test "Simple with-accessors test -- does not really exercise the walker."
((:functions foo bar))
(defmethod foo ((obj test-class-1))
(with-accessors ((x test-class-1-x)
(y test-class-1-y))
obj
(list x y)))
(defmethod bar ((obj test-class-1))
(with-accessors ((x test-class-1-x)
(y test-class-1-y))
obj
(setq x 1
y 2)))
(or (and (equal '(nil nil) (foo (make-instance 'test-class-1)))
(equal '(1 2) (foo (make-instance 'test-class-1 :x 1 :y 2))))
(do-test-error () "FOO (the one that reads) failed"))
(or (let ((foo (make-instance 'test-class-1)))
(bar foo)
(or (and (equal (slot-value foo 'x) 1)
(equal (slot-value foo 'y) 2))
(do-test-error () "BAR (the one that writes) failed")))))
(do-test "Simple with-slots test -- does not really exercise the walker."
((:functions foo bar))
(defmethod foo ((obj test-class-1))
(with-slots (x y)
obj
(list x y)))
(defmethod bar ((obj test-class-1))
(with-slots ((obj-x x)
(obj-y y))
obj
(setq obj-x 1
obj-y 2)))
(or (and (equal '(nil nil) (foo (make-instance 'test-class-1)))
(equal '(1 2) (foo (make-instance 'test-class-1 :x 1 :y 2))))
(do-test-error () "FOO (the one that reads) failed"))
(or (let ((foo (make-instance 'test-class-1)))
(bar foo)
(or (and (equal (slot-value foo 'x) 1)
(equal (slot-value foo 'y) 2))
(do-test-error () "BAR (the one that writes) failed")))))
;;
;;;;;; things that bug fixes prompted.
;;
(do-test "with-slots inside of lexical closures"
((:functions frog barg))
;; 6/20/86
;; The walker was confused about what (FUNCTION (LAMBDA ..)) meant. It
;; didn't walk inside there. Its sort of surprising this didn't get
;; caught sooner.
(defun frog (fn foos)
(and foos (cons (funcall fn (car foos)) (frog fn (cdr foos)))))
(defun barg ()
(let ((the-test-class (make-instance 'test-class-1 :x 0 :y 3)))
(with-slots (x y)
the-test-class
(frog #'(lambda (foo) (incf x) (decf y))
(make-list 3)))))
(or (equal (barg) '(2 1 0))
(do-test-error t "lost")))
(do-test "redefinition of default method has proper effect"
((:functions foo))
;; 5/26/86
;; This was caused because the hair for trying to avoid making a
;; new discriminating function didn't know that changing the default
;; method was a reason to make a new discriminating function. Fixed
;; by always making a new discriminating function when a method is
;; added or removed. The template stuff should keep this from being
;; expensive.
(defmethod foo ((x standard-class)) 'standard-class)
(defmethod foo (x) 'default)
(defmethod foo (x) 'new-default)
(or (eq (foo nil) 'new-default)
(do-test-error t "lost")))
(defvar *call-next-method-test-object* (make-instance 'standard-object))
(do-test "call-next-method passes original arguments"
((:functions foo))
;; 2/4/88
;; The spec says that call-next-method must pass the original arguments
;; to call-next-method when none are supplied. This tests that.
(defmethod foo ((x t))
(unless (eq x *call-next-method-test-object*)
(do-test-error t "got wrong value")))
(defmethod foo ((x standard-object))
(setq x nil)
(call-next-method))
(foo *call-next-method-test-object*)
)
(do-test "call-next-method closures pass original arguments - 1"
((:functions foo))
;; 2/4/88
;; call-next-method must pass the original arguments even when it is
;; returned as a lexical closure with indefinite extent
(defmethod foo ((x t))
(unless (eq x *call-next-method-test-object*)
(do-test-error t "got wrong value")))
(defmethod foo ((x standard-object))
(setq x nil)
#'call-next-method)
(funcall (foo *call-next-method-test-object*))
)
(do-test "call-next-method closures pass original arguments - 2"
((:functions foo))
;; 2/4/88
;; call-next-method must pass the original arguments even when it is
;; returned as a lexical closure with indefinite extent
(defmethod foo ((x t))
(unless (eq x *call-next-method-test-object*)
(do-test-error t "got wrong value")))
(defmethod foo ((x standard-object))
#'(lambda ()
(setq x nil)
(call-next-method)))
(funcall (foo *call-next-method-test-object*))
)
(do-test "call-next-method passes supplied arguments"
((:functions foo))
;; 2/4/88
;; The spec says that call-next-method must pass the original arguments
;; to call-next-method when none are supplied. This tests that.
(defmethod foo ((x t))
(unless (eq x *call-next-method-test-object*)
(do-test-error t "got wrong value")))
(defmethod foo ((x standard-object))
(call-next-method *call-next-method-test-object*))
(foo (make-instance 'standard-object))
)
(do-test "call-next-method closures pass supplied arguments - 1"
((:functions foo))
;; 2/4/88
;; call-next-method must pass the original arguments even when it is
;; returned as a lexical closure with indefinite extent
(defmethod foo ((x t))
(unless (eq x *call-next-method-test-object*)
(do-test-error t "got wrong value")))
(defmethod foo ((x standard-object))
#'call-next-method)
(funcall (foo (make-instance 'standard-object)) *call-next-method-test-object*)
)
(do-test "call-next-method closures pass supplied arguments - 2"
((:functions foo))
;; 2/4/88
;; call-next-method must pass the original arguments even when it is
;; returned as a lexical closure with indefinite extent
(defmethod foo ((x t))
(unless (eq x *call-next-method-test-object*)
(do-test-error t "got wrong value")))
(defmethod foo ((x standard-object))
#'(lambda (x)
(call-next-method x)))
(funcall (foo (make-instance 'standard-object))
*call-next-method-test-object*))
(do-test "call-next-method inside of default value form of &optional"
((:functions foo))
;; 5/3/88
;; call-next-method must work inside the default value forms of the
;; method's &mumble arguments.
(defmethod foo1 ((x t) &optional y)
(declare (ignore y))
*call-next-method-test-object*)
(defmethod foo1 ((x standard-object) &optional (y (call-next-method)))
(list x y))
(let ((object (make-instance 'standard-object)))
(unless (equal (foo1 object) (list object *call-next-method-test-object*))
(do-test-error t "Got wrong value"))))
(do-test "specifying :type when superclass doesn't"
((:classes foo bar))
;; 3/23/88
;; if a suclass specifies the :type slot option for a slot for which no
;; superclass specifies a type then the inheritance rule is just to take
;; the type specified by the subclass
(defclass foo ()
((x)))
(defclass bar (foo)
((x :type number))))
(do-test "Leaky next methods"
((:functions foo bar))
;; 6/23/88
;; Since I use special variables to communicate the next methods info,
;; there can be bugs which cause them to leak to the wrong method.
(defmethod foo ((x standard-class))
(bar x))
(defmethod foo ((x class))
(call-next-method))
(defmethod foo ((x t))
t)
(defmethod bar ((x standard-class))
(next-method-p))
(unless (foo (find-class 't))
(do-test-error nil "Method leaked.")))
;;;
;;; some simple tests for initialization protocols
;;; 8/5/88
;;;
(proclaim '(special x-initform-fired y-initform-fired z-initform-fired))
(defclass initialization-test-1 ()
((x :initform (setq x-initform-fired 'x-initform))
(y :initform (setq y-initform-fired 'y-initform))
(z :initform (setq z-initform-fired 'z-initform))))
(defclass initialization-test-2 ()
((x :initform (setq x-initform-fired 'x-initform) :initarg :x)
(y :initform (setq y-initform-fired 'y-initform) :initarg :y)
(z :initform (setq z-initform-fired 'z-initform) :initarg :z)))
(defclass initialization-test-3 ()
((x :initform (setq x-initform-fired 'x-initform) :initarg :x)
(y :initform (setq y-initform-fired 'y-initform) :initarg :y)
(z :initform (setq z-initform-fired 'z-initform) :initarg :z))
(:default-initargs :x 'x-default))
(defclass initalization-test-4 (initialization-test-3)
()
(:default-initargs :z 'z-default))
(defclass initialization-test-5 (initialization-test-4)
()
(:default-initargs :x 'x-default-from-5))
(do-test "shared-initialize with T argument and no initargs"
()
(let (x-initform-fired y-initform-fired z-initform-fired)
(let* ((class (find-class 'initialization-test-1))
(instance (allocate-instance class)))
(shared-initialize instance 't)
(unless x-initform-fired (do-test-error nil "x initform not evaluated"))
(unless y-initform-fired (do-test-error nil "y initform not evaluated"))
(unless z-initform-fired (do-test-error nil "z initform not evaluated"))
(unless (eq (slot-value instance 'x) 'x-initform)
(do-test-error nil "Value of X doesn't match initform"))
(unless (eq (slot-value instance 'y) 'y-initform)
(do-test-error nil "Value of X doesn't match initform"))
(unless (eq (slot-value instance 'z) 'z-initform)
(do-test-error nil "Value of X doesn't match initform"))
)))
(do-test "shared-initialize with T argument and initargs"
()
(let (x-initform-fired y-initform-fired z-initform-fired)
(let* ((class (find-class 'initialization-test-2))
(instance (allocate-instance class)))
(shared-initialize instance 't :y 'y-initarg)
(unless x-initform-fired
(do-test-error nil "x initform not evaluated"))
(unless (not y-initform-fired)
(do-test-error nil "y initform was evaluated"))
(unless z-initform-fired
(do-test-error nil "z initform not evaluated"))
(unless (eq (slot-value instance 'x) 'x-initform)
(do-test-error nil "Value of X doesn't match initform"))
(unless (eq (slot-value instance 'y) 'y-initarg)
(do-test-error nil "Value of X doesn't match initform"))
(unless (eq (slot-value instance 'z) 'z-initform)
(do-test-error nil "Value of X doesn't match initform"))
)))
(do-test "initialization arguments rules test"
((:classes foo bar))
(defclass foo ()
((x :initarg a)))
(defclass bar (foo)
((x :initarg b))
(:default-initargs a 1 b 2))
(unless (and (equal (default-initargs (find-class 'bar) '())
'(b 2 a 1))
(equal (default-initargs (find-class 'bar) '(a 3))
'(a 3 b 2))
(equal (default-initargs (find-class 'bar) '(b 4))
'(b 4 a 1))
(equal (default-initargs (find-class 'bar) '(a 1 a 2))
'(a 1 a 2 b 2)))
(do-test-error nil "default-initargs got wrong value"))
(unless (and (eq (slot-value (make-instance 'bar) 'x) 1)
(eq (slot-value (make-instance 'bar 'a 3) 'x) 3)
(eq (slot-value (make-instance 'bar 'b 4) 'x) 4)
(eq (slot-value (make-instance 'bar 'a 1 'a 2) 'x) 1))
(do-test-error nil "initialization in make-instance failed"))
)
#| testing a pair of lists for equality bogus, '(a b c) <> '(b c a)
(do-test "more tests for initialization arguments rules"
((:classes foo fie bar baz))
(defclass foo ()
((a :initform 'initform-foo-a)
(b :initarg :foo-b)
(c :initform 'initform-foo-c)
(d :initarg :foo-d))
(:default-initargs :foo-b 'initarg-foo-b
:foo-d 'initarg-foo-d))
(defclass fie (foo)
((a :initform 'initform-fie-a)
(b :initarg :fie-b)
(c :initform 'initform-fie-c :allocation :class)
(d :initarg :fie-d :allocation :class))
(:default-initargs :fie-b 'initarg-fie-b
:fie-d 'initarg-fie-d))
(defclass bar (foo)
((a :initform 'initform-bar-a)
(b :initarg :bar-b)
(c :initform 'initform-bar-c)
(d :initarg :bar-d))
(:default-initargs :bar-b 'initarg-bar-b
:bar-d 'initarg-bar-d))
(defclass baz (fie bar)
((a :initform 'initform-baz-a)
(b :initarg :baz-b)
(c :initform 'initform-baz-c)
(d :initarg :baz-d))
(:default-initargs :baz-b 'initarg-baz-b
:baz-d 'initarg-baz-d))
(unless (and (equal (default-initargs (find-class 'foo) ())
'(:foo-d initarg-foo-d
:foo-b initarg-foo-b))
(equal (default-initargs (find-class 'fie) ())
'(:fie-b initarg-fie-b
:fie-d initarg-fie-d
:foo-b initarg-foo-b
:foo-d initarg-foo-d))
(equal (default-initargs (find-class 'bar) ())
'(:bar-b initarg-bar-b
:bar-d initarg-bar-d
:foo-b initarg-foo-b
:foo-d initarg-foo-d))
(equal (default-initargs (find-class 'baz) ())
'(:baz-b initarg-baz-b
:baz-d initarg-baz-d
:fie-b initarg-fie-b
:fie-d initarg-fie-d
:bar-b initarg-bar-b
:bar-d initarg-bar-d
:foo-b initarg-foo-b
:foo-d initarg-foo-d)))
(do-test-error nil "default-initargs got wrong value"))
)
|#
(do-test "initialization protocols"
((:classes foo))
(let ((initform-for-x 'initform-x)
(initform-for-y 'initform-y)
(initform-for-z 'initform-z)
(default-initarg-for-x 'default-initarg-x)
(initarg-supplied-for-z 'initarg-z)
instance-of-foo)
(defclass foo ()
((x :initform initform-for-x :initarg :x)
(y :initform initform-for-y :initarg :y)
(z :initform initform-for-z :initarg :z))
(:default-initargs :x default-initarg-for-x))
(setq instance-of-foo (make-instance 'foo :z initarg-supplied-for-z))
(unless (and (eq (slot-value instance-of-foo 'x)
default-initarg-for-x)
(eq (slot-value instance-of-foo 'y)
initform-for-y)
(eq (slot-value instance-of-foo 'z)
initarg-supplied-for-z))
(do-test-error nil "initialization failed"))
(setq instance-of-foo
(reinitialize-instance (allocate-instance (find-class 'foo))
:z initarg-supplied-for-z))
(unless (and (not (slot-boundp instance-of-foo 'x))
(not (slot-boundp instance-of-foo 'y))
(eq (slot-value instance-of-foo 'z)
initarg-supplied-for-z))
(do-test-error nil "initialization failed")))
)
(do-test "update-instance-for-different-class"
((:classes foo bar))
(let ((initform-for-x 'initform-x)
(initform-for-y 'initform-y)
(default-initarg-for-x 'default-initarg-x)
(initform-for-z 'initform-z)
(initform-for-u 'initform-u)
(initform-for-v 'initform-v)
(default-initarg-for-z 'default-intiarg-z)
(initarg-supplied-for-v 'initarg-v)
instance-of-foo
instance-of-bar)
(defclass foo ()
((x :initform initform-for-x :initarg :x)
(y :initform initform-for-y :initarg :y))
(:default-initargs :x default-initarg-for-x))
(defclass bar ()
((x :initform initform-for-x :initarg :x)
(y :initform initform-for-y :initarg :y)
(z :initform initform-for-z :initarg :z)
(u :initform initform-for-u :initarg :u)
(v :initform initform-for-v :initarg :v))
(:default-initargs :z default-initarg-for-z))
(setq instance-of-foo (make-instance 'foo))
(setq instance-of-bar (allocate-instance (find-class 'bar)))
(update-instance-for-different-class instance-of-foo instance-of-bar
:v initarg-supplied-for-v)
(unless (and (not (slot-boundp instance-of-bar 'x))
(not (slot-boundp instance-of-bar 'y))
(eq (slot-value instance-of-bar 'z) initform-for-z)
(eq (slot-value instance-of-bar 'u) initform-for-u)
(eq (slot-value instance-of-bar 'v) initarg-supplied-for-v))
(do-test-error nil "initialization failed"))))
(do-test "only needed forms should be evaluated in initializing instances"
((:classes foo))
(defclass foo ()
((x :initform (do-test-error nil "x initform was evaluated")
:initarg :x)
(y :initform (do-test-error nil "y initform was evaluated")
:initarg :y)
(z :initform (do-test-error nil "z initform was evaluated")
:initarg :z))
(:default-initargs :y 1
:z (do-test-error nil "z default initarg was evaluated")))
(make-instance 'foo :x 1 :z 1))
;;;
;;; We need to put these class defenitions in top level.
;;;
(defclass class-for-testing-change-class-1 ()
((x :initform 'x :accessor class-1-x)
(y :initform 'y :accessor class-1-y)))
(defclass class-for-testing-change-class-2 ()
((a :initform 'a :accessor class-2-a)
(b :initform 'b :accessor class-2-b)))
(do-test "update-instance-for-different-class/change-class"
()
(defmethod update-instance-for-different-class
((previous class-for-testing-change-class-1)
(current class-for-testing-change-class-2)
&rest initargs)
(declare (ignore initargs))
(setf (class-2-a current) (class-1-x previous))
(setf (class-2-b current) (class-1-y previous)))
(let ((f1 (make-instance 'class-for-testing-change-class-1))
(f2 (make-instance 'class-for-testing-change-class-1)))
(change-class f1 (find-class 'class-for-testing-change-class-2))
(unless (and (eq (class-2-a f1) (class-1-x f2))
(eq (class-2-b f1) (class-1-y f2)))
(do-test-error nil "change class failed")))
)
(cleanup-do-test '((:classes class-for-testing-redefined-class)
(:functions test-x test-y test-a)
(:setf-generic-functions class-x class-y)))
(let (foo)
(defclass class-for-testing-redefined-class ()
((x :initform 'x :accessor test-x)
(y :initform 'y :accessor test-y)))
(setq foo (make-instance 'class-for-testing-redefined-class))
(defclass class-for-testing-redefined-class ()
((a :initform 0 :accessor test-a)
(y :initform 1 :accessor test-y)))
(do-test "update-instance-for-redefined-class/make-instances-obsolete(1)"
()
(unless (and (eq (test-a foo) 0)
(eq (test-y foo) 'y))
(do-test-error nil "default behavior failed"))))
(cleanup-do-test '((:classes x-y-pos)
(:functions pos-x pos-y pos-rho pos-theta)
(:setf-generic-functions pos-x pos-y pos-rho pos-theta)))
(let (old-pos new-pos)
(defclass x-y-pos ()
((x :initform 3 :accessor pos-x)
(y :initform 4 :accessor pos-y)))
(setq old-pos (make-instance 'x-y-pos))
(defclass x-y-pos ()
((rho :initform 0 :accessor pos-rho)
(theta :initform 0 :accessor pos-theta)))
(do-test "update-instance-for-redefined-class/make-instances-obsolete(2)"
()
(defmethod update-instance-for-redefined-class :before
((pos x-y-pos) added deleted plist &key)
;; Transform the x-y coordinates to polar coordinates
;; and store into the new slots
(let ((x (getf plist 'x))
(y (getf plist 'y)))
(setf (pos-rho pos) (sqrt (+ (* x x) (* y y)))
(pos-theta pos) (atan y x))))
(defmethod pos-x ((pos x-y-pos))
(with-slots (rho theta) pos (* rho (cos theta))))
(defmethod (setf pos-x) (new-x (pos x-y-pos))
(with-slots (rho theta) pos
(let ((y (pos-y pos)))
(setq rho (sqrt (+ (* new-x new-x) (* y y)))
theta (atan y new-x))
new-x)))
(defmethod pos-y ((pos x-y-pos))
(with-slots (rho theta) pos (* rho (sin theta))))
(defmethod (setf pos-y) (new-y (pos x-y-pos))
(with-slots (rho theta)
(let ((x (pos-x pos)))
(setq rho (sqrt (+ (* x x) (* new-y new-y)))
theta (atan new-y x))
new-y)))
(unless (and (equalp 5 (pos-rho old-pos))
(equalp (* 5 (cos (atan 4 3))) (pos-x old-pos))
(equalp (* 5 (sin (atan 4 3))) (pos-y old-pos)))
(do-test-error nil "specialized behaivior failed"))
))
(cleanup-do-test '((:classes class-for-testing-redefined-class
test-obsolete-class)
(:functions test-x test-y test-a)
(:setf-generic-functions class-x class-y)))
(defclass test-obsolete-class (standard-class) ())
(defmethod check-super-metaclass-compatibility ((x test-obsolete-class)
(y standard-class))
't)
(let ((foo 'nil)
bar)
(defmethod make-instances-obsolete ((x test-obsolete-class))
(setq foo 'called)
(call-next-method))
(defclass class-for-testing-redefined-class ()
((x :initform 'x :accessor test-x)
(y :initform 'y :accessor test-y))
(:metaclass test-obsolete-class))
(setq bar (make-instance 'class-for-testing-redefined-class))
(defclass class-for-testing-redefined-class ()
((a :initform 0 :accessor test-a)
(y :initform 1 :accessor test-y)))
(do-test "update-instance-for-redefined-class/make-instances-obsolete(3)"
()
(unless (and (eq (test-a bar) 0)
(eq (test-y bar) '1)
(eq foo 'called))
(do-test-error nil "imcompatible class change failed"))))
(cleanup-do-test '((:classes class-for-testing-redefined-class)
(:functions test-x test-y test-a)
(:setf-generic-functions class-x class-y)))
(let (foo)
(defclass class-for-testing-redefined-class ()
((x :initform 'x :accessor test-x)
(y :initform 'y :accessor test-y)))
(setq foo (make-instance 'class-for-testing-redefined-class))
(make-instances-obsolete 'class-for-testing-redefined-class)
(do-test "update-instance-for-redefined-class/make-instances-obsolete(4)"
()
(unless (and (eq (test-x foo) 'x)
(eq (test-y foo) 'y))
(do-test-error nil "call make-instances-obsolete by hand failed"))))
(do-test "slot-mumble functions"
((:variables foo1 bar1)
(:classes foo bar))
(defclass foo-sm ()
((x :initform 'x :allocation :class)
(y :initform 'y)
(z :allocation :class)
(u)))
(defclass bar-sm ()
((x :initform 'x :allocation :class)
(y :initform 'y)
(z :allocation :class)
(u))
(:metaclass funcallable-standard-class))
(defmethod slot-missing ((class standard-class)
(instance foo-sm)
slot-name operation &optional new-value)
(list* class instance slot-name operation new-value))
(defmethod slot-missing ((class standard-class)
(instance bar-sm)
slot-name operation &optional new-value)
(list* class instance slot-name operation new-value))
(defmethod slot-unbound ((class standard-class)
(instance foo-sm)
slot-name)
(list class instance slot-name))
(defmethod slot-unbound ((class funcallable-standard-class)
(instance bar-sm)
slot-name)
(list class instance slot-name))
(setq foo1 (make-instance 'foo-sm))
(setq bar1 (make-instance 'bar-sm))
(flet ((test1 (instance)
(and (eq (slot-value instance 'x) 'x)
(eq (slot-value instance 'y) 'y)
(equal (slot-value instance 'z)
(list (class-of instance) instance 'z))
(equal (slot-value instance 'u)
(list (class-of instance) instance 'u))
(slot-boundp instance 'x)
(slot-boundp instance 'y)
(not (slot-boundp instance 'z))
(not (slot-boundp instance 'u))))
(test2 (instance)
(and (not (slot-boundp instance 'x))
(not (slot-boundp instance 'y))
(slot-boundp instance 'z)
(slot-boundp instance 'u)
(equal (slot-value instance 'x)
(list (class-of instance) instance 'x))
(equal (slot-value instance 'y)
(list (class-of instance) instance 'y))
(eq (slot-value instance 'z) 'z)
(eq (slot-value instance 'u) 'u)))
(test3 (instance)
(and (slot-exists-p instance 'x)
(slot-exists-p instance 'y)))
(test4 (instance)
(and (equal (slot-value instance 'a)
(list (class-of instance)
instance
'a
'slot-value))
(equal (setf (slot-value instance 'a) 'b)
(list* (class-of instance)
instance
'a
'setf
'b))
(equal (slot-boundp instance 'a)
(list (class-of instance)
instance
'a
'slot-boundp))
(equal (slot-makunbound instance 'a)
(list (class-of instance)
instance
'a
'slot-makunbound)))))
(unless (and (test1 foo1)
(test1 bar1))
(do-test-error nil "slot functions test1 failed"))
(slot-makunbound foo1 'x)
(slot-makunbound foo1 'y)
(setf (slot-value foo1 'z) 'z)
(setf (slot-value foo1 'u) 'u)
(slot-makunbound bar1 'x)
(slot-makunbound bar1 'y)
(setf (slot-value bar1 'z) 'z)
(setf (slot-value bar1 'u) 'u)
(unless (and (test2 foo1)
(test2 bar1))
(do-test-error nil "slot functions test2 failed"))
(unless (and (test3 foo1)
(test3 bar1))
(do-test-error nil "slot functions test3 failed"))
(unless (and (test4 foo1)
(test4 bar1))
(do-test-error nil "slot function test4 failed"))
))
(cleanup-do-test '((:classes foo-sm bar-sm)
(:functions foo-x foo-y bar-x bar-y)))
(defclass foo ()
((x :initform 'x :allocation :class :reader foo-x)
(y :initform 'y :reader foo-y)))
(defclass bar ()
((x :allocation :class :reader bar-x)
(y :reader bar-y)))
(do-test "slot-value/slot-unbound for pv optimization case and :reader method"
((:functions get-foo-x get-foo-y get-x-1 get-y-1
get-bar-x get-bar-y get-x-2 get-y-2)
(:variables foo1 bar1))
(defmethod get-foo-x ((foo1 foo))
(slot-value foo1 'x))
(defmethod get-foo-y ((foo1 foo))
(slot-value foo1 'y))
(defun get-x-1 (foo1)
(slot-value foo1 'x))
(defun get-y-1 (foo1)
(slot-value foo1 'y))
(defmethod slot-unbound ((class standard-class) (instance foo) slot-name)
(list class instance slot-name))
(setq foo1 (make-instance 'foo))
(unless (and (eq (get-foo-x foo1) 'x)
(eq (get-foo-y foo1) 'y)
(eq (get-x-1 foo1) 'x)
(eq (get-y-1 foo1) 'y)
(eq (foo-x foo1) 'x)
(eq (foo-y foo1) 'y))
(do-test-error nil "slot-value failed"))
(unless (and (eq (slot-makunbound foo1 'x) foo1)
(eq (slot-makunbound foo1 'y) foo1))
(do-test-error nil "slot-makunbound returns wrong value"))
(unless (and (equal (get-foo-x foo1)
(list (find-class 'foo) foo1 'x))
(equal (get-foo-y foo1)
(list (find-class 'foo) foo1 'y))
(equal (get-x-1 foo1)
(list (find-class 'foo) foo1 'x))
(equal (get-y-1 foo1)
(list (find-class 'foo) foo1 'y))
(equal (foo-x foo1)
(list (find-class 'foo) foo1 'x))
(equal (foo-y foo1)
(list (find-class 'foo) foo1 'y)))
(do-test-error nil "slot-value/slot-unbound failed"))
(defmethod get-bar-x ((bar1 bar))
(slot-value bar1 'x))
(defmethod get-bar-y ((bar1 bar))
(slot-value bar1 'y))
(defun get-x-2 (bar1)
(slot-value bar1 'x))
(defun get-y-2 (bar1)
(slot-value bar1 'y))
(defmethod slot-unbound ((class standard-class) (instance bar) slot-name)
(list class instance slot-name))
(setq bar1 (make-instance 'bar))
(unless (and (equal (get-bar-x bar1)
(list (find-class 'bar) bar1 'x))
(equal (get-bar-y bar1)
(list (find-class 'bar) bar1 'y))
(equal (get-x-2 bar1)
(list (find-class 'bar) bar1 'x))
(equal (get-y-2 bar1)
(list (find-class 'bar) bar1 'y))
(equal (bar-x bar1)
(list (find-class 'bar) bar1 'x))
(equal (bar-y bar1)
(list (find-class 'bar) bar1 'y)))
(do-test-error nil "slot-value/slot-unbound failed")))
(do-test "defmethod/call-next-method/&aux variable"
((:variables foo1 bar1)
(:classes foo bar)
(:functions test1 test2 test3))
(defclass foo ()
((x :initform 0)
(y :initform 1)))
(defclass bar (foo) ())
(defmethod test1 ((foo1 foo) &aux aux-arg)
(setq aux-arg (list foo1)))
(defmethod test1 ((bar1 bar) &aux aux-arg)
(setq aux-arg (list (list bar1)))
(call-next-method)
aux-arg)
(setq foo1 (make-instance 'foo))
(setq bar1 (make-instance 'bar))
(unless (and (equal (test1 foo1) (list foo1))
(equal (test1 bar1) (list (list bar1))))
(do-test-error nil "defmethod with call-next-method and &aux failed")))
;;;
;;; defconstructor tests
;;;
(format t
"~%Testing defconstructor [methods, default/initform, slot-filling]")
(defun check-slots (object &rest names-and-values)
(doplist (name value) names-and-values
(unless (if (eq value :unbound)
(not (slot-boundp object name))
(and (slot-boundp object name)
(eq (slot-value object name) value)))
(return-from check-slots nil)))
't)
;;;
;;; [methods, default/initform, slot-filling]
;;; methods: [nil, :after, t]
;;; default/initform: [nil, :constant, t]
;;; slot-filling: [:instance, :class]
;;;
;;; supplied: [nil, :constant, t]
(cleanup-do-test '((:classes foo1 foo2 foo3 foo4
foo5 foo6 foo7 foo8
foo9 foo10 foo11 foo12)
(:variables *a-initform* *b-initform* *c-initform*
*a-default* *b-default* *c-default*
*a-supplied* *b-supplied* *c-supplied*)
(:functions foo1-test1 foo1-test2 foo1-test3
foo2-test1 foo2-test2 foo2-test3
foo3-test1 foo3-test2 foo3-test3
foo4-test1 foo4-test2 foo4-test3
foo5-test1 foo5-test2 foo5-test3
foo6-test1 foo6-test2 foo6-test3
foo7-test1 foo7-test2 foo7-test3
foo8-test1 foo8-test2 foo8-test3
foo9-test1 foo9-test2 foo9-test3
foo10-test1 foo10-test2 foo10-test3
foo11-test1 foo11-test2 foo11-test3
foo12-test1 foo12-test2 foo12-test3)))
(defvar *a-initform* 'a-initform)
(defvar *b-initform* 'b-initform)
(defvar *c-initform* 'c-initform)
(defvar *a-default* 'a-default)
(defvar *b-default* 'b-default)
(defvar *c-default* 'c-default)
(defvar *a-supplied* 'a-supplied)
(defvar *b-supplied* 'b-supplied)
(defvar *c-supplied* 'c-supplied)
;;;
;;; foo1
;;; [methods, default/initform, slot-filing]
;;; (t, t, :class)
(defclass foo1 ()
((a :initarg :a :initform *a-initform*)
(b :initarg :b :initform *b-initform*)
(c :initarg :c :allocation :class :initform *c-initform*))
(:default-initargs :b *b-default* :c *c-default*))
(defmethod *initialize-instance :before ((instance foo1) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (t, t, :class) (1)"
((:functions foo1-test1 foo1-test2 foo1-test3))
(defconstructor foo1-test1 foo1 ())
(defconstructor foo1-test2 foo1 () :a 1 :b 2 :c 3)
(defconstructor foo1-test3 foo1 (a b c) :a a :b b :c c)
(dotimes (i 2) ;Do it twice to be sure that
;the constructor works more
;than just the first time.
(unless (check-slots (foo1-test1)
'a *a-initform*
'b *b-default*
'c *c-default*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo1-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo1-test3 *a-supplied* *b-supplied* *c-supplied*)
'a *a-supplied*
'b *b-supplied*
'c *c-supplied*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo2
;;; [methods, default/initform, slot-filling]
;;; (t, t, :class)
(defclass foo2 ()
((a :initform *a-initform* :initarg :a)
(b :initform *b-initform* :initarg :b)
(c :allocation :class :initform *c-initform* :initarg :c))
(:default-initargs :b *b-default*))
(defmethod *initialize-instance :before ((instance foo2) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (t, t, :class) (2)"
((:functions foo2-test1 foo2-test2 foo2-test3))
(defconstructor foo2-test1 foo2 ())
(defconstructor foo2-test2 foo2 () :a 1 :b 2 :c 3)
(defconstructor foo2-test3 foo2 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (foo2-test1) 'a *a-initform*
'b *b-default*
'c *c-initform*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo2-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo2-test3 *a-supplied* *b-supplied* *c-supplied*)
'a *a-supplied*
'b *b-supplied*
'c *c-supplied*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo3
;;; [methods, default/initform, slot-filling]
;;; (t, t, :instance)
(defclass foo3 ()
((a :initform *a-initform* :initarg :a)
(b :initform *b-initform* :initarg :b)
(c :allocation :class :initform *c-initform*))
(:default-initargs :b *b-default*))
(defmethod *initialize-instance :before ((instance foo3) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (t, t, :instance) (1)"
((:functions foo3-test1 foo3-test2 foo3-test3))
(defconstructor foo3-test1 foo3 ())
(defconstructor foo3-test2 foo3 () :a 1 :b 2)
(defconstructor foo3-test3 foo3 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (foo3-test1) 'a *a-initform*
'b *b-default*
'c *c-initform*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo3-test2) 'a '1 'b '2 'c *c-initform*)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo3-test3 *a-supplied* *b-supplied*)
'a *a-supplied*
'b *b-supplied*
'c *c-initform*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo4
;;; [methods, default/initform, slot-filling]
;;; (t, t, :instance)
(defclass foo4 ()
((a :initform *a-initform* :initarg :a)
(b :initform *b-initform* :initarg :b)
(c :allocation :class))
(:default-initargs :b *b-default*))
(defmethod *initialize-instance :before ((instance foo4) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (t, t, :instance) (2)"
((:functions foo4-test1 foo4-test2 foo4-test3))
(defconstructor foo4-test1 foo4 ())
(defconstructor foo4-test2 foo4 () :a 1 :b 2)
(defconstructor foo4-test3 foo4 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (foo4-test1) 'a *a-initform*
'b *b-default*
'c :unbound)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo4-test2) 'a '1 'b '2 'c :unbound)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo4-test3 *a-supplied* *b-supplied*)
'a *a-supplied*
'b *b-supplied*
'c :unbound)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo5
;;; [methods, default/initform, slot-filling]
;;; (:after, t, :class)
(defclass foo5 ()
((a :initarg :a :initform *a-initform*)
(b :initarg :b :initform *b-initform*)
(c :initarg :c :allocation :class :initform *c-initform*))
(:default-initargs :b *b-default* :c *c-default*))
(defmethod *initialize-instance :after ((instance foo5) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (:after, t, :class) (1)"
((:functions foo5-test1 foo5-test2 foo5-test3))
(defconstructor foo5-test1 foo5 ())
(defconstructor foo5-test2 foo5 () :a 1 :b 2 :c 3)
(defconstructor foo5-test3 foo5 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (foo5-test1) 'a *a-initform*
'b *b-default*
'c *c-default*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo5-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo5-test3 *a-supplied* *b-supplied* *c-supplied*)
'a *a-supplied*
'b *b-supplied*
'c *c-supplied*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo6
;;; [methods, default/initform, slot-filling]
;;; (:after, t, :class)
(defclass foo6 ()
((a :initform *a-initform* :initarg :a)
(b :initform *b-initform* :initarg :b)
(c :allocation :class :initform *c-initform* :initarg :c))
(:default-initargs :b *b-default*))
(defmethod *initialize-instance :after ((instance foo6) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (:after, t, :class) (2)"
((:functions foo6-test1 foo6-test2 foo6-test3))
(defconstructor foo6-test1 foo6 ())
(defconstructor foo6-test2 foo6 () :a 1 :b 2 :c 3)
(defconstructor foo6-test3 foo6 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (foo6-test1) 'a *a-initform*
'b *b-default*
'c *c-initform*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo6-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo6-test3 *a-supplied* *b-supplied* *c-supplied*)
'a *a-supplied*
'b *b-supplied*
'c *c-supplied*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo7
;;; [methods, default/initform, slot-filling]
;;; (:after, t, :instance)
(defclass foo7 ()
((a :initform *a-initform* :initarg :a)
(b :initform *b-initform* :initarg :b)
(c :allocation :class :initform *c-initform*))
(:default-initargs :b *b-default*))
(defmethod *initialize-instance :after ((instance foo7) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (:after, t, :instance) (1)"
((:functions foo7-test1 foo7-test2 foo7-test3))
(defconstructor foo7-test1 foo7 ())
(defconstructor foo7-test2 foo7 () :a 1 :b 2)
(defconstructor foo7-test3 foo7 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (foo7-test1) 'a *a-initform*
'b *b-default*
'c *c-initform*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo7-test2) 'a '1 'b '2 'c *c-initform*)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo7-test3 *a-supplied* *b-supplied*)
'a *a-supplied*
'b *b-supplied*
'c *c-initform*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo8
;;; [methods, default/initform, slot-filling]
;;; (:after, t, :instance)
(defclass foo8 ()
((a :initform *a-initform* :initarg :a)
(b :initform *b-initform* :initarg :b)
(c :allocation :class))
(:default-initargs :b *b-default*))
(defmethod *initialize-instance :after ((instance foo8) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (:after, t, :instance) (2)"
((:functions foo8-test1 foo8-test2 foo8-test3))
(defconstructor foo8-test1 foo8 ())
(defconstructor foo8-test2 foo8 () :a 1 :b 2)
(defconstructor foo8-test3 foo8 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (foo8-test1) 'a *a-initform*
'b *b-default*
'c :unbound)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo8-test2) 'a '1 'b '2 'c :unbound)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo8-test3 *a-supplied* *b-supplied*)
'a *a-supplied*
'b *b-supplied*
'c :unbound)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo9
;;; [methods, default/initform, slot-filling]
;;; (nil, t, :class)
(defclass foo9 ()
((a :initarg :a :initform *a-initform*)
(b :initarg :b :initform *b-initform*)
(c :initarg :c :allocation :class :initform *c-initform*))
(:default-initargs :b *b-default* :c *c-default*))
(do-test "defconstructor (nil, t, :class) (1)"
((:functions foo9-test1 foo9-test2 foo9-test3))
(defconstructor foo9-test1 foo9 ())
(defconstructor foo9-test2 foo9 () :a 1 :b 2 :c 3)
(defconstructor foo9-test3 foo9 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (foo9-test1) 'a *a-initform*
'b *b-default*
'c *c-default*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo9-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo9-test3 *a-supplied* *b-supplied* *c-supplied*)
'a *a-supplied*
'b *b-supplied*
'c *c-supplied*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo10
;;; [methods, default/initform, slot-filling]
;;; (nil, t, :class)
(defclass foo10 ()
((a :initform *a-initform* :initarg :a)
(b :initform *b-initform* :initarg :b)
(c :allocation :class :initform *c-initform* :initarg :c))
(:default-initargs :b *b-default*))
(do-test "defconstructor (nil, t, :class) (2)"
((:functions foo10-test1 foo10-test2 foo10-test3))
(defconstructor foo10-test1 foo10 ())
(defconstructor foo10-test2 foo10 () :a 1 :b 2 :c 3)
(defconstructor foo10-test3 foo10 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (foo10-test1) 'a *a-initform*
'b *b-default*
'c *c-initform*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo10-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo10-test3 *a-supplied* *b-supplied* *c-supplied*)
'a *a-supplied*
'b *b-supplied*
'c *c-supplied*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo11
;;; [methods, default/initform, slot-filling]
;;; (nil, t, :instance)
(defclass foo11 ()
((a :initform *a-initform* :initarg :a)
(b :initform *b-initform* :initarg :b)
(c :allocation :class :initform *c-initform*))
(:default-initargs :b *b-default*))
(do-test "defconstructor (nil, t, :instance) (1)"
((:functions foo11-test1 foo11-test2 foo11-test3))
(defconstructor foo11-test1 foo11 ())
(defconstructor foo11-test2 foo11 () :a 1 :b 2)
(defconstructor foo11-test3 foo11 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (foo11-test1) 'a *a-initform*
'b *b-default*
'c *c-initform*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo11-test2) 'a '1 'b '2 'c *c-initform*)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo11-test3 *a-supplied* *b-supplied*)
'a *a-supplied*
'b *b-supplied*
'c *c-initform*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; foo12
;;; [methods, default/initform, slot-filling]
;;; (nil, t, :instance)
(defclass foo12 ()
((a :initform *a-initform* :initarg :a)
(b :initform *b-initform* :initarg :b)
(c :allocation :class))
(:default-initargs :b *b-default*))
(defmethod *initialize-instance :after ((instance foo12) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (nil, t, :instance) (2)"
((:functions foo12-test1 foo12-test2 foo12-test3))
(defconstructor foo12-test1 foo12 ())
(defconstructor foo12-test2 foo12 () :a 1 :b 2)
(defconstructor foo12-test3 foo12 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (foo12-test1) 'a *a-initform*
'b *b-default*
'c :unbound)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo12-test2) 'a '1 'b '2 'c :unbound)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (foo12-test3 *a-supplied* *b-supplied*)
'a *a-supplied*
'b *b-supplied*
'c :unbound)
(do-test-error nil "non constant initargs failed (~D time)" i))))
(cleanup-do-test '((:classes bar1 bar2 bar3 bar4
bar5 bar6 bar7 bar8
bar9 bar10 bar11 bar12)
(:functions bar1-test1 bar1-test2 bar1-test3
bar2-test1 bar2-test2 bar2-test3
bar3-test1 bar3-test2 bar3-test3
bar4-test1 bar4-test2 bar4-test3
bar5-test1 bar5-test2 bar5-test3
bar6-test1 bar6-test2 bar6-test3
bar7-test1 bar7-test2 bar7-test3
bar8-test1 bar8-test2 bar8-test3
bar9-test1 bar9-test2 bar9-test3
bar10-test1 bar10-test2 bar10-test3
bar11-test1 bar11-test2 bar11-test3
bar12-test1 bar12-test2 bar12-test3)))
;;;
;;; bar1
;;; [methods, default/initform, slot-filling]
;;; (t, :constant, :class)
(defclass bar1 ()
((a :initarg :a :initform 1)
(b :initarg :b :initform 2)
(c :initarg :c :allocation :class :initform 3))
(:default-initargs :b 5 :c 6))
(defmethod *initialize-instance :before ((instance bar1) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (t, :constant, :class) (1)"
((:functions bar1-test1 bar1-test2 bar1-test3))
(defconstructor bar1-test1 bar1 ())
(defconstructor bar1-test2 bar1 () :a 1 :b 2 :c 3)
(defconstructor bar1-test3 bar1 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (bar1-test1) 'a '1 'b '5 'c '6)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar1-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar1-test3 7 8 9) 'a '7 'b '8 'c '9)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar2
;;; [methods, default/initform, slot-filling]
;;; (t, :constant, :class)
(defclass bar2 ()
((a :initform 1 :initarg :a)
(b :initform 2 :initarg :b)
(c :allocation :class :initform 3 :initarg :c))
(:default-initargs :b 5))
(defmethod *initialize-instance :before ((instance bar2) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (t, :constant, :class) (2)"
((:functions bar2-test1 bar2-test2 bar2-test3))
(defconstructor bar2-test1 bar2 ())
(defconstructor bar2-test2 bar2 () :a 1 :b 2 :c 3)
(defconstructor bar2-test3 bar2 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (bar2-test1) 'a '1 'b '5 'c '3)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar2-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar2-test3 7 8 9) 'a '7 'b '8 'c '9)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar3
;;; [methods, default/initform, slot-filling]
;;; (t, :constant, :instance)
(defclass bar3 ()
((a :initform 1 :initarg :a)
(b :initform 2 :initarg :b)
(c :allocation :class :initform 3))
(:default-initargs :b 5))
(defmethod *initialize-instance :before ((instance bar3) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (t, :constant, :instance) (1)"
((:functions bar3-test1 bar3-test2 bar3-test3))
(defconstructor bar3-test1 bar3 ())
(defconstructor bar3-test2 bar3 () :a 1 :b 2)
(defconstructor bar3-test3 bar3 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (bar3-test1) 'a '1 'b '5 'c '3)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar3-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar3-test3 7 8) 'a '7 'b '8 'c '3)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar4
;;; [methods, default/initform, slot-filling]
;;; (t, :constant, :instance)
(defclass bar4 ()
((a :initform 1 :initarg :a)
(b :initform 2 :initarg :b)
(c :allocation :class))
(:default-initargs :b 5))
(defmethod *initialize-instance :before ((instance bar4) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (t, :constant, :instance) (2)"
((:functions bar4-test1 bar4-test2 bar4-test3))
(defconstructor bar4-test1 bar4 ())
(defconstructor bar4-test2 bar4 () :a 1 :b 2)
(defconstructor bar4-test3 bar4 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (bar4-test1) 'a '1 'b '5 'c :unbound)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar4-test2) 'a '1 'b '2 'c :unbound)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar4-test3 7 8) 'a '7 'b '8 'c :unbound)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar5
;;; [methods, default/initform, slot-filling]
;;; (:after, :constant, :class)
(defclass bar5 ()
((a :initarg :a :initform 1)
(b :initarg :b :initform 2)
(c :initarg :c :allocation :class :initform 3))
(:default-initargs :b 5 :c 6))
(defmethod *initialize-instance :after ((instance bar5) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (:after, :constant, :class) (1)"
((:functions bar5-test1 bar5-test2 bar5-test3))
(defconstructor bar5-test1 bar5 ())
(defconstructor bar5-test2 bar5 () :a 1 :b 2 :c 3)
(defconstructor bar5-test3 bar5 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (bar5-test1) 'a '1 'b '5 'c '6)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar5-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar5-test3 7 8 9) 'a '7 'b '8 'c '9)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar6
;;; [methods, default/initform, slot-filling]
;;; (:after, :constant, :class)
(defclass bar6 ()
((a :initform 1 :initarg :a)
(b :initform 2 :initarg :b)
(c :allocation :class :initform 3 :initarg :c))
(:default-initargs :b 5))
(defmethod *initialize-instance :after ((instance bar6) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (:after, :constant, :class) (2)"
((:functions bar6-test1 bar6-test2 bar6-test3))
(defconstructor bar6-test1 bar6 ())
(defconstructor bar6-test2 bar6 () :a 1 :b 2 :c 3)
(defconstructor bar6-test3 bar6 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (bar6-test1) 'a '1 'b '5 'c '3)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar6-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar6-test3 7 8 9) 'a '7 'b '8 'c '9)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar7
;;; [methods, default/initform, slot-filling]
;;; (:after, :constant, :instance)
(defclass bar7 ()
((a :initform 1 :initarg :a)
(b :initform 2 :initarg :b)
(c :allocation :class :initform 3))
(:default-initargs :b 5))
(defmethod *initialize-instance :after ((instance bar7) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (:after, :constant, :instance) (1)"
((:functions bar7-test1 bar7-test2 bar7-test3))
(defconstructor bar7-test1 bar7 ())
(defconstructor bar7-test2 bar7 () :a 1 :b 2)
(defconstructor bar7-test3 bar7 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (bar7-test1) 'a '1 'b '5 'c '3)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar7-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar7-test3 7 8) 'a '7 'b '8 'c '3)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar8
;;; [methods, default/initform, slot-filling]
;;; (:after, :constant, :instance)
(defclass bar8 ()
((a :initform 1 :initarg :a)
(b :initform 2 :initarg :b)
(c :allocation :class))
(:default-initargs :b 5))
(defmethod *initialize-instance :after ((instance bar8) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (:after, :constant, :instance) (2)"
((:functions bar8-test1 bar8-test2 bar8-test3))
(defconstructor bar8-test1 bar8 ())
(defconstructor bar8-test2 bar8 () :a 1 :b 2)
(defconstructor bar8-test3 bar8 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (bar8-test1) 'a '1 'b '5 'c :unbound)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar8-test2) 'a '1 'b '2 'c :unbound)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar8-test3 7 8) 'a '7 'b '8 'c :unbound)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar9
;;; [methods, default/initform, slot-filling]
;;; (nil, :constant, :class)
(defclass bar9 ()
((a :initarg :a :initform 1)
(b :initarg :b :initform 2)
(c :initarg :c :allocation :class :initform 3))
(:default-initargs :b 5 :c 6))
(do-test "defconstructor (nil, :constant, :class) (1)"
((:functions bar9-test1 bar9-test2 bar9-test3))
(defconstructor bar9-test1 bar9 ())
(defconstructor bar9-test2 bar9 () :a 1 :b 2 :c 3)
(defconstructor bar9-test3 bar9 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (bar9-test1) 'a '1 'b '5 'c '6)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar9-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar9-test3 7 8 9) 'a '7 'b '8 'c '9)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar10
;;; [methods, default/initform, slot-filling]
;;; (nil, :constant, :class)
(defclass bar10 ()
((a :initform 1 :initarg :a)
(b :initform 2 :initarg :b)
(c :allocation :class :initform 3 :initarg :c))
(:default-initargs :b 5))
(do-test "defconstructor (nil, :constant, :class) (2)"
((:functions bar10-test1 bar10-test2 bar10-test3))
(defconstructor bar10-test1 bar10 ())
(defconstructor bar10-test2 bar10 () :a 1 :b 2 :c 3)
(defconstructor bar10-test3 bar10 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (bar10-test1) 'a '1 'b '5 'c '3)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar10-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar10-test3 7 8 9) 'a '7 'b '8 'c '9)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar11
;;; [methods, default/initform, slot-filling]
;;; (nil, :constant, :instance)
(defclass bar11 ()
((a :initform 1 :initarg :a)
(b :initform 2 :initarg :b)
(c :allocation :class :initform 3))
(:default-initargs :b 5))
(do-test "defconstructor (nil, :constant, :instance) (1)"
((:functions bar11-test1 bar11-test2 bar11-test3))
(defconstructor bar11-test1 bar11 ())
(defconstructor bar11-test2 bar11 () :a 1 :b 2)
(defconstructor bar11-test3 bar11 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (bar11-test1) 'a '1 'b '5 'c '3)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar11-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar11-test3 7 8) 'a '7 'b '8 'c '3)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; bar12
;;; [methods, default/initform, slot-filling]
;;; (nil, :constant, :instance)
(defclass bar12 ()
((a :initform 1 :initarg :a)
(b :initform 2 :initarg :b)
(c :allocation :class))
(:default-initargs :b 5))
(defmethod *initialize-instance :after ((instance bar12) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (nil, :constant, :instance) (2)"
((:functions bar12-test1 bar12-test2 bar12-test3))
(defconstructor bar12-test1 bar12 ())
(defconstructor bar12-test2 bar12 () :a 1 :b 2)
(defconstructor bar12-test3 bar12 (a b) :a a :b b)
(dotimes (i 2)
(unless (check-slots (bar12-test1) 'a '1 'b '5 'c :unbound)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar12-test2) 'a '1 'b '2 'c :unbound)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (bar12-test3 7 8) 'a '7 'b '8 'c :unbound)
(do-test-error nil "non constant initargs failed (~D time)" i))))
(cleanup-do-test '((:classes baz1 baz2 baz3)
(:functions baz1-test1 baz1-test2 baz1-test3
baz2-test1 baz2-test2 baz2-test3
baz3-test1 baz3-test2 baz3-test3)))
;;;
;;; baz1
;;; [methods, default/initform, slot-filling]
;;; (t, nil, :class)
(defclass baz1 ()
((a :initarg :a)
(b :initarg :b)
(c :initarg :c :allocation :class)))
(defmethod *initialize-instance :before ((instance baz1) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (t, nil, :class) (1)"
((:functions baz1-test1 baz1-test2 baz1-test3))
(defconstructor baz1-test1 baz1 ())
(defconstructor baz1-test2 baz1 () :a 1 :b 2 :c 3)
(defconstructor baz1-test3 baz1 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (baz1-test1) 'a :unbound 'b :unbound 'c :unbound)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (baz1-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (baz1-test3 7 8 9) 'a '7 'b '8 'c '9)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; baz2
;;; [methods, default/initform, slot-filling]
;;; (:after, nil, :class)
(defclass baz2 ()
((a :initarg :a)
(b :initarg :b)
(c :initarg :c :allocation :class)))
(defmethod *initialize-instance :after ((instance baz2) &rest ignore)
(declare (ignore ignore))
())
(do-test "defconstructor (:after, nil, :class) (1)"
((:functions baz2-test1 baz2-test2 baz2-test3))
(defconstructor baz2-test1 baz2 ())
(defconstructor baz2-test2 baz2 () :a 1 :b 2 :c 3)
(defconstructor baz2-test3 baz2 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (baz2-test1) 'a :unbound 'b :unbound 'c :unbound)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (baz2-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (baz2-test3 7 8 9) 'a '7 'b '8 'c '9)
(do-test-error nil "non constant initargs failed (~D time)" i))))
;;;
;;; baz3
;;; [methods, default/initform, slot-filling]
;;; (nil, nil, :class)
(defclass baz3 ()
((a :initarg :a)
(b :initarg :b)
(c :initarg :c :allocation :class)))
(do-test "defconstructor (nil, nil, :class) (1)"
((:functions baz3-test1 baz3-test2 baz3-test3))
(defconstructor baz3-test1 baz3 ())
(defconstructor baz3-test2 baz3 () :a 1 :b 2 :c 3)
(defconstructor baz3-test3 baz3 (a b c) :a a
:b b
:c c)
(dotimes (i 2)
(unless (check-slots (baz3-test1) 'a :unbound 'b :unbound 'c :unbound)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (baz3-test2) 'a '1 'b '2 'c '3)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (baz3-test3 7 8 9) 'a '7 'b '8 'c '9)
(do-test-error nil "non constant initargs failed (~D time)" i))))
(cleanup-do-test '((:classes foo bar)
(:functions make-bar-1 make-bar-2 make-bar-3)))
(setq *foo-a* 'foo-a
*foo-b* 'foo-b
*foo-c* 'foo-c
*bar-a* 'bar-a
*bar-b* 'bar-b
*bar-c* 'bar-c
*supplied-a* 'a
*supplied-b* 'b
*supplied-c* 'c)
(defclass foo ()
((a :initarg :a)
(b :initarg :b)
(c :initarg :c))
(:default-initargs :a *foo-a* :b *foo-b* :c *foo-c*))
(defclass bar (foo)
((c :initarg :a))
(:default-initargs :a *bar-a* :c *bar-c*))
(defconstructor make-bar-1 bar ())
(defconstructor make-bar-2 bar () :a 1 :b 2 :c 3)
(defconstructor make-bar-3 bar (a b c) :a a :b b :c c)
(do-test "defconstructor/shadowing"
()
(dotimes (i 2)
(unless (check-slots (make-bar-1) 'a *bar-a* 'b *foo-b* 'c *bar-a*)
(do-test-error nil "no initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (make-bar-2) 'a '1 'b '2 'c '1)
(do-test-error nil "constant initargs failed (~D time)" i)))
(dotimes (i 2)
(unless (check-slots (make-bar-3 *supplied-a* *supplied-b* *supplied-c*)
'a *supplied-a* 'b *supplied-b* 'c *supplied-a*)
(do-test-error nil "non constant initargs failed (~D time)" i))))
(do-test "defconstructor/only needed forms should be evaluated"
((:classes foo)
(:functions make-foo-1 make-foo-2))
(defclass foo ()
((x :initform (do-test-error nil "foo x initform was evaluated")
:initarg :x)
(y :initform (do-test-error nil "foo y initform was evaluated")
:initarg :y)
(z :initform (do-test-error nil "foo z initform was evaluated")
:initarg :z))
(:default-initargs :y 2
:z (do-test-error
nil
"z default was evaluated")))
(defconstructor make-foo-1 foo () :x 1 :z 3)
(defconstructor make-foo-2 foo (x z) :x x :z z)
(make-foo-1)
(make-foo-1)
(make-foo-2 'x 'z)
(make-foo-2 'x 'z))
(do-test "defconstructor/shadowing/only needed forms should be evaluated"
((:classes foo bar)
(:functions make-bar-4 make-bar-5))
(defclass foo ()
((x :initform (do-test-error nil "foo x initform was evaluated")
:initarg :x)
(y :initform (do-test-error nil "foo y initform was evaluated")
:initarg :y)
(z :initform (do-test-error nil "foo z initform was evaluated")
:initarg :z))
(:default-initargs :x (do-test-error
nil
"foo z default was evaluated")
:y (do-test-error
nil
"foo y default was evaluated")
:z (do-test-error
nil
"foo z default was evaluated")))
(defclass bar (foo)
((x :initform (do-test-error nil "bar x initform was evaluated"))
(y :initform (do-test-error nil "bar y initform was evaluated"))
(z :initform (do-test-error nil "bar z initform was evaluated")))
(:default-initargs :y 2
:z (do-test-error
nil
"bar z default was evaluated")))
(defconstructor make-bar-4 bar () :x 1 :z 3)
(defconstructor make-bar-5 bar (x z) :x x :z z)
(make-bar-4)
(make-bar-4)
(make-bar-5 'x 'z)
(make-bar-5 'x 'z))
;;;
;;; 11/1 test to make sure reader/writer call slot-value-using-class
;;;
;;; **********************************************************************
;;; This test codes will have to change in each of the next releases
;;; **********************************************************************
;;;
(cleanup-do-test '((:classes test-deoptimized-slot-access-class
test-deoptimized-slot-access)
(:functions test-a test-b test-c)
(:setf-generic-functions test-a test-b)))
(defclass test-deoptimized-slot-access-class (standard-class) ())
(defmethod check-super-metaclass-compatibility
((x test-deoptimized-slot-access-class) (y standard-class))
't)
(defmethod all-std-class-reader-miss-1
((class test-deoptimized-slot-access-class) wrapper slot-name)
(declare (ignore wrapper slot-name))
())
(defmethod lookup-pv-miss-1
((class test-deoptimized-slot-access-class) slots pv)
(let ((pv (call-next-method)))
(make-list (length pv) :initial-element nil)))
(defclass test-deoptimized-slot-access ()
((a :initform 'a :accessor test-a)
(b :initform 'b :accessor test-b))
(:metaclass test-deoptimized-slot-access-class))
(defmethod test-c ((o test-deoptimized-slot-access))
(list (slot-value o 'a) (slot-value o 'b)))
(let ((called-p 'nil)
instance)
(defmethod slot-value-using-class ((class test-deoptimized-slot-access-class)
object
slot-name)
(setq called-p 'read)
(call-next-method))
(defmethod (setf slot-value-using-class)
(nv (class test-deoptimized-slot-access-class) object slot-name)
(setq called-p 'written)
(call-next-method))
(setq instance (make-instance 'test-deoptimized-slot-access))
(do-test "deoptimized slot access should call slot-value-using-class"
()
(unless (and (eq (test-a instance) 'a)
(eq called-p 'read))
(do-test-error nil "reader doesn't call slot-value-using-class"))
(setq called-p 'nil)
(setf (test-b instance) 'c)
(unless (eq called-p 'written)
(do-test-error nil "writer doesn't call slot-value-using-class"))
(setq called-p 'nil)
(unless (and (equal (test-c instance) '(a c))
(eq called-p 'read))
(do-test-error nil "slot-value doesn't call slot-value-using-class"))))
;;;
;;; 5/3/89 eql specializers tests
;;;
(cleanup-do-test '((:classes foo bar)))
(defclass foo () ())
(defclass bar (foo) ())
(do-test "eql specializers(eql and other methods/symbol only)"
((:functions test)
(:variables i))
(defmethod test ((self foo) x) 'foo)
(defmethod test ((self bar) (x (eql 'a))) 'a)
(defmethod test ((self bar) (x (eql 'b))) 'b)
(setq i (make-instance 'bar))
(unless (eq (test i 'a) 'a)
(do-test-error () "for (bar (eql a)) wrong method was called"))
(unless (eq (test i 'b) 'b)
(do-test-error () "for (bar (eql b)) wrong method was called"))
(unless (eq (test i 'c) 'foo)
(do-test-error () "for (bar (eql c)) wrong method was called"))
)
(do-test "eql specializers(only eql methods/symbol only)"
((:functions test2)
(:variables i))
(defmethod test2 ((self bar) (x (eql 'a))) 'a)
(defmethod test2 ((self bar) (x (eql 'b))) 'b)
(setq i (make-instance 'bar))
(unless (eq (test2 i 'a) 'a)
(do-test-error () "for (bar (eql a)) wrong method was called"))
(unless (eq (test2 i 'b) 'b)
(do-test-error () "for (bar (eql b)) wrong method was called"))
)
(do-test "eql specializers(only eql methods/symbol and integer)"
((:functions test3))
(defmethod test3 ((x (eql 'a)) (y (eql '1))) 'a-1)
(defmethod test3 ((x (eql 'b)) (y (eql '1))) 'b-1)
(defmethod test3 ((x (eql 'c)) (y (eql '1))) 'c-1)
(defmethod test3 ((x (eql 'a)) (y (eql '2))) 'a-2)
(defmethod test3 ((x (eql 'b)) (y (eql '2))) 'b-2)
(defmethod test3 ((x (eql 'c)) (y (eql '2))) 'c-2)
(defmethod test3 ((x (eql 'a)) (y (eql '3))) 'a-3)
(defmethod test3 ((x (eql 'b)) (y (eql '3))) 'b-3)
(defmethod test3 ((x (eql 'c)) (y (eql '3))) 'c-3)
(unless (eq (test3 'a '1) 'a-1)
(do-test-error () "for (a 1) wrong method was called"))
(unless (eq (test3 'a '2) 'a-2)
(do-test-error () "for (a 2) wrong method was called"))
(unless (eq (test3 'a '3) 'a-3)
(do-test-error () "for (a 3) wrong method was called"))
(unless (eq (test3 'b '1) 'b-1)
(do-test-error () "for (b 1) wrong method was called"))
(unless (eq (test3 'b '2) 'b-2)
(do-test-error () "for (b 2) wrong method was called"))
(unless (eq (test3 'b '3) 'b-3)
(do-test-error () "for (b 3) wrong method was called"))
(unless (eq (test3 'c '1) 'c-1)
(do-test-error () "for (c 1) wrong method was called"))
(unless (eq (test3 'c '2) 'c-2)
(do-test-error () "for (c 2) wrong method was called"))
(unless (eq (test3 'c '3) 'c-3)
(do-test-error () "for (c 3) wrong method was called"))
)
(do-test "eql specializers(eql and other methods/symbol and integer)"
((:functions test4))
(defmethod test4 ((x (eql 'a)) (y (eql '1))) 'a-1)
(defmethod test4 ((x (eql 'b)) (y (eql '1))) 'b-1)
(defmethod test4 ((x (eql 'c)) (y (eql '2))) 'c-2)
(defmethod test4 ((x (eql 'b)) (y (eql '3))) 'b-3)
(defmethod test4 (x y) 'other)
(unless (eq (test4 'a '1) 'a-1)
(do-test-error () "for (a 1) wrong method was called"))
(unless (eq (test4 'a '2) 'other)
(do-test-error () "for (a 2) wrong method was called"))
(unless (eq (test4 'a '3) 'other)
(do-test-error () "for (a 3) wrong method was called"))
(unless (eq (test4 'b '1) 'b-1)
(do-test-error () "for (b 1) wrong method was called"))
(unless (eq (test4 'b '2) 'other)
(do-test-error () "for (b 2) wrong method was called"))
(unless (eq (test4 'b '3) 'b-3)
(do-test-error () "for (b 3) wrong method was called"))
(unless (eq (test4 'c '1) 'other)
(do-test-error () "for (c 1) wrong method was called"))
(unless (eq (test4 'c '2) 'c-2)
(do-test-error () "for (c 2) wrong method was called"))
(unless (eq (test4 'c '3) 'other)
(do-test-error () "for (c 3) wrong method was called"))
)
(do-test "eql specializers(call-next-method)"
((:functions test5))
(defmethod test5 (x) ())
(defmethod test5 ((x (eql 'a))) (cons 'a (call-next-method)))
(defmethod test5 ((x (eql 'b))) (cons 'b (call-next-method)))
(unless (equal (test5 'a) '(a))
(do-test-error () "for (a) wrong method was called"))
(unless (equal (test5 'b) '(b))
(do-test-error () "for (b) wrong method was called"))
(unless (eq (test5 'c) '())
(do-test-error () "for (c) wrong method was called"))
)
(do-test "eql specializers(for random types)"
((:functions test6))
(defmethod test6 (x) ())
(defmethod test6 ((x symbol)) (cons 'the-class-symbol (call-next-method)))
(defmethod test6 ((x null)) (cons 'the-class-null (call-next-method)))
(defmethod test6 ((x number)) (cons 'the-class-number (call-next-method)))
(defmethod test6 ((x integer)) (cons 'the-class-integer (call-next-method)))
(defmethod test6 ((x (eql 'foo))) (cons 'foo (call-next-method)))
(defmethod test6 ((x (eql 'bar))) (cons 'bar (call-next-method)))
(defmethod test6 ((x (eql 'nil))) (cons 'nil (call-next-method)))
(defmethod test6 ((x (eql '1.7))) (cons '1.7 (call-next-method)))
(defmethod test6 ((x (eql '321))) (cons '321 (call-next-method)))
(unless (eq (test6 '(other)) ())
(do-test-error () "for ((other)) wrong method was called"))
(unless (equal (test6 'symbol) '(the-class-symbol))
(do-test-error () "for (symbol) wrong method was called"))
(unless (equal (test6 '5.5) '(the-class-number))
(do-test-error () "for (number) wrong method was called"))
(unless (equal (test6 '123) '(the-class-integer the-class-number))
(do-test-error () "for (integer) wrong method was called"))
(unless (equal (test6 'foo) '(foo the-class-symbol))
(do-test-error () "for ((eql foo)) wrong method was called"))
(unless (equal (test6 'bar) '(bar the-class-symbol))
(do-test-error () "for ((eql bar)) wrong method was called"))
(unless (equal (test6 'nil) '(nil the-class-null the-class-symbol))
(do-test-error () "for ((eql nil)) wrong method was called"))
(unless (equal (test6 '1.7) '(1.7 the-class-number))
(do-test-error () "for ((eql 1.7)) wrong method was called"))
(unless (equal (test6 '321) '(321 the-class-integer the-class-number))
(do-test-error () "for ((eql 321)) wrong method was called"))
)
;;;
;;; (5/3/89)Testing :allocation :class for funcallable-instance
;;;
(format t "~%Testing :allocation :class test(for standard-instance)~%")
(cleanup-do-test '((:classes foo bar)
(:variables foo1 bar1)))
(defclass foo ()
((a :initform (list 'foo-a) :allocation :class)
(b :initform (list 'foo-b) :allocation :class)
(c :initform (list 'foo-c) :allocation :class)
(d :allocation :class)
(e :allocation :class)
(f :allocation :class)))
(defclass bar (foo)
((b :initform (list 'bar-b) :allocation :class)
(c :allocation :class)
(e :initform (list 'bar-e) :allocation :class)
(f :allocation :class)))
(defmethod slot-missing ((class standard-class)
(instance foo)
slot-name operation &optional new-value)
(list* class instance slot-name operation new-value))
(defmethod slot-missing ((class standard-class)
(instance bar)
slot-name operation &optional new-value)
(list* class instance slot-name operation new-value))
(defmethod slot-unbound ((class standard-class)
(instance foo)
slot-name)
(list class instance slot-name))
(defmethod slot-unbound ((class standard-class)
(instance bar)
slot-name)
(list class instance slot-name))
(setq foo1 (make-instance 'foo)
bar1 (make-instance 'bar))
(do-test ":allocation :class(:initform/slot-value)"
()
(unless (and (equal (slot-value foo1 'a) '(foo-a))
(equal (slot-value foo1 'b) '(foo-b))
(equal (slot-value foo1 'c) '(foo-c))
(equal (slot-value bar1 'a) '(foo-a))
(equal (slot-value bar1 'b) '(bar-b))
(equal (slot-value bar1 'c) '(foo-c))
(equal (slot-value bar1 'e) '(bar-e)))
(do-test-error () ":initform/slot-value failed")))
(do-test ":allocation :class(shared by instances of super and sub case)"
()
(unless (eq (slot-value foo1 'a)
(slot-value bar1 'a))
(do-test-error () ":class slot should be shared by instances")))
(do-test ":allocation :class(not shared by instances of super and sub case)"
()
(unless (not (eq (slot-value foo1 'c)
(slot-value bar1 'c)))
(do-test-error () ":class slot should not be shared by instances")))
(do-test ":allocation :class(slot-boundp)"
()
(unless (and (slot-boundp foo1 'a)
(slot-boundp foo1 'b)
(slot-boundp foo1 'c)
(not (slot-boundp foo1 'd))
(not (slot-boundp foo1 'e))
(not (slot-boundp foo1 'f))
(slot-boundp bar1 'a)
(slot-boundp bar1 'b)
(slot-boundp bar1 'c)
(not (slot-boundp bar1 'd))
(slot-boundp bar1 'e)
(not (slot-boundp bar1 'f)))
(do-test-error () "slot-boundp failed")))
(slot-makunbound foo1 'a)
(slot-makunbound foo1 'b)
(do-test ":allocation :class(slot-makunbound)"
()
(unless (and (not (slot-boundp foo1 'a))
(not (slot-boundp foo1 'b))
(not (slot-boundp bar1 'a))
(slot-boundp bar1 'b))
(do-test-error () "slot-makunbound failed")))
(setf (slot-value foo1 'a) '(new-foo-a)
(slot-value foo1 'b) '(new-foo-b)
(slot-value foo1 'c) '(new-foo-c)
(slot-value bar1 'b) '(new-bar-b)
(slot-value bar1 'e) '(new-bar-e))
(do-test ":allocation :class(slot-value/(setf slot-value))"
()
(unless (and (equal (slot-value foo1 'a) '(new-foo-a))
(equal (slot-value foo1 'b) '(new-foo-b))
(equal (slot-value foo1 'c) '(new-foo-c))
(equal (slot-value bar1 'a) '(new-foo-a))
(equal (slot-value bar1 'b) '(new-bar-b))
(equal (slot-value bar1 'e) '(new-bar-e)))
(do-test-error () "slot-value/(setf slot-value failed")))
(do-test ":allocation :class(slot-exists-p)"
()
(unless (and (slot-exists-p foo1 'a)
(slot-exists-p foo1 'b)
(slot-exists-p foo1 'c)
(slot-exists-p foo1 'd)
(slot-exists-p foo1 'e)
(slot-exists-p foo1 'f)
(slot-exists-p bar1 'a)
(slot-exists-p bar1 'b)
(slot-exists-p bar1 'c)
(slot-exists-p bar1 'd)
(slot-exists-p bar1 'e)
(slot-exists-p bar1 'f))
(do-test-error () "slot-exist-p failed")))
(do-test ":allocation :class(slot-missing)"
()
(unless (and (equal (slot-value foo1 'x)
(list (class-of foo1)
foo1
'x
'slot-value))
(equal (setf (slot-value foo1 'x) 'dummy)
(list* (class-of foo1)
foo1
'x
'setf
'dummy))
(equal (slot-boundp foo1 'x)
(list (class-of foo1)
foo1
'x
'slot-boundp))
(equal (slot-makunbound foo1 'x)
(list (class-of foo1)
foo1
'x
'slot-makunbound))
(equal (slot-value bar1 'x)
(list (class-of bar1)
bar1
'x
'slot-value))
(equal (setf (slot-value bar1 'x) 'dummy)
(list* (class-of bar1)
bar1
'x
'setf
'dummy))
(equal (slot-boundp bar1 'x)
(list (class-of bar1)
bar1
'x
'slot-boundp))
(equal (slot-makunbound bar1 'x)
(list (class-of bar1)
bar1
'x
'slot-makunbound)))
(do-test-error () "slot-missing failed")))
;;;
;;; (5/4/89)Testing :allocation :class for funcallable-instance
;;;
(format t "~%Testing :allocation :class test~
(for funcallable-standard-instance)~%")
(cleanup-do-test '((:classes foo bar)
(:variables foo2 bar2)))
(defclass foo ()
((a :initform (list 'foo-a) :allocation :class)
(b :initform (list 'foo-b) :allocation :class)
(c :initform (list 'foo-c) :allocation :class)
(d :allocation :class)
(e :allocation :class)
(f :allocation :class))
(:metaclass funcallable-standard-class))
(defclass bar (foo)
((b :initform (list 'bar-b) :allocation :class)
(c :allocation :class)
(e :initform (list 'bar-e) :allocation :class)
(f :allocation :class))
(:metaclass funcallable-standard-class))
(defmethod slot-missing ((class standard-class)
(instance foo)
slot-name operation &optional new-value)
(list* class instance slot-name operation new-value))
(defmethod slot-missing ((class standard-class)
(instance bar)
slot-name operation &optional new-value)
(list* class instance slot-name operation new-value))
(defmethod slot-unbound ((class standard-class)
(instance foo)
slot-name)
(list class instance slot-name))
(defmethod slot-unbound ((class standard-class)
(instance bar)
slot-name)
(list class instance slot-name))
(setq foo2 (make-instance 'foo)
bar2 (make-instance 'bar))
(do-test ":allocation :class(:initform/slot-value)"
()
(unless (and (equal (slot-value foo2 'a) '(foo-a))
(equal (slot-value foo2 'b) '(foo-b))
(equal (slot-value foo2 'c) '(foo-c))
(equal (slot-value bar2 'a) '(foo-a))
(equal (slot-value bar2 'b) '(bar-b))
(equal (slot-value bar2 'c) '(foo-c))
(equal (slot-value bar2 'e) '(bar-e)))
(do-test-error () ":initform/slot-value failed")))
(do-test ":allocation :class(shared by instances of super and sub case)"
()
(unless (eq (slot-value foo2 'a)
(slot-value bar2 'a))
(do-test-error () ":class slot should be shared by instances")))
(do-test ":allocation :class(not shared by instances of super and sub case)"
()
(unless (not (eq (slot-value foo2 'c)
(slot-value bar2 'c)))
(do-test-error () ":class slot should not be shared by instances")))
(do-test ":allocation :class(slot-boundp)"
()
(unless (and (slot-boundp foo2 'a)
(slot-boundp foo2 'b)
(slot-boundp foo2 'c)
(not (slot-boundp foo2 'd))
(not (slot-boundp foo2 'e))
(not (slot-boundp foo2 'f))
(slot-boundp bar2 'a)
(slot-boundp bar2 'b)
(slot-boundp bar2 'c)
(not (slot-boundp bar2 'd))
(slot-boundp bar2 'e)
(not (slot-boundp bar2 'f)))
(do-test-error () "slot-boundp failed")))
(slot-makunbound foo2 'a)
(slot-makunbound foo2 'b)
(do-test ":allocation :class(slot-makunbound)"
()
(unless (and (not (slot-boundp foo2 'a))
(not (slot-boundp foo2 'b))
(not (slot-boundp bar2 'a))
(slot-boundp bar2 'b))
(do-test-error () "slot-makunbound failed")))
(setf (slot-value foo2 'a) '(new-foo-a)
(slot-value foo2 'b) '(new-foo-b)
(slot-value foo2 'c) '(new-foo-c)
(slot-value bar2 'b) '(new-bar-b)
(slot-value bar2 'e) '(new-bar-e))
(do-test ":allocation :class(slot-value/(setf slot-value))"
()
(unless (and (equal (slot-value foo2 'a) '(new-foo-a))
(equal (slot-value foo2 'b) '(new-foo-b))
(equal (slot-value foo2 'c) '(new-foo-c))
(equal (slot-value bar2 'a) '(new-foo-a))
(equal (slot-value bar2 'b) '(new-bar-b))
(equal (slot-value bar2 'e) '(new-bar-e)))
(do-test-error () "slot-value/(setf slot-value failed")))
(do-test ":allocation :class(slot-exists-p)"
()
(unless (and (slot-exists-p foo2 'a)
(slot-exists-p foo2 'b)
(slot-exists-p foo2 'c)
(slot-exists-p foo2 'd)
(slot-exists-p foo2 'e)
(slot-exists-p foo2 'f)
(slot-exists-p bar2 'a)
(slot-exists-p bar2 'b)
(slot-exists-p bar2 'c)
(slot-exists-p bar2 'd)
(slot-exists-p bar2 'e)
(slot-exists-p bar2 'f))
(do-test-error () "slot-exist-p failed")))
;(do-test ":allocation :class(slot-missing)"
; ()
; (unless (and (equal (slot-value foo2 'x)
; (list (class-of foo2)
; foo2
; 'x
; 'slot-value))
; (equal (setf (slot-value foo2 'x) 'dummy)
; (list* (class-of foo2)
; foo2
; 'x
; 'setf
; 'dummy))
; (equal (slot-boundp foo2 'x)
; (list (class-of foo2)
; foo2
; 'x
; 'slot-boundp))
;
; (equal (slot-makunbound foo2 'x)
; (list (class-of foo2)
; foo2
; 'x
; 'slot-makunbound))
; (equal (slot-value bar2 'x)
; (list (class-of bar2)
; bar2
; 'x
; 'slot-value))
; (equal (setf (slot-value bar2 'x) 'dummy)
; (list* (class-of bar2)
; bar2
; 'x
; 'setf
; 'dummy))
; (equal (slot-boundp bar2 'x)
; (list (class-of bar2)
; bar2
; 'x
; 'slot-boundp))
;
; (equal (slot-makunbound bar2 'x)
; (list (class-of bar2)
; bar2
; 'x
; 'slot-makunbound)))
; (do-test-error () "slot-missing failed")))