0.7.4.28:
[sbcl.git] / tests / clos.impure.lisp
index edcfcd0..237e5ea 100644 (file)
@@ -15,8 +15,8 @@
   (:use "CL"))
 (in-package "FOO")
 \f
-;;;; It should be possible to do DEFGENERIC and DEFMETHOD referring to
-;;;; structure types defined earlier in the file.
+;;; It should be possible to do DEFGENERIC and DEFMETHOD referring to
+;;; structure types defined earlier in the file.
 (defstruct struct-a x y)
 (defstruct struct-b x y z)
 (defmethod wiggle ((a struct-a))
                'structure-class))
 (assert (typep (make-instance 'structure-class-foo1) 'structure-class-foo1))
 (assert (typep (make-instance 'standard-class-foo1) 'standard-class-foo1))
+
+;;; DEFGENERIC's blow-away-old-methods behavior is specified to have
+;;; special hacks to distinguish between defined-with-DEFGENERIC-:METHOD
+;;; methods and defined-with-DEFMETHOD methods, so that reLOADing
+;;; DEFGENERIC-containing files does the right thing instead of 
+;;; randomly slicing your generic functions. (APD made this work
+;;; in sbcl-0.7.0.2.)
+(defgeneric born-to-be-redefined (x)
+  (:method ((x integer))
+    'integer))
+(defmethod born-to-be-redefined ((x real))
+  'real)
+(assert (eq (born-to-be-redefined 1) 'integer))
+(defgeneric born-to-be-redefined (x))
+(assert (eq (born-to-be-redefined 1) 'real)) ; failed until sbcl-0.7.0.2
+(defgeneric born-to-be-redefined (x)
+  (:method ((x integer))
+    'integer))
+(defmethod born-to-be-redefined ((x integer))
+  'int)
+(assert (eq (born-to-be-redefined 1) 'int))
+(defgeneric born-to-be-redefined (x))
+(assert (eq (born-to-be-redefined 1) 'int))
+\f
+;;; In the removal of ITERATE from SB-PCL, a bug was introduced
+;;; preventing forward-references and also change-class (which
+;;; forward-references used interally) from working properly.  One
+;;; symptom was reported by Brian Spilsbury (sbcl-devel 2002-04-08),
+;;; and another on IRC by Dan Barlow simultaneously.  Better check
+;;; that it doesn't happen again.
+;;;
+;;; First, the forward references:
+(defclass a (b) ())
+(defclass b () ())
+;;; Then change-class
+(defclass class-with-slots ()
+  ((a-slot :initarg :a-slot :accessor a-slot)
+   (b-slot :initarg :b-slot :accessor b-slot)
+   (c-slot :initarg :c-slot :accessor c-slot)))
+
+(let ((foo (make-instance 'class-with-slots
+                         :a-slot 1
+                         :b-slot 2
+                         :c-slot 3)))
+  (let ((bar (change-class foo 'class-with-slots)))
+    (assert (= (a-slot bar) 1))
+    (assert (= (b-slot bar) 2))
+    (assert (= (c-slot bar) 3))))
+
+;;; some more change-class testing, now that we have an ANSI-compliant
+;;; version (thanks to Espen Johnsen):
+(defclass from-class ()
+  ((foo :initarg :foo :accessor foo)))
+
+(defclass to-class ()
+  ((foo :initarg :foo :accessor foo)
+   (bar :initarg :bar :accessor bar)))
+
+(let* ((from (make-instance 'from-class :foo 1))
+       (to (change-class from 'to-class :bar 2)))
+  (assert (= (foo to) 1))
+  (assert (= (bar to) 2)))
+\f
+;;; printing a structure class should not loop indefinitely (or cause
+;;; a stack overflow):
+(defclass test-printing-structure-class ()
+  ((slot :initarg :slot))
+  (:metaclass structure-class))
+
+(print (make-instance 'test-printing-structure-class :slot 2))
+
+;;; structure-classes should behave nicely when subclassed
+(defclass super-structure ()
+  ((a :initarg :a :accessor a-accessor)
+   (b :initform 2 :reader b-reader))
+  (:metaclass structure-class))
+
+(defclass sub-structure (super-structure)
+  ((c :initarg :c :writer c-writer :accessor c-accessor))
+  (:metaclass structure-class))
+
+(let ((foo (make-instance 'sub-structure :a 1 :c 3)))
+  (assert (= (a-accessor foo) 1))
+  (assert (= (b-reader foo) 2))
+  (assert (= (c-accessor foo) 3))
+  (setf (a-accessor foo) 4)
+  (c-writer 5 foo)
+  (assert (= (a-accessor foo) 4))
+  (assert (= (c-accessor foo) 5)))
 \f
 ;;;; success