mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@e81b3cd
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67361 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0f64776745
commit
a28aa80c73
53 changed files with 932 additions and 106 deletions
|
@ -88,7 +88,6 @@ IncludeSpecsClass
|
|||
IncludeSpecsMiddle
|
||||
IncludeSpecsTop
|
||||
IncludesMath
|
||||
InvalidTostrTest
|
||||
JSON
|
||||
KSAutoloadA
|
||||
KSAutoloadB
|
||||
|
@ -177,6 +176,7 @@ StringRefinement
|
|||
StringScanner
|
||||
StringSubclass
|
||||
StructClasses
|
||||
Syck
|
||||
Syslog
|
||||
TCPServer
|
||||
TCPSocket
|
||||
|
@ -205,7 +205,6 @@ UserObject
|
|||
UserPreviouslyDefinedWithInitializedIvar
|
||||
UserRegexp
|
||||
UserString
|
||||
ValidTostrTest
|
||||
Vector
|
||||
WEBrick
|
||||
WIN32OLE
|
||||
|
|
|
@ -96,3 +96,7 @@ Lint/UnreachableCode:
|
|||
Lint/UriRegexp:
|
||||
Exclude:
|
||||
- 'library/uri/regexp_spec.rb'
|
||||
|
||||
Lint/Debugger:
|
||||
Exclude:
|
||||
- 'core/binding/fixtures/irb.rb'
|
||||
|
|
|
@ -6,14 +6,14 @@ script:
|
|||
- ../mspec/bin/mspec $MSPEC_OPTS
|
||||
matrix:
|
||||
include:
|
||||
- rvm: 2.5.3
|
||||
- rvm: 2.5.5
|
||||
env: MSPEC_OPTS="-R2 -ff"
|
||||
- rvm: 2.3.8
|
||||
- rvm: 2.4.5
|
||||
env: CHECK_LEAKS=true
|
||||
- rvm: 2.5.3
|
||||
- rvm: 2.5.5
|
||||
env: CHECK_LEAKS=true
|
||||
- rvm: 2.6.1
|
||||
- rvm: 2.6.2
|
||||
env: CHECK_LEAKS=true
|
||||
- env: RUBOCOP=true
|
||||
rvm: 2.4.5
|
||||
|
|
|
@ -1,23 +1,6 @@
|
|||
require_relative '../spec_helper'
|
||||
require_relative 'shared/change_directory'
|
||||
|
||||
describe 'The -C command line option' do
|
||||
before :all do
|
||||
@script = fixture(__FILE__, 'dash_upper_c_script.rb')
|
||||
@tempdir = File.dirname(@script)
|
||||
end
|
||||
|
||||
it 'changes the PWD when using a file' do
|
||||
output = ruby_exe(@script, options: "-C #{@tempdir}")
|
||||
output.should == @tempdir
|
||||
end
|
||||
|
||||
it 'does not need a space after -C for the argument' do
|
||||
output = ruby_exe(@script, options: "-C#{@tempdir}")
|
||||
output.should == @tempdir
|
||||
end
|
||||
|
||||
it 'changes the PWD when using -e' do
|
||||
output = ruby_exe(nil, options: "-C #{@tempdir} -e 'print Dir.pwd'")
|
||||
output.should == @tempdir
|
||||
end
|
||||
describe "The -C command line option" do
|
||||
it_behaves_like :command_line_change_directory, "-C"
|
||||
end
|
||||
|
|
6
spec/ruby/command_line/dash_upper_x_spec.rb
Normal file
6
spec/ruby/command_line/dash_upper_x_spec.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
require_relative '../spec_helper'
|
||||
require_relative 'shared/change_directory'
|
||||
|
||||
describe "The -X command line option" do
|
||||
it_behaves_like :command_line_change_directory, "-X"
|
||||
end
|
65
spec/ruby/command_line/feature_spec.rb
Normal file
65
spec/ruby/command_line/feature_spec.rb
Normal file
|
@ -0,0 +1,65 @@
|
|||
require_relative '../spec_helper'
|
||||
|
||||
describe "The --enable and --disable flags" do
|
||||
|
||||
it "can be used with gems" do
|
||||
ruby_exe("p defined?(Gem)", options: "--enable=gems").chomp.should == "\"constant\""
|
||||
ruby_exe("p defined?(Gem)", options: "--disable=gems").chomp.should == "nil"
|
||||
ruby_exe("p defined?(Gem)", options: "--enable-gems").chomp.should == "\"constant\""
|
||||
ruby_exe("p defined?(Gem)", options: "--disable-gems").chomp.should == "nil"
|
||||
end
|
||||
|
||||
it "can be used with gem" do
|
||||
ruby_exe("p defined?(Gem)", options: "--enable=gem").chomp.should == "\"constant\""
|
||||
ruby_exe("p defined?(Gem)", options: "--disable=gem").chomp.should == "nil"
|
||||
ruby_exe("p defined?(Gem)", options: "--enable-gem").chomp.should == "\"constant\""
|
||||
ruby_exe("p defined?(Gem)", options: "--disable-gem").chomp.should == "nil"
|
||||
end
|
||||
|
||||
it "can be used with did_you_mean" do
|
||||
ruby_exe("p defined?(DidYouMean)", options: "--enable=did_you_mean").chomp.should == "\"constant\""
|
||||
ruby_exe("p defined?(DidYouMean)", options: "--disable=did_you_mean").chomp.should == "nil"
|
||||
ruby_exe("p defined?(DidYouMean)", options: "--enable-did_you_mean").chomp.should == "\"constant\""
|
||||
ruby_exe("p defined?(DidYouMean)", options: "--disable-did_you_mean").chomp.should == "nil"
|
||||
end
|
||||
|
||||
it "can be used with rubyopt" do
|
||||
ruby_exe("p $VERBOSE", options: "--enable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "true"
|
||||
ruby_exe("p $VERBOSE", options: "--disable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false"
|
||||
ruby_exe("p $VERBOSE", options: "--enable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "true"
|
||||
ruby_exe("p $VERBOSE", options: "--disable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false"
|
||||
end
|
||||
|
||||
it "can be used with frozen-string-literal" do
|
||||
ruby_exe("p 'foo'.frozen?", options: "--enable=frozen-string-literal").chomp.should == "true"
|
||||
ruby_exe("p 'foo'.frozen?", options: "--disable=frozen-string-literal").chomp.should == "false"
|
||||
ruby_exe("p 'foo'.frozen?", options: "--enable-frozen-string-literal").chomp.should == "true"
|
||||
ruby_exe("p 'foo'.frozen?", options: "--disable-frozen-string-literal").chomp.should == "false"
|
||||
end
|
||||
|
||||
ruby_version_is "2.6" do
|
||||
it "can be used with jit" do
|
||||
ruby_exe("p RubyVM::MJIT.enabled?", options: "--enable=jit").chomp.should == "true"
|
||||
ruby_exe("p RubyVM::MJIT.enabled?", options: "--disable=jit").chomp.should == "false"
|
||||
ruby_exe("p RubyVM::MJIT.enabled?", options: "--enable-jit").chomp.should == "true"
|
||||
ruby_exe("p RubyVM::MJIT.enabled?", options: "--disable-jit").chomp.should == "false"
|
||||
end
|
||||
end
|
||||
|
||||
it "can be used with all" do
|
||||
e = "p [defined?(Gem), defined?(DidYouMean), $VERBOSE, 'foo'.frozen?]"
|
||||
env = {'RUBYOPT' => '-w'}
|
||||
ruby_exe(e, options: "--enable=all", env: env).chomp.should == "[\"constant\", \"constant\", true, true]"
|
||||
ruby_exe(e, options: "--enable-all", env: env).chomp.should == "[\"constant\", \"constant\", true, true]"
|
||||
ruby_exe(e, options: "--disable=all", env: env).chomp.should == "[nil, nil, false, false]"
|
||||
ruby_exe(e, options: "--disable-all", env: env).chomp.should == "[nil, nil, false, false]"
|
||||
end
|
||||
|
||||
it "prints a warning for unknown features" do
|
||||
ruby_exe("p 14", options: "--enable=ruby-spec-feature-does-not-exist 2>&1").chomp.should include('warning: unknown argument for --enable')
|
||||
ruby_exe("p 14", options: "--disable=ruby-spec-feature-does-not-exist 2>&1").chomp.should include('warning: unknown argument for --disable')
|
||||
ruby_exe("p 14", options: "--enable-ruby-spec-feature-does-not-exist 2>&1").chomp.should include('warning: unknown argument for --enable')
|
||||
ruby_exe("p 14", options: "--disable-ruby-spec-feature-does-not-exist 2>&1").chomp.should include('warning: unknown argument for --disable')
|
||||
end
|
||||
|
||||
end
|
|
@ -30,6 +30,7 @@ describe "The RUBYLIB environment variable" do
|
|||
dir = tmp("rubylib/incl_front")
|
||||
ENV["RUBYLIB"] = @pre + dir
|
||||
paths = ruby_exe("puts $LOAD_PATH").lines.map(&:chomp)
|
||||
paths.shift if paths.first.end_with?('/gem-rehash')
|
||||
if PlatformGuard.implementation? :ruby
|
||||
# In a MRI checkout, $PWD and some extra -I entries end up as
|
||||
# the first entries in $LOAD_PATH. So just assert that it's not last.
|
||||
|
|
21
spec/ruby/command_line/shared/change_directory.rb
Normal file
21
spec/ruby/command_line/shared/change_directory.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
describe :command_line_change_directory, shared: true do
|
||||
before :all do
|
||||
@script = fixture(__FILE__, 'change_directory_script.rb')
|
||||
@tempdir = File.dirname(@script)
|
||||
end
|
||||
|
||||
it 'changes the PWD when using a file' do
|
||||
output = ruby_exe(@script, options: "#{@method} #{@tempdir}")
|
||||
output.should == @tempdir
|
||||
end
|
||||
|
||||
it 'does not need a space after -C for the argument' do
|
||||
output = ruby_exe(@script, options: "#{@method}#{@tempdir}")
|
||||
output.should == @tempdir
|
||||
end
|
||||
|
||||
it 'changes the PWD when using -e' do
|
||||
output = ruby_exe(nil, options: "#{@method} #{@tempdir} -e 'print Dir.pwd'")
|
||||
output.should == @tempdir
|
||||
end
|
||||
end
|
3
spec/ruby/core/binding/fixtures/irb.rb
Normal file
3
spec/ruby/core/binding/fixtures/irb.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
a = 10
|
||||
|
||||
binding.irb
|
17
spec/ruby/core/binding/irb_spec.rb
Normal file
17
spec/ruby/core/binding/irb_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "2.5" do
|
||||
describe "Binding#irb" do
|
||||
it "creates an IRB session with the binding in scope" do
|
||||
irb_fixture = fixture __FILE__, "irb.rb"
|
||||
|
||||
out = IO.popen([*ruby_exe, irb_fixture], "r+") do |pipe|
|
||||
pipe.puts "a ** 2"
|
||||
pipe.puts "exit"
|
||||
pipe.readlines.map(&:chomp)
|
||||
end
|
||||
|
||||
out[-3..-1].should == ["a ** 2", "100", "exit"]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,7 +12,7 @@ describe "File.mtime" do
|
|||
|
||||
it "returns the modification Time of the file" do
|
||||
File.mtime(@filename).should be_kind_of(Time)
|
||||
File.mtime(@filename).should be_close(@mtime, 2.0)
|
||||
File.mtime(@filename).should be_close(@mtime, 60.0)
|
||||
end
|
||||
|
||||
guard -> { platform_is :linux or (platform_is :windows and ruby_version_is '2.5') } do
|
||||
|
|
|
@ -75,11 +75,11 @@ describe "Float#to_s" do
|
|||
-10000000000000000.0.to_s.should == "-1.0e+16"
|
||||
end
|
||||
|
||||
it "uses non-e format for a positive value with whole part having 17 significant figures" do
|
||||
it "uses e format for a positive value with whole part having 17 significant figures" do
|
||||
1000000000000000.0.to_s.should == "1.0e+15"
|
||||
end
|
||||
|
||||
it "uses non-e format for a negative value with whole part having 17 significant figures" do
|
||||
it "uses e format for a negative value with whole part having 17 significant figures" do
|
||||
-1000000000000000.0.to_s.should == "-1.0e+15"
|
||||
end
|
||||
|
||||
|
@ -95,6 +95,201 @@ describe "Float#to_s" do
|
|||
it "outputs the minimal, unique form to represent the value" do
|
||||
0.56.to_s.should == "0.56"
|
||||
end
|
||||
|
||||
describe "matches" do
|
||||
ruby_version_is "2.4" do # For unpack1
|
||||
it "random examples in all ranges" do
|
||||
# 50.times do
|
||||
# bytes = (0...8).map { rand(256) }
|
||||
# string = bytes.pack('C8')
|
||||
# float = string.unpack('D').first
|
||||
# puts " #{bytes.pack('C8').inspect}.unpack1('D').to_s.should == #{float.to_s.inspect}"
|
||||
# end
|
||||
|
||||
"\x97\x15\xC1| \xF5\x19\xAD".unpack1('D').to_s.should == "-1.9910613439044092e-91"
|
||||
"\xBF\xF0\x14\xAD\xDF\x17q\xD1".unpack1('D').to_s.should == "-2.075408637901046e+84"
|
||||
"\xDF\xBD\xC0\x89\xDA\x1F&$".unpack1('D').to_s.should == "1.5219626883645564e-134"
|
||||
"|0<?a\xFB\xBFG".unpack1('D').to_s.should == "4.251130678455814e+37"
|
||||
"U\xEE*\xB7\xF1\xB8\xE7\x18".unpack1('D').to_s.should == "1.0648588700899858e-188"
|
||||
"\x15Y\xD1J\x80/7\xD0".unpack1('D').to_s.should == "-2.6847034291392176e+78"
|
||||
"\x1D\x1E\xD2\x9A3)\xF5q".unpack1('D').to_s.should == "8.818842365424256e+240"
|
||||
"M\xD0C\xA3\x19-\xE3\xE5".unpack1('D').to_s.should == "-6.365746090981858e+182"
|
||||
"\xAFf\xFE\xF0$\x85\x01L".unpack1('D').to_s.should == "1.374692728674642e+58"
|
||||
"'N\xB7\x12\xE0\xC8t\t".unpack1('D').to_s.should == "4.1254080603298014e-263"
|
||||
"\xAFn\xF2x\x85\xB5\x15j".unpack1('D').to_s.should == "1.0635019031720867e+203"
|
||||
"nQ\x95\xFA\xD9\xE3\xC5)".unpack1('D').to_s.should == "1.8641386367625094e-107"
|
||||
"\xC2\x9A\xB1|/\xCAJM".unpack1('D').to_s.should == "2.204135837758401e+64"
|
||||
"q n\xD8\x86\xF2\xA8D".unpack1('D').to_s.should == "5.890531214599543e+22"
|
||||
"dmR\xC6\xB3\xF3\x95G".unpack1('D').to_s.should == "7.294790578028111e+36"
|
||||
"6I\x0E)?E\xB5\xE1".unpack1('D').to_s.should == "-4.7847061687992665e+162"
|
||||
"\xCD\xE0\xBBy\x9F\xD8\xE89".unpack1('D').to_s.should == "9.800091365433584e-30"
|
||||
"\xB8\x98TN\x98\xEE\xC1\xF9".unpack1('D').to_s.should == "-3.178740061599073e+278"
|
||||
"\x8F_\xFF\x15\x1F2\x17B".unpack1('D').to_s.should == "24906286463.84332"
|
||||
"\x94\x18V\xC5&\xE6\xEAi".unpack1('D').to_s.should == "1.6471900588998988e+202"
|
||||
"\xECq\xB1\x01\ai\xBD,".unpack1('D').to_s.should == "3.5248469410018065e-93"
|
||||
"\x9C\xC6\x13pG\xDAx\x9A".unpack1('D').to_s.should == "-3.743306318201459e-181"
|
||||
"\xEA7,gJ\xEE\x8E*".unpack1('D').to_s.should == "1.0789044330549825e-103"
|
||||
"1\xD3\xF5K\x8D\xEF\xA7\r".unpack1('D').to_s.should == "7.011009309284311e-243"
|
||||
"o\xB3\x02\xAF\x9D\xFC\r\xF6".unpack1('D').to_s.should == "-4.610585875652112e+260"
|
||||
"&:x\x15\xFC3P\x01".unpack1('D').to_s.should == "2.362770515774595e-302"
|
||||
"\xE6<C\xB8\x90\xF2\xCF\x90".unpack1('D').to_s.should == "-1.0535871178808475e-227"
|
||||
"\x9Al\aB6's}".unpack1('D').to_s.should == "1.957205609213647e+296"
|
||||
"+\v\x16\xFD\x19\x0E\x9B\x06".unpack1('D').to_s.should == "7.631200870990123e-277"
|
||||
"\xEC\xF8~\xDA\xE7Tf\x92".unpack1('D').to_s.should == "-4.942358450191624e-220"
|
||||
"\xE0\xA0\xC9\x906\xBDcI".unpack1('D').to_s.should == "3.521575588133954e+45"
|
||||
"\xBD\xFD\xC9\xFD\rp\x02\x0F".unpack1('D').to_s.should == "2.2651682962118346e-236"
|
||||
"\xE9\xA8\xAD\xC4\xF6u\xF7\x19".unpack1('D').to_s.should == "1.3803378872547194e-183"
|
||||
"\"f\xED9\x17\xF0\xF1!".unpack1('D').to_s.should == "3.591307506787987e-145"
|
||||
"\xE6\xF2\xB6\x9CFl\xB3O".unpack1('D').to_s.should == "8.785250953340842e+75"
|
||||
"g\xFD\xEA\r~x\xBA\x9D".unpack1('D').to_s.should == "-1.7955908504285607e-165"
|
||||
"\xE2\x84J\xC7\x00\n/\x06".unpack1('D').to_s.should == "6.839790344291208e-279"
|
||||
"s\xFB\xA58x\xF1\xA9\xD9".unpack1('D').to_s.should == "-8.574967051032431e+123"
|
||||
"\xE2\x9D\xBE\xE2\x10k{\xFC".unpack1('D').to_s.should == "-4.2751876153404507e+291"
|
||||
"!z \xB4i4\x8C5".unpack1('D').to_s.should == "9.423078517655126e-51"
|
||||
"!_\xEAp- 7R".unpack1('D').to_s.should == "1.1500944673871687e+88"
|
||||
"\x03\xAD=\\\xCB >\xBB".unpack1('D').to_s.should == "-2.4921382721208654e-23"
|
||||
"\x94\x01\xB1\x87\x10\x9B#\x88".unpack1('D').to_s.should == "-1.8555672851958583e-269"
|
||||
"\x90H\xFF\\S\x01)\x89".unpack1('D').to_s.should == "-1.5509713490195968e-264"
|
||||
"HW@\x13\x85&=)".unpack1('D').to_s.should == "4.848496966571536e-110"
|
||||
"\x14\xDB\\\x10\x93\x9C\xD66".unpack1('D').to_s.should == "1.5842813502410472e-44"
|
||||
"\x9D8p>\xFF\x9B[\xF3".unpack1('D').to_s.should == "-4.826061446912647e+247"
|
||||
"c\x9D}\t]\xF9pg".unpack1('D').to_s.should == "1.8907034486212682e+190"
|
||||
"\xA51\xC9WJ\xB5a^".unpack1('D').to_s.should == "4.422435231445608e+146"
|
||||
"\x8BL\x90\xCB\xEARf\f".unpack1('D').to_s.should == "6.235963569982745e-249"
|
||||
end
|
||||
|
||||
it "random examples in human ranges" do
|
||||
# 50.times do
|
||||
# formatted = ''
|
||||
# rand(1..3).times do
|
||||
# formatted << rand(10).to_s
|
||||
# end
|
||||
# formatted << '.'
|
||||
# rand(1..9).times do
|
||||
# formatted << rand(10).to_s
|
||||
# end
|
||||
# float = formatted.to_f
|
||||
# string = [float].pack('D')
|
||||
# puts " #{string.inspect}.unpack1('D').to_s.should == #{float.to_s.inspect}"
|
||||
# end
|
||||
|
||||
";\x01M\x84\r\xF7M@".unpack1('D').to_s.should == "59.9301"
|
||||
"\xAE\xD3HKe|\x8A@".unpack1('D').to_s.should == "847.54946"
|
||||
"/\xDD$\x06\x81u8@".unpack1('D').to_s.should == "24.459"
|
||||
"E\xD8\xF0\xF4JY\xF0?".unpack1('D').to_s.should == "1.0218"
|
||||
"[\brP\xC2\xCC\x05@".unpack1('D').to_s.should == "2.72498"
|
||||
"\xE6w\x9A\xCCx\xF6T@".unpack1('D').to_s.should == "83.851123"
|
||||
"\xB4\xD4&\xC0C\xFD.@".unpack1('D').to_s.should == "15.494657521"
|
||||
"\xCD\xCC\xCC\xCC\xCCLM@".unpack1('D').to_s.should == "58.6"
|
||||
"\xA1\x84\x99\xB6\x7F\xE5\x13@".unpack1('D').to_s.should == "4.97412"
|
||||
"\xD7\xA3p=\n\x9C\x80@".unpack1('D').to_s.should == "531.505"
|
||||
"S\x96!\x8E\xF5\x0E\x8F@".unpack1('D').to_s.should == "993.8699"
|
||||
"\xF1F\xE6\x91?\x18\xD7?".unpack1('D').to_s.should == "0.360855"
|
||||
"=\n\xD7\xA3p=\x15@".unpack1('D').to_s.should == "5.31"
|
||||
"\x90Ci\x147\xC74@".unpack1('D').to_s.should == "20.7781842"
|
||||
"A\ft\xED\v\xE8\xB9?".unpack1('D').to_s.should == "0.101197"
|
||||
"\x9A\x99\x99\x99\x999T@".unpack1('D').to_s.should == "80.9"
|
||||
"\x00\x00\x00\x00\x00\x00\x1A@".unpack1('D').to_s.should == "6.5"
|
||||
"\xD3J\xC6\xD6\x98\x8Es@".unpack1('D').to_s.should == "312.9123142"
|
||||
"SQ\xE5I\fQ\x1E@".unpack1('D').to_s.should == "7.57914844"
|
||||
"k]Q\xE7\xDDb\x1E@".unpack1('D').to_s.should == "7.59654962"
|
||||
"\x1F\x85\xEBQ\xB8\xEAz@".unpack1('D').to_s.should == "430.67"
|
||||
"\x00\x00\x00\x00\x00\x00\x14@".unpack1('D').to_s.should == "5.0"
|
||||
"{\x14\xAEG\xE1\n}@".unpack1('D').to_s.should == "464.68"
|
||||
"\x12\x83\xC0\xCA\xA1=V@".unpack1('D').to_s.should == "88.963"
|
||||
"\x9Aw\x9C\xA2#y\e@".unpack1('D').to_s.should == "6.8683"
|
||||
"(\x0F\v\xB5\xA6y\xFB?".unpack1('D').to_s.should == "1.7172"
|
||||
"\xD5x\xE9&1H!@".unpack1('D').to_s.should == "8.641"
|
||||
"w'Deh\x1Ab@".unpack1('D').to_s.should == "144.8252436"
|
||||
":X\xFF\xE70_\x04@".unpack1('D').to_s.should == "2.54648"
|
||||
"E4\xB2\x12\x90\xCA\x1E@".unpack1('D').to_s.should == "7.69781522"
|
||||
"fffff\xAA\x80@".unpack1('D').to_s.should == "533.3"
|
||||
"\xCD\x92\x005\xB5p:@".unpack1('D').to_s.should == "26.440265"
|
||||
"\xBE\x1D<nS\x7F\x19@".unpack1('D').to_s.should == "6.3743417"
|
||||
"R\xB8\x1E\x85\xEBYb@".unpack1('D').to_s.should == "146.81"
|
||||
"\x02\x87\xAB^\xD9\xC0\xF4?".unpack1('D').to_s.should == "1.2970823"
|
||||
"\x00\x00\x00\x00\x00\x00\"@".unpack1('D').to_s.should == "9.0"
|
||||
"Zd;\xDFO3\x84@".unpack1('D').to_s.should == "646.414"
|
||||
"\x9A\x99\x99\x99\x99\x99\t@".unpack1('D').to_s.should == "3.2"
|
||||
"\xCD#\x7F0\xF0\xE5i@".unpack1('D').to_s.should == "207.18557"
|
||||
"\xBE\x9F\x1A/\xDD$\xF2?".unpack1('D').to_s.should == "1.134"
|
||||
"\xEE|?5^\xBA\xF3?".unpack1('D').to_s.should == "1.233"
|
||||
"\xB4\xB7\xFE\xD7\x05\x03i@".unpack1('D').to_s.should == "200.094463346"
|
||||
"N\x95\xD6|\xE8HG@".unpack1('D').to_s.should == "46.56959496"
|
||||
"Y\x868\xD6\xC5-!@".unpack1('D').to_s.should == "8.5894"
|
||||
"myE\xED\a;\x12@".unpack1('D').to_s.should == "4.557647426"
|
||||
"\xA7s\xEAo\xAE\x96B@".unpack1('D').to_s.should == "37.1771984"
|
||||
"\x14\x7Fo.\x99\x11|@".unpack1('D').to_s.should == "449.0998978"
|
||||
"\xB2\x9EZ}u\x89;@".unpack1('D').to_s.should == "27.536949"
|
||||
"\xD7\xA3p=\nwY@".unpack1('D').to_s.should == "101.86"
|
||||
"\xF3\xE6p\xAD\xF6\xC3x@".unpack1('D').to_s.should == "396.247724"
|
||||
end
|
||||
end
|
||||
|
||||
it "random values from divisions" do
|
||||
(1.0 / 7).to_s.should == "0.14285714285714285"
|
||||
|
||||
# 50.times do
|
||||
# a = rand(10)
|
||||
# b = rand(10)
|
||||
# c = rand(10)
|
||||
# d = rand(10)
|
||||
# expression = "#{a}.#{b} / #{c}.#{d}"
|
||||
# puts " (#{expression}).to_s.should == #{eval(expression).to_s.inspect}"
|
||||
# end
|
||||
|
||||
(1.1 / 7.1).to_s.should == "0.15492957746478875"
|
||||
(6.5 / 8.8).to_s.should == "0.7386363636363635"
|
||||
(4.8 / 4.3).to_s.should == "1.1162790697674418"
|
||||
(4.0 / 1.9).to_s.should == "2.1052631578947367"
|
||||
(9.1 / 0.8).to_s.should == "11.374999999999998"
|
||||
(5.3 / 7.5).to_s.should == "0.7066666666666667"
|
||||
(2.8 / 1.8).to_s.should == "1.5555555555555554"
|
||||
(2.1 / 2.5).to_s.should == "0.8400000000000001"
|
||||
(3.5 / 6.0).to_s.should == "0.5833333333333334"
|
||||
(4.6 / 0.3).to_s.should == "15.333333333333332"
|
||||
(0.6 / 2.4).to_s.should == "0.25"
|
||||
(1.3 / 9.1).to_s.should == "0.14285714285714288"
|
||||
(0.3 / 5.0).to_s.should == "0.06"
|
||||
(5.0 / 4.2).to_s.should == "1.1904761904761905"
|
||||
(3.0 / 2.0).to_s.should == "1.5"
|
||||
(6.3 / 2.0).to_s.should == "3.15"
|
||||
(5.4 / 6.0).to_s.should == "0.9"
|
||||
(9.6 / 8.1).to_s.should == "1.1851851851851851"
|
||||
(8.7 / 1.6).to_s.should == "5.437499999999999"
|
||||
(1.9 / 7.8).to_s.should == "0.24358974358974358"
|
||||
(0.5 / 2.1).to_s.should == "0.23809523809523808"
|
||||
(9.3 / 5.8).to_s.should == "1.6034482758620692"
|
||||
(2.7 / 8.0).to_s.should == "0.3375"
|
||||
(9.7 / 7.8).to_s.should == "1.2435897435897436"
|
||||
(8.1 / 2.4).to_s.should == "3.375"
|
||||
(7.7 / 2.7).to_s.should == "2.8518518518518516"
|
||||
(7.9 / 1.7).to_s.should == "4.647058823529412"
|
||||
(6.5 / 8.2).to_s.should == "0.7926829268292683"
|
||||
(7.8 / 9.6).to_s.should == "0.8125"
|
||||
(2.2 / 4.6).to_s.should == "0.47826086956521746"
|
||||
(0.0 / 1.0).to_s.should == "0.0"
|
||||
(8.3 / 2.9).to_s.should == "2.8620689655172415"
|
||||
(3.1 / 6.1).to_s.should == "0.5081967213114754"
|
||||
(2.8 / 7.8).to_s.should == "0.358974358974359"
|
||||
(8.0 / 0.1).to_s.should == "80.0"
|
||||
(1.7 / 6.4).to_s.should == "0.265625"
|
||||
(1.8 / 5.4).to_s.should == "0.3333333333333333"
|
||||
(8.0 / 5.8).to_s.should == "1.3793103448275863"
|
||||
(5.2 / 4.1).to_s.should == "1.2682926829268295"
|
||||
(9.8 / 5.8).to_s.should == "1.6896551724137934"
|
||||
(5.4 / 9.5).to_s.should == "0.5684210526315789"
|
||||
(8.4 / 4.9).to_s.should == "1.7142857142857142"
|
||||
(1.7 / 3.5).to_s.should == "0.4857142857142857"
|
||||
(1.2 / 5.1).to_s.should == "0.23529411764705882"
|
||||
(1.4 / 2.0).to_s.should == "0.7"
|
||||
(4.8 / 8.0).to_s.should == "0.6"
|
||||
(9.0 / 2.5).to_s.should == "3.6"
|
||||
(0.2 / 0.6).to_s.should == "0.33333333333333337"
|
||||
(7.8 / 5.2).to_s.should == "1.5"
|
||||
(9.5 / 5.5).to_s.should == "1.7272727272727273"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
with_feature :encoding do
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
describe :hash_each, shared: true do
|
||||
|
||||
# This is inconsistent with below, MRI checks the block arity in rb_hash_each_pair()
|
||||
it "yields a [[key, value]] Array for each pair to a block expecting |*args|" do
|
||||
all_args = []
|
||||
{ 1 => 2, 3 => 4 }.send(@method) { |*args| all_args << args }
|
||||
|
@ -19,6 +21,21 @@ describe :hash_each, shared: true do
|
|||
ary.sort.should == ["a", "b", "c"]
|
||||
end
|
||||
|
||||
it "yields 2 values and not an Array of 2 elements" do
|
||||
obj = Object.new
|
||||
def obj.foo(key, value)
|
||||
ScratchPad << key << value
|
||||
end
|
||||
|
||||
ScratchPad.record([])
|
||||
{ "a" => 1 }.send(@method, &obj.method(:foo))
|
||||
ScratchPad.recorded.should == ["a", 1]
|
||||
|
||||
ScratchPad.record([])
|
||||
{ "a" => 1 }.send(@method, &-> key, value { ScratchPad << key << value })
|
||||
ScratchPad.recorded.should == ["a", 1]
|
||||
end
|
||||
|
||||
it "uses the same order as keys() and values()" do
|
||||
h = { a: 1, b: 2, c: 3, d: 5 }
|
||||
keys = []
|
||||
|
|
|
@ -77,6 +77,13 @@ describe "IO#read_nonblock" do
|
|||
buffer.should == "1"
|
||||
end
|
||||
|
||||
it "returns the passed buffer" do
|
||||
buffer = ""
|
||||
@write.write("1")
|
||||
output = @read.read_nonblock(1, buffer)
|
||||
output.should equal(buffer)
|
||||
end
|
||||
|
||||
it "raises IOError on closed stream" do
|
||||
lambda { IOSpecs.closed_io.read_nonblock(5) }.should raise_error(IOError)
|
||||
end
|
||||
|
|
11
spec/ruby/core/kernel/pp_spec.rb
Normal file
11
spec/ruby/core/kernel/pp_spec.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "2.5" do
|
||||
describe "Kernel#pp" do
|
||||
it "lazily loads the 'pp' library and delegates the call to that library" do
|
||||
# Run in child process to ensure 'pp' hasn't been loaded yet.
|
||||
output = ruby_exe("pp [1, 2, 3]")
|
||||
output.should == "[1, 2, 3]\n"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,16 +6,20 @@ describe "Kernel#sleep" do
|
|||
Kernel.should have_private_instance_method(:sleep)
|
||||
end
|
||||
|
||||
it "returns an Integer" do
|
||||
sleep(0.001).should be_kind_of(Integer)
|
||||
end
|
||||
|
||||
it "accepts a Float" do
|
||||
sleep(0.1).should be_close(0, 2)
|
||||
sleep(0.001).should >= 0
|
||||
end
|
||||
|
||||
it "accepts a Fixnum" do
|
||||
sleep(0).should be_close(0, 2)
|
||||
sleep(0).should >= 0
|
||||
end
|
||||
|
||||
it "accepts a Rational" do
|
||||
sleep(Rational(1, 9)).should be_close(0, 2)
|
||||
sleep(Rational(1, 999)).should >= 0
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when passed a negative duration" do
|
||||
|
|
|
@ -241,4 +241,19 @@ describe "Method#parameters" do
|
|||
m = MethodSpecs::Methods.new
|
||||
m.method(:writer=).parameters.should == [[:req]]
|
||||
end
|
||||
|
||||
it "returns [[:rest]] for core methods with variable-length argument lists" do
|
||||
m = "foo"
|
||||
|
||||
# match takes rest args
|
||||
m.method(:match).parameters.should == [[:rest]]
|
||||
|
||||
# [] takes 1 to 3 args
|
||||
m.method(:[]).parameters.should == [[:rest]]
|
||||
end
|
||||
|
||||
it "returns [[:req]] for each parameter for core methods with fixed-length argument lists" do
|
||||
m = "foo"
|
||||
m.method(:+).parameters.should == [[:req]]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -90,4 +90,15 @@ describe "Method#to_proc" do
|
|||
array.each(&obj)
|
||||
ScratchPad.recorded.should == [[1, 2]]
|
||||
end
|
||||
|
||||
it "returns a proc that properly invokes module methods with super" do
|
||||
m1 = Module.new { def foo(ary); ary << :m1; end; }
|
||||
m2 = Module.new { def foo(ary = []); super(ary); ary << :m2; end; }
|
||||
c2 = Class.new do
|
||||
include m1
|
||||
include m2
|
||||
end
|
||||
|
||||
c2.new.method(:foo).to_proc.call.should == %i[m1 m2]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,17 +16,28 @@ end
|
|||
describe "Module#autoload" do
|
||||
before :all do
|
||||
@non_existent = fixture __FILE__, "no_autoload.rb"
|
||||
|
||||
# Require RubyGems eagerly, to ensure #require is already the RubyGems
|
||||
# version, before starting #autoload specs which snapshot #require, and
|
||||
# could end up redefining #require as the original core Kernel#require.
|
||||
begin
|
||||
require "rubygems"
|
||||
rescue LoadError
|
||||
end
|
||||
end
|
||||
|
||||
before :each do
|
||||
@loaded_features = $".dup
|
||||
@frozen_module = Module.new.freeze
|
||||
|
||||
ScratchPad.clear
|
||||
@remove = []
|
||||
end
|
||||
|
||||
after :each do
|
||||
$".replace @loaded_features
|
||||
@remove.each { |const|
|
||||
ModuleSpecs::Autoload.send :remove_const, const
|
||||
}
|
||||
end
|
||||
|
||||
it "registers a file to load the first time the named constant is accessed" do
|
||||
|
@ -39,16 +50,29 @@ describe "Module#autoload" do
|
|||
ModuleSpecs::Autoload.should have_constant(:B)
|
||||
end
|
||||
|
||||
it "can be overridden with a second autoload on the same constant" do
|
||||
ModuleSpecs::Autoload.autoload :Overridden, @non_existent
|
||||
@remove << :Overridden
|
||||
ModuleSpecs::Autoload.autoload?(:Overridden).should == @non_existent
|
||||
|
||||
path = fixture(__FILE__, "autoload_overridden.rb")
|
||||
ModuleSpecs::Autoload.autoload :Overridden, path
|
||||
ModuleSpecs::Autoload.autoload?(:Overridden).should == path
|
||||
|
||||
ModuleSpecs::Autoload::Overridden.should == :overridden
|
||||
end
|
||||
|
||||
it "loads the registered constant when it is accessed" do
|
||||
ModuleSpecs::Autoload.should_not have_constant(:X)
|
||||
ModuleSpecs::Autoload.autoload :X, fixture(__FILE__, "autoload_x.rb")
|
||||
@remove << :X
|
||||
ModuleSpecs::Autoload::X.should == :x
|
||||
ModuleSpecs::Autoload.send(:remove_const, :X)
|
||||
end
|
||||
|
||||
it "loads the registered constant into a dynamically created class" do
|
||||
cls = Class.new { autoload :C, fixture(__FILE__, "autoload_c.rb") }
|
||||
ModuleSpecs::Autoload::DynClass = cls
|
||||
@remove << :DynClass
|
||||
|
||||
ScratchPad.recorded.should be_nil
|
||||
ModuleSpecs::Autoload::DynClass::C.new.loaded.should == :dynclass_c
|
||||
|
@ -58,6 +82,7 @@ describe "Module#autoload" do
|
|||
it "loads the registered constant into a dynamically created module" do
|
||||
mod = Module.new { autoload :D, fixture(__FILE__, "autoload_d.rb") }
|
||||
ModuleSpecs::Autoload::DynModule = mod
|
||||
@remove << :DynModule
|
||||
|
||||
ScratchPad.recorded.should be_nil
|
||||
ModuleSpecs::Autoload::DynModule::D.new.loaded.should == :dynmodule_d
|
||||
|
@ -95,6 +120,7 @@ describe "Module#autoload" do
|
|||
|
||||
it "does not load the file when the constant is already set" do
|
||||
ModuleSpecs::Autoload.autoload :I, fixture(__FILE__, "autoload_i.rb")
|
||||
@remove << :I
|
||||
ModuleSpecs::Autoload.const_set :I, 3
|
||||
ModuleSpecs::Autoload::I.should == 3
|
||||
ScratchPad.recorded.should be_nil
|
||||
|
@ -116,6 +142,7 @@ describe "Module#autoload" do
|
|||
it "does not load the file if the file is manually required" do
|
||||
filename = fixture(__FILE__, "autoload_k.rb")
|
||||
ModuleSpecs::Autoload.autoload :KHash, filename
|
||||
@remove << :KHash
|
||||
|
||||
require filename
|
||||
ScratchPad.recorded.should == :loaded
|
||||
|
@ -135,8 +162,8 @@ describe "Module#autoload" do
|
|||
ScratchPad.clear
|
||||
|
||||
ModuleSpecs::Autoload.autoload :S, filename
|
||||
@remove << :S
|
||||
ModuleSpecs::Autoload.autoload?(:S).should be_nil
|
||||
ModuleSpecs::Autoload.send(:remove_const, :S)
|
||||
end
|
||||
|
||||
it "retains the autoload even if the request to require fails" do
|
||||
|
@ -182,11 +209,10 @@ describe "Module#autoload" do
|
|||
module ModuleSpecs::Autoload
|
||||
autoload :GoodParent, fixture(__FILE__, "autoload_nested.rb")
|
||||
end
|
||||
@remove << :GoodParent
|
||||
|
||||
defined?(ModuleSpecs::Autoload::GoodParent::Nested).should == 'constant'
|
||||
ScratchPad.recorded.should == :loaded
|
||||
|
||||
ModuleSpecs::Autoload.send(:remove_const, :GoodParent)
|
||||
end
|
||||
|
||||
it "returns nil when it fails to load an autoloaded parent when referencing a nested constant" do
|
||||
|
@ -199,11 +225,12 @@ describe "Module#autoload" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "the autoload is removed when the same file is required directly without autoload" do
|
||||
describe "the autoload is triggered when the same file is required directly" do
|
||||
before :each do
|
||||
module ModuleSpecs::Autoload
|
||||
autoload :RequiredDirectly, fixture(__FILE__, "autoload_required_directly.rb")
|
||||
end
|
||||
@remove << :RequiredDirectly
|
||||
@path = fixture(__FILE__, "autoload_required_directly.rb")
|
||||
@check = -> {
|
||||
[
|
||||
|
@ -214,10 +241,6 @@ describe "Module#autoload" do
|
|||
ScratchPad.record @check
|
||||
end
|
||||
|
||||
after :each do
|
||||
ModuleSpecs::Autoload.send(:remove_const, :RequiredDirectly)
|
||||
end
|
||||
|
||||
it "with a full path" do
|
||||
@check.call.should == ["constant", @path]
|
||||
require @path
|
||||
|
@ -242,7 +265,7 @@ describe "Module#autoload" do
|
|||
nested_require = -> {
|
||||
result = nil
|
||||
ScratchPad.record -> {
|
||||
result = [@check.call, Thread.new { @check.call }.value]
|
||||
result = @check.call
|
||||
}
|
||||
require nested
|
||||
result
|
||||
|
@ -251,24 +274,41 @@ describe "Module#autoload" do
|
|||
|
||||
@check.call.should == ["constant", @path]
|
||||
require @path
|
||||
cur, other = ScratchPad.recorded
|
||||
cur.should == [nil, nil]
|
||||
other.should == [nil, nil]
|
||||
ScratchPad.recorded.should == [nil, nil]
|
||||
@check.call.should == ["constant", nil]
|
||||
end
|
||||
end
|
||||
|
||||
describe "after the autoload is triggered by require" do
|
||||
before :each do
|
||||
@path = tmp("autoload.rb")
|
||||
end
|
||||
|
||||
after :each do
|
||||
rm_r @path
|
||||
end
|
||||
|
||||
it "the mapping feature to autoload is removed, and a new autoload with the same path is considered" do
|
||||
ModuleSpecs::Autoload.autoload :RequireMapping1, @path
|
||||
touch(@path) { |f| f.puts "ModuleSpecs::Autoload::RequireMapping1 = 1" }
|
||||
ModuleSpecs::Autoload::RequireMapping1.should == 1
|
||||
|
||||
$LOADED_FEATURES.delete(@path)
|
||||
ModuleSpecs::Autoload.autoload :RequireMapping2, @path[0...-3]
|
||||
@remove << :RequireMapping2
|
||||
touch(@path) { |f| f.puts "ModuleSpecs::Autoload::RequireMapping2 = 2" }
|
||||
ModuleSpecs::Autoload::RequireMapping2.should == 2
|
||||
end
|
||||
end
|
||||
|
||||
describe "during the autoload before the constant is assigned" do
|
||||
before :each do
|
||||
@path = fixture(__FILE__, "autoload_during_autoload.rb")
|
||||
ModuleSpecs::Autoload.autoload :DuringAutoload, @path
|
||||
@remove << :DuringAutoload
|
||||
raise unless ModuleSpecs::Autoload.autoload?(:DuringAutoload) == @path
|
||||
end
|
||||
|
||||
after :each do
|
||||
ModuleSpecs::Autoload.send(:remove_const, :DuringAutoload)
|
||||
end
|
||||
|
||||
def check_before_during_thread_after(&check)
|
||||
before = check.call
|
||||
to_autoload_thread, from_autoload_thread = Queue.new, Queue.new
|
||||
|
@ -419,6 +459,7 @@ describe "Module#autoload" do
|
|||
X = get_value
|
||||
end
|
||||
end
|
||||
@remove << :U
|
||||
|
||||
ModuleSpecs::Autoload::U::V::X.should == :autoload_uvx
|
||||
end
|
||||
|
@ -474,6 +515,7 @@ describe "Module#autoload" do
|
|||
end
|
||||
|
||||
it "and fails when finding the undefined autoload constant in the 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
|
||||
|
@ -494,6 +536,7 @@ describe "Module#autoload" do
|
|||
end
|
||||
|
||||
it "in the included modules" do
|
||||
@remove << :DefinedInIncludedModule
|
||||
module ModuleSpecs::Autoload
|
||||
ScratchPad.record -> {
|
||||
module DefinedInIncludedModule
|
||||
|
@ -507,6 +550,7 @@ describe "Module#autoload" do
|
|||
end
|
||||
|
||||
it "in the included modules of the superclass" do
|
||||
@remove << :DefinedInSuperclassIncludedModule
|
||||
module ModuleSpecs::Autoload
|
||||
class LookupAfterAutoloadSuper
|
||||
end
|
||||
|
@ -528,6 +572,7 @@ describe "Module#autoload" do
|
|||
end
|
||||
|
||||
it "in the prepended modules" do
|
||||
@remove << :DefinedInPrependedModule
|
||||
module ModuleSpecs::Autoload
|
||||
ScratchPad.record -> {
|
||||
module DefinedInPrependedModule
|
||||
|
@ -567,10 +612,10 @@ describe "Module#autoload" do
|
|||
end
|
||||
end
|
||||
end
|
||||
@remove << :W
|
||||
|
||||
ModuleSpecs::Autoload::W::Y.should be_kind_of(Class)
|
||||
ScratchPad.recorded.should == :loaded
|
||||
ModuleSpecs::Autoload::W.send(:remove_const, :Y)
|
||||
end
|
||||
|
||||
it "does not call #require a second time and does not warn if already loading the same feature with #require" do
|
||||
|
@ -611,6 +656,7 @@ describe "Module#autoload" do
|
|||
|
||||
it "shares the autoload request across dup'ed copies of modules" do
|
||||
require fixture(__FILE__, "autoload_s.rb")
|
||||
@remove << :S
|
||||
filename = fixture(__FILE__, "autoload_t.rb")
|
||||
mod1 = Module.new { autoload :T, filename }
|
||||
lambda {
|
||||
|
@ -651,8 +697,9 @@ describe "Module#autoload" do
|
|||
|
||||
describe "on a frozen module" do
|
||||
it "raises a #{frozen_error_class} before setting the name" do
|
||||
lambda { @frozen_module.autoload :Foo, @non_existent }.should raise_error(frozen_error_class)
|
||||
@frozen_module.should_not have_constant(:Foo)
|
||||
frozen_module = Module.new.freeze
|
||||
lambda { frozen_module.autoload :Foo, @non_existent }.should raise_error(frozen_error_class)
|
||||
frozen_module.should_not have_constant(:Foo)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -675,6 +722,7 @@ describe "Module#autoload" do
|
|||
describe "(concurrently)" do
|
||||
it "blocks a second thread while a first is doing the autoload" do
|
||||
ModuleSpecs::Autoload.autoload :Concur, fixture(__FILE__, "autoload_concur.rb")
|
||||
@remove << :Concur
|
||||
|
||||
start = false
|
||||
|
||||
|
@ -717,8 +765,6 @@ describe "Module#autoload" do
|
|||
t2_val.should == t1_val
|
||||
|
||||
t2_exc.should be_nil
|
||||
|
||||
ModuleSpecs::Autoload.send(:remove_const, :Concur)
|
||||
end
|
||||
|
||||
# https://bugs.ruby-lang.org/issues/10892
|
||||
|
|
|
@ -72,6 +72,53 @@ describe "Module#const_set" do
|
|||
lambda { ConstantSpecs.const_set name, 1 }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
describe "when overwriting an existing constant" do
|
||||
it "warns if the previous value was a normal value" do
|
||||
mod = Module.new
|
||||
mod.const_set :Foo, 42
|
||||
-> {
|
||||
mod.const_set :Foo, 1
|
||||
}.should complain(/already initialized constant/)
|
||||
mod.const_get(:Foo).should == 1
|
||||
end
|
||||
|
||||
it "does not warn if the previous value was an autoload" do
|
||||
mod = Module.new
|
||||
mod.autoload :Foo, "not-existing"
|
||||
-> {
|
||||
mod.const_set :Foo, 1
|
||||
}.should_not complain
|
||||
mod.const_get(:Foo).should == 1
|
||||
end
|
||||
|
||||
it "does not warn if the previous value was undefined" do
|
||||
path = fixture(__FILE__, "autoload_o.rb")
|
||||
ScratchPad.record []
|
||||
mod = Module.new
|
||||
|
||||
mod.autoload :Foo, path
|
||||
-> { mod::Foo }.should raise_error(NameError)
|
||||
|
||||
mod.should have_constant(:Foo)
|
||||
mod.const_defined?(:Foo).should == false
|
||||
mod.autoload?(:Foo).should == nil
|
||||
|
||||
-> {
|
||||
mod.const_set :Foo, 1
|
||||
}.should_not complain
|
||||
mod.const_get(:Foo).should == 1
|
||||
end
|
||||
|
||||
it "does not warn if the new value is an autoload" do
|
||||
mod = Module.new
|
||||
mod.const_set :Foo, 42
|
||||
-> {
|
||||
mod.autoload :Foo, "not-existing"
|
||||
}.should_not complain
|
||||
mod.const_get(:Foo).should == 42
|
||||
end
|
||||
end
|
||||
|
||||
describe "on a frozen module" do
|
||||
before :each do
|
||||
@frozen = Module.new.freeze
|
||||
|
|
3
spec/ruby/core/module/fixtures/autoload_overridden.rb
Normal file
3
spec/ruby/core/module/fixtures/autoload_overridden.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
module ModuleSpecs::Autoload
|
||||
Overridden = :overridden
|
||||
end
|
|
@ -47,4 +47,11 @@ describe "String#end_with?" do
|
|||
"céréale".end_with?("réale").should be_true
|
||||
end
|
||||
|
||||
it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
|
||||
pat = "ア".encode Encoding::EUC_JP
|
||||
lambda do
|
||||
"あれ".end_with?(pat)
|
||||
end.should raise_error(Encoding::CompatibilityError)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -489,4 +489,12 @@ describe "String#inspect" do
|
|||
].should be_computed_by(:inspect)
|
||||
end
|
||||
end
|
||||
|
||||
describe "when the string's encoding is different than the result's encoding" do
|
||||
describe "and the string's encoding is ASCII-compatible but the characters are non-ASCII" do
|
||||
it "returns a string with the non-ASCII characters replaced by \\x notation" do
|
||||
"\u{3042}".encode("EUC-JP").inspect.should == '"\\x{A4A2}"'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,8 +35,21 @@ describe "Thread.list" do
|
|||
t.join
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Thread.list" do
|
||||
it "needs to be reviewed for spec completeness"
|
||||
it "returns instances of Thread and not null or nil values" do
|
||||
spawner = Thread.new do
|
||||
Array.new(100) do
|
||||
Thread.new {}
|
||||
end
|
||||
end
|
||||
|
||||
while spawner.alive?
|
||||
Thread.list.each { |th|
|
||||
th.should be_kind_of(Thread)
|
||||
}
|
||||
end
|
||||
|
||||
threads = spawner.value
|
||||
threads.each(&:join)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,21 +2,23 @@ require_relative '../../spec_helper'
|
|||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "2.6" do
|
||||
describe "#eval_script" do
|
||||
ScratchPad.record []
|
||||
describe "TracePoint#eval_script" do
|
||||
it "is the evald source code" do
|
||||
ScratchPad.record []
|
||||
|
||||
script = <<-CODE
|
||||
def foo
|
||||
p :hello
|
||||
script = <<-CODE
|
||||
def foo
|
||||
p :hello
|
||||
end
|
||||
CODE
|
||||
|
||||
TracePoint.new(:script_compiled) do |e|
|
||||
ScratchPad << e.eval_script
|
||||
end.enable do
|
||||
eval script
|
||||
end
|
||||
CODE
|
||||
|
||||
TracePoint.new(:script_compiled) do |e|
|
||||
ScratchPad << e.eval_script
|
||||
end.enable do
|
||||
eval script
|
||||
ScratchPad.recorded.should == [script]
|
||||
end
|
||||
|
||||
ScratchPad.recorded.should == [script]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,22 +2,24 @@ require_relative '../../spec_helper'
|
|||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "2.6" do
|
||||
describe "#instruction_sequence" do
|
||||
ScratchPad.record []
|
||||
describe "TracePoint#instruction_sequence" do
|
||||
it "is an instruction sequence" do
|
||||
ScratchPad.record []
|
||||
|
||||
script = <<-CODE
|
||||
def foo
|
||||
p :hello
|
||||
script = <<-CODE
|
||||
def foo
|
||||
p :hello
|
||||
end
|
||||
CODE
|
||||
|
||||
TracePoint.new(:script_compiled) do |e|
|
||||
ScratchPad << e.instruction_sequence
|
||||
end.enable do
|
||||
eval script
|
||||
end
|
||||
CODE
|
||||
|
||||
TracePoint.new(:script_compiled) do |e|
|
||||
ScratchPad << e.instruction_sequence
|
||||
end.enable do
|
||||
eval script
|
||||
ScratchPad.recorded.size.should == 1
|
||||
ScratchPad.recorded[0].class.should == RubyVM::InstructionSequence
|
||||
end
|
||||
|
||||
ScratchPad.recorded.size.should == 1
|
||||
ScratchPad.recorded[0].class.should == RubyVM::InstructionSequence
|
||||
end
|
||||
end
|
||||
|
|
|
@ -244,3 +244,15 @@ describe "The alias keyword" do
|
|||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "The alias keyword" do
|
||||
it "can create a new global variable, synonym of the original" do
|
||||
code = '$a = 1; alias $b $a; p [$a, $b]; $b = 2; p [$a, $b]'
|
||||
ruby_exe(code).should == "[1, 1]\n[2, 2]\n"
|
||||
end
|
||||
|
||||
it "can override an existing global variable and make them synonyms" do
|
||||
code = '$a = 1; $b = 2; alias $b $a; p [$a, $b]; $b = 3; p [$a, $b]'
|
||||
ruby_exe(code).should == "[1, 1]\n[3, 3]\n"
|
||||
end
|
||||
end
|
||||
|
|
15
spec/ruby/language/fixtures/for_scope.rb
Normal file
15
spec/ruby/language/fixtures/for_scope.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
module ForSpecs
|
||||
class ForInClassMethod
|
||||
m = :same_variable_set_outside
|
||||
|
||||
def self.foo
|
||||
all = []
|
||||
for m in [:bar, :baz]
|
||||
all << m
|
||||
end
|
||||
all
|
||||
end
|
||||
|
||||
READER = -> { m }
|
||||
end
|
||||
end
|
|
@ -1,4 +1,5 @@
|
|||
require_relative '../spec_helper'
|
||||
require_relative 'fixtures/for_scope'
|
||||
|
||||
# for name[, name]... in expr [do]
|
||||
# body
|
||||
|
@ -130,6 +131,11 @@ describe "The for expression" do
|
|||
a.should == 123
|
||||
end
|
||||
|
||||
it "does not try to access variables outside the method" do
|
||||
ForSpecs::ForInClassMethod.foo.should == [:bar, :baz]
|
||||
ForSpecs::ForInClassMethod::READER.call.should == :same_variable_set_outside
|
||||
end
|
||||
|
||||
it "returns expr" do
|
||||
for i in 1..3; end.should == (1..3)
|
||||
for i,j in { 1 => 10, 2 => 20 }; end.should == { 1 => 10, 2 => 20 }
|
||||
|
|
|
@ -574,6 +574,7 @@ describe "A method" do
|
|||
m(a: 1, b: 2).should == { a: 1, b: 2 }
|
||||
m(*[]).should == {}
|
||||
m(**{}).should == {}
|
||||
m(**{a: 1, b: 2}, **{a: 4, c: 7}).should == { a: 4, b: 2, c: 7 }
|
||||
lambda { m(2) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
|
|
|
@ -73,6 +73,14 @@ describe "BigDecimal#add" do
|
|||
# BigDecimal("0.88").add(0.0, 1).should == BigDecimal("0.9")
|
||||
# end
|
||||
|
||||
describe "with Object" do
|
||||
it "tries to coerce the other operand to self" do
|
||||
object = mock("Object")
|
||||
object.should_receive(:coerce).with(@frac_3).and_return([@frac_3, @frac_4])
|
||||
@frac_3.add(object, 1).should == BigDecimal("0.1E16")
|
||||
end
|
||||
end
|
||||
|
||||
it "favors the precision specified in the second argument over the global limit" do
|
||||
BigDecimalSpecs.with_limit(1) do
|
||||
BigDecimal('0.888').add(@zero, 3).should == BigDecimal('0.888')
|
||||
|
|
|
@ -42,6 +42,14 @@ describe "BigDecimal#div" do
|
|||
}
|
||||
end
|
||||
|
||||
describe "with Object" do
|
||||
it "tries to coerce the other operand to self" do
|
||||
object = mock("Object")
|
||||
object.should_receive(:coerce).with(@one).and_return([@one, @two])
|
||||
@one.div(object).should == @zero
|
||||
end
|
||||
end
|
||||
|
||||
it "raises FloatDomainError if NaN is involved" do
|
||||
lambda { @one.div(@nan) }.should raise_error(FloatDomainError)
|
||||
lambda { @nan.div(@one) }.should raise_error(FloatDomainError)
|
||||
|
|
|
@ -9,7 +9,8 @@ end
|
|||
describe "BigDecimal#mult" do
|
||||
before :each do
|
||||
@one = BigDecimal "1"
|
||||
@e3_minus = BigDecimal "3E-20001"
|
||||
@e3_minus = BigDecimal("3E-20001")
|
||||
@e3_plus = BigDecimal("3E20001")
|
||||
@e = BigDecimal "1.00000000000000000000123456789"
|
||||
@tolerance = @e.sub @one, 1000
|
||||
@tolerance2 = BigDecimal "30001E-20005"
|
||||
|
@ -21,4 +22,11 @@ describe "BigDecimal#mult" do
|
|||
@e3_minus.mult(@one, 1).should be_close(0, @tolerance2)
|
||||
end
|
||||
|
||||
describe "with Object" do
|
||||
it "tries to coerce the other operand to self" do
|
||||
object = mock("Object")
|
||||
object.should_receive(:coerce).with(@e3_minus).and_return([@e3_minus, @e3_plus])
|
||||
@e3_minus.mult(object, 1).should == BigDecimal("9")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -23,4 +23,12 @@ describe "BigDecimal#*" do
|
|||
(@e3_minus * @e3_minus).should == BigDecimal("9E-40002")
|
||||
(@e * @one).should == @e
|
||||
end
|
||||
|
||||
describe "with Object" do
|
||||
it "tries to coerce the other operand to self" do
|
||||
object = mock("Object")
|
||||
object.should_receive(:coerce).with(@e3_minus).and_return([@e3_minus, @e3_plus])
|
||||
(@e3_minus * object).should == BigDecimal("9")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,8 @@ describe "BigDecimal#remainder" do
|
|||
|
||||
before :each do
|
||||
@zero = BigDecimal("0")
|
||||
@one = BigDecimal("0")
|
||||
@one = BigDecimal("1")
|
||||
@three = BigDecimal("3")
|
||||
@mixed = BigDecimal("1.23456789")
|
||||
@pos_int = BigDecimal("2E5555")
|
||||
@neg_int = BigDecimal("-2E5555")
|
||||
|
@ -71,9 +72,16 @@ describe "BigDecimal#remainder" do
|
|||
end
|
||||
|
||||
it "coerces arguments to BigDecimal if possible" do
|
||||
@one.remainder(2).should == @one
|
||||
@three.remainder(2).should == @one
|
||||
end
|
||||
|
||||
describe "with Object" do
|
||||
it "tries to coerce the other operand to self" do
|
||||
object = mock("Object")
|
||||
object.should_receive(:coerce).with(@three).and_return([@three, 2])
|
||||
@three.remainder(object).should == @one
|
||||
end
|
||||
end
|
||||
|
||||
it "raises TypeError if the argument cannot be coerced to BigDecimal" do
|
||||
lambda {
|
||||
|
|
|
@ -70,6 +70,15 @@ describe :bigdecimal_modulo, shared: true do
|
|||
res.kind_of?(BigDecimal).should == true
|
||||
end
|
||||
|
||||
describe "with Object" do
|
||||
it "tries to coerce the other operand to self" do
|
||||
bd6543 = BigDecimal("6543.21")
|
||||
object = mock("Object")
|
||||
object.should_receive(:coerce).with(bd6543).and_return([bd6543, 137])
|
||||
bd6543.send(@method, object, *@object).should == BigDecimal("104.21")
|
||||
end
|
||||
end
|
||||
|
||||
it "returns NaN if NaN is involved" do
|
||||
@nan.send(@method, @nan).nan?.should == true
|
||||
@nan.send(@method, @one).nan?.should == true
|
||||
|
|
|
@ -29,6 +29,14 @@ describe :bigdecimal_quo, shared: true do
|
|||
@one.send(@method, BigDecimal('2E-5555'), *@object).should == BigDecimal('0.5E5555')
|
||||
end
|
||||
|
||||
describe "with Object" do
|
||||
it "tries to coerce the other operand to self" do
|
||||
object = mock("Object")
|
||||
object.should_receive(:coerce).with(@one).and_return([@one, @two])
|
||||
@one.send(@method, object, *@object).should == BigDecimal("0.5")
|
||||
end
|
||||
end
|
||||
|
||||
it "returns 0 if divided by Infinity" do
|
||||
@zero.send(@method, @infinity, *@object).should == 0
|
||||
@frac_2.send(@method, @infinity, *@object).should == 0
|
||||
|
|
|
@ -13,6 +13,8 @@ describe "BigDecimal#sub" do
|
|||
@one_minus = BigDecimal("-1")
|
||||
@frac_1 = BigDecimal("1E-99999")
|
||||
@frac_2 = BigDecimal("0.9E-99999")
|
||||
@frac_3 = BigDecimal("12345E10")
|
||||
@frac_4 = BigDecimal("98765E10")
|
||||
end
|
||||
|
||||
it "returns a - b with given precision" do
|
||||
|
@ -32,6 +34,14 @@ describe "BigDecimal#sub" do
|
|||
@frac_1.sub(@frac_1, 1000000).should == @zero
|
||||
end
|
||||
|
||||
describe "with Object" do
|
||||
it "tries to coerce the other operand to self" do
|
||||
object = mock("Object")
|
||||
object.should_receive(:coerce).with(@frac_3).and_return([@frac_3, @frac_4])
|
||||
@frac_3.sub(object, 1).should == BigDecimal("-0.9E15")
|
||||
end
|
||||
end
|
||||
|
||||
it "returns NaN if NaN is involved" do
|
||||
@one.sub(@nan, 1).nan?.should == true
|
||||
@nan.sub(@one, 1).nan?.should == true
|
||||
|
|
42
spec/ruby/library/bigdecimal/util_spec.rb
Normal file
42
spec/ruby/library/bigdecimal/util_spec.rb
Normal file
|
@ -0,0 +1,42 @@
|
|||
require_relative '../../spec_helper'
|
||||
require 'bigdecimal'
|
||||
require 'bigdecimal/util'
|
||||
|
||||
describe "BigDecimal's util method definitions" do
|
||||
describe "#to_d" do
|
||||
it "should define #to_d on Integer" do
|
||||
42.to_d.should == BigDecimal(42)
|
||||
end
|
||||
|
||||
it "should define #to_d on Float" do
|
||||
0.5.to_d.should == BigDecimal(0.5, Float::DIG)
|
||||
1.234.to_d(2).should == BigDecimal(1.234, 2)
|
||||
end
|
||||
|
||||
it "should define #to_d on String" do
|
||||
"0.5".to_d.should == BigDecimal(0.5, Float::DIG)
|
||||
"45.67 degrees".to_d.should == BigDecimal(45.67, Float::DIG)
|
||||
end
|
||||
|
||||
it "should define #to_d on BigDecimal" do
|
||||
bd = BigDecimal("3.14")
|
||||
bd.to_d.should equal(bd)
|
||||
end
|
||||
|
||||
it "should define #to_d on Rational" do
|
||||
Rational(22, 7).to_d(3).should == BigDecimal(3.14, 3)
|
||||
end
|
||||
|
||||
ruby_version_is "2.6" do
|
||||
it "should define #to_d on nil" do
|
||||
nil.to_d.should == BigDecimal(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_digits" do
|
||||
it "should define #to_digits on BigDecimal" do
|
||||
BigDecimal("3.14").to_digits.should == "3.14"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@ describe 'RbConfig::CONFIG' do
|
|||
end
|
||||
|
||||
# These directories have no meanings before the installation.
|
||||
if RbConfig::TOPDIR
|
||||
guard -> { RbConfig::TOPDIR } do
|
||||
it "['rubylibdir'] returns the directory containing Ruby standard libraries" do
|
||||
rubylibdir = RbConfig::CONFIG['rubylibdir']
|
||||
File.directory?(rubylibdir).should == true
|
||||
|
|
|
@ -358,6 +358,14 @@ static VALUE string_spec_rb_sprintf2(VALUE self, VALUE str, VALUE repl1, VALUE r
|
|||
return rb_sprintf(RSTRING_PTR(str), RSTRING_PTR(repl1), RSTRING_PTR(repl2));
|
||||
}
|
||||
|
||||
static VALUE string_spec_rb_sprintf3(VALUE self, VALUE str) {
|
||||
return rb_sprintf("Result: %"PRIsVALUE".", str);
|
||||
}
|
||||
|
||||
static VALUE string_spec_rb_sprintf4(VALUE self, VALUE str) {
|
||||
return rb_sprintf("Result: %+"PRIsVALUE".", str);
|
||||
}
|
||||
|
||||
static VALUE string_spec_rb_vsprintf_worker(char* fmt, ...) {
|
||||
va_list varargs;
|
||||
VALUE str;
|
||||
|
@ -463,6 +471,8 @@ void Init_string_spec(void) {
|
|||
rb_define_method(cls, "rb_str_free", string_spec_rb_str_free, 1);
|
||||
rb_define_method(cls, "rb_sprintf1", string_spec_rb_sprintf1, 2);
|
||||
rb_define_method(cls, "rb_sprintf2", string_spec_rb_sprintf2, 3);
|
||||
rb_define_method(cls, "rb_sprintf3", string_spec_rb_sprintf3, 1);
|
||||
rb_define_method(cls, "rb_sprintf4", string_spec_rb_sprintf4, 1);
|
||||
rb_define_method(cls, "rb_vsprintf", string_spec_rb_vsprintf, 4);
|
||||
rb_define_method(cls, "rb_str_equal", string_spec_rb_str_equal, 2);
|
||||
rb_define_method(cls, "rb_usascii_str_new", string_spec_rb_usascii_str_new, 2);
|
||||
|
|
|
@ -43,7 +43,11 @@ void sample_typed_wrapped_struct_mark(void* st) {
|
|||
}
|
||||
|
||||
size_t sample_typed_wrapped_struct_memsize(const void* st) {
|
||||
return sizeof(struct sample_typed_wrapped_struct);
|
||||
if (st == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
return ((struct sample_typed_wrapped_struct *)st)->foo;
|
||||
}
|
||||
}
|
||||
|
||||
static const rb_data_type_t sample_typed_wrapped_struct_data_type = {
|
||||
|
|
|
@ -244,6 +244,10 @@ describe "C-API Kernel function" do
|
|||
@s.rb_yield_splat([1, 2]) { |x, y| x + y }.should == 3
|
||||
end
|
||||
|
||||
it "passes arguments to a block accepting splatted args" do
|
||||
@s.rb_yield_splat([1, 2]) { |*v| v }.should == [1, 2]
|
||||
end
|
||||
|
||||
it "raises LocalJumpError when no block is given" do
|
||||
lambda { @s.rb_yield_splat([1, 2]) }.should raise_error(LocalJumpError)
|
||||
end
|
||||
|
|
|
@ -72,9 +72,10 @@ describe "C-API Mutex functions" do
|
|||
|
||||
it "sleeps when the mutex is locked" do
|
||||
@m.lock
|
||||
start = Time.now
|
||||
@s.rb_mutex_sleep(@m, 0.1)
|
||||
(Time.now - start).should be_close(0.1, 0.2)
|
||||
t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||
@s.rb_mutex_sleep(@m, 0.001)
|
||||
t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||
(t2 - t1).should >= 0
|
||||
@m.locked?.should be_true
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,30 @@ require_relative '../../shared/string/times'
|
|||
|
||||
load_extension('string')
|
||||
|
||||
class CApiStringSpecs
|
||||
class ValidTostrTest
|
||||
def to_str
|
||||
"ruby"
|
||||
end
|
||||
end
|
||||
|
||||
class InvalidTostrTest
|
||||
def to_str
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
class ToSOrInspect
|
||||
def to_s
|
||||
'A string'
|
||||
end
|
||||
|
||||
def inspect
|
||||
'A different string'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :rb_str_new2, shared: true do
|
||||
it "returns a new string object calling strlen on the passed C string" do
|
||||
# Hardcoded to pass const char * = "hello\0invisible"
|
||||
|
@ -20,18 +44,6 @@ describe "C-API String function" do
|
|||
@s = CApiStringSpecs.new
|
||||
end
|
||||
|
||||
class ValidTostrTest
|
||||
def to_str
|
||||
"ruby"
|
||||
end
|
||||
end
|
||||
|
||||
class InvalidTostrTest
|
||||
def to_str
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
||||
[Encoding::BINARY, Encoding::UTF_8].each do |enc|
|
||||
describe "rb_str_set_len on a #{enc.name} String" do
|
||||
before :each do
|
||||
|
@ -438,12 +450,12 @@ describe "C-API String function" do
|
|||
describe "rb_str_to_str" do
|
||||
it "calls #to_str to coerce the value to a String" do
|
||||
@s.rb_str_to_str("foo").should == "foo"
|
||||
@s.rb_str_to_str(ValidTostrTest.new).should == "ruby"
|
||||
@s.rb_str_to_str(CApiStringSpecs::ValidTostrTest.new).should == "ruby"
|
||||
end
|
||||
|
||||
it "raises a TypeError if coercion fails" do
|
||||
lambda { @s.rb_str_to_str(0) }.should raise_error(TypeError)
|
||||
lambda { @s.rb_str_to_str(InvalidTostrTest.new) }.should raise_error(TypeError)
|
||||
lambda { @s.rb_str_to_str(CApiStringSpecs::InvalidTostrTest.new) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -875,6 +887,26 @@ describe "C-API String function" do
|
|||
s = "Awesome %s is here with %s"
|
||||
@s.rb_sprintf2(s, "string", "content").should == "Awesome string is here with content"
|
||||
end
|
||||
|
||||
it "formats a string VALUE using to_s if sign not specified in format" do
|
||||
s = 'Result: A string.'
|
||||
@s.rb_sprintf3(CApiStringSpecs::ToSOrInspect.new).should == s
|
||||
end
|
||||
|
||||
it "formats a string VALUE using inspect if sign specified in format" do
|
||||
s = 'Result: A different string.'
|
||||
@s.rb_sprintf4(CApiStringSpecs::ToSOrInspect.new).should == s
|
||||
end
|
||||
|
||||
it "formats a TrueClass VALUE as `TrueClass` if sign not specified in format" do
|
||||
s = 'Result: TrueClass.'
|
||||
@s.rb_sprintf3(true.class).should == s
|
||||
end
|
||||
|
||||
it "formats a TrueClass VALUE as 'true' if sign specified in format" do
|
||||
s = 'Result: true.'
|
||||
@s.rb_sprintf4(true.class).should == s
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_vsprintf" do
|
||||
|
@ -890,11 +922,11 @@ describe "C-API String function" do
|
|||
end
|
||||
|
||||
it "tries to convert the passed argument to a string by calling #to_str first" do
|
||||
@s.rb_String(ValidTostrTest.new).should == "ruby"
|
||||
@s.rb_String(CApiStringSpecs::ValidTostrTest.new).should == "ruby"
|
||||
end
|
||||
|
||||
it "raises a TypeError if #to_str does not return a string" do
|
||||
lambda { @s.rb_String(InvalidTostrTest.new) }.should raise_error(TypeError)
|
||||
lambda { @s.rb_String(CApiStringSpecs::InvalidTostrTest.new) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "tries to convert the passed argument to a string by calling #to_s" do
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require_relative 'spec_helper'
|
||||
require 'objspace'
|
||||
|
||||
load_extension("typed_data")
|
||||
|
||||
|
@ -7,6 +8,14 @@ describe "CApiAllocTypedSpecs (a class with an alloc func defined)" do
|
|||
@s = CApiAllocTypedSpecs.new
|
||||
@s.typed_wrapped_data.should == 42 # not defined in initialize
|
||||
end
|
||||
|
||||
it "uses the specified memsize function for ObjectSpace.memsize" do
|
||||
@s = CApiAllocTypedSpecs.new
|
||||
# The defined memsize function for the type should return 42 as
|
||||
# the size, and this should be added to the size of the object as
|
||||
# known by Ruby.
|
||||
ObjectSpace.memsize_of(@s).should > 42
|
||||
end
|
||||
end
|
||||
|
||||
describe "CApiWrappedTypedStruct" do
|
||||
|
|
|
@ -23,6 +23,10 @@ describe "C-API Util function" do
|
|||
lambda { @o.rb_scan_args([1, 2], "3", 0, @acc) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError if there are too many arguments" do
|
||||
lambda { @o.rb_scan_args([1, 2, 3, 4], "3", 0, @acc) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "assigns the required and optional arguments scanned" do
|
||||
@o.rb_scan_args([1, 2], "11", 2, @acc).should == 2
|
||||
ScratchPad.recorded.should == [1, 2]
|
||||
|
|
22
spec/ruby/security/cve_2019_8321_spec.rb
Normal file
22
spec/ruby/security/cve_2019_8321_spec.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
require_relative '../spec_helper'
|
||||
|
||||
require 'rubygems'
|
||||
require 'rubygems/user_interaction'
|
||||
|
||||
ruby_version_is "2.5.5" do
|
||||
describe "CVE-2019-8321 is resisted by" do
|
||||
it "sanitising verbose messages" do
|
||||
ui = Class.new {
|
||||
include Gem::UserInteraction
|
||||
}.new
|
||||
ui.should_receive(:say).with(".]2;nyan.")
|
||||
verbose_before = Gem.configuration.verbose
|
||||
begin
|
||||
Gem.configuration.verbose = :really_verbose
|
||||
ui.verbose("\e]2;nyan\a")
|
||||
ensure
|
||||
Gem.configuration.verbose = verbose_before
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
23
spec/ruby/security/cve_2019_8322_spec.rb
Normal file
23
spec/ruby/security/cve_2019_8322_spec.rb
Normal file
|
@ -0,0 +1,23 @@
|
|||
require_relative '../spec_helper'
|
||||
|
||||
require 'yaml'
|
||||
require 'rubygems'
|
||||
require 'rubygems/safe_yaml'
|
||||
require 'rubygems/commands/owner_command'
|
||||
|
||||
ruby_version_is "2.5.5" do
|
||||
describe "CVE-2019-8322 is resisted by" do
|
||||
it "sanitising owner names" do
|
||||
command = Gem::Commands::OwnerCommand.new
|
||||
def command.rubygems_api_request(*args)
|
||||
Struct.new(:body).new("---\n- email: \"\e]2;nyan\a\"\n handle: handle\n id: id\n")
|
||||
end
|
||||
def command.with_response(response)
|
||||
yield response
|
||||
end
|
||||
command.should_receive(:say).with("Owners for gem: name")
|
||||
command.should_receive(:say).with("- .]2;nyan.")
|
||||
command.show_owners "name"
|
||||
end
|
||||
end
|
||||
end
|
38
spec/ruby/security/cve_2019_8323_spec.rb
Normal file
38
spec/ruby/security/cve_2019_8323_spec.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
require_relative '../spec_helper'
|
||||
|
||||
require 'optparse'
|
||||
|
||||
require 'rubygems'
|
||||
require 'rubygems/gemcutter_utilities'
|
||||
|
||||
ruby_version_is "2.5.5" do
|
||||
describe "CVE-2019-8323 is resisted by" do
|
||||
describe "sanitising the body" do
|
||||
it "for success codes" do
|
||||
cutter = Class.new {
|
||||
include Gem::GemcutterUtilities
|
||||
}.new
|
||||
response = Net::HTTPSuccess.new(nil, nil, nil)
|
||||
def response.body
|
||||
"\e]2;nyan\a"
|
||||
end
|
||||
cutter.should_receive(:say).with(".]2;nyan.")
|
||||
cutter.with_response response
|
||||
end
|
||||
|
||||
it "for error codes" do
|
||||
cutter = Class.new {
|
||||
include Gem::GemcutterUtilities
|
||||
}.new
|
||||
def cutter.terminate_interaction(n)
|
||||
end
|
||||
response = Net::HTTPNotFound.new(nil, nil, nil)
|
||||
def response.body
|
||||
"\e]2;nyan\a"
|
||||
end
|
||||
cutter.should_receive(:say).with(".]2;nyan.")
|
||||
cutter.with_response response
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
38
spec/ruby/security/cve_2019_8325_spec.rb
Normal file
38
spec/ruby/security/cve_2019_8325_spec.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
require_relative '../spec_helper'
|
||||
|
||||
require 'rubygems'
|
||||
require 'rubygems/command_manager'
|
||||
|
||||
ruby_version_is "2.5.5" do
|
||||
describe "CVE-2019-8325 is resisted by" do
|
||||
describe "sanitising error message components" do
|
||||
it "for the 'while executing' message" do
|
||||
manager = Gem::CommandManager.new
|
||||
def manager.process_args(args, build_args)
|
||||
raise StandardError, "\e]2;nyan\a"
|
||||
end
|
||||
def manager.terminate_interaction(n)
|
||||
end
|
||||
manager.should_receive(:alert_error).with("While executing gem ... (StandardError)\n .]2;nyan.")
|
||||
manager.run nil, nil
|
||||
end
|
||||
|
||||
it "for the 'invalid option' message" do
|
||||
manager = Gem::CommandManager.new
|
||||
def manager.terminate_interaction(n)
|
||||
end
|
||||
manager.should_receive(:alert_error).with("Invalid option: --.]2;nyan.. See 'gem --help'.")
|
||||
manager.process_args ["--\e]2;nyan\a"], nil
|
||||
end
|
||||
|
||||
it "for the 'loading command' message" do
|
||||
manager = Gem::CommandManager.new
|
||||
def manager.require(x)
|
||||
raise 'foo'
|
||||
end
|
||||
manager.should_receive(:alert_error).with("Loading command: .]2;nyan. (RuntimeError)\n\tfoo")
|
||||
manager.send :load_and_instantiate, "\e]2;nyan\a"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -114,4 +114,15 @@ describe :basicobject_send, shared: true do
|
|||
it "has a negative arity" do
|
||||
method(@method).arity.should < 0
|
||||
end
|
||||
|
||||
it "invokes module methods with super correctly" do
|
||||
m1 = Module.new { def foo(ary); ary << :m1; end; }
|
||||
m2 = Module.new { def foo(ary = []); super(ary); ary << :m2; end; }
|
||||
c2 = Class.new do
|
||||
include m1
|
||||
include m2
|
||||
end
|
||||
|
||||
c2.new.send(@method, :foo, *[[]]).should == %i[m1 m2]
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue