1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
This commit is contained in:
Benoit Daloze 2021-10-20 21:57:05 +02:00
parent 500ba24882
commit 030b1892d5
7 changed files with 146 additions and 50 deletions

View file

@ -9,6 +9,35 @@ describe "Array#sum" do
[1, 2, 3].sum { |i| i * 10 }.should == 60 [1, 2, 3].sum { |i| i * 10 }.should == 60
end end
# https://bugs.ruby-lang.org/issues/12217
# https://github.com/ruby/ruby/blob/master/doc/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]
naive_sum = floats.reduce { |sum, e| sum + e }
naive_sum.should == 50.00000000000001
floats.sum.should == 50.0
end
it "handles infinite values and NaN" do
[1.0, Float::INFINITY].sum.should == Float::INFINITY
[1.0, -Float::INFINITY].sum.should == -Float::INFINITY
[1.0, Float::NAN].sum.should.nan?
[Float::INFINITY, 1.0].sum.should == Float::INFINITY
[-Float::INFINITY, 1.0].sum.should == -Float::INFINITY
[Float::NAN, 1.0].sum.should.nan?
[Float::NAN, Float::INFINITY].sum.should.nan?
[Float::INFINITY, Float::NAN].sum.should.nan?
[Float::INFINITY, -Float::INFINITY].sum.should.nan?
[-Float::INFINITY, Float::INFINITY].sum.should.nan?
[Float::INFINITY, Float::INFINITY].sum.should == Float::INFINITY
[-Float::INFINITY, -Float::INFINITY].sum.should == -Float::INFINITY
[Float::NAN, Float::NAN].sum.should.nan?
end
it "returns init value if array is empty" do it "returns init value if array is empty" do
[].sum(-1).should == -1 [].sum(-1).should == -1
end end

View file

@ -25,4 +25,13 @@ describe 'Enumerable#sum' do
it 'takes a block to transform the elements' do it 'takes a block to transform the elements' do
@enum.sum { |element| element * 2 }.should == 10/3r @enum.sum { |element| element * 2 }.should == 10/3r
end end
# https://bugs.ruby-lang.org/issues/12217
# https://github.com/ruby/ruby/blob/master/doc/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 end

View file

@ -70,13 +70,11 @@ describe "File.utime" do
end end
end end
platform_is_not :windows do it "may set nanosecond precision" do
it "sets nanosecond precision" do
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r) t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r)
File.utime(t, t, @file1) File.utime(t, t, @file1)
File.atime(@file1).nsec.should == 123456789 File.atime(@file1).nsec.should.between?(0, 123500000)
File.mtime(@file1).nsec.should == 123456789 File.mtime(@file1).nsec.should.between?(0, 123500000)
end
end end
platform_is :linux do platform_is :linux do

View file

@ -441,6 +441,26 @@ describe "Module#autoload" do
ScratchPad.recorded.should == [:raise, :raise] ScratchPad.recorded.should == [:raise, :raise]
end end
ruby_version_is "3.1" do
it "removes the constant from Module#constants if the loaded file does not define it" do
path = fixture(__FILE__, "autoload_o.rb")
ScratchPad.record []
ModuleSpecs::Autoload.autoload :O, path
ModuleSpecs::Autoload.const_defined?(:O).should == true
ModuleSpecs::Autoload.should have_constant(:O)
ModuleSpecs::Autoload.autoload?(:O).should == path
-> { ModuleSpecs::Autoload::O }.should raise_error(NameError)
ModuleSpecs::Autoload.const_defined?(:O).should == false
ModuleSpecs::Autoload.should_not have_constant(:O)
ModuleSpecs::Autoload.autoload?(:O).should == nil
-> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError)
end
end
ruby_version_is ""..."3.1" do
it "does not remove the constant from Module#constants if the loaded file does not define it, but leaves it as 'undefined'" do it "does not remove the constant from Module#constants if the loaded file does not define it, but leaves it as 'undefined'" do
path = fixture(__FILE__, "autoload_o.rb") path = fixture(__FILE__, "autoload_o.rb")
ScratchPad.record [] ScratchPad.record []
@ -452,11 +472,12 @@ describe "Module#autoload" do
-> { ModuleSpecs::Autoload::O }.should raise_error(NameError) -> { ModuleSpecs::Autoload::O }.should raise_error(NameError)
ModuleSpecs::Autoload.should have_constant(:O)
ModuleSpecs::Autoload.const_defined?(:O).should == false ModuleSpecs::Autoload.const_defined?(:O).should == false
ModuleSpecs::Autoload.should have_constant(:O)
ModuleSpecs::Autoload.autoload?(:O).should == nil ModuleSpecs::Autoload.autoload?(:O).should == nil
-> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError) -> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError)
end end
end
it "does not try to load the file again if the loaded file did not define the constant" do it "does not try to load the file again if the loaded file did not define the constant" do
path = fixture(__FILE__, "autoload_o.rb") path = fixture(__FILE__, "autoload_o.rb")
@ -554,13 +575,35 @@ describe "Module#autoload" do
# Basically, the parent autoload constant remains in a "undefined" state # Basically, the parent autoload constant remains in a "undefined" state
self.autoload?(:DeclaredInParentDefinedInCurrent).should == nil self.autoload?(:DeclaredInParentDefinedInCurrent).should == nil
const_defined?(:DeclaredInParentDefinedInCurrent).should == false const_defined?(:DeclaredInParentDefinedInCurrent).should == false
self.should have_constant(:DeclaredInParentDefinedInCurrent)
-> { DeclaredInParentDefinedInCurrent }.should raise_error(NameError) -> { DeclaredInParentDefinedInCurrent }.should raise_error(NameError)
ModuleSpecs::Autoload::LexicalScope.send(:remove_const, :DeclaredInParentDefinedInCurrent) ModuleSpecs::Autoload::LexicalScope.send(:remove_const, :DeclaredInParentDefinedInCurrent)
end end
end end
ruby_version_is "3.1" do
it "looks up in parent scope after failed autoload" do
@remove << :DeclaredInCurrentDefinedInParent
module ModuleSpecs::Autoload
ScratchPad.record -> {
DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
}
class LexicalScope
autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
-> { DeclaredInCurrentDefinedInParent }.should_not raise_error(NameError)
# Basically, the autoload constant remains in a "undefined" state
self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
const_defined?(:DeclaredInCurrentDefinedInParent).should == false
-> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError)
end
DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
end
end
end
ruby_version_is ""..."3.1" do
it "and fails when finding the undefined autoload constant in the current scope when declared in current and defined in parent" do it "and fails when finding the undefined autoload constant in the current scope when declared in current and defined in parent" do
@remove << :DeclaredInCurrentDefinedInParent @remove << :DeclaredInCurrentDefinedInParent
module ModuleSpecs::Autoload module ModuleSpecs::Autoload
@ -581,6 +624,7 @@ describe "Module#autoload" do
DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
end end
end end
end
it "in the included modules" do it "in the included modules" do
@remove << :DefinedInIncludedModule @remove << :DefinedInIncludedModule

View file

@ -101,7 +101,7 @@ describe "Module#const_set" do
mod.const_get(:Foo).should == 1 mod.const_get(:Foo).should == 1
end end
it "does not warn if the previous value was undefined" do it "does not warn after a failed autoload" do
path = fixture(__FILE__, "autoload_o.rb") path = fixture(__FILE__, "autoload_o.rb")
ScratchPad.record [] ScratchPad.record []
mod = Module.new mod = Module.new
@ -109,7 +109,6 @@ describe "Module#const_set" do
mod.autoload :Foo, path mod.autoload :Foo, path
-> { mod::Foo }.should raise_error(NameError) -> { mod::Foo }.should raise_error(NameError)
mod.should have_constant(:Foo)
mod.const_defined?(:Foo).should == false mod.const_defined?(:Foo).should == false
mod.autoload?(:Foo).should == nil mod.autoload?(:Foo).should == nil

View file

@ -77,6 +77,7 @@ describe "IPAddr#new" do
a.family.should == Socket::AF_INET6 a.family.should == Socket::AF_INET6
end end
ruby_version_is ""..."3.1" do
it "raises on incorrect IPAddr strings" do it "raises on incorrect IPAddr strings" do
[ [
["fe80::1%fxp0"], ["fe80::1%fxp0"],
@ -91,3 +92,19 @@ describe "IPAddr#new" do
} }
end end
end end
ruby_version_is "3.1" do
it "raises on incorrect IPAddr strings" do
[
["::1/255.255.255.0"],
[IPAddr.new("::1").to_i],
["::ffff:192.168.1.2/120", Socket::AF_INET],
["[192.168.1.2]/120"],
].each { |args|
->{
IPAddr.new(*args)
}.should raise_error(ArgumentError)
}
end
end
end

View file

@ -30,7 +30,7 @@ describe "StringIO#ungetbyte" do
io.string.should == 'Shis is a simple string.' io.string.should == 'Shis is a simple string.'
end end
it "ungets the bytes of a string if given a string as an arugment" do it "ungets the bytes of a string if given a string as an argument" do
str = "\u01a9" str = "\u01a9"
io = StringIO.new(str) io = StringIO.new(str)
b = io.getbyte b = io.getbyte