1 USING: accessors arrays assocs calendar classes classes.algebra
2 classes.private classes.tuple classes.tuple.private columns
3 combinators.short-circuit compiler.errors compiler.units
4 definitions eval generic generic.single io.streams.string kernel
5 kernel.private literals math math.constants memory namespaces
6 parser parser.notes see sequences sequences.private slots
7 splitting strings threads tools.test vectors vocabs words
9 IN: classes.tuple.tests
12 : <rect> ( x y w h -- rect ) rect boa ;
14 : move ( x rect -- rect )
17 { f } [ 10 20 30 40 <rect> dup clone 5 swap move = ] unit-test
19 { t } [ 10 20 30 40 <rect> dup clone 0 swap move = ] unit-test
21 ! Make sure we handle tuple class redefinition
22 TUPLE: redefinition-test ;
24 C: <redefinition-test> redefinition-test
26 <redefinition-test> "redefinition-test" set
28 { t } [ "redefinition-test" get redefinition-test? ] unit-test
30 "IN: classes.tuple.tests TUPLE: redefinition-test ;" eval( -- )
32 { t } [ "redefinition-test" get redefinition-test? ] unit-test
34 ! Make sure we handle changing shapes!
37 { } [ 100 200 point boa "p" set ] unit-test
39 ! Use eval to sequence parsing explicitly
40 { } [ "IN: classes.tuple.tests TUPLE: point x y z ;" eval( -- ) ] unit-test
42 { 100 } [ "p" get x>> ] unit-test
43 { 200 } [ "p" get y>> ] unit-test
44 { f } [ "p" get "z>>" "accessors" lookup-word execute ] unit-test
46 { } [ "p" get 300 ">>z" "accessors" lookup-word execute drop ] unit-test
48 { 3 } [ "p" get tuple-size ] unit-test
50 { 300 } [ "p" get "z>>" "accessors" lookup-word execute ] unit-test
52 { } [ "IN: classes.tuple.tests TUPLE: point z y ;" eval( -- ) ] unit-test
54 { 2 } [ "p" get tuple-size ] unit-test
56 [ "p" get x>> ] must-fail
57 { 200 } [ "p" get y>> ] unit-test
58 { 300 } [ "p" get "z>>" "accessors" lookup-word execute ] unit-test
62 { T{ slotty } } [ H{ } slotty from-slots ] unit-test
63 { T{ slotty f 1 2 f } } [ H{ { "a" 1 } { "b" 2 } } slotty from-slots ] unit-test
64 [ H{ { "d" 0 } } slotty new set-slots ] must-fail
66 TUPLE: predicate-test ;
68 C: <predicate-test> predicate-test
70 : predicate-test ( a -- ? ) drop f ;
72 { t } [ <predicate-test> predicate-test? ] unit-test
74 PREDICATE: silly-pred < tuple
77 GENERIC: area ( obj -- n )
78 M: silly-pred area dup w>> swap h>> * ;
80 TUPLE: circle radius ;
81 M: circle area radius>> sq pi * ;
83 { 200 } [ T{ rect f 0 0 10 20 } area ] unit-test
90 { t } [ <empty> hashcode fixnum? ] unit-test
93 [ t length ] [ object>> t eq? ] must-fail-with
95 { "<constructor-test>" }
96 [ "IN: classes.tuple.test TUPLE: constructor-test ; C: <constructor-test> constructor-test" eval( -- ) last-word name>> ] unit-test
98 TUPLE: size-test a b c d ;
101 T{ size-test } tuple-size
102 size-test tuple-layout second =
105 GENERIC: <yo-momma> ( a -- b )
109 { } [ "IN: classes.tuple.tests C: <yo-momma> yo-momma" eval( -- ) ] unit-test
111 { f } [ \ <yo-momma> generic? ] unit-test
115 [ t ] [ \ yo-momma class? ] unit-test
116 [ ] [ \ yo-momma forget ] unit-test
117 [ ] [ \ <yo-momma> forget ] unit-test
118 [ f ] [ \ yo-momma update-map get values member-eq? ] unit-test
119 ] with-compilation-unit
121 TUPLE: loc-recording ;
123 { f } [ \ loc-recording where not ] unit-test
125 ! 'forget' wasn't robust enough
127 TUPLE: forget-robustness ;
129 GENERIC: forget-robustness-generic ( a -- b )
131 M: forget-robustness forget-robustness-generic ;
133 M: integer forget-robustness-generic ;
136 [ ] [ \ forget-robustness-generic forget ] unit-test
137 [ ] [ \ forget-robustness forget ] unit-test
138 [ ] [ M\ forget-robustness forget-robustness-generic forget ] unit-test
139 ] with-compilation-unit
141 ! rapido found this one
142 GENERIC# m1 0 ( s n -- n )
143 GENERIC# m2 1 ( s n -- v )
167 { 1 } [ 1 <t4> m1 ] unit-test
168 { 1 } [ <t4> 1 m2 ] unit-test
170 ! another combination issue
171 GENERIC: silly ( obj -- obj obj )
173 UNION: my-union slice repetition column array vector reversed ;
175 M: my-union silly "x" ;
179 M: column silly "fdsfds" ;
181 M: repetition silly "zzz" ;
183 M: reversed silly "zz" ;
185 M: slice silly "tt" ;
187 M: string silly "t" ;
189 M: vector silly "z" ;
191 { "zz" } [ 123 <reversed> silly nip ] unit-test
194 SYMBOL: not-a-tuple-class
197 [ not-a-tuple-class boa ] must-fail
198 [ not-a-tuple-class new ] must-fail
200 TUPLE: erg's-reshape-problem a b c d ;
202 C: <erg's-reshape-problem> erg's-reshape-problem
205 TUPLE: computer cpu ram ;
206 C: <computer> computer
208 { "TUPLE: computer cpu ram ;" } [
209 [ \ computer see ] with-string-writer string-lines second
212 TUPLE: laptop < computer battery ;
215 { t } [ laptop tuple-class? ] unit-test
216 { t } [ laptop tuple class<= ] unit-test
217 { t } [ laptop computer class<= ] unit-test
218 { t } [ laptop computer classes-intersect? ] unit-test
220 { } [ "Pentium" 128 3 hours <laptop> "laptop" set ] unit-test
221 { t } [ "laptop" get laptop? ] unit-test
222 { t } [ "laptop" get computer? ] unit-test
223 { t } [ "laptop" get tuple? ] unit-test
225 : test-laptop-slot-values ( -- )
226 [ laptop ] [ "laptop" get class-of ] unit-test
227 [ "Pentium" ] [ "laptop" get cpu>> ] unit-test
228 [ 128 ] [ "laptop" get ram>> ] unit-test
229 [ t ] [ "laptop" get battery>> 3 hours = ] unit-test ;
231 test-laptop-slot-values
233 { "TUPLE: laptop < computer battery ;" } [
234 [ \ laptop see ] with-string-writer string-lines second
237 { { tuple computer laptop } } [ laptop superclasses-of ] unit-test
239 TUPLE: server < computer rackmount ;
242 { t } [ server tuple-class? ] unit-test
243 { t } [ server tuple class<= ] unit-test
244 { t } [ server computer class<= ] unit-test
245 { t } [ server computer classes-intersect? ] unit-test
247 { } [ "PowerPC" 64 "1U" <server> "server" set ] unit-test
248 { t } [ "server" get server? ] unit-test
249 { t } [ "server" get computer? ] unit-test
250 { t } [ "server" get tuple? ] unit-test
252 : test-server-slot-values ( -- )
253 [ server ] [ "server" get class-of ] unit-test
254 [ "PowerPC" ] [ "server" get cpu>> ] unit-test
255 [ 64 ] [ "server" get ram>> ] unit-test
256 [ "1U" ] [ "server" get rackmount>> ] unit-test ;
258 test-server-slot-values
260 { f } [ "server" get laptop? ] unit-test
261 { f } [ "laptop" get server? ] unit-test
263 { f } [ server laptop class<= ] unit-test
264 { f } [ laptop server class<= ] unit-test
265 { f } [ laptop server classes-intersect? ] unit-test
267 { f } [ 1 2 <computer> laptop? ] unit-test
268 { f } [ \ + server? ] unit-test
270 { "TUPLE: server < computer rackmount ;" } [
271 [ \ server see ] with-string-writer string-lines second
275 "IN: classes.tuple.tests TUPLE: invalid-superclass < word ;" eval( -- )
278 ! Dynamically changing inheritance hierarchy
279 TUPLE: electronic-device ;
281 : computer?' ( a -- b ) computer? ;
283 { t } [ laptop new computer?' ] unit-test
285 { } [ "IN: classes.tuple.tests TUPLE: computer < electronic-device cpu ram ; C: <computer> computer C: <laptop> laptop C: <server> server" eval( -- ) ] unit-test
287 { t } [ laptop new computer?' ] unit-test
289 { f } [ electronic-device laptop class<= ] unit-test
290 { t } [ server electronic-device class<= ] unit-test
291 { t } [ laptop server class-or electronic-device class<= ] unit-test
293 { t } [ "laptop" get electronic-device? ] unit-test
294 { t } [ "laptop" get computer? ] unit-test
295 { t } [ "laptop" get laptop? ] unit-test
296 { f } [ "laptop" get server? ] unit-test
298 { t } [ "server" get electronic-device? ] unit-test
299 { t } [ "server" get computer? ] unit-test
300 { f } [ "server" get laptop? ] unit-test
301 { t } [ "server" get server? ] unit-test
303 { } [ "IN: classes.tuple.tests TUPLE: computer cpu ram ; C: <computer> computer C: <laptop> laptop C: <server> server" eval( -- ) ] unit-test
305 { f } [ "laptop" get electronic-device? ] unit-test
306 { t } [ "laptop" get computer? ] unit-test
308 { } [ "IN: classes.tuple.tests TUPLE: computer < electronic-device cpu ram disk ; C: <computer> computer C: <laptop> laptop C: <server> server" eval( -- ) ] unit-test
310 test-laptop-slot-values
311 test-server-slot-values
313 { } [ "IN: classes.tuple.tests TUPLE: electronic-device voltage ; C: <computer> computer C: <laptop> laptop C: <server> server" eval( -- ) ] unit-test
315 test-laptop-slot-values
316 test-server-slot-values
318 TUPLE: make-me-some-accessors voltage grounded? ;
320 { f } [ "laptop" get voltage>> ] unit-test
321 { f } [ "server" get voltage>> ] unit-test
323 { } [ "laptop" get 220 >>voltage drop ] unit-test
324 { } [ "server" get 110 >>voltage drop ] unit-test
326 { } [ "IN: classes.tuple.tests TUPLE: electronic-device voltage grounded? ; C: <computer> computer" eval( -- ) ] unit-test
328 test-laptop-slot-values
329 test-server-slot-values
331 { 220 } [ "laptop" get voltage>> ] unit-test
332 { 110 } [ "server" get voltage>> ] unit-test
334 { } [ "IN: classes.tuple.tests TUPLE: electronic-device grounded? voltage ; C: <computer> computer C: <laptop> laptop C: <server> server" eval( -- ) ] unit-test
336 test-laptop-slot-values
337 test-server-slot-values
339 { 220 } [ "laptop" get voltage>> ] unit-test
340 { 110 } [ "server" get voltage>> ] unit-test
342 ! Reshaping superclass and subclass simultaneously
343 { } [ "IN: classes.tuple.tests TUPLE: electronic-device voltage ; TUPLE: computer < electronic-device cpu ram ; C: <computer> computer C: <laptop> laptop C: <server> server" eval( -- ) ] unit-test
345 test-laptop-slot-values
346 test-server-slot-values
348 { 220 } [ "laptop" get voltage>> ] unit-test
349 { 110 } [ "server" get voltage>> ] unit-test
352 TUPLE: test1 a ; TUPLE: test2 < test1 b ;
354 "a" "b" test2 boa "test" set
357 [ "a" ] [ "test" get a>> ] unit-test
358 [ "b" ] [ "test" get b>> ] unit-test ;
362 { } [ "IN: classes.tuple.tests TUPLE: test1 a x ; TUPLE: test2 < test1 b y ;" eval( -- ) ] unit-test
366 { } [ "IN: classes.tuple.tests TUPLE: test1 a ; TUPLE: test2 < test1 b ;" eval( -- ) ] unit-test
370 ! Twice in the same compilation unit
372 test1 tuple { "a" "x" "y" } define-tuple-class
373 test1 tuple { "a" "y" } define-tuple-class
374 ] with-compilation-unit
378 ! Moving slots up and down
379 TUPLE: move-up-1 a b ;
380 TUPLE: move-up-2 < move-up-1 c ;
382 T{ move-up-2 f "a" "b" "c" } "move-up" set
384 : test-move-up ( -- )
385 [ "a" ] [ "move-up" get a>> ] unit-test
386 [ "b" ] [ "move-up" get b>> ] unit-test
387 [ "c" ] [ "move-up" get c>> ] unit-test ;
391 { } [ "IN: classes.tuple.tests TUPLE: move-up-1 a b c ; TUPLE: move-up-2 < move-up-1 ;" eval( -- ) ] unit-test
395 { } [ "IN: classes.tuple.tests TUPLE: move-up-1 a c ; TUPLE: move-up-2 < move-up-1 b ;" eval( -- ) ] unit-test
399 { } [ "IN: classes.tuple.tests TUPLE: move-up-1 c ; TUPLE: move-up-2 < move-up-1 b a ;" eval( -- ) ] unit-test
403 { } [ "IN: classes.tuple.tests TUPLE: move-up-1 ; TUPLE: move-up-2 < move-up-1 a b c ;" eval( -- ) ] unit-test
405 ! Constructors must be recompiled when changing superclass
406 TUPLE: constructor-update-1 xxx ;
408 TUPLE: constructor-update-2 < constructor-update-1 yyy zzz ;
410 : <constructor-update-2> ( a b c -- tuple ) constructor-update-2 boa ;
412 { 3 1 } [ <constructor-update-2> ] must-infer-as
414 { } [ "IN: classes.tuple.tests TUPLE: constructor-update-1 xxx ttt www ;" eval( -- ) ] unit-test
416 { 3 1 } [ <constructor-update-2> ] must-infer-as
418 [ 1 2 3 4 5 <constructor-update-2> ] [ not-compiled? ] must-fail-with
420 { } [ [ \ <constructor-update-2> forget ] with-compilation-unit ] unit-test
422 ! Redefinition problem
423 TUPLE: redefinition-problem ;
425 UNION: redefinition-problem' redefinition-problem integer ;
427 { t } [ 3 redefinition-problem'? ] unit-test
429 TUPLE: redefinition-problem-2 ;
431 "IN: classes.tuple.tests TUPLE: redefinition-problem < redefinition-problem-2 ;" eval( -- )
433 { t } [ 3 redefinition-problem'? ] unit-test
435 ! Hardcore unit tests
437 \ thread "slots" word-prop "slots" set
441 \ thread tuple { "xxx" } "slots" get append
443 ] with-compilation-unit
445 [ 1337 sleep ] "Test" spawn drop
448 \ thread tuple "slots" get
450 ] with-compilation-unit
453 \ vocab "slots" word-prop "slots" set
457 \ vocab identity-tuple { "xxx" } "slots" get append
459 ] with-compilation-unit
464 \ vocab identity-tuple "slots" get
466 ] with-compilation-unit
469 [ "USE: words T{ word }" eval( -- ) ]
470 [ error>> T{ no-method f word new } = ]
473 ! Accessors not being forgotten...
475 "IN: classes.tuple.tests TUPLE: forget-accessors-test x y z ;"
477 "forget-accessors-test" parse-stream
480 { t } [ "forget-accessors-test" "classes.tuple.tests" lookup-word class? ] unit-test
482 : accessor-exists? ( name -- ? )
483 [ "forget-accessors-test" "classes.tuple.tests" lookup-word ] dip
484 ">>" append "accessors" lookup-word ?lookup-method >boolean ;
486 { t } [ "x" accessor-exists? ] unit-test
487 { t } [ "y" accessor-exists? ] unit-test
488 { t } [ "z" accessor-exists? ] unit-test
491 "IN: classes.tuple.tests GENERIC: forget-accessors-test ( a -- b )"
493 "forget-accessors-test" parse-stream
496 { f } [ "forget-accessors-test" "classes.tuple.tests" lookup-word class? ] unit-test
498 { f } [ "x" accessor-exists? ] unit-test
499 { f } [ "y" accessor-exists? ] unit-test
500 { f } [ "z" accessor-exists? ] unit-test
502 TUPLE: another-forget-accessors-test ;
506 "IN: classes.tuple.tests GENERIC: another-forget-accessors-test ( a -- b )"
508 "another-forget-accessors-test" parse-stream
511 { t } [ \ another-forget-accessors-test class? ] unit-test
517 "IN: classes.tuple.tests TUPLE: shadow-1 a b ; TUPLE: shadow-2 < shadow-1 a b ;" eval( -- )
518 ] with-string-writer empty?
522 ! Missing error check
523 [ "IN: classes.tuple.tests USE: words TUPLE: wrong-superclass < word ;" eval( -- ) ] must-fail
525 ! Insufficient type checking
526 [ \ vocab tuple>array drop ] must-fail
528 ! Check type declarations
529 TUPLE: declared-types { n fixnum } { m string } ;
531 { T{ declared-types f 0 "hi" } }
532 [ { declared-types 0 "hi" } >tuple ]
535 [ { declared-types "hi" 0 } >tuple ]
536 [ T{ bad-slot-value f "hi" fixnum } = ]
539 ! Check fixnum coercer
540 [ 0.0 "hi" declared-types boa n>> ] [ T{ no-method f 0.0 integer>fixnum-strict } = ] must-fail-with
542 [ declared-types new 0.0 >>n n>> ] [ T{ no-method f 0.0 integer>fixnum-strict } = ] must-fail-with
544 { T{ declared-types f 33333 "asdf" } }
545 [ 33333 >bignum "asdf" declared-types boa ] unit-test
547 [ 444444444444444444444444444444444444444444444444433333 >bignum "asdf" declared-types boa ]
549 ${ KERNEL-ERROR ERROR-OUT-OF-FIXNUM-RANGE
550 444444444444444444444444444444444444444444444444433333 f } =
553 ! Check bignum coercer
554 TUPLE: bignum-coercer { n bignum initial: $[ 0 >bignum ] } ;
556 { 13 bignum } [ 13.5 bignum-coercer boa n>> dup class-of ] unit-test
558 { 13 bignum } [ bignum-coercer new 13.5 >>n n>> dup class-of ] unit-test
560 ! Check float coercer
561 TUPLE: float-coercer { n float } ;
563 { 13.0 float } [ 13 float-coercer boa n>> dup class-of ] unit-test
565 { 13.0 float } [ float-coercer new 13 >>n n>> dup class-of ] unit-test
567 ! Check integer coercer
568 TUPLE: integer-coercer { n integer } ;
570 [ 13.5 integer-coercer boa n>> dup class-of ] [ T{ bad-slot-value f 13.5 integer } = ] must-fail-with
572 [ integer-coercer new 13.5 >>n n>> dup class-of ] [ T{ bad-slot-value f 13.5 integer } = ] must-fail-with
574 : foo ( a b -- c ) declared-types boa ;
576 \ foo def>> must-infer
578 [ 0.0 "hi" foo ] [ T{ no-method f 0.0 integer>fixnum-strict } = ] must-fail-with
580 [ "hi" 0.0 declared-types boa ]
581 [ T{ no-method f "hi" integer>fixnum-strict } = ]
584 [ 0 { } declared-types boa ]
585 [ T{ bad-slot-value f { } string } = ]
589 [ T{ no-method f "hi" integer>fixnum-strict } = ]
593 [ T{ bad-slot-value f { } string } = ]
596 { T{ declared-types f 0 "" } } [ declared-types new ] unit-test
598 : blah ( -- vec ) vector new ;
600 [ vector new ] must-infer
602 { V{ } } [ blah ] unit-test
606 "IN: classes.tuple.tests TUPLE: forget-subclass-test ; TUPLE: forget-subclass-test' < forget-subclass-test ;"
607 <string-reader> "forget-subclass-test" parse-stream
611 { } [ "forget-subclass-test'" "classes.tuple.tests" lookup-word new "bad-object" set ] unit-test
614 "IN: classes.tuple.tests TUPLE: forget-subclass-test a ;"
615 <string-reader> "forget-subclass-test" parse-stream
621 "IN: sequences TUPLE: reversed { seq read-only } ;" eval( -- )
625 TUPLE: bogus-hashcode-1 x ;
627 TUPLE: bogus-hashcode-2 x ;
629 M: bogus-hashcode-1 hashcode* 2drop 0 >bignum ;
631 { } [ T{ bogus-hashcode-2 f T{ bogus-hashcode-1 } } hashcode drop ] unit-test
633 DEFER: change-slot-test
637 "IN: classes.tuple.tests USING: kernel accessors ; TUPLE: change-slot-test ; SLOT: kex M: change-slot-test kex>> drop 3 ;"
638 <string-reader> "change-slot-test" parse-stream
642 { t } [ \ change-slot-test \ kex>> ?lookup-method >boolean ] unit-test
645 "IN: classes.tuple.tests USING: kernel accessors ; TUPLE: change-slot-test kex ;"
646 <string-reader> "change-slot-test" parse-stream
650 { t } [ \ change-slot-test \ kex>> ?lookup-method >boolean ] unit-test
653 "IN: classes.tuple.tests USING: kernel accessors ; TUPLE: change-slot-test ; SLOT: kex M: change-slot-test kex>> drop 3 ;"
654 <string-reader> "change-slot-test" parse-stream
658 { t } [ \ change-slot-test \ kex>> ?lookup-method >boolean ] unit-test
659 { f } [ \ change-slot-test \ kex>> ?lookup-method "reading" word-prop ] unit-test
661 DEFER: redefine-tuple-twice
663 { } [ "IN: classes.tuple.tests TUPLE: redefine-tuple-twice ;" eval( -- ) ] unit-test
665 { t } [ \ redefine-tuple-twice symbol? ] unit-test
667 { } [ "IN: classes.tuple.tests DEFER: redefine-tuple-twice" eval( -- ) ] unit-test
669 { t } [ \ redefine-tuple-twice deferred? ] unit-test
671 { } [ "IN: classes.tuple.tests TUPLE: redefine-tuple-twice ;" eval( -- ) ] unit-test
673 { t } [ \ redefine-tuple-twice symbol? ] unit-test
676 ! Test reshaping with type declarations and slot attributes
677 TUPLE: reshape-test x ;
679 T{ reshape-test f "hi" } "tuple" set
681 { } [ "IN: classes.tuple.tests TUPLE: reshape-test { x read-only } ;" eval( -- ) ] unit-test
683 { f } [ \ reshape-test \ x<< ?lookup-method ] unit-test
685 [ "tuple" get 5 >>x ] must-fail
687 { "hi" } [ "tuple" get x>> ] unit-test
689 { } [ "IN: classes.tuple.tests USE: math TUPLE: reshape-test { x integer read-only } ;" eval( -- ) ] unit-test
691 { 0 } [ "tuple" get x>> ] unit-test
693 { } [ "IN: classes.tuple.tests USE: math TUPLE: reshape-test { x fixnum initial: 4 read-only } ;" eval( -- ) ] unit-test
695 { 0 } [ "tuple" get x>> ] unit-test
697 TUPLE: boa-coercer-test { x array-capacity } ;
699 { fixnum } [ 0 >bignum boa-coercer-test boa x>> class-of ] unit-test
701 { T{ boa-coercer-test f 0 } } [ T{ boa-coercer-test } ] unit-test
703 TUPLE: boa-iac { x integer-array-capacity initial: 77 } ;
705 { fixnum bignum 77 } [
706 30 boa-iac boa x>> class-of
707 10 >bignum boa-iac boa x>> class-of
711 [ -99 boa-iac boa ] [ bad-slot-value? ] must-fail-with
713 ! Make sure that tuple reshaping updates code heap roots
714 TUPLE: code-heap-ref ;
716 : code-heap-ref' ( -- a ) T{ code-heap-ref } ;
718 ! Push foo's literal to tenured space
722 { } [ "IN: classes.tuple.tests USE: math TUPLE: code-heap-ref { x integer initial: 5 } ;" eval( -- ) ] unit-test
724 ! Code heap reference
725 { t } [ code-heap-ref' code-heap-ref? ] unit-test
726 { 5 } [ code-heap-ref' x>> ] unit-test
728 ! Data heap reference
729 { t } [ \ code-heap-ref' def>> first code-heap-ref? ] unit-test
730 { 5 } [ \ code-heap-ref' def>> first x>> ] unit-test
732 ! If the metaclass of a superclass changes into something other
733 ! than a tuple class, the tuple needs to have its superclass reset
734 TUPLE: metaclass-change ;
735 TUPLE: metaclass-change-subclass < metaclass-change ;
737 { metaclass-change } [ metaclass-change-subclass superclass-of ] unit-test
739 { } [ "IN: classes.tuple.tests MIXIN: metaclass-change" eval( -- ) ] unit-test
741 { t } [ metaclass-change-subclass tuple-class? ] unit-test
742 { tuple } [ metaclass-change-subclass superclass-of ] unit-test
744 ! Reshaping bug related to the above
748 { } [ g new "g" set ] unit-test
750 { } [ "IN: classes.tuple.tests MIXIN: a-g TUPLE: g ;" eval( -- ) ] unit-test
752 { t } [ g new layout-of "g" get layout-of eq? ] unit-test
754 ! Joe Groff discovered this bug
755 DEFER: factor-crashes-anymore
758 "IN: classes.tuple.tests
759 TUPLE: unsafe-slot-access ;
760 CONSTANT: unsafe-slot-access' T{ unsafe-slot-access }" eval( -- )
764 "IN: classes.tuple.tests
766 TUPLE: unsafe-slot-access { x read-only initial: 31337 } ;
767 : factor-crashes-anymore ( -- x ) unsafe-slot-access' x>> ;" eval( -- )
770 { 31337 } [ factor-crashes-anymore ] unit-test
772 TUPLE: tuple-predicate-redefine-test ;
774 { } [ "IN: classes.tuple.tests TUPLE: tuple-predicate-redefine-test ;" eval( -- ) ] unit-test
776 { t } [ \ tuple-predicate-redefine-test? predicate? ] unit-test
779 TUPLE: final-superclass ;
780 TUPLE: final-subclass < final-superclass ;
782 { final-superclass } [ final-subclass superclass-of ] unit-test
784 ! Making the superclass final should change the superclass of the subclass
785 { } [ "IN: classes.tuple.tests TUPLE: final-superclass ; final" eval( -- ) ] unit-test
787 { tuple } [ final-subclass superclass-of ] unit-test
789 { f } [ \ final-subclass final-class? ] unit-test
791 ! Subclassing a final class should fail
792 [ "IN: classes.tuple.tests TUPLE: final-subclass < final-superclass ;" eval( -- ) ]
793 [ error>> bad-superclass? ] must-fail-with
795 ! Making a final class non-final should work
796 { } [ "IN: classes.tuple.tests TUPLE: final-superclass ;" eval( -- ) ] unit-test
798 { } [ "IN: classes.tuple.tests TUPLE: final-subclass < final-superclass ; final" eval( -- ) ] unit-test
800 ! Changing a superclass should not change the final status of a subclass
801 { } [ "IN: classes.tuple.tests TUPLE: final-superclass x ;" eval( -- ) ] unit-test
803 { t } [ \ final-subclass final-class? ] unit-test
805 ! Test reset-class on tuples
806 ! Should forget all accessors on rclasstest
807 TUPLE: rclasstest a b ;
808 { } [ [ \ rclasstest reset-class ] with-compilation-unit ] unit-test
809 { f } [ \ rclasstest \ a>> ?lookup-method ] unit-test
810 { f } [ \ rclasstest \ a<< ?lookup-method ] unit-test
811 { f } [ \ rclasstest \ b>> ?lookup-method ] unit-test
812 { f } [ \ rclasstest \ b<< ?lookup-method ] unit-test
814 << \ rclasstest forget >>
816 ! initial: should type check
817 TUPLE: initial-class ;
821 { } [ "IN: classes.tuple.tests TUPLE: initial-slot { x initial-class } ;" eval( -- ) ] unit-test
823 { t } [ initial-slot new x>> initial-class? ] unit-test
825 [ "IN: classes.tuple.tests TUPLE: initial-slot { x initial-class initial: f } ;" eval( -- ) ]
826 [ error>> T{ bad-initial-value f "x" f initial-class } = ] must-fail-with
828 [ "IN: classes.tuple.tests TUPLE: initial-slot { x initial-class initial: 3 } ;" eval( -- ) ]
829 [ error>> T{ bad-initial-value f "x" 3 initial-class } = ] must-fail-with
831 [ "IN: classes.tuple.tests USE: math TUPLE: foo < foo ;" eval( -- ) ] [ error>> bad-superclass? ] must-fail-with
833 [ "IN: classes.tuple.tests USE: math TUPLE: foo < + ;" eval( -- ) ] [ error>> bad-superclass? ] must-fail-with
836 ! Test no-slot error and get/set-slot-named
838 TUPLE: no-slot-tuple0 a b c ;
839 C: <no-slot-tuple0> no-slot-tuple0
841 [ 1 2 3 <no-slot-tuple0> "d" over get-slot-named ]
845 [ tuple>> no-slot-tuple0? ]
851 [ 1 2 3 <no-slot-tuple0> "a" swap get-slot-named ] unit-test
854 [ 1 2 3 <no-slot-tuple0> "b" swap get-slot-named ] unit-test
857 [ 1 2 3 <no-slot-tuple0> "c" swap get-slot-named ] unit-test
860 1 2 3 <no-slot-tuple0> 4 "a" pick set-slot-named
861 "a" swap get-slot-named
864 [ 1 2 3 <no-slot-tuple0> 4 "d" pick set-slot-named ]
868 [ tuple>> no-slot-tuple0? ]
873 [ "IN: classes.tuple.tests TUPLE: too-many-slots-test a b c d ; T{ too-many-slots-test f 1 2 3 4 5 }" eval( -- x ) ]
874 [ error>> too-many-slots? ] must-fail-with