2 # Copyright (C) 2001-2010, Parrot Foundation.
7 t/pmc/hash.t - Test the Hash PMC
15 Tests the C<Hash> PMC. Checks key access with various types of
16 normal and potentially hazardous keys. Does a bit of stress testing as
21 .include 'except_types.pasm'
22 .include 'datatypes.pasm'
23 .include 'hash_key_type.pasm'
26 .include 'test_more.pir'
35 hash_keys_with_nulls_in_them()
36 nearly_the_same_hash_keys()
38 key_that_hashes_to_zero()
40 stress_test_loop_set_check()
41 stress_test_lots_of_keys()
42 stress_test_loop_set_loop_check()
43 testing_two_hash_indices_with_integers_at_a_time()
44 testing_two_hash_indices_with_numbers_at_a_time()
45 testing_two_hash_indices_with_strings_at_a_time()
46 setting_and_getting_scalar_pmcs()
47 setting_scalar_pmcs_and_getting_scalar_values()
48 getting_values_from_undefined_keys()
49 setting_and_getting_non_scalar_pmcs()
51 clone_doesnt_crash_on_deleted_keys()
52 clone_preserves_order()
53 freeze_thaw_preserves_order()
55 getting_pmcs_from_compound_keys()
56 getting_pmcs_from_string_int_compound_keys()
64 delete_and_free_list()
65 exists_with_constant_string_key()
67 setting_with_compound_keys()
68 mutating_the_lookup_string()
69 check_whether_interface_is_done()
72 unicode_keys_register_rt_39249()
73 unicode_keys_literal_rt_39249()
76 value_types_convertion()
83 .sub initial_hash_tests
88 set $P0["baz"], "value"
94 is( $I0, -7, 'lookup Int in hash' )
95 is( $N0, 3.500000, 'lookup Num in hash' )
96 is( $S0, "value", 'lookup Str in hash' )
104 set $P0[$S3], "VALUE"
110 is( $I0, 7, 'lookup Int in hash via Str' )
111 is( $N0, -3.500000, 'lookup Num in hash via Str' )
112 is( $S0, "VALUE", 'lookup Str in hash via Str' )
116 .sub more_than_one_hash
122 set $S1, "another_key"
128 is( $I0, 1, 'two hashes: lookup Int from hash via Str' )
129 is( $I1, 2, 'two hashes: lookup Int from hash via Str in second' )
136 h = .Hash_key_type_int
139 is(i, 42, 'key type int')
141 # Use the method here to check it at the same time.
142 h.'set_key_type'(.Hash_key_type_STRING)
145 isnt(i, 42, 'key type STRING')
146 i = h.'get_key_type'()
147 is(i, .Hash_key_type_STRING, 'method get_key_type return type STRING')
150 h = -973 # Let's hope it will never become a valid type
152 ok(0, "Setting invalid type should throw")
156 ok(1, 'Setting invalid type throws')
165 h.'set_value_type'(.DATATYPE_INTVAL)
166 r = h.'get_value_type'()
167 is(r, .DATATYPE_INTVAL, 'get/set _value_type')
170 eh = new ['ExceptionHandler']
171 eh.'handle_types'(.EXCEPTION_UNIMPLEMENTED)
174 h.'set_value_type'(999999)
177 is(r, 1, 'set_value_type with invalid type throws')
186 $P2 = new ['ExceptionHandler']
187 $P2.'handle_types'(.EXCEPTION_UNEXPECTED_NULL)
188 set_addr $P2, null_ex_eh
200 is( $I0, 1, 'using null string as key throws' )
203 .sub hash_keys_with_nulls_in_them
208 set $P0[$S0], 1 # $P0{parp\0me} = 1
209 set $P0[$S1], 2 # $P0{parp\0you} = 2
214 is( $I0, 1, 'hash key with null 1' )
215 is( $I1, 2, 'hash key will null 2' )
218 .sub nearly_the_same_hash_keys
229 is( $I0, 1, 'hash key with null' )
230 is( $I1, 2, 'almost identical hash key with null' )
233 .sub the_same_hash_keys
240 is( $I0, 1, 'lookup by $S0' )
245 is( $I1, 2, 'set and lookup by $S1 (identical to $S0)' )
248 # NB Next test depends on "key2" hashing to zero, which it does with
249 # the current algorithm; if the algorithm changes, change the test!
252 .sub key_that_hashes_to_zero
258 is( $I0, 1, 'key that hashes to zero XXX' )
261 .sub size_of_the_hash
266 is( $I0, 1, 'hash size of 1' )
270 is( $I0, 2, 'hash size of 2' )
274 is( $I0, 2, 'hash size of 2' )
277 .sub stress_test_loop_set_check
284 set $P0[$S1], "bases"
287 set $P0[$S1], "start"
288 set $S3, $P0["mikey"]
289 is( $S3, 'base', 'setup: lookup mikey' )
290 set $S3, $P0["mikeys"]
291 is( $S3, 'bases', 'setup: lookup mikeys' )
292 set $S3, $P0["mikey200"]
293 is( $S3, 'start', 'setup: lookup mikey200' )
301 ## this should be fail(), but it is not implemented yet
302 ok( 0, 'concat mismatch' )
307 ## this should be fail(), but it is not implemented yet
308 ok( 0, 'lookup mismatch' )
312 set $I0, $P0["mikey199"]
313 is( $I0, 199, 'lookup: mikey199' )
314 set $I0, $P0["mikey117"]
315 is( $I0, 117, 'lookup: mikey117' )
316 set $I0, $P0["mikey1"]
317 is( $I0, 1, 'lookup: mikey1' )
318 set $I0, $P0["mikey23"]
319 is( $I0, 23, 'lookup: miky23' )
320 set $I0, $P0["mikey832"]
321 is( $I0, 0, 'lookup: mikey832 (never set)' )
324 ## stuff them in, and check periodically that we can pull selected ones out.
325 ## *_multiple_keys are used by stress_test_lots_of_keys
327 .sub set_multiple_keys
334 if count <= 0 goto ret
336 $S1 = concat "key", $S0
337 $S2 = concat "value", $S0
339 key_index = key_index + step
345 .sub delete_multiple_keys
352 if count <= 0 goto ret
354 $S1 = concat "key", $S0
356 key_index = key_index + step
367 $S0 = concat "key", $S10
368 $S1 = concat "value", $S10
371 $S3 = concat "correct value for key ", $S10
375 .sub stress_test_lots_of_keys
382 set_multiple_keys($P30, $I29, $I30, $I31)
384 check_key( $P30, 1001 )
385 check_key( $P30, 2001 )
389 set_multiple_keys($P30, $I21, $I30, $I31)
391 check_key( $P30, 1001 )
392 check_key( $P30, 2001 )
393 check_key( $P30, 100000 )
394 check_key( $P30, 101000 )
395 check_key( $P30, 102000 )
399 set_multiple_keys($P30, $I22, $I29, $I22)
401 check_key( $P30, 1001 )
402 check_key( $P30, 2001 )
403 check_key( $P30, 500000 )
404 check_key( $P30, 510000 )
405 check_key( $P30, 520000 )
408 delete_multiple_keys($P30, $I22, $I29, $I22)
409 check_key( $P30, 1001 )
410 check_key( $P30, 2001 )
411 $I50 = exists $P30['key50000']
412 $I51 = exists $P30['key51000']
413 $I52 = exists $P30['key52000']
414 is( $I50, 0, 'key50000 does not exist after delete' )
415 is( $I51, 0, 'key51000 does not exist after delete' )
416 is( $I52, 0, 'key52000 does not exist after delete' )
419 # Check all values after setting all of them
420 .sub stress_test_loop_set_loop_check
441 is( $I0, $I1, 'lookup mismatch in stress test loop' )
446 ok( 1, 'stress test: loop set with loop check' )
449 .sub testing_two_hash_indices_with_integers_at_a_time
456 is( $I0, 37, 'lookup int in foo' )
459 is( $I0, -15, 'lookup int in bar' )
463 is( $I0,37, 'lookup int in foo via var' )
467 is( $I0,-15, 'lookup int in bar via var' )
470 .sub testing_two_hash_indices_with_numbers_at_a_time
473 set $P0["foo"],37.100000
474 set $P0["bar"],-15.100000
477 is( $N0,37.100000, 'lookup num in foo' )
480 is( $N0,-15.100000, 'lookup num in bar' )
484 is( $N0,37.100000, 'lookup num in foo via var' )
488 is( $N0,-15.100000, 'lookup num in bar via var' )
492 .sub testing_two_hash_indices_with_strings_at_a_time
499 is( $S0,"baz", 'lookup str in foo' )
502 is( $S0,"qux", 'lookup str in bar' )
506 is( $S0,"baz", 'lookup str in foo via var' )
510 is( $S0,"qux", 'lookup str in bar via var' )
514 # So far, we have only used INTVALs, FLOATVALs and STRINGs as values
515 # and/or keys. Now we try PMCs.
517 .sub setting_and_getting_scalar_pmcs
522 set $S0, "non-PMC key"
527 is( $P2, $P1, 'lookup PMC Integer' )
529 set $P1, -1234.000000
532 is( $P2, $P1, 'lookup num after PMC Integer in slot' )
534 set $P1, "abcdefghijklmnopq"
537 is( $P2, $P1, 'lookup string' )
543 is( $S1, "Undef", 'lookup Undef PMC' )
547 .sub setting_scalar_pmcs_and_getting_scalar_values
551 set $S0, "A rather large key"
557 is( $I1, $I0, 'lookup PMC and get scalar Int' )
559 set $N0, -1234.000000
563 is( $N1, $N0, 'lookup PMC and get scalar Num' )
565 set $S1, "abcdefghijklmnopq"
569 is( $S2, $S1, 'lookup PMC and get scalar Str' )
573 .sub getting_values_from_undefined_keys
576 set $I0, $P2["qwerty"]
577 set $N0, $P2["asdfgh"]
578 set $S0, $P2["zxcvbn"]
579 set $P0, $P2["123456"]
581 is( $I0, 0, 'undefined key returns Int 0' )
582 is( $N0, 0.0, 'undefined key returns Num 0.0' )
583 is( $S0, "", 'undefined key returns Str ""' )
586 if_null $P0, P0_is_null
589 ok( $I1, 'undefined key returns null PMC' )
592 .sub setting_and_getting_non_scalar_pmcs
594 new $P1, ['ResizablePMCArray']
595 new $P2, ['ResizablePMCArray']
600 is( $S0, 'string', 'set and get non-scalar PMCs' )
607 new $P2, ['ResizablePMCArray']
611 # $P0 = { a => "a", b => [undef, undef] }
620 # $P0 = { a => "a", b => [undef, undef, undef], c => 4 }
621 # $P1 = { a => "A", b => [undef, undef] }
624 is( $S0, "a", 'original hash lookup pre-clone value' )
628 is( $I0, 3, 'original hash lookup post-clone value' )
631 is( $I0, 4, 'original hash lookup post-clone value in new slot' )
634 is( $S0, "A", 'cloned hash lookup post-clone value' )
638 is( $I0, 2, 'cloned hash lookup pre-clone complex value' )
640 # XXX: this should return undef or something, but it dies instead.
648 .sub clone_doesnt_crash_on_deleted_keys
649 .local pmc hash1, hash2
650 .local string key1, key2
658 ok( 1, "clone doesn't crash on deleted keys" )
662 # This test failure depends on the value if the hash seed, which is randomized.
663 # To try to ensure that the test fails reliably if there's a regression, it's
664 # run 3 times with different hash keys.
665 .sub clone_preserves_order
687 #If the bug is present, the order of elements in the get_repr string will
692 if s1 != s2 goto fail
712 if s1 != s2 goto fail
732 if s1 != s2 goto fail
738 ok(all_ok, "clone preserves hash internal order")
741 .sub freeze_thaw_preserves_order
742 # is internal order important somehow?
743 todo("freeze/thaw preserves hash internal order")
771 if s1 != s2 goto fail
792 if s1 != s2 goto fail
813 if s1 != s2 goto fail
819 ok(all_ok, "freeze/thaw preserves hash internal order")
825 new $P2, ['ResizablePMCArray']
828 set $S0, $P0["a";"b"]
829 is( $S0, "ab", 'Str from compound key' )
833 set $I0, $P0["a";"n";20]
834 is( $I0, 77, 'Int from compound key^2' )
839 set $I0, $P0[$S0;$S1;$I0]
840 is( $I0, 77, 'Int from indirect compound key^2' )
844 set $S0, $P0["c";33;"b"]
845 is( $S0, "ab", 'Str from indirect/direct compound key^2' )
850 set $S0, $P0[$S0;$I1;$S2]
851 is( $S0, "ab", 'Str from indirect compound key^2' )
854 set $N0, $P0["c";$I1;$S2]
855 is( $N0, 47.11, 'Num from indirect compound key^2' )
858 .sub getting_pmcs_from_compound_keys
865 set $P3, $P0["a";"b"]
867 is( $S0, "12", "lookup PMC from compound key" )
871 .sub getting_pmcs_from_string_int_compound_keys
878 is( $I0, 4, 'lookup Int PMC from hash' )
882 is( $I0, 4, 'lookup Inc PMC from compound hash' )
885 # A hash is only false if it has size 0
890 ## Could just use Test::More tests directly, but then we are really
891 ## checking casting to Int then testing value (I think)
892 ## ie. ok( $P0, '...' )
898 ok( $I1, 'Empty hash is false' )
900 set $P0["key"], "value"
905 ok( $I1, 'Hash with one slot is true' )
912 ok( $I1, 'Hash with one value ("") is true' )
920 ok( $P0, 'Hash with one value (Undef PMC) is true' )
931 ok( $I0, 'Empty hash is false in unless' )
934 set $P0["key"], "value"
938 ok( $I0, 'Hash with one value is true' )
945 ok( $I0, 'Hash with one value ("\0") is true' )
953 ok( $I0, 'Hash with one value (Undef PMC) is true' )
961 ok( $I0, 'Empty has is defined' )
963 ## nok() had not been (correctly) implemented when this test was written
967 ok( $I0, 'Unassigned var is undefined' )
970 defined $I0, $P0["a"]
971 ok( $I0, 'Int in hash value is defined' )
973 defined $I0, $P0["b"]
975 ok( $I0, 'Unassigned hash slot is undefined' )
979 defined $I0, $P0["c"]
981 ok( $I0, 'Undef PMC in hash slot is undefined' )
989 ok( $I0, 'assigned hash key exists' )
993 ok( $I0, 'unassigned hash key does not exist' )
998 ok( $I0, 'hash key assigned Undef PMC exists' )
1001 .sub delete_hash_key
1005 exists $I0, $P0["a"]
1006 ok( $I0, 'assigned hash key exists' )
1009 exists $I0, $P0["a"]
1011 ok( $I0, 'delete hash key does not exist' )
1019 set $P10[$P1], "Food"
1022 is( $S0, "Food", 'cloned key looks up same value' )
1025 set $P10[$S1], "Sheep"
1028 is( $S0, "Sheep", 'cloned key again look up same value' )
1031 .sub cloning_pmc_vals
1036 set $P10["str"], $P1
1040 set $P10["int"], $P1
1044 is( $P0, 42, 'cloned hash contained pre-clone set int' )
1046 is( $P0, 'value', 'cloned hash contains pre-clone set str' )
1049 .sub delete_and_free_list
1052 new $P0, ['FixedPMCArray']
1057 sprintf $S0, "ok %vd\n", $P0
1060 ## set $P1[key]=1 then delete it 100 times
1074 is( $I0, 10, 'hash has size 10' )
1077 ## XXX already tested?
1078 .sub exists_with_constant_string_key
1081 set $P16["key1"], "value for key1"
1082 set $S16, $P16["key1"]
1083 is( $S16, "value for key1" , 'set and lookup value for const str key' )
1085 exists $I17, $P16["key1"]
1086 ok( $I17, 'exists with constant string key' )
1088 exists $I17, $P16["no such"]
1090 ok( $I17, 'does not exist with unassigned const string key' )
1095 hash1 = new ['Hash']
1099 is( val1, "U", 'hash in PIR' )
1102 .sub setting_with_compound_keys
1103 .local pmc outer_hash
1104 outer_hash = new ['Hash']
1105 .local pmc inner_hash
1106 inner_hash = new ['Hash']
1107 .local pmc inner_array
1108 inner_array = new ['ResizablePMCArray']
1109 .local string elem_string
1114 # setting and retrieving strings in an inner ResizablePMCArray
1115 inner_array[128] = 'inner_array:128'
1116 outer_hash['inner_array'] = inner_array
1117 elem_string = outer_hash['inner_array';128]
1118 is( elem_string, 'inner_array:128', 'string in inner ResizeablePMCArray' )
1119 outer_hash['inner_array';128] = 'changed inner_array:128'
1120 elem_string = outer_hash['inner_array';128]
1121 is( elem_string, 'changed inner_array:128', 'string in inner ResizeablePMCArray' )
1123 # setting and retrieving strings in an inner Hash
1124 inner_hash['129'] = 'inner_hash:129'
1125 outer_hash['inner_hash'] = inner_hash
1126 elem_string = outer_hash['inner_hash';'129']
1127 is( elem_string, 'inner_hash:129', 'string in inner Hash' )
1128 outer_hash['inner_hash';'129'] = 'changed inner_hash:129'
1129 elem_string = outer_hash['inner_hash';'129']
1130 is( elem_string, 'changed inner_hash:129', 'string in inner Hash' )
1132 # setting and retrieving integer in an inner ResizablePMCArray
1133 inner_array[130] = 130
1134 outer_hash['inner_array'] = inner_array
1135 elem_int = outer_hash['inner_array';130]
1136 is( elem_int, 130, 'int in inner ResizablePMCArray' )
1137 outer_hash['inner_array';130] = -130
1138 elem_int = outer_hash['inner_array';130]
1139 is( elem_int, -130, 'int in inner ResizablePMCArray' )
1141 # setting and retrieving integer in an inner Hash
1142 inner_hash['131'] = 131
1143 outer_hash['inner_hash'] = inner_hash
1144 elem_int = outer_hash['inner_hash';'131']
1145 is( elem_int, 131, 'int in inner Hash' )
1146 outer_hash['inner_hash';'131'] = -131
1147 elem_int = outer_hash['inner_hash';'131']
1148 is( elem_int, -131, 'int in inner Hash' )
1150 # setting and retrieving a PMC in an inner ResizablePMCArray
1152 in_pmc = new ['String']
1153 in_pmc = 'inner_array:132'
1154 inner_array[132] = in_pmc
1155 outer_hash['inner_array'] = inner_array
1156 elem_pmc = outer_hash['inner_array';132]
1157 is( elem_pmc, 'inner_array:132', 'PMC in inner ResizablePMCArray' )
1158 in_pmc = 'changed inner_array:132'
1159 outer_hash['inner_array';132] = in_pmc
1160 elem_pmc = outer_hash['inner_array';132]
1161 is( elem_pmc, 'changed inner_array:132', 'PMC in inner ResizablePMCArray' )
1163 # setting and retrieving a PMC in an inner Hash
1164 in_pmc = 'inner_array:133'
1165 inner_hash['133'] = in_pmc
1166 outer_hash['inner_hash'] = inner_hash
1167 elem_string = outer_hash['inner_hash';'133']
1168 is( elem_string, 'inner_array:133', 'PMC in inner Hash' )
1169 in_pmc = 'changed inner_hash:133'
1170 outer_hash['inner_hash';'133'] = in_pmc
1171 elem_string = outer_hash['inner_hash';'133']
1172 is( elem_string, 'changed inner_hash:133', 'PMC in inner Hash' )
1174 # setting and retrieving a float in an inner ResizablePMCArray
1175 inner_array[134] = 134.134
1176 outer_hash['inner_array'] = inner_array
1177 elem_num = outer_hash['inner_array';134]
1178 is( elem_num, 134.134000, 'float in inner ResizablePMCArray' )
1179 outer_hash['inner_array';134] = -134.134
1180 elem_num = outer_hash['inner_array';134]
1181 is( elem_num, -134.134000, 'float in inner ResizablePMCArray' )
1183 # setting and retrieving a float in an inner Hash
1184 inner_hash['135'] = 135.135
1185 outer_hash['inner_hash'] = inner_hash
1186 elem_num = outer_hash['inner_hash';'135']
1187 is( elem_num, 135.135000, 'float in inner Hash' )
1188 outer_hash['inner_hash';'135'] = -135.135
1189 elem_num = outer_hash['inner_hash';'135']
1190 is( elem_num, -135.135000, 'float in inner Hash' )
1194 .sub mutating_the_lookup_string
1197 set $P0["ab"], "two"
1198 set $P0["abc"], "three"
1202 is( $S1, "one", 'lookup via str in reg' )
1206 is( $S1, "two", 'lookup via concated str in reg' )
1210 is( $S1, "three", 'lookup via concated^2 str in reg' )
1213 .sub check_whether_interface_is_done
1218 does bool1, pmc1, "scalar"
1220 ok( bool1, 'Hash PMC does not do scalar' )
1222 does bool1, pmc1, "hash"
1223 ok( bool1, 'Hash PMC does hash' )
1225 does bool1, pmc1, "no_interface"
1227 ok( bool1, 'Hash PMC does not do no_interface' )
1239 ok( $I0, 'iterator is true' )
1242 is( $P2, 'a', 'shifting iterator give the key' )
1248 ok( $I0, 'iterator is now false' )
1251 ## thx to azuroth on irc
1253 .include "iterator.pasm"
1254 .local string result
1259 # just put in some dummy data...
1260 thash = new ['Hash']
1267 it = .ITERATE_FROM_START
1269 .local pmc keys, key
1270 keys = new ['ResizablePMCArray']
1272 # go through the hash, print out all the keys: should be a c and e
1274 unless it goto preit_end
1284 result = join '', keys
1285 is( result, 'ace', 'iterated through keys successfully' )
1287 # get rid of the c element?
1289 keys = new ['ResizablePMCArray']
1291 # what do we have after deletion?
1295 it = .ITERATE_FROM_START
1297 # go through the hash, print out all the keys... I believe it should be a and e?
1298 # it actually outputs a, c and e.
1300 unless it goto postit_end
1311 result = join '', keys
1312 is( result, 'ae', 'the c key was no longer iterated over' )
1315 .sub unicode_keys_register_rt_39249
1318 $S99 = unicode:"\u7777"
1321 is( $S1, 'ok', 'unicode key' )
1324 .sub unicode_keys_literal_rt_39249
1327 $P1[unicode:"\u7777"] = "ok"
1328 $S1 = $P1[unicode:"\u7777"]
1329 is( $S1, 'ok', 'literal unicode key' )
1331 $S2 = unicode:"\u7777"
1333 is( $S1, 'ok', 'literal unicode key lookup via var' )
1336 # Switch to use integer keys instead of strings.
1338 .include "hash_key_type.pasm"
1341 hash = .Hash_key_type_int
1351 # 'foo' numifies to '0'. So check it
1353 is($S0, 'BAZ', 'Key was numified')
1355 # '42 parrots' numifies to '42'. So check it
1357 is($S0, 'Wins!', 'Key was numified again')
1360 # Check that we can set various value types and they properly converted
1361 .sub value_types_convertion
1365 # PMC is first value type
1366 hash.'set_value_type'(.DATATYPE_PMC)
1367 $P0 = new 'Env' # arbitary choice. Just to prevent possible casting.
1370 hash['bar'] = 21285.06
1371 hash['baz'] = 'forty two'
1373 # Check that original value preserved
1375 $I0 = isa $P1, 'Env'
1376 ok($I0, 'Env PMC preserved')
1378 is($I0, 42, 'Intval preserved')
1380 is($N0, 21285.06, 'Number preserved')
1382 is($S0, 'forty two', 'String preserved')
1384 # Clear the Hash and set INTVAL as stored values.
1385 hash.'set_value_type'(.DATATYPE_INTVAL)
1386 hash['foo'] = 42 # Use as-is
1387 hash['bar'] = 21285.06 # Truncate to int
1388 hash['baz'] = 'forty two' # Cast to int
1391 is($I0, 42, 'Intval preserved with datatype int')
1393 is($I0, 21285, 'Floatval trunkated to int')
1395 is($I0, 0, 'String casted to int')
1397 # TODO Add tests for String.
1400 # Check number of elements in Hash
1401 .sub 'elements_in_hash'
1406 is($I0, 0, "Empty hash has 0 items")
1410 is($I0, 1, "Hash has 1 item")
1414 is($I0, 1, "Hash still has 1 item after update")
1418 is($I0, 2, "Hash has 2 items")
1422 is($I0, 1, "Hash has 1 item after delete")
1426 is($I0, 0, "Hash has 0 items after delete")
1430 .sub 'equality_tests'
1431 .local pmc hash1, hash2, hash3, hash4, hash5
1432 hash1 = new ['Hash']
1433 hash2 = new ['Hash']
1434 hash3 = new ['Hash']
1435 hash4 = new ['Hash']
1437 hash1['one'] = "Hello Parrot!"
1439 hash1['three'] = 2.718
1441 hash2['ONE'] = "Hello Parrot!"
1443 hash2['THREE'] = 2.718
1445 $P0 = box "Hello Parrot!"
1450 hash3['three'] = $P0
1452 hash4['one'] = "Goodbye Parrot!"
1454 hash4['three'] = 2.718
1458 isnt(hash1, hash2, 'Hashes with different keys')
1459 is(hash1, hash3, 'Equal hashes, physically disjoint')
1460 isnt(hash1, hash4, 'Different hash values')
1461 is(hash1, hash5, 'Clones are equal')
1464 # Switch to use PMC keys instead of strings.
1466 .include "hash_key_type.pasm"
1469 hash = .Hash_key_type_PMC
1471 $P0 = new ['ResizableStringArray']
1474 # Autoconvert INTVAL to Integer
1477 # Autoconvert STRING to String
1481 is($I0, 3, "Got 3 elements in Hash")
1483 # Iterate over keys and get types. We should have 3 different types:
1484 # ResizableStringArray, Integer and String
1485 .local pmc types, it
1486 types = new ['Hash']
1497 $I0 = elements types
1498 is($I0, 3, "Got 3 different types of PMC keys")
1499 $I0 = types['ResizableStringArray']
1500 ok($I0, "Including ResizableStringArray")
1507 # vim: expandtab shiftwidth=4 ft=pir: