diff options
author | Benoit Daloze <eregontp@gmail.com> | 2020-01-28 20:47:48 +0100 |
---|---|---|
committer | Benoit Daloze <eregontp@gmail.com> | 2020-01-28 20:47:48 +0100 |
commit | 809f0b8a1357f14f9645210d4812f4400c8d397e (patch) | |
tree | 7ce6192f94b1dc4b004798aa5d0c4d6bac02577f /spec/ruby/core/range | |
parent | ed377cc9aaf1ccbede19ddc6c464f5fbf3cabc34 (diff) |
Update to ruby/spec@f8a2d54
Diffstat (limited to 'spec/ruby/core/range')
-rw-r--r-- | spec/ruby/core/range/bsearch_spec.rb | 200 | ||||
-rw-r--r-- | spec/ruby/core/range/each_spec.rb | 22 | ||||
-rw-r--r-- | spec/ruby/core/range/equal_value_spec.rb | 6 | ||||
-rw-r--r-- | spec/ruby/core/range/inspect_spec.rb | 7 | ||||
-rw-r--r-- | spec/ruby/core/range/last_spec.rb | 6 | ||||
-rw-r--r-- | spec/ruby/core/range/max_spec.rb | 6 | ||||
-rw-r--r-- | spec/ruby/core/range/min_spec.rb | 7 | ||||
-rw-r--r-- | spec/ruby/core/range/shared/cover_and_include.rb | 7 | ||||
-rw-r--r-- | spec/ruby/core/range/shared/equal_value.rb | 8 | ||||
-rw-r--r-- | spec/ruby/core/range/size_spec.rb | 7 | ||||
-rw-r--r-- | spec/ruby/core/range/step_spec.rb | 96 | ||||
-rw-r--r-- | spec/ruby/core/range/to_a_spec.rb | 6 | ||||
-rw-r--r-- | spec/ruby/core/range/to_s_spec.rb | 7 |
13 files changed, 383 insertions, 2 deletions
diff --git a/spec/ruby/core/range/bsearch_spec.rb b/spec/ruby/core/range/bsearch_spec.rb index 009cafb00e..38ccd35170 100644 --- a/spec/ruby/core/range/bsearch_spec.rb +++ b/spec/ruby/core/range/bsearch_spec.rb @@ -81,6 +81,19 @@ describe "Range#bsearch" do [1, 2].should include(result) end end + + it "returns nil for empty ranges" do + (0...0).bsearch { true }.should == nil + (0...0).bsearch { false }.should == nil + (0...0).bsearch { 1 }.should == nil + (0...0).bsearch { 0 }.should == nil + (0...0).bsearch { -1 }.should == nil + + (4..2).bsearch { true }.should == nil + (4..2).bsearch { 1 }.should == nil + (4..2).bsearch { 0 }.should == nil + (4..2).bsearch { -1 }.should == nil + end end context "with Float values" do @@ -94,13 +107,46 @@ describe "Range#bsearch" do end it "returns minimum element if the block returns true for every element" do - (-0.2..4.8).bsearch { |x| x < 4 }.should == -0.2 + (-0.2..4.8).bsearch { |x| x < 5 }.should == -0.2 end it "returns the smallest element for which block returns true" do (0..4.2).bsearch { |x| x >= 2 }.should == 2 (-1.2..4.3).bsearch { |x| x >= 1 }.should == 1 end + + it "returns a boundary element if appropriate" do + (1.0..3.0).bsearch { |x| x >= 3.0 }.should == 3.0 + (1.0...3.0).bsearch { |x| x >= 3.0.prev_float }.should == 3.0.prev_float + (1.0..3.0).bsearch { |x| x >= 1.0 }.should == 1.0 + (1.0...3.0).bsearch { |x| x >= 1.0 }.should == 1.0 + end + + it "works with infinity bounds" do + inf = Float::INFINITY + (0..inf).bsearch { |x| x == inf }.should == inf + (0...inf).bsearch { |x| x == inf }.should == nil + (-inf..0).bsearch { |x| x == -inf }.should == nil + (-inf...0).bsearch { |x| x == -inf }.should == nil + (inf..inf).bsearch { |x| true }.should == inf + (inf...inf).bsearch { |x| true }.should == nil + (-inf..-inf).bsearch { |x| true }.should == -inf + (-inf...-inf).bsearch { |x| true }.should == nil + (inf..0).bsearch { true }.should == nil + (inf...0).bsearch { true }.should == nil + (0..-inf).bsearch { true }.should == nil + (0...-inf).bsearch { true }.should == nil + (inf..-inf).bsearch { true }.should == nil + (inf...-inf).bsearch { true }.should == nil + (0..inf).bsearch { |x| x >= 3 }.should == 3.0 + (0...inf).bsearch { |x| x >= 3 }.should == 3.0 + (-inf..0).bsearch { |x| x >= -3 }.should == -3.0 + (-inf...0).bsearch { |x| x >= -3 }.should == -3.0 + (-inf..inf).bsearch { |x| x >= 3 }.should == 3.0 + (-inf...inf).bsearch { |x| x >= 3 }.should == 3.0 + (0..inf).bsearch { |x| x >= Float::MAX }.should == Float::MAX + (0...inf).bsearch { |x| x >= Float::MAX }.should == Float::MAX + end end context "with a block returning negative, zero, positive numbers" do @@ -130,7 +176,157 @@ describe "Range#bsearch" do it "returns an element at an index for which block returns 0" do result = (0.1..4.9).bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 } result.should >= 1 - result.should <= 2 + result.should <= 3 + end + + it "returns an element at an index for which block returns 0 (small numbers)" do + result = (0.1..0.3).bsearch { |x| x < 0.1 ? 1 : x > 0.3 ? -1 : 0 } + result.should >= 0.1 + result.should <= 0.3 + end + + it "returns a boundary element if appropriate" do + (1.0..3.0).bsearch { |x| 3.0 - x }.should == 3.0 + (1.0...3.0).bsearch { |x| 3.0.prev_float - x }.should == 3.0.prev_float + (1.0..3.0).bsearch { |x| 1.0 - x }.should == 1.0 + (1.0...3.0).bsearch { |x| 1.0 - x }.should == 1.0 + end + + it "works with infinity bounds" do + inf = Float::INFINITY + (0..inf).bsearch { |x| x == inf ? 0 : -1 }.should == nil + (0...inf).bsearch { |x| x == inf ? 0 : -1 }.should == nil + (-inf...0).bsearch { |x| x == -inf ? 0 : 1 }.should == nil + (-inf..0).bsearch { |x| x == -inf ? 0 : 1 }.should == nil + (inf..inf).bsearch { 0 }.should == inf + (inf...inf).bsearch { 0 }.should == nil + (-inf..-inf).bsearch { 0 }.should == -inf + (-inf...-inf).bsearch { 0 }.should == nil + (inf..0).bsearch { 0 }.should == nil + (inf...0).bsearch { 0 }.should == nil + (0..-inf).bsearch { 0 }.should == nil + (0...-inf).bsearch { 0 }.should == nil + (inf..-inf).bsearch { 0 }.should == nil + (inf...-inf).bsearch { 0 }.should == nil + (-inf..inf).bsearch { |x| 3 - x }.should == 3.0 + (-inf...inf).bsearch { |x| 3 - x }.should == 3.0 + (0...inf).bsearch { |x| x >= Float::MAX ? 0 : 1 }.should == Float::MAX + end + end + end + + ruby_version_is "2.6" do + context "with endless ranges and Integer values" do + context "with a block returning true or false" do + it "returns minimum element if the block returns true for every element" do + eval("(-2..)").bsearch { |x| true }.should == -2 + end + + it "returns the smallest element for which block returns true" do + eval("(0..)").bsearch { |x| x >= 2 }.should == 2 + eval("(-1..)").bsearch { |x| x >= 1 }.should == 1 + end + end + + context "with a block returning negative, zero, positive numbers" do + it "returns nil if the block returns less than zero for every element" do + eval("(0..)").bsearch { |x| -1 }.should be_nil + end + + it "returns nil if the block never returns zero" do + eval("(0..)").bsearch { |x| x > 5 ? -1 : 1 }.should be_nil + end + + it "accepts -Float::INFINITY from the block" do + eval("(0..)").bsearch { |x| -Float::INFINITY }.should be_nil + end + + it "returns an element at an index for which block returns 0.0" do + result = eval("(0..)").bsearch { |x| x < 2 ? 1.0 : x > 2 ? -1.0 : 0.0 } + result.should == 2 + end + + it "returns an element at an index for which block returns 0" do + result = eval("(0..)").bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 } + [1, 2].should include(result) + end + end + end + + context "with endless ranges and Float values" do + context "with a block returning true or false" do + it "returns nil if the block returns false for every element" do + eval("(0.1..)").bsearch { |x| x < 0.0 }.should be_nil + eval("(0.1...)").bsearch { |x| x < 0.0 }.should be_nil + end + + it "returns nil if the block returns nil for every element" do + eval("(-0.0..)").bsearch { |x| nil }.should be_nil + eval("(-0.0...)").bsearch { |x| nil }.should be_nil + end + + it "returns minimum element if the block returns true for every element" do + eval("(-0.2..)").bsearch { |x| true }.should == -0.2 + eval("(-0.2...)").bsearch { |x| true }.should == -0.2 + end + + it "returns the smallest element for which block returns true" do + eval("(0..)").bsearch { |x| x >= 2 }.should == 2 + eval("(-1.2..)").bsearch { |x| x >= 1 }.should == 1 + end + + it "works with infinity bounds" do + inf = Float::INFINITY + eval("(inf..)").bsearch { |x| true }.should == inf + eval("(inf...)").bsearch { |x| true }.should == nil + eval("(-inf..)").bsearch { |x| true }.should == -inf + eval("(-inf...)").bsearch { |x| true }.should == -inf + end + end + + context "with a block returning negative, zero, positive numbers" do + it "returns nil if the block returns less than zero for every element" do + eval("(-2.0..)").bsearch { |x| -1 }.should be_nil + eval("(-2.0...)").bsearch { |x| -1 }.should be_nil + end + + it "returns nil if the block returns greater than zero for every element" do + eval("(0.3..)").bsearch { |x| 1 }.should be_nil + eval("(0.3...)").bsearch { |x| 1 }.should be_nil + end + + it "returns nil if the block never returns zero" do + eval("(0.2..)").bsearch { |x| x < 2 ? 1 : -1 }.should be_nil + end + + it "accepts (+/-)Float::INFINITY from the block" do + eval("(0.1..)").bsearch { |x| Float::INFINITY }.should be_nil + eval("(-5.0..)").bsearch { |x| -Float::INFINITY }.should be_nil + end + + it "returns an element at an index for which block returns 0.0" do + result = eval("(0.0..)").bsearch { |x| x < 2 ? 1.0 : x > 2 ? -1.0 : 0.0 } + result.should == 2 + end + + it "returns an element at an index for which block returns 0" do + result = eval("(0.1..)").bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 } + result.should >= 1 + result.should <= 3 + end + + it "works with infinity bounds" do + inf = Float::INFINITY + eval("(inf..)").bsearch { |x| 1 }.should == nil + eval("(inf...)").bsearch { |x| 1 }.should == nil + eval("(inf..)").bsearch { |x| x == inf ? 0 : 1 }.should == inf + eval("(inf...)").bsearch { |x| x == inf ? 0 : 1 }.should == nil + eval("(-inf..)").bsearch { |x| x == -inf ? 0 : -1 }.should == -inf + eval("(-inf...)").bsearch { |x| x == -inf ? 0 : -1 }.should == -inf + eval("(-inf..)").bsearch { |x| 3 - x }.should == 3 + eval("(-inf...)").bsearch { |x| 3 - x }.should == 3 + eval("(0.0...)").bsearch { 0 }.should != inf + end end end end diff --git a/spec/ruby/core/range/each_spec.rb b/spec/ruby/core/range/each_spec.rb index 110b0602d0..8935d86829 100644 --- a/spec/ruby/core/range/each_spec.rb +++ b/spec/ruby/core/range/each_spec.rb @@ -32,6 +32,28 @@ describe "Range#each" do a.should == [x, y] end + ruby_version_is "2.6" do + it "works with endless ranges" do + a = [] + eval("(-2..)").each { |x| break if x > 2; a << x } + a.should == [-2, -1, 0, 1, 2] + + a = [] + eval("(-2...)").each { |x| break if x > 2; a << x } + a.should == [-2, -1, 0, 1, 2] + end + + it "works with String endless ranges" do + a = [] + eval("('A'..)").each { |x| break if x > "D"; a << x } + a.should == ["A", "B", "C", "D"] + + a = [] + eval("('A'...)").each { |x| break if x > "D"; a << x } + a.should == ["A", "B", "C", "D"] + end + end + it "raises a TypeError if the first element does not respond to #succ" do -> { (0.5..2.4).each { |i| i } }.should raise_error(TypeError) diff --git a/spec/ruby/core/range/equal_value_spec.rb b/spec/ruby/core/range/equal_value_spec.rb index 889557fc2a..43d5e0e38a 100644 --- a/spec/ruby/core/range/equal_value_spec.rb +++ b/spec/ruby/core/range/equal_value_spec.rb @@ -7,4 +7,10 @@ describe "Range#==" do it "returns true if the endpoints are ==" do (0..1).should == (0..1.0) end + + ruby_version_is "2.6" do + it "returns true if the endpoints are == for endless ranges" do + eval("(1.0..)").should == eval("(1.0..)") + end + end end diff --git a/spec/ruby/core/range/inspect_spec.rb b/spec/ruby/core/range/inspect_spec.rb index 837f7e69ab..d1072531e9 100644 --- a/spec/ruby/core/range/inspect_spec.rb +++ b/spec/ruby/core/range/inspect_spec.rb @@ -12,6 +12,13 @@ describe "Range#inspect" do (0.5..2.4).inspect.should == "0.5..2.4" end + ruby_version_is "2.6" do + it "works for endless ranges" do + eval("(1..)").inspect.should == "1.." + eval("(0.1...)").inspect.should == "0.1..." + end + end + ruby_version_is ''...'2.7' do it "returns a tainted string if either end is tainted" do (("a".taint)..."c").inspect.tainted?.should be_true diff --git a/spec/ruby/core/range/last_spec.rb b/spec/ruby/core/range/last_spec.rb index c7e629e62c..54884ba4d6 100644 --- a/spec/ruby/core/range/last_spec.rb +++ b/spec/ruby/core/range/last_spec.rb @@ -46,4 +46,10 @@ describe "Range#last" do it "raises a TypeError when passed a String" do -> { (2..3).last("1") }.should raise_error(TypeError) end + + ruby_version_is "2.6" do + it "raises a RangeError when called on an endless range" do + -> { eval("(1..)").last }.should raise_error(RangeError) + end + end end diff --git a/spec/ruby/core/range/max_spec.rb b/spec/ruby/core/range/max_spec.rb index faac0a2032..728053cefd 100644 --- a/spec/ruby/core/range/max_spec.rb +++ b/spec/ruby/core/range/max_spec.rb @@ -45,6 +45,12 @@ describe "Range#max" do time_end = Time.now + 1.0 -> { (time_start...time_end).max }.should raise_error(TypeError) end + + ruby_version_is "2.6" do + it "raises RangeError when called on an endless range" do + -> { eval("(1..)").max }.should raise_error(RangeError) + end + end end describe "Range#max given a block" do diff --git a/spec/ruby/core/range/min_spec.rb b/spec/ruby/core/range/min_spec.rb index 424bd1dc87..f1dff73e6d 100644 --- a/spec/ruby/core/range/min_spec.rb +++ b/spec/ruby/core/range/min_spec.rb @@ -72,4 +72,11 @@ describe "Range#min given a block" do ('z'..'l').min {|x,y| x <=> y}.should be_nil (7...7).min {|x,y| x <=> y}.should be_nil end + + ruby_version_is "2.6" do + it "returns the start point for endless ranges" do + eval("(1..)").min.should == 1 + eval("(1.0...)").min.should == 1.0 + end + end end diff --git a/spec/ruby/core/range/shared/cover_and_include.rb b/spec/ruby/core/range/shared/cover_and_include.rb index a19e2c6ead..b308524310 100644 --- a/spec/ruby/core/range/shared/cover_and_include.rb +++ b/spec/ruby/core/range/shared/cover_and_include.rb @@ -19,6 +19,13 @@ describe :range_cover_and_include, shared: true do (0.5...2.4).send(@method, 2.4).should == false end + ruby_version_is "2.6" do + it "returns true if other is an element of self for endless ranges" do + eval("(1..)").send(@method, 2.4).should == true + eval("(0.5...)").send(@method, 2.4).should == true + end + end + it "compares values using <=>" do rng = (1..5) m = mock("int") diff --git a/spec/ruby/core/range/shared/equal_value.rb b/spec/ruby/core/range/shared/equal_value.rb index 9d8bb13351..8872b4efc0 100644 --- a/spec/ruby/core/range/shared/equal_value.rb +++ b/spec/ruby/core/range/shared/equal_value.rb @@ -42,4 +42,12 @@ describe :range_eql, shared: true do b = RangeSpecs::MyRange.new(RangeSpecs::Xs.new(3), RangeSpecs::Xs.new(5)) a.send(@method, b).should == true end + + ruby_version_is "2.6" do + it "works for endless Ranges" do + eval("(1..)").send(@method, eval("(1..)")).should == true + eval("(0.5...)").send(@method, eval("(0.5...)")).should == true + eval("(1..)").send(@method, eval("(1...)")).should == false + end + end end diff --git a/spec/ruby/core/range/size_spec.rb b/spec/ruby/core/range/size_spec.rb index 09759940dd..b687342b72 100644 --- a/spec/ruby/core/range/size_spec.rb +++ b/spec/ruby/core/range/size_spec.rb @@ -24,6 +24,13 @@ describe "Range#size" do (-Float::INFINITY..Float::INFINITY).size.should == Float::INFINITY end + ruby_version_is "2.6" do + it 'returns Float::INFINITY for endless ranges' do + eval("(1..)").size.should == Float::INFINITY + eval("(0.5...)").size.should == Float::INFINITY + end + end + it "returns nil if first and last are not Numeric" do (:a..:z).size.should be_nil ('a'..'z').size.should be_nil diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb index d564e4a5cd..d83868a0fb 100644 --- a/spec/ruby/core/range/step_spec.rb +++ b/spec/ruby/core/range/step_spec.rb @@ -274,6 +274,102 @@ describe "Range#step" do end end + ruby_version_is "2.6" do + describe "with an endless range" do + describe "and Integer values" do + it "yield Integer values incremented by 1 when not passed a step" do + eval("(-2..)").step { |x| break if x > 2; ScratchPad << x } + ScratchPad.recorded.should eql([-2, -1, 0, 1, 2]) + + ScratchPad.record [] + eval("(-2...)").step { |x| break if x > 2; ScratchPad << x } + ScratchPad.recorded.should eql([-2, -1, 0, 1, 2]) + end + + it "yields Integer values incremented by an Integer step" do + eval("(-5..)").step(2) { |x| break if x > 3; ScratchPad << x } + ScratchPad.recorded.should eql([-5, -3, -1, 1, 3]) + + ScratchPad.record [] + eval("(-5...)").step(2) { |x| break if x > 3; ScratchPad << x } + ScratchPad.recorded.should eql([-5, -3, -1, 1, 3]) + end + + it "yields Float values incremented by a Float step" do + eval("(-2..)").step(1.5) { |x| break if x > 1.0; ScratchPad << x } + ScratchPad.recorded.should eql([-2.0, -0.5, 1.0])\ + + ScratchPad.record [] + eval("(-2..)").step(1.5) { |x| break if x > 1.0; ScratchPad << x } + ScratchPad.recorded.should eql([-2.0, -0.5, 1.0]) + end + end + + describe "and Float values" do + it "yields Float values incremented by 1 and less than end when not passed a step" do + eval("(-2.0..)").step { |x| break if x > 1.5; ScratchPad << x } + ScratchPad.recorded.should eql([-2.0, -1.0, 0.0, 1.0]) + + ScratchPad.record [] + eval("(-2.0...)").step { |x| break if x > 1.5; ScratchPad << x } + ScratchPad.recorded.should eql([-2.0, -1.0, 0.0, 1.0]) + end + + it "yields Float values incremented by an Integer step" do + eval("(-5.0..)").step(2) { |x| break if x > 3.5; ScratchPad << x } + ScratchPad.recorded.should eql([-5.0, -3.0, -1.0, 1.0, 3.0]) + + ScratchPad.record [] + eval("(-5.0...)").step(2) { |x| break if x > 3.5; ScratchPad << x } + ScratchPad.recorded.should eql([-5.0, -3.0, -1.0, 1.0, 3.0]) + end + + it "yields Float values incremented by a Float step" do + eval("(-1.0..)").step(0.5) { |x| break if x > 0.6; ScratchPad << x } + ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5]) + + ScratchPad.record [] + eval("(-1.0...)").step(0.5) { |x| break if x > 0.6; ScratchPad << x } + ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5]) + end + + it "handles infinite values at the start" do + eval("(-Float::INFINITY..)").step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 } + ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY]) + + ScratchPad.record [] + eval("(-Float::INFINITY...)").step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 } + ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY]) + end + end + + describe "and String values" do + it "yields String values incremented by #succ and less than or equal to end when not passed a step" do + eval("('A'..)").step { |x| break if x > "D"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "B", "C", "D"] + + ScratchPad.record [] + eval("('A'...)").step { |x| break if x > "D"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "B", "C", "D"] + end + + it "yields String values incremented by #succ called Integer step times" do + eval("('A'..)").step(2) { |x| break if x > "F"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "C", "E"] + + ScratchPad.record [] + eval("('A'...)").step(2) { |x| break if x > "F"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "C", "E"] + end + + it "raises a TypeError when passed a Float step" do + -> { eval("('A'..)").step(2.0) { } }.should raise_error(TypeError) + -> { eval("('A'...)").step(2.0) { } }.should raise_error(TypeError) + end + end + end + end + describe "when no block is given" do describe "returned Enumerator" do describe "size" do diff --git a/spec/ruby/core/range/to_a_spec.rb b/spec/ruby/core/range/to_a_spec.rb index 15f0b44a9c..b0067f0e07 100644 --- a/spec/ruby/core/range/to_a_spec.rb +++ b/spec/ruby/core/range/to_a_spec.rb @@ -19,4 +19,10 @@ describe "Range#to_a" do it "works with Ranges of Symbols" do (:A..:z).to_a.size.should == 58 end + + ruby_version_is "2.6" do + it "throws an exception for endless ranges" do + -> { eval("(1..)").to_a }.should raise_error(RangeError) + end + end end diff --git a/spec/ruby/core/range/to_s_spec.rb b/spec/ruby/core/range/to_s_spec.rb index 7392aa9890..ccbc5d8e7e 100644 --- a/spec/ruby/core/range/to_s_spec.rb +++ b/spec/ruby/core/range/to_s_spec.rb @@ -11,6 +11,13 @@ describe "Range#to_s" do (0.5..2.4).to_s.should == "0.5..2.4" end + ruby_version_is "2.6" do + it "can show endless ranges" do + eval("(1..)").to_s.should == "1.." + eval("(1.0...)").to_s.should == "1.0..." + end + end + ruby_version_is ''...'2.7' do it "returns a tainted string if either end is tainted" do (("a".taint)..."c").to_s.tainted?.should be_true |