@@ -404,6 +404,10 @@ func TestArrayPhaseTwoHelpers(t *testing.T) {
404404 end
405405
406406 {
407+ size: values.size,
408+ length: values.length,
409+ empty_false: values.empty?,
410+ empty_true: [].empty?,
407411 include_hit: values.include?(2),
408412 include_miss: values.include?(9),
409413 index_hit: values.index(1),
@@ -412,6 +416,9 @@ func TestArrayPhaseTwoHelpers(t *testing.T) {
412416 rindex_hit: values.rindex(1),
413417 rindex_offset_hit: values.rindex(1, 2),
414418 rindex_miss: values.rindex(9),
419+ fetch_hit: values.fetch(2),
420+ fetch_default: values.fetch(9, 42),
421+ fetch_miss: values.fetch(9),
415422 find_hit: find_hit,
416423 find_miss: find_miss,
417424 find_index_hit: find_index_hit,
@@ -446,6 +453,12 @@ func TestArrayPhaseTwoHelpers(t *testing.T) {
446453 t .Fatalf ("expected hash, got %v" , result .Kind ())
447454 }
448455 got := result .Hash ()
456+ if ! got ["size" ].Equal (NewInt (4 )) || ! got ["length" ].Equal (NewInt (4 )) {
457+ t .Fatalf ("size/length mismatch: size=%v length=%v" , got ["size" ], got ["length" ])
458+ }
459+ if got ["empty_false" ].Bool () || ! got ["empty_true" ].Bool () {
460+ t .Fatalf ("empty? mismatch: false=%v true=%v" , got ["empty_false" ], got ["empty_true" ])
461+ }
449462 if ! got ["include_hit" ].Bool () || got ["include_miss" ].Bool () {
450463 t .Fatalf ("include? mismatch: %#v" , got )
451464 }
@@ -461,6 +474,12 @@ func TestArrayPhaseTwoHelpers(t *testing.T) {
461474 if got ["rindex_miss" ].Kind () != KindNil {
462475 t .Fatalf ("rindex_miss expected nil, got %v" , got ["rindex_miss" ])
463476 }
477+ if ! got ["fetch_hit" ].Equal (NewInt (2 )) || ! got ["fetch_default" ].Equal (NewInt (42 )) {
478+ t .Fatalf ("fetch mismatch: hit=%v default=%v" , got ["fetch_hit" ], got ["fetch_default" ])
479+ }
480+ if got ["fetch_miss" ].Kind () != KindNil {
481+ t .Fatalf ("fetch_miss expected nil, got %v" , got ["fetch_miss" ])
482+ }
464483 if ! got ["find_hit" ].Equal (NewInt (3 )) || got ["find_miss" ].Kind () != KindNil {
465484 t .Fatalf ("find mismatch: hit=%v miss=%v" , got ["find_hit" ], got ["find_miss" ])
466485 }
@@ -642,20 +661,20 @@ func TestArrayConcatAndSubtract(t *testing.T) {
642661
643662func TestLogicalOperatorsShortCircuit (t * testing.T ) {
644663 script := compileScript (t , `
645- def bad_index()
664+ def bad_index
646665 [1][4]
647666 end
648667
649- def explode()
668+ def explode
650669 raise "boom"
651670 end
652671
653- def false_and_bad_index()
654- false && bad_index()
672+ def false_and_bad_index
673+ false && bad_index
655674 end
656675
657- def true_or_explode()
658- true || explode()
676+ def true_or_explode
677+ true || explode
659678 end
660679
661680 def adjacent_run(values, index)
@@ -677,6 +696,65 @@ func TestLogicalOperatorsShortCircuit(t *testing.T) {
677696 }
678697}
679698
699+ func TestIntegerDivisionAndModulo (t * testing.T ) {
700+ script := compileScript (t , `
701+ def gcd(a, b)
702+ while b != 0
703+ next_value = a % b
704+ a = b
705+ b = next_value
706+ end
707+ a
708+ end
709+
710+ def hailstone(n)
711+ out = [n]
712+ while n != 1
713+ if n % 2 == 0
714+ n = n / 2
715+ else
716+ n = n * 3 + 1
717+ end
718+ out = out + [n]
719+ end
720+ out
721+ end
722+
723+ def arithmetic
724+ {
725+ int_div: 7 / 2,
726+ float_div: 7.0 / 2,
727+ mod_chain: 10 / 2 % 3,
728+ gcd: gcd(54, 24),
729+ hailstone: hailstone(7)
730+ }
731+ end
732+ ` )
733+
734+ result := callFunc (t , script , "arithmetic" , nil )
735+ if result .Kind () != KindHash {
736+ t .Fatalf ("expected hash, got %v" , result .Kind ())
737+ }
738+ got := result .Hash ()
739+ if ! got ["int_div" ].Equal (NewInt (3 )) {
740+ t .Fatalf ("int_div mismatch: %v" , got ["int_div" ])
741+ }
742+ if got ["float_div" ].Kind () != KindFloat || got ["float_div" ].Float () != 3.5 {
743+ t .Fatalf ("float_div mismatch: %v" , got ["float_div" ])
744+ }
745+ if ! got ["mod_chain" ].Equal (NewInt (2 )) {
746+ t .Fatalf ("mod_chain mismatch: %v" , got ["mod_chain" ])
747+ }
748+ if ! got ["gcd" ].Equal (NewInt (6 )) {
749+ t .Fatalf ("gcd mismatch: %v" , got ["gcd" ])
750+ }
751+ compareArrays (t , got ["hailstone" ], []Value {
752+ NewInt (7 ), NewInt (22 ), NewInt (11 ), NewInt (34 ), NewInt (17 ), NewInt (52 ),
753+ NewInt (26 ), NewInt (13 ), NewInt (40 ), NewInt (20 ), NewInt (10 ), NewInt (5 ),
754+ NewInt (16 ), NewInt (8 ), NewInt (4 ), NewInt (2 ), NewInt (1 ),
755+ })
756+ }
757+
680758func TestHashLiteralSyntaxRestriction (t * testing.T ) {
681759 _ = compileScriptErrorDefault (t , `
682760 def broken()
@@ -1032,31 +1110,31 @@ func TestUntilLoops(t *testing.T) {
10321110
10331111func TestLineTerminatedHeadersAndStatements (t * testing.T ) {
10341112 script := compileScript (t , `
1035- def if_empty_array()
1113+ def if_empty_array
10361114 if true
10371115 []
10381116 else
10391117 [2]
10401118 end
10411119 end
10421120
1043- def if_array()
1121+ def if_array
10441122 if true
10451123 [1]
10461124 else
10471125 [2]
10481126 end
10491127 end
10501128
1051- def if_hash()
1129+ def if_hash
10521130 if false
10531131 [1]
10541132 else
10551133 { a: 1 }
10561134 end
10571135 end
10581136
1059- def while_body()
1137+ def while_body
10601138 seen = []
10611139 i = 0
10621140 while i < 1
@@ -1067,7 +1145,7 @@ func TestLineTerminatedHeadersAndStatements(t *testing.T) {
10671145 seen
10681146 end
10691147
1070- def until_body()
1148+ def until_body
10711149 seen = []
10721150 i = 0
10731151 until i == 1
@@ -1078,7 +1156,7 @@ func TestLineTerminatedHeadersAndStatements(t *testing.T) {
10781156 seen
10791157 end
10801158
1081- def for_body()
1159+ def for_body
10821160 seen = []
10831161 for item in [1, 2]
10841162 [item]
@@ -1087,17 +1165,17 @@ func TestLineTerminatedHeadersAndStatements(t *testing.T) {
10871165 seen
10881166 end
10891167
1090- def return_value()
1168+ def return_value
10911169 return true
10921170 [1]
10931171 end
10941172
1095- def bare_return()
1173+ def bare_return
10961174 return
10971175 [1]
10981176 end
10991177
1100- def raise_message()
1178+ def raise_message
11011179 raise "boom"
11021180 [1]
11031181 end
@@ -1252,7 +1330,7 @@ func TestBeginRescueEnsure(t *testing.T) {
12521330 end
12531331 ` )
12541332
1255- if got := callFunc (t , script , "safe_div" , []Value {NewInt (10 ), NewInt (2 )}); ! got .Equal (NewFloat (5 )) {
1333+ if got := callFunc (t , script , "safe_div" , []Value {NewInt (10 ), NewInt (2 )}); ! got .Equal (NewInt (5 )) {
12561334 t .Fatalf ("safe_div success mismatch: %v" , got )
12571335 }
12581336 if got := callFunc (t , script , "safe_div" , []Value {NewInt (10 ), NewInt (0 )}); ! got .Equal (NewString ("fallback" )) {
@@ -3571,6 +3649,16 @@ func TestMethodErrorHandling(t *testing.T) {
35713649 script : `def run() [].rindex(1, -1) end` ,
35723650 errMsg : "offset must be non-negative integer" ,
35733651 },
3652+ {
3653+ name : "array.fetch with missing index" ,
3654+ script : `def run() [1, 2, 3].fetch end` ,
3655+ errMsg : "expects index and optional default" ,
3656+ },
3657+ {
3658+ name : "array.fetch with non-integer index" ,
3659+ script : `def run() [1, 2, 3].fetch("1") end` ,
3660+ errMsg : "index must be integer" ,
3661+ },
35743662 {
35753663 name : "array.count with argument and block" ,
35763664 script : `def run()
0 commit comments