X-Git-Url: http://git.hcoop.net/bpt/guile.git/blobdiff_plain/c32929d14d40f9e00c3fd10d3f51d54733ebf687..583a23bf104c84d9617222856e188f3f3af4934d:/test-suite/tests/goops.test diff --git a/test-suite/tests/goops.test b/test-suite/tests/goops.test index 8861d23a9..1c6d33ec0 100644 --- a/test-suite/tests/goops.test +++ b/test-suite/tests/goops.test @@ -1,26 +1,28 @@ ;;;; goops.test --- test suite for GOOPS -*- scheme -*- ;;;; -;;;; Copyright (C) 2001,2003,2004, 2006, 2008 Free Software Foundation, Inc. +;;;; Copyright (C) 2001,2003,2004, 2006, 2008, 2009, 2011, 2012, 2014, 2015 Free Software Foundation, Inc. ;;;; -;;;; This program is free software; you can redistribute it and/or modify -;;;; it under the terms of the GNU General Public License as published by -;;;; the Free Software Foundation; either version 2, or (at your option) -;;;; any later version. +;;;; This library is free software; you can redistribute it and/or +;;;; modify it under the terms of the GNU Lesser General Public +;;;; License as published by the Free Software Foundation; either +;;;; version 3 of the License, or (at your option) any later version. ;;;; -;;;; This program is distributed in the hope that it will be useful, +;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -;;;; GNU General Public License for more details. +;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;;; Lesser General Public License for more details. ;;;; -;;;; You should have received a copy of the GNU General Public License -;;;; along with this software; see the file COPYING. If not, write to -;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;;;; Boston, MA 02110-1301 USA +;;;; You should have received a copy of the GNU Lesser General Public +;;;; License along with this library; if not, write to the Free Software +;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite test-goops) #:use-module (test-suite lib) #:autoload (srfi srfi-1) (unfold)) +(define exception:no-applicable-method + '(goops-error . "^No applicable method")) + (pass-if "GOOPS loads" (false-if-exception (begin (resolve-module '(oop goops)) @@ -125,6 +127,31 @@ table)))) ) +(with-test-prefix "classes for built-in types" + + (pass-if "subr" + (eq? (class-of fluid-ref) )) + + (pass-if "gsubr" + (eq? (class-of hashq-ref) )) + + (pass-if "car" + (eq? (class-of car) )) + + (pass-if "string" + (eq? (class-of "foo") )) + + (pass-if "port" + (is-a? (%make-void-port "w") )) + + (pass-if "struct vtable" + ;; Previously, `class-of' would fail for nameless structs, i.e., structs + ;; for which `struct-vtable-name' is #f. + (is-a? (class-of (make-vtable + (string-append standard-vtable-fields "prprpr"))) + ))) + + (with-test-prefix "defining classes" (with-test-prefix "define-class" @@ -141,14 +168,15 @@ (eval '(is-a? ) (current-module))) (expect-fail "bad init-thunk" - (catch #t - (lambda () - (eval '(define-class () - (x #:init-thunk (lambda (x) 1))) - (current-module)) - #t) - (lambda args - #f))) + (begin + (catch #t + (lambda () + (eval '(define-class () + (x #:init-thunk (lambda (x) 1))) + (current-module)) + #t) + (lambda args + #f)))) (pass-if "interaction with `struct-ref'" (eval '(define-class () @@ -180,8 +208,15 @@ (x #:accessor x #:init-value 123) (z #:accessor z #:init-value 789)) (current-module)) - (eval '(equal? (x (make )) 123) (current-module))))) - + (eval '(equal? (x (make )) 123) (current-module))) + + (pass-if-exception "cannot redefine fields of " + '(misc-error . "cannot be redefined") + (eval '(begin + (define-class () + name) + (make )) + (current-module))))) (with-test-prefix "defining generics" @@ -208,7 +243,11 @@ (eval '(define-generic foo) (current-module)) (eval '(and (is-a? foo ) (null? (generic-function-methods foo))) - (current-module))))) + (current-module))) + + (pass-if-exception "getters do not have setters" + exception:wrong-type-arg + (eval '(setter foo) (current-module))))) (with-test-prefix "defining methods" @@ -243,6 +282,19 @@ (method-more-specific? m1 m2 '())) (current-module)))) +(with-test-prefix "the method cache" + (pass-if "defining a method with a rest arg" + (let ((m (current-module))) + (eval '(define-method (foo bar . baz) + (cons bar baz)) + m) + (eval '(foo 1) + m) + (eval '(foo 1 2) + m) + (eval '(equal? (foo 1 2) '(1 2)) + m)))) + (with-test-prefix "defining accessors" (with-test-prefix "define-accessor" @@ -255,6 +307,9 @@ (null? (generic-function-methods foo-1))) (current-module))) + (pass-if "accessors have setters" + (procedure? (eval '(setter foo-1) (current-module)))) + (pass-if "overwriting a top-level binding to a non-accessor" (eval '(define (foo) #f) (current-module)) (eval '(define-accessor foo) (current-module)) @@ -370,18 +425,6 @@ (define o4 (make #:x '(4) #:y '(3))) (not (eqv? o1 o2))) (current-module))) - (pass-if "eqv?" - (eval '(begin - (define-method (eqv? (a ) (b )) - (equal? (x a) (x b))) - (eqv? o1 o2)) - (current-module))) - (pass-if "not eqv?" - (eval '(not (eqv? o2 o3)) - (current-module))) - (pass-if "transfer eqv? => equal?" - (eval '(equal? o1 o2) - (current-module))) (pass-if "equal?" (eval '(begin (define-method (equal? (a ) (b )) @@ -431,9 +474,9 @@ (x bar) (set! (x bar) 2) (equal? (reverse z) - '(before-ref before-set! 1 before-ref after-ref - after-set! 1 1 before-ref after-ref - before-set! 2 before-ref after-ref after-set! 2 2))) + '(before-set! 1 before-ref after-ref + after-set! 1 1 before-ref after-ref + before-set! 2 before-ref after-ref after-set! 2 2))) (current-module)))) (use-modules (oop goops composite-slot)) @@ -464,3 +507,129 @@ (= (x (o2 o)) 3) (= (y (o2 o)) 5))) (current-module)))) + +(with-test-prefix "no-applicable-method" + (pass-if-exception "calling generic, no methods" + exception:no-applicable-method + (eval '(begin + (define-class ()) + (define-generic quxy) + (quxy 1)) + (current-module))) + (pass-if "calling generic, one method, applicable" + (eval '(begin + (define-method (quxy (q )) + #t) + (define q (make )) + (quxy q)) + (current-module))) + (pass-if-exception "calling generic, one method, not applicable" + exception:no-applicable-method + (eval '(quxy 1) + (current-module)))) + +(with-test-prefix "foreign slots" + (define-class () + (a #:init-keyword #:a #:class + #:accessor test-a) + (b #:init-keyword #:b #:init-form 3 #:class + #:accessor test-b)) + + (pass-if-equal "constructing, no initargs" + '(0 3) + (let ((x (make ))) + (list (slot-ref x 'a) + (slot-ref x 'b)))) + + (pass-if-equal "constructing, initargs" + '(1 2) + (let ((x (make #:a 1 #:b 2))) + (list (slot-ref x 'a) + (slot-ref x 'b)))) + + (pass-if-equal "getters" + '(0 3) + (let ((x (make ))) + (list (test-a x) (test-b x)))) + + (pass-if-equal "setters" + '(10 20) + (let ((x (make ))) + (set! (test-a x) 10) + (set! (test-b x) 20) + (list (test-a x) (test-b x)))) + + (pass-if-exception "out of range" + exception:out-of-range + (make #:a (ash 1 64)))) + +(with-test-prefix "#:each-subclass" + (let* (( + (class () + (test #:init-value '() #:allocation #:each-subclass) + #:name ')) + (a (make ))) + (pass-if-equal '() (slot-ref a 'test)) + (let ((b (make ))) + (pass-if-equal '() (slot-ref b 'test)) + (slot-set! a 'test 100) + (pass-if-equal 100 (slot-ref a 'test)) + (pass-if-equal 100 (slot-ref b 'test)) + + ;; #:init-value of the class shouldn't reinitialize slot when + ;; instances are allocated. + (make ) + + (pass-if-equal 100 (slot-ref a 'test)) + (pass-if-equal 100 (slot-ref b 'test)) + + (let (( + (class ()))) + (pass-if-equal 100 (slot-ref a 'test)) + (pass-if-equal 100 (slot-ref b 'test)) + (let ((c (make ))) + (pass-if-equal 100 (slot-ref a 'test)) + (pass-if-equal 100 (slot-ref b 'test)) + (pass-if-equal '() (slot-ref c 'test)) + (slot-set! c 'test 200) + (pass-if-equal 200 (slot-ref c 'test)) + + (make ) + + (pass-if-equal 100 (slot-ref a 'test)) + (pass-if-equal 100 (slot-ref b 'test)) + (pass-if-equal 200 (slot-ref c 'test))))))) + +(with-test-prefix "accessor slots" + (let* ((a-accessor (make-accessor 'a)) + (b-accessor (make-accessor 'b)) + ( (class () + (a #:init-keyword #:a #:accessor a-accessor) + #:name ')) + ( (class () + (b #:init-keyword #:b #:accessor b-accessor) + #:name ')) + ( (class ( ) #:name ')) + ( (class ( ) #:name ')) + ( (class () + (a #:init-keyword #:a) + #:name ')) + ( (class () + (a #:init-keyword #:a) + #:name ')) + (a (make #:a 'a)) + (b (make #:b 'b)) + (ab (make #:a 'a #:b 'b)) + (ba (make #:a 'a #:b 'b)) + (cab (make #:a 'a #:b 'b)) + (cba (make #:a 'a #:b 'b))) + (pass-if-equal "a accessor on a" 'a (a-accessor a)) + (pass-if-equal "a accessor on ab" 'a (a-accessor ab)) + (pass-if-equal "a accessor on ba" 'a (a-accessor ba)) + (pass-if-equal "a accessor on cab" 'a (a-accessor cab)) + (pass-if-equal "a accessor on cba" 'a (a-accessor cba)) + (pass-if-equal "b accessor on a" 'b (b-accessor b)) + (pass-if-equal "b accessor on ab" 'b (b-accessor ab)) + (pass-if-equal "b accessor on ba" 'b (b-accessor ba)) + (pass-if-equal "b accessor on cab" 'b (b-accessor cab)) + (pass-if-equal "b accessor on cba" 'b (b-accessor cba))))