1 USING: definitions generic kernel kernel.private math
2 math.constants parser sequences tools.test words assocs
3 namespaces quotations sequences.private classes continuations
4 generic.standard effects classes.tuple classes.tuple.private
5 arrays vectors strings compiler.units accessors classes.algebra
6 calendar prettyprint io.streams.string splitting inspector
7 columns math.order classes.private slots.private ;
8 IN: classes.tuple.tests
11 : <rect> ( x y w h -- rect ) rect boa ;
13 : move ( x rect -- rect )
16 [ f ] [ 10 20 30 40 <rect> dup clone 5 swap move = ] unit-test
18 [ t ] [ 10 20 30 40 <rect> dup clone 0 swap move = ] unit-test
20 ! Make sure we handle tuple class redefinition
21 TUPLE: redefinition-test ;
23 C: <redefinition-test> redefinition-test
25 <redefinition-test> "redefinition-test" set
27 [ t ] [ "redefinition-test" get redefinition-test? ] unit-test
29 "IN: classes.tuple.tests TUPLE: redefinition-test ;" eval
31 [ t ] [ "redefinition-test" get redefinition-test? ] unit-test
33 ! Make sure we handle changing shapes!
38 [ ] [ 100 200 <point> "p" set ] unit-test
40 ! Use eval to sequence parsing explicitly
41 [ ] [ "IN: classes.tuple.tests TUPLE: point x y z ;" eval ] unit-test
43 [ 100 ] [ "p" get x>> ] unit-test
44 [ 200 ] [ "p" get y>> ] unit-test
45 [ f ] [ "p" get "z>>" "accessors" lookup execute ] unit-test
47 [ ] [ "p" get 300 ">>z" "accessors" lookup execute drop ] unit-test
49 [ 4 ] [ "p" get tuple-size ] unit-test
51 [ 300 ] [ "p" get "z>>" "accessors" lookup execute ] unit-test
53 [ ] [ "IN: classes.tuple.tests TUPLE: point z y ;" eval ] unit-test
55 [ 3 ] [ "p" get tuple-size ] unit-test
57 [ "p" get x>> ] must-fail
58 [ 200 ] [ "p" get y>> ] unit-test
59 [ 300 ] [ "p" get "z>>" "accessors" lookup execute ] unit-test
61 TUPLE: predicate-test ;
63 C: <predicate-test> predicate-test
65 : predicate-test drop f ;
67 [ t ] [ <predicate-test> predicate-test? ] unit-test
69 PREDICATE: silly-pred < tuple
72 GENERIC: area ( obj -- n )
73 M: silly-pred area dup w>> swap h>> * ;
75 TUPLE: circle radius ;
76 M: circle area radius>> sq pi * ;
78 [ 200 ] [ T{ rect f 0 0 10 20 } area ] unit-test
85 [ t ] [ <empty> hashcode fixnum? ] unit-test
88 [ t length ] [ object>> t eq? ] must-fail-with
90 [ "<constructor-test>" ]
91 [ "IN: classes.tuple.test TUPLE: constructor-test ; C: <constructor-test> constructor-test" eval word word-name ] unit-test
93 TUPLE: size-test a b c d ;
96 T{ size-test } tuple-size
97 size-test tuple-layout layout-size =
104 "IN: classes.tuple.tests C: <yo-momma> yo-momma" eval
106 [ f ] [ \ <yo-momma> generic? ] unit-test
110 [ t ] [ \ yo-momma class? ] unit-test
111 [ ] [ \ yo-momma forget ] unit-test
112 [ ] [ \ <yo-momma> forget ] unit-test
113 [ f ] [ \ yo-momma update-map get values memq? ] unit-test
115 [ f ] [ \ yo-momma crossref get at ] unit-test
116 ] with-compilation-unit
118 TUPLE: loc-recording ;
120 [ f ] [ \ loc-recording where not ] unit-test
122 ! 'forget' wasn't robust enough
124 TUPLE: forget-robustness ;
126 GENERIC: forget-robustness-generic
128 M: forget-robustness forget-robustness-generic ;
130 M: integer forget-robustness-generic ;
133 [ ] [ \ forget-robustness-generic forget ] unit-test
134 [ ] [ \ forget-robustness forget ] unit-test
135 [ ] [ { forget-robustness forget-robustness-generic } forget ] unit-test
136 ] with-compilation-unit
138 ! rapido found this one
139 GENERIC# m1 0 ( s n -- n )
140 GENERIC# m2 1 ( s n -- v )
164 [ 1 ] [ 1 <t4> m1 ] unit-test
165 [ 1 ] [ <t4> 1 m2 ] unit-test
167 ! another combination issue
168 GENERIC: silly ( obj -- obj obj )
170 UNION: my-union slice repetition column array vector reversed ;
172 M: my-union silly "x" ;
176 M: column silly "fdsfds" ;
178 M: repetition silly "zzz" ;
180 M: reversed silly "zz" ;
182 M: slice silly "tt" ;
184 M: string silly "t" ;
186 M: vector silly "z" ;
188 [ "zz" ] [ 123 <reversed> silly nip ] unit-test
191 SYMBOL: not-a-tuple-class
194 "IN: classes.tuple.tests C: <not-a-tuple-class> not-a-tuple-class"
199 "not-a-tuple-class" "classes.tuple.tests" lookup symbol?
203 [ not-a-tuple-class boa ] must-fail
204 [ not-a-tuple-class new ] must-fail
206 TUPLE: erg's-reshape-problem a b c d ;
208 C: <erg's-reshape-problem> erg's-reshape-problem
210 ! We want to make sure constructors are recompiled when
211 ! tuples are reshaped
212 : cons-test-1 ( -- tuple ) \ erg's-reshape-problem new ;
213 : cons-test-2 ( a b c d -- tuple ) \ erg's-reshape-problem boa ;
215 "IN: classes.tuple.tests TUPLE: erg's-reshape-problem a b c d e f ;" eval
217 [ ] [ 1 2 3 4 5 6 cons-test-2 "a" set ] unit-test
219 [ t ] [ cons-test-1 tuple-size "a" get tuple-size = ] unit-test
222 "IN: classes.tuple.tests SYMBOL: not-a-class C: <not-a-class> not-a-class" eval
223 ] [ error>> not-a-tuple-class? ] must-fail-with
226 TUPLE: computer cpu ram ;
227 C: <computer> computer
229 [ "TUPLE: computer cpu ram ;" ] [
230 [ \ computer see ] with-string-writer string-lines second
233 TUPLE: laptop < computer battery ;
236 [ t ] [ laptop tuple-class? ] unit-test
237 [ t ] [ laptop tuple class<= ] unit-test
238 [ t ] [ laptop computer class<= ] unit-test
239 [ t ] [ laptop computer classes-intersect? ] unit-test
241 [ ] [ "Pentium" 128 3 hours <laptop> "laptop" set ] unit-test
242 [ t ] [ "laptop" get laptop? ] unit-test
243 [ t ] [ "laptop" get computer? ] unit-test
244 [ t ] [ "laptop" get tuple? ] unit-test
246 : test-laptop-slot-values ( -- )
247 [ laptop ] [ "laptop" get class ] unit-test
248 [ "Pentium" ] [ "laptop" get cpu>> ] unit-test
249 [ 128 ] [ "laptop" get ram>> ] unit-test
250 [ t ] [ "laptop" get battery>> 3 hours = ] unit-test ;
252 test-laptop-slot-values
256 dup layout-echelon swap
257 layout-superclasses nth
260 [ "TUPLE: laptop < computer battery ;" ] [
261 [ \ laptop see ] with-string-writer string-lines second
264 [ { tuple computer laptop } ] [ laptop superclasses ] unit-test
266 TUPLE: server < computer rackmount ;
269 [ t ] [ server tuple-class? ] unit-test
270 [ t ] [ server tuple class<= ] unit-test
271 [ t ] [ server computer class<= ] unit-test
272 [ t ] [ server computer classes-intersect? ] unit-test
274 [ ] [ "PowerPC" 64 "1U" <server> "server" set ] unit-test
275 [ t ] [ "server" get server? ] unit-test
276 [ t ] [ "server" get computer? ] unit-test
277 [ t ] [ "server" get tuple? ] unit-test
279 : test-server-slot-values ( -- )
280 [ server ] [ "server" get class ] unit-test
281 [ "PowerPC" ] [ "server" get cpu>> ] unit-test
282 [ 64 ] [ "server" get ram>> ] unit-test
283 [ "1U" ] [ "server" get rackmount>> ] unit-test ;
285 test-server-slot-values
287 [ f ] [ "server" get laptop? ] unit-test
288 [ f ] [ "laptop" get server? ] unit-test
290 [ f ] [ server laptop class<= ] unit-test
291 [ f ] [ laptop server class<= ] unit-test
292 [ f ] [ laptop server classes-intersect? ] unit-test
294 [ f ] [ 1 2 <computer> laptop? ] unit-test
295 [ f ] [ \ + server? ] unit-test
297 [ "TUPLE: server < computer rackmount ;" ] [
298 [ \ server see ] with-string-writer string-lines second
302 "IN: classes.tuple.tests TUPLE: bad-superclass < word ;" eval
305 ! Dynamically changing inheritance hierarchy
306 TUPLE: electronic-device ;
308 [ ] [ "IN: classes.tuple.tests TUPLE: computer < electronic-device cpu ram ;" eval ] unit-test
310 [ f ] [ electronic-device laptop class<= ] unit-test
311 [ t ] [ server electronic-device class<= ] unit-test
312 [ t ] [ laptop server class-or electronic-device class<= ] unit-test
314 [ t ] [ "laptop" get electronic-device? ] unit-test
315 [ t ] [ "laptop" get computer? ] unit-test
316 [ t ] [ "laptop" get laptop? ] unit-test
317 [ f ] [ "laptop" get server? ] unit-test
319 [ t ] [ "server" get electronic-device? ] unit-test
320 [ t ] [ "server" get computer? ] unit-test
321 [ f ] [ "server" get laptop? ] unit-test
322 [ t ] [ "server" get server? ] unit-test
324 [ ] [ "IN: classes.tuple.tests TUPLE: computer cpu ram ;" eval ] unit-test
326 [ f ] [ "laptop" get electronic-device? ] unit-test
327 [ t ] [ "laptop" get computer? ] unit-test
329 [ ] [ "IN: classes.tuple.tests TUPLE: computer < electronic-device cpu ram disk ;" eval ] unit-test
331 test-laptop-slot-values
332 test-server-slot-values
334 [ ] [ "IN: classes.tuple.tests TUPLE: electronic-device voltage ;" eval ] unit-test
336 test-laptop-slot-values
337 test-server-slot-values
339 TUPLE: make-me-some-accessors voltage grounded? ;
341 [ f ] [ "laptop" get voltage>> ] unit-test
342 [ f ] [ "server" get voltage>> ] unit-test
344 [ ] [ "laptop" get 220 >>voltage drop ] unit-test
345 [ ] [ "server" get 110 >>voltage drop ] unit-test
347 [ ] [ "IN: classes.tuple.tests TUPLE: electronic-device voltage grounded? ;" eval ] unit-test
349 test-laptop-slot-values
350 test-server-slot-values
352 [ 220 ] [ "laptop" get voltage>> ] unit-test
353 [ 110 ] [ "server" get voltage>> ] unit-test
355 [ ] [ "IN: classes.tuple.tests TUPLE: electronic-device grounded? voltage ;" eval ] unit-test
357 test-laptop-slot-values
358 test-server-slot-values
360 [ 220 ] [ "laptop" get voltage>> ] unit-test
361 [ 110 ] [ "server" get voltage>> ] unit-test
363 ! Reshaping superclass and subclass simultaneously
364 "IN: classes.tuple.tests TUPLE: electronic-device voltage ; TUPLE: computer < electronic-device cpu ram ;" eval
366 test-laptop-slot-values
367 test-server-slot-values
369 [ 220 ] [ "laptop" get voltage>> ] unit-test
370 [ 110 ] [ "server" get voltage>> ] unit-test
373 TUPLE: test1 a ; TUPLE: test2 < test1 b ;
377 "a" "b" <test2> "test" set
380 [ "a" ] [ "test" get a>> ] unit-test
381 [ "b" ] [ "test" get b>> ] unit-test ;
385 [ ] [ "IN: classes.tuple.tests TUPLE: test1 a x ; TUPLE: test2 < test1 b y ;" eval ] unit-test
389 [ ] [ "IN: classes.tuple.tests TUPLE: test1 a ; TUPLE: test2 < test1 b ;" eval ] unit-test
393 ! Twice in the same compilation unit
395 test1 tuple { "a" "x" "y" } define-tuple-class
396 test1 tuple { "a" "y" } define-tuple-class
397 ] with-compilation-unit
401 ! Moving slots up and down
402 TUPLE: move-up-1 a b ;
403 TUPLE: move-up-2 < move-up-1 c ;
405 T{ move-up-2 f "a" "b" "c" } "move-up" set
407 : test-move-up ( -- )
408 [ "a" ] [ "move-up" get a>> ] unit-test
409 [ "b" ] [ "move-up" get b>> ] unit-test
410 [ "c" ] [ "move-up" get c>> ] unit-test ;
414 [ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 a b c ; TUPLE: move-up-2 < move-up-1 ;" eval ] unit-test
418 [ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 a c ; TUPLE: move-up-2 < move-up-1 b ;" eval ] unit-test
422 [ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 c ; TUPLE: move-up-2 < move-up-1 b a ;" eval ] unit-test
426 [ ] [ "IN: classes.tuple.tests TUPLE: move-up-1 ; TUPLE: move-up-2 < move-up-1 a b c ;" eval ] unit-test
428 ! Constructors must be recompiled when changing superclass
429 TUPLE: constructor-update-1 xxx ;
431 TUPLE: constructor-update-2 < constructor-update-1 yyy zzz ;
433 C: <constructor-update-2> constructor-update-2
435 { 3 1 } [ <constructor-update-2> ] must-infer-as
437 [ ] [ "IN: classes.tuple.tests TUPLE: constructor-update-1 xxx ttt www ;" eval ] unit-test
439 { 5 1 } [ <constructor-update-2> ] must-infer-as
441 [ { f 1 2 3 4 5 } ] [ 1 2 3 4 5 <constructor-update-2> tuple-slots ] unit-test
443 ! Redefinition problem
444 TUPLE: redefinition-problem ;
446 UNION: redefinition-problem' redefinition-problem integer ;
448 [ t ] [ 3 redefinition-problem'? ] unit-test
450 TUPLE: redefinition-problem-2 ;
452 "IN: classes.tuple.tests TUPLE: redefinition-problem < redefinition-problem-2 ;" eval
454 [ t ] [ 3 redefinition-problem'? ] unit-test
456 ! Hardcore unit tests
459 \ thread slot-names "slot-names" set
463 \ thread tuple { "xxx" } "slot-names" get append
465 ] with-compilation-unit
467 [ 1337 sleep ] "Test" spawn drop
470 \ thread tuple "slot-names" get
472 ] with-compilation-unit
477 \ vocab slot-names "slot-names" set
481 \ vocab tuple { "xxx" } "slot-names" get append
483 ] with-compilation-unit
488 \ vocab tuple "slot-names" get
490 ] with-compilation-unit
493 [ "USE: words T{ word }" eval ] [ error>> not-a-tuple-class? ] must-fail-with
495 ! Accessors not being forgotten...
497 "IN: classes.tuple.tests TUPLE: forget-accessors-test x y z ;"
499 "forget-accessors-test" parse-stream
502 [ t ] [ "forget-accessors-test" "classes.tuple.tests" lookup class? ] unit-test
504 : accessor-exists? ( class name -- ? )
505 >r "forget-accessors-test" "classes.tuple.tests" lookup r>
506 ">>" append "accessors" lookup method >boolean ;
508 [ t ] [ "x" accessor-exists? ] unit-test
509 [ t ] [ "y" accessor-exists? ] unit-test
510 [ t ] [ "z" accessor-exists? ] unit-test
513 "IN: classes.tuple.tests GENERIC: forget-accessors-test"
515 "forget-accessors-test" parse-stream
518 [ f ] [ "forget-accessors-test" "classes.tuple.tests" lookup class? ] unit-test
520 [ f ] [ "x" accessor-exists? ] unit-test
521 [ f ] [ "y" accessor-exists? ] unit-test
522 [ f ] [ "z" accessor-exists? ] unit-test
524 TUPLE: another-forget-accessors-test ;
528 "IN: classes.tuple.tests GENERIC: another-forget-accessors-test"
530 "another-forget-accessors-test" parse-stream
533 [ t ] [ \ another-forget-accessors-test class? ] unit-test
539 "IN: classes.tuple.tests TUPLE: shadow-1 a b ; TUPLE: shadow-2 < shadow-1 a b ;" eval
540 ] with-string-writer empty?
544 ! Missing error check
545 [ "IN: classes.tuple.tests USE: words TUPLE: wrong-superclass < word ;" eval ] must-fail
547 ! Class forget messyness
548 TUPLE: subclass-forget-test ;
550 TUPLE: subclass-forget-test-1 < subclass-forget-test ;
551 TUPLE: subclass-forget-test-2 < subclass-forget-test ;
552 TUPLE: subclass-forget-test-3 < subclass-forget-test-2 ;
554 [ ] [ "IN: classes.tuple.tests FORGET: subclass-forget-test" eval ] unit-test
556 [ { subclass-forget-test-2 } ]
557 [ subclass-forget-test-2 class-usages ]
560 [ { subclass-forget-test-3 } ]
561 [ subclass-forget-test-3 class-usages ]
564 [ f ] [ subclass-forget-test-1 tuple-class? ] unit-test
565 [ f ] [ subclass-forget-test-2 tuple-class? ] unit-test
566 [ subclass-forget-test-3 new ] must-fail
568 [ "IN: classes.tuple.tests TUPLE: subclass-forget-test-4 < subclass-forget-test-2 ;" eval ] must-fail
571 DEFER: subclass-reset-test
572 DEFER: subclass-reset-test-1
573 DEFER: subclass-reset-test-2
574 DEFER: subclass-reset-test-3
576 GENERIC: break-me ( obj -- )
578 [ ] [ [ { integer break-me } forget ] with-compilation-unit ] unit-test
580 [ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test ;" <string-reader> "subclass-reset-test" parse-stream drop ] unit-test
581 [ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-1 < subclass-reset-test ;" eval ] unit-test
582 [ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-2 < subclass-reset-test ;" eval ] unit-test
583 [ ] [ "IN: classes.tuple.tests TUPLE: subclass-reset-test-3 < subclass-reset-test-2 ;" eval ] unit-test
585 [ ] [ "IN: classes.tuple.tests USE: kernel M: subclass-reset-test-1 break-me drop ;" eval ] unit-test
587 [ ] [ "IN: classes.tuple.tests : subclass-reset-test ;" <string-reader> "subclass-reset-test" parse-stream drop ] unit-test
589 [ f ] [ subclass-reset-test-1 tuple-class? ] unit-test
590 [ f ] [ subclass-reset-test-2 tuple-class? ] unit-test
591 [ subclass-forget-test-3 new ] must-fail
593 [ t ] [ \ break-me "methods" word-prop assoc-empty? ] unit-test
595 [ ] [ "IN: classes.tuple.tests USE: math USE: kernel M: integer break-me drop ;" eval ] unit-test
597 [ f ] [ \ break-me "methods" word-prop assoc-empty? ] unit-test
599 ! Insufficient type checking
600 [ \ vocab tuple>array drop ] must-fail