summaryrefslogtreecommitdiff
path: root/spec/ruby/core/enumerable/sum_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/enumerable/sum_spec.rb')
-rw-r--r--spec/ruby/core/enumerable/sum_spec.rb60
1 files changed, 40 insertions, 20 deletions
diff --git a/spec/ruby/core/enumerable/sum_spec.rb b/spec/ruby/core/enumerable/sum_spec.rb
index 4881039a8d..2eb74db6ac 100644
--- a/spec/ruby/core/enumerable/sum_spec.rb
+++ b/spec/ruby/core/enumerable/sum_spec.rb
@@ -1,30 +1,50 @@
-require File.expand_path('../../../spec_helper', __FILE__)
-require File.expand_path('../fixtures/classes', __FILE__)
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
-ruby_version_is '2.4' do
- describe 'Enumerable#sum' do
- before :each do
- @enum = Object.new.to_enum
- class << @enum
- def each
- yield 0
- yield(-1)
- yield 2
- yield 2/3r
- end
+describe 'Enumerable#sum' do
+ before :each do
+ @enum = Object.new.to_enum
+ class << @enum
+ def each
+ yield 0
+ yield(-1)
+ yield 2
+ yield 2/3r
end
end
+ end
- it 'returns amount of the elements with taking an argument as the initial value' do
- @enum.sum(10).should == 35/3r
- end
+ it 'returns amount of the elements with taking an argument as the initial value' do
+ @enum.sum(10).should == 35/3r
+ end
- it 'gives 0 as a default argument' do
- @enum.sum.should == 5/3r
- end
+ it 'gives 0 as a default argument' do
+ @enum.sum.should == 5/3r
+ end
- it 'takes a block to transform the elements' do
+ context 'with a block' do
+ it 'transforms the elements' do
@enum.sum { |element| element * 2 }.should == 10/3r
end
+
+ it 'does not destructure array elements' do
+ class << @enum
+ def each
+ yield [1,2]
+ yield [3]
+ end
+ end
+
+ @enum.sum(&:last).should == 5
+ end
+ end
+
+ # https://bugs.ruby-lang.org/issues/12217
+ # https://github.com/ruby/ruby/blob/master/doc/ChangeLog/ChangeLog-2.4.0#L6208-L6214
+ it "uses Kahan's compensated summation algorithm for precise sum of float numbers" do
+ floats = [2.7800000000000002, 5.0, 2.5, 4.44, 3.89, 3.89, 4.44, 7.78, 5.0, 2.7800000000000002, 5.0, 2.5].to_enum
+ naive_sum = floats.reduce { |sum, e| sum + e }
+ naive_sum.should == 50.00000000000001
+ floats.sum.should == 50.0
end
end