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.between?(0, 123500000)
File.atime(@file1).nsec.should == 123456789 File.mtime(@file1).nsec.should.between?(0, 123500000)
File.mtime(@file1).nsec.should == 123456789
end
end end
platform_is :linux do platform_is :linux do

View file

@ -441,21 +441,42 @@ describe "Module#autoload" do
ScratchPad.recorded.should == [:raise, :raise] ScratchPad.recorded.should == [:raise, :raise]
end end
it "does not remove the constant from Module#constants if the loaded file does not define it, but leaves it as 'undefined'" do ruby_version_is "3.1" do
path = fixture(__FILE__, "autoload_o.rb") it "removes the constant from Module#constants if the loaded file does not define it" do
ScratchPad.record [] path = fixture(__FILE__, "autoload_o.rb")
ModuleSpecs::Autoload.autoload :O, path ScratchPad.record []
ModuleSpecs::Autoload.autoload :O, path
ModuleSpecs::Autoload.const_defined?(:O).should == true ModuleSpecs::Autoload.const_defined?(:O).should == true
ModuleSpecs::Autoload.should have_constant(:O) ModuleSpecs::Autoload.should have_constant(:O)
ModuleSpecs::Autoload.autoload?(:O).should == path ModuleSpecs::Autoload.autoload?(:O).should == path
-> { 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_not 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
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
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 have_constant(:O)
ModuleSpecs::Autoload.autoload?(:O).should == nil
-> { 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
@ -554,31 +575,54 @@ 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
it "and fails when finding the undefined autoload constant in the current scope when declared in current and defined in parent" do ruby_version_is "3.1" do
@remove << :DeclaredInCurrentDefinedInParent it "looks up in parent scope after failed autoload" do
module ModuleSpecs::Autoload @remove << :DeclaredInCurrentDefinedInParent
ScratchPad.record -> { module ModuleSpecs::Autoload
DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent ScratchPad.record -> {
} DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
}
class LexicalScope class LexicalScope
autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb") autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
-> { DeclaredInCurrentDefinedInParent }.should raise_error(NameError) -> { DeclaredInCurrentDefinedInParent }.should_not raise_error(NameError)
# Basically, the autoload constant remains in a "undefined" state # Basically, the autoload constant remains in a "undefined" state
self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
const_defined?(:DeclaredInCurrentDefinedInParent).should == false const_defined?(:DeclaredInCurrentDefinedInParent).should == false
self.should have_constant(:DeclaredInCurrentDefinedInParent) -> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError)
-> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError) end
DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
end end
end
end
DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent 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
@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 raise_error(NameError)
# Basically, the autoload constant remains in a "undefined" state
self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
const_defined?(:DeclaredInCurrentDefinedInParent).should == false
self.should have_constant(:DeclaredInCurrentDefinedInParent)
-> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError)
end
DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
end
end end
end end

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