[t][TT #763] Fix is_deeply() on hashes with undefs and add tests
[parrot.git] / t / library / test_more.t
blob913eca2db5038fa6dda733d3b7d986127576ea68
1 #!parrot
2 # Copyright (C) 2005-2009, Parrot Foundation.
3 # $Id$
5 .sub _main :main
6     load_bytecode 'Test/Builder/Tester.pbc'
7     load_bytecode 'Test/More.pbc'
9     .local pmc tb_args
10     tb_args = new 'Hash'
12     .local pmc test
13     test = new [ 'Test'; 'Builder' ], tb_args
15     .local pmc exports, curr_namespace, test_namespace
16     curr_namespace = get_namespace
17     test_namespace = get_namespace [ 'Test'; 'More' ]
18     exports = split " ", "ok nok is diag like skip todo is_deeply isa_ok isnt throws_like"
19     test_namespace.'export_to'(curr_namespace, exports)
21     test_namespace = get_namespace [ 'Test'; 'Builder'; 'Tester' ]
22     exports = split " ", "plan test_out test_diag test_fail test_pass test_test"
23     test_namespace.'export_to'(curr_namespace, exports)
25     plan( 93 )
27     test_skip()
28     test_todo()
29     test_ok()
30     test_nok()
31     test_is()
32     test_isnt()
33     test_like()
34     test_is_deeply()
35     test_diagnostics()
36     test_throws_like()
37     test_isa_ok()
39     test.'finish'()
40 .end
42 .sub test_throws_like
44     test_fail('throws_like fails when there is no error')
45     throws_like( <<'CODE', 'somejunk', 'throws_like fails when there is no error')
46 .sub main
47     $I0 = 42
48 .end
49 CODE
50     test_diag( 'no error thrown' )
51     test_test( 'throws_like fails when there is no error')
53     test_pass('throws_like passes when error matches pattern')
54     throws_like( <<'CODE', 'for\ the\ lulz','throws_like passes when error matches pattern')
55 .sub main
56     die 'I did it for the lulz'
57 .end
58 CODE
59     test_test( 'throws_like passes when error matches pattern' )
61     test_fail( 'throws_like fails when error does not match pattern' )
62     throws_like( <<'CODE', 'for\ the\ lulz','throws_like fails when error does not match pattern')
63 .sub main
64     die 'DO NOT WANT'
65 .end
66 CODE
67     .local string diagnostic
68     diagnostic  = "match failed: target 'DO NOT WANT' does not match pattern '"
69     diagnostic .= 'for\ the\ lulz'
70     diagnostic .= "'"
71     test_diag( diagnostic )
72     test_test('throws_like fails when error does not match pattern' )
74 .end
76 .namespace ['MyFalseClass']
78 .sub '' :anon :load :init
79     $P0 = newclass ['MyFalseClass']
80 .end
82 .sub 'get_bool' :vtable
83     .return(0)
84 .end
86 .sub 'get_integer' :vtable
87     .return(1)
88 .end
90 .namespace ['MyTrueClass']
92 .sub '' :anon :load :init
93     $P0 = newclass ['MyTrueClass']
94 .end
96 .sub 'get_bool' :vtable
97     .return(1)
98 .end
100 .sub 'get_integer' :vtable
101     .return(0)
102 .end
104 .namespace []
106 .sub test_ok
107     test_pass()
108     ok( 1 )
109     test_test( 'passing test ok()')
111     test_fail()
112     ok( 0 )
113     test_test( 'failing test ok()')
115     test_pass( 'with description' )
116     ok( 1, 'with description' )
117     test_test( 'passing test ok() with description')
119     test_fail( 'with description' )
120     ok( 0, 'with description' )
121     test_test( 'failing test ok() with description')
123     $P0 = new ['MyFalseClass']
124     test_fail()
125     ok( $P0 )
126     test_test( 'failing ok() calls get_bool')
128     $P0 = new ['MyTrueClass']
129     test_pass()
130     ok( $P0 )
131     test_test( 'passing ok() calls get_bool')
132 .end
134 .sub test_nok
135     test_fail()
136     nok( 1 )
137     test_test( 'failing test nok()')
139     test_pass()
140     nok( 0 )
141     test_test( 'passing test nok()')
143     test_fail( 'with description' )
144     nok( 1, 'with description' )
145     test_test( 'failing test nok() with description')
147     test_pass( 'with description' )
148     nok( 0, 'with description' )
149     test_test( 'passing test nok() with description')
151     $P0 = new ['MyFalseClass']
152     test_pass()
153     nok( $P0 )
154     test_test( 'passing nok() calls get_bool')
156     $P0 = new ['MyTrueClass']
157     test_fail()
158     nok( $P0 )
159     test_test( 'failing nok() calls get_bool')
160 .end
162 .sub test_is
163     test_pass()
164     is( 100, 100 )
165     test_test( 'passing test is() for ints')
167     test_fail()
168     test_diag( 'Have: -100' )
169     test_diag( 'Want: 200' )
170     is( -100, 200 )
171     test_test( 'failing test is() for ints')
173     test_pass( 'comparing two integers' )
174     is( 512, 512, 'comparing two integers' )
175     test_test( 'passing test is() for ints with description')
177     test_fail( 'comparing two integers' )
178     is( -512, 5120, 'comparing two integers' )
179     test_diag( 'Have: -512' )
180     test_diag( 'Want: 5120' )
181     test_test( 'failing test is() for ints with description')
183     test_pass()
184     is( 6.5, 6.5 )
185     test_test( 'passing test is() for floats')
187     test_fail()
188     is( 1.235, 5.321 )
189     test_diag( 'Have: 1.235' )
190     test_diag( 'Want: 5.321' )
191     test_test( 'failing test is() for floats')
193     test_pass( 'comparing two floats' )
194     is( 80.80, 80.80, 'comparing two floats' )
195     test_test( 'passing test is() for floats with description')
197     test_fail( 'comparing two floats' )
198     is( 777.1, 888.8, 'comparing two floats' )
199     test_diag( 'Have: 777.1' )
200     test_diag( 'Want: 888.8' )
201     test_test( 'failing test is() for floats with description')
203     test_pass()
204     is( 'bob', 'bob' )
205     test_test( 'passing test is() for strings')
207     test_fail()
208     is( 'larry', 'bob' )
209     test_diag( 'Have: larry' )
210     test_diag( 'Want: bob' )
211     test_test( 'failing test is() for strings')
213     test_pass( 'comparing two strings' )
214     is( 'larry', 'larry', 'comparing two strings' )
215     test_test( 'passing test is() for strings with description')
217     test_fail( 'comparing two strings' )
218     is( 'zeke', 'zelda', 'comparing two strings' )
219     test_diag( 'Have: zeke' )
220     test_diag( 'Want: zelda' )
221     test_test( 'failing test is() for strings with description')
223     .local pmc left
224     .local pmc right
225     left  = new 'String'
226     right = new 'String'
227     left  = 'zero'
228     right = 'zero'
230     test_pass()
231     is( left, right )
232     test_test( 'passing test is() for pmcs')
234     right = new 'Integer'
235     right = 1
236     test_fail( 'zero versus 1' )
237     test_diag( 'Have: zero' )
238     test_diag( 'Want: 1' )
239     is( left, right, 'zero versus 1' )
240     test_test( 'failing test is() for pmcs')
242     left = '1'
243     test_pass( 'comparing two pmcs' )
244     is( left, right, 'comparing two pmcs' )
245     test_test( 'passing test is() for pmcs with description')
247     right = new 'Hash'
249     .local string expected
250     .local string hash_string
251     expected     = 'Want: '
252     hash_string  = right
253     expected    .= hash_string
255     test_fail( 'comparing two pmcs' )
256     test_diag( 'Have: 1' )
257     test_diag( expected )
258     is( left, right, 'comparing two pmcs' )
259     test_test( 'failing test is() for pmcs with description')
260 .end
262 .sub test_isnt
263     test_pass()
264     isnt( 100, 200 )
265     test_test( 'passing test isnt() for ints')
267     test_fail()
268     test_diag( 'Have: -100' )
269     test_diag( 'Want: not -100' )
270     isnt( -100, -100 )
271     test_test( 'failing test isnt() for ints')
273     test_pass( 'comparing two unidentical integers' )
274     isnt( 512, 215, 'comparing two unidentical integers' )
275     test_test( 'passing test isnt() for ints with description')
277     test_fail( 'comparing two integers' )
278     isnt( -512, -512, 'comparing two integers' )
279     test_diag( 'Have: -512' )
280     test_diag( 'Want: not -512' )
281     test_test( 'failing test isnt() for ints with description')
283     test_pass()
284     isnt( -6.5, 6.5 )
285     test_test( 'passing test isnt() for floats')
287     test_fail()
288     isnt( 1.235, 1.235 )
289     test_diag( 'Have: 1.235' )
290     test_diag( 'Want: not 1.235' )
291     test_test( 'failing test isnt() for floats')
293     test_pass( 'comparing two floats' )
294     isnt( 777.1, 888.8, 'comparing two floats' )
295     test_test( 'passing test isnt() for floats with description')
297     test_fail( 'comparing two floats' )
298     isnt( 80.8, 80.8, 'comparing two floats' )
299     test_diag( 'Have: 80.8' )
300     test_diag( 'Want: not 80.8' )
301     test_test( 'failing test isnt() for floats with description')
303     test_pass()
304     isnt( 'bob', 'BoB' )
305     test_test( 'passing test isnt() for strings')
307     test_fail()
308     isnt( 'larry', 'larry' )
309     test_diag( 'Have: larry' )
310     test_diag( 'Want: not larry' )
311     test_test( 'failing test isnt() for strings')
313     test_pass( 'comparing two strings' )
314     isnt( 'zeke', 'zelda', 'comparing two strings' )
315     test_test( 'passing test isnt() for strings with description')
317     test_fail( 'comparing two strings' )
318     isnt( 'larry', 'larry', 'comparing two strings' )
319     test_diag( 'Have: larry' )
320     test_diag( 'Want: not larry' )
321     test_test( 'failing test isnt() for strings with description')
323     .local pmc left
324     .local pmc right
325     left  = new 'String'
326     right = new 'String'
327     left  = 'zero'
328     right = '0'
330     test_pass()
331     isnt( left, right )
332     test_test( 'passing test isnt() for pmcs')
334     right = new 'String'
335     right = 'zero'
336     test_fail()
337     test_diag( 'Have: zero' )
338     test_diag( 'Want: not zero' )
339     isnt( left, right )
340     test_test( 'failing test isnt() for pmcs')
342     left = '0'
343     test_pass( 'comparing two pmcs' )
344     isnt( left, right, 'comparing two pmcs' )
345     test_test( 'passing test isnt() for pmcs with description')
347     right = new 'Hash'
349     .local string expected
350     .local string hash_string
351     expected     = 'Want: '
352     hash_string  = right
353     expected    .= hash_string
355     test_pass( 'comparing two pmcs' )
356     isnt( left, right, 'comparing two pmcs' )
357     test_test( 'failing test isnt() for pmcs with description')
358 .end
360 .sub test_like
361     test_pass()
362     like( 'abcdef', '<[c]>' )
363     test_test( 'passing test like()' )
365     test_pass( 'testing like()' )
366     like( 'abcdef', '<[c]>', 'testing like()' )
367     test_test( 'passing test like() with description' )
369     test_fail()
371     test_diag( "match failed: target 'abcdef' does not match pattern '<[g]>'" )
372     like( 'abcdef', '<[g]>' )
373     test_test( 'failing test like()' )
375     test_fail( 'testing like()' )
376     test_diag( "match failed: target 'abcdef' does not match pattern '<[g]>'" )
377     like( 'abcdef', '<[g]>', 'testing like()' )
378     test_test( 'failing test like() with description' )
380     test_pass( 'like() can match literal strings' )
381     like( 'foobar', 'foobar', 'like() can match literal strings' )
382     test_test( 'like() can match literal strings' )
384     test_pass( 'like() can match partial literal strings' )
385     like( 'foobar()', 'foobar', 'like() can match partial literal strings' )
386     test_test( 'like() can match partial literal strings' )
388     test_pass( 'like() can match partial literal strings with spaces' )
389     like( 'foo bar()', 'foo\ bar', 'like() can match partial literal strings with spaces' )
390     test_test( 'like() can match partial literal strings with spaces' )
391 .end
393 .sub test_is_deeply
394     test_is_deeply_array()
395     test_is_deeply_hash()
396     test_is_deeply_hash_tt763()
397     test_is_deeply_mismatch()
398     test_is_deeply_nested()
399 .end
401 .sub test_is_deeply_array
402     .local pmc left
403     .local pmc right
404     left  = new 'ResizablePMCArray'
405     right = new 'ResizablePMCArray'
407     push left,  7
408     push right, 7
409     push left,  'seven'
410     push right, 'seven'
412     test_pass()
413     is_deeply( left, right )
414     test_test( 'passing test is_deeply() for pmc arrays' )
416     test_pass( 'comparing two pmc arrays' )
417     is_deeply( left, right, 'comparing two pmc arrays' )
418     test_test( 'passing test is_deeply() for pmc arrays with description' )
420     push left,  '9 - 2'
422     test_fail()
423     test_diag( 'Mismatch: expected 3 elements, received 2' )
424     is_deeply( left, right )
425     test_test( 'failing test is_deeply() for pmc arrays' )
427     test_fail( 'comparing two pmc arrays' )
428     test_diag( 'Mismatch: expected 3 elements, received 2' )
429     is_deeply( left, right, 'comparing two pmc arrays' )
430     test_test( 'failing test is_deeply() for pmc arrays with description' )
432     push right, '9 - 3'
433     test_fail()
434     test_diag( 'Mismatch at [2]: expected 9 - 2, received 9 - 3' )
435     is_deeply( left, right )
436     test_test( 'failing test is_deeply() for item mismatch at position' )
438     test_fail( 'comparing mismatch of elements' )
439     test_diag( 'Mismatch at [2]: expected 9 - 2, received 9 - 3' )
440     is_deeply( left, right, 'comparing mismatch of elements' )
441     test_test( 'failing test is_deeply() for item mismatch at position' )
442 .end
444 .sub test_is_deeply_hash
445     .local pmc left
446     .local pmc right
447     .local pmc undef1
448     .local pmc undef2
450     left   = new 'Hash'
451     right  = new 'Hash'
452     undef1 = new 'Undef'
453     undef2 = new 'Undef'
455     test_pass()
456     is_deeply( left, right )
457     test_test( 'passing test is_deeply() for empty pmc hashes' )
459     test_pass( 'empty hashes match' )
460     is_deeply( left, right, 'empty hashes match' )
461     test_test( 'passing test is_deeply() for empty pmc hashes with diagnostic' )
463     left['foo'] = 1
465     test_fail()
466     is_deeply( left, right )
467     test_diag( 'Mismatch: expected 1 element, received 0' )
468     test_test( 'failing is_deeply() for hashes with different numbers of keys' )
470     left['bar']  = 1
471     right['bar'] = 1
473     test_fail( 'more diag' )
474     is_deeply( left, right, 'more diag' )
475     test_diag( 'Mismatch: expected 2 elements, received 1' )
476     test_test( '... with description and proper pluralization' )
478     right['foo'] = 2
480     test_fail()
481     is_deeply( left, right )
482     test_diag( 'Mismatch at [foo]: expected 1, received 2' )
483     test_test( 'failing is_deeply() for hash with value mismatch' )
485     test_fail( '2 is not 1' )
486     is_deeply( left, right, '2 is not 1' )
487     test_diag( 'Mismatch at [foo]: expected 1, received 2' )
488     test_test( '... with description' )
490     right['foo'] = 1
491     test_pass()
492     is_deeply( left, right )
493     test_test( 'passing test is_deeply() for hashes created in different orders' )
494 .end
496 .sub test_is_deeply_hash_tt763
497     .local pmc left
498     .local pmc right
499     .local pmc undef1
500     .local pmc undef2
502     left   = new 'Hash'
503     right  = new 'Hash'
504     undef1 = new 'Undef'
505     undef2 = new 'Undef'
506     right['undef1'] = undef1
507     left['undef2']  = undef2
509     test_fail()
510     is_deeply( left, right )
511     test_diag( 'Mismatch at [undef2]: expected (undef), received nonexistent' )
512     test_test( 'failing is_deeply() for undef in left, nonexistent in right' )
514     test_fail()
515     is_deeply( right, left )
516     test_diag( 'Mismatch at [undef1]: expected (undef), received nonexistent' )
517     test_test( 'failing is_deeply() for undef in left, nonexistent in right' )
519     right['undef2'] = undef2
520     left['undef1']  = undef1
522     test_pass()
523     is_deeply( left, right )
524     test_test( 'passing is_deeply() with undef values' )
526     left['foo'] = undef1
527     test_fail()
528     is_deeply( left, right )
529     test_diag( 'Mismatch: expected 3 elements, received 2')
530     test_test( 'failing is_deeply() for hashes differing by keys with undef values' )
532 .end
534 .sub test_is_deeply_mismatch
535 .end
537 .sub test_is_deeply_nested
538     .local pmc left
539     .local pmc right
541     left  = new 'Hash'
542     right = new 'Hash'
544     .local pmc left_array
545     .local pmc right_array
546     left_array  = new 'Array'
547     left_array  = 3
548     right_array = new 'Array'
549     right_array = 3
551     left[  'array' ] = left_array
552     right[ 'array' ] = right_array
554     left_array[0]  = 1
555     right_array[0] = 1
557     test_pass()
558     is_deeply( left, right )
559     test_test( 'Nested data structure equality' )
561     test_pass( '... are they equal?' )
562     is_deeply( left, right, '... are they equal?' )
563     test_test( '... with description' )
565     right_array[2] = 2
567     test_fail()
568     is_deeply( left, right )
569     test_diag( 'Mismatch at [array][2]: expected (undef), received 2' )
570     test_test( 'Nested data structure inequality' )
572     test_fail( '... are they inequal?' )
573     is_deeply( left, right, '... are they inequal?' )
574     test_diag( 'Mismatch at [array][2]: expected (undef), received 2' )
575     test_test( '... with description' )
576 .end
578 .sub test_diagnostics
579     test_pass()
580     ok( 1 )
581     diag( 'foo bar baz' )
582     test_diag( 'foo bar baz' )
583     test_test( 'single line diagnostics' )
585     test_pass()
586     ok( 1 )
587     diag( 'foo bar baz' )
588     diag( 'rum tum tugger')
589     test_diag( "foo bar baz\nrum tum tugger" )
590     test_test( 'multi line diagnostics' )
591 .end
593 .sub test_skip
595     .local pmc test
596     test = new [ 'Test'; 'Builder' ]
598     test_out( 'ok 1 #skip skipping' )
599     test_out( 'ok 2 #skip skipping' )
600     test.'skip'( 2, 'skipping' )
601     test_test( 'skip test should pass' )
603     test_out( 'ok 3 #skip skipped' )
604     skip( 1 )
605     test_test( 'skip(int)' )
607     test_out( 'ok 4 #skip jumping' )
608     skip( "jumping" )
609     test_test( 'skip(string)' )
611     test_out( 'ok 5 #skip lunch' )
612     test_out( 'ok 6 #skip lunch' )
613     skip( 2, "lunch" )
614     test_test( 'skip(int, string)' )
616     test_out( 'ok 7 #skip skipped' )
617     skip()
618     test_test( 'skip()' )
619 .end
621 .sub test_todo
623     .local pmc test
624     test = new [ 'Test'; 'Builder' ]
626     test_out( 'ok 8 # TODO passing test' )
627     test.'todo'( 1, 'passing test', 'todo reason' )
628     test_test( 'todo test should pass, marked as TODO' )
630     test_out( 'not ok 9 # TODO failing test' )
631     test.'todo'( 0, 'failing test', 'todo reason' )
632     test_test( 'todo test should fail, marked as TODO' )
634     test_out( 'ok 10 # TODO passing test' )
635     todo( 1, 'passing test', 'todo reason' )
636     test_test( 'todo test should pass, marked as TODO' )
638     test_out( 'not ok 11 # TODO failing test' )
639     todo( 0, 'failing test', 'todo reason' )
640     test_test( 'todo test should fail, marked as TODO' )
642     test_out( 'not ok 12 # TODO' )
643     todo( 0 )
644     test_test( 'todo test with no description or reason' )
646 .end
648 .sub test_isa_ok
649     .local pmc dog, terrier, daschund, Spot, Sossy
651     dog = newclass "dog"
652     terrier = subclass dog, "terrier"
653     daschund = subclass dog, "daschund"
655     Spot = new "terrier"
656     Sossy = new "daschund"
658     test_pass( 'Spot isa terrier' )
659     isa_ok(Spot, "terrier", "Spot")
660     test_test( 'passing isa_ok for PMC/string (class =)' )
662     test_pass( 'Spot isa dog' )
663     isa_ok(Spot, "dog", "Spot")
664     test_test( 'passing isa_ok for PMC/string (super)')
666     test_pass( 'Sossy isa daschund' )
667     $P1 = new 'String'
668         $P1 = "daschund"
669     isa_ok(Sossy, $P1, "Sossy")
670     test_test( 'passing isa_ok for PMC/PMC (class =)' )
672     test_pass( 'Sossy isa dog' )
673     $P2 = new 'String'
674         $P2 = "dog"
675     isa_ok(Sossy, $P2, "Sossy")
676     test_test( 'passing isa_ok for PMC/PMC (super)')
678     test_pass( 'The object isa terrier' )
679     isa_ok(Spot, "terrier")
680     test_test( 'passing isa_ok with no object description (class =)' )
682     test_fail( 'Spot isa daschund' )
683     test_diag( "Spot isn't a daschund it's a terrier" )
684     isa_ok(Spot, 'daschund', "Spot")
685     test_test( 'failing test isnt() for PMC/string')
687 .end
688 # Local Variables:
689 #   mode: pir
690 #   fill-column: 100
691 # End:
692 # vim: expandtab shiftwidth=4 ft=pir: