mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@a0b7d0d
This commit is contained in:
parent
a4fbc7e288
commit
22e2a6a999
66 changed files with 943 additions and 167 deletions
|
@ -30,7 +30,7 @@ ruby/spec is known to be tested in these implementations for every commit:
|
|||
* [Opal](https://github.com/opal/opal/tree/master/spec)
|
||||
|
||||
ruby/spec describes the behavior of Ruby 2.5 and more recent Ruby versions.
|
||||
More precisely, every latest stable MRI release should [pass](https://travis-ci.org/ruby/spec) all specs of ruby/spec (2.5.x, 2.6.x, 2.7.x, etc), and those are tested in TravisCI.
|
||||
More precisely, every latest stable MRI release should [pass](https://github.com/ruby/spec/actions/workflows/ci.yml) all specs of ruby/spec (2.5.x, 2.6.x, 2.7.x, etc), and those are tested in CI.
|
||||
|
||||
### Synchronization with Ruby Implementations
|
||||
|
||||
|
|
|
@ -25,6 +25,12 @@ describe "The --encoding command line option" do
|
|||
end
|
||||
|
||||
it "does not accept a third encoding" do
|
||||
ruby_exe(@test_string, options: "--disable-gems --encoding big5:#{@enc2}:utf-32le", args: "2>&1").should =~ /extra argument for --encoding: utf-32le/
|
||||
options = {
|
||||
options: "--disable-gems --encoding big5:#{@enc2}:utf-32le",
|
||||
args: "2>&1",
|
||||
exit_status: 1
|
||||
}
|
||||
|
||||
ruby_exe(@test_string, options).should =~ /extra argument for --encoding: utf-32le/
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ describe "The -r command line option" do
|
|||
end
|
||||
|
||||
it "requires the file before parsing the main script" do
|
||||
out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), options: "-r #{@test_file}", args: "2>&1")
|
||||
out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), options: "-r #{@test_file}", args: "2>&1", exit_status: 1)
|
||||
$?.should_not.success?
|
||||
out.should include("REQUIRED")
|
||||
out.should include("syntax error")
|
||||
|
|
|
@ -31,6 +31,7 @@ describe "ruby -E" do
|
|||
it "raises a RuntimeError if used with -U" do
|
||||
ruby_exe("p 1",
|
||||
options: '-Eascii:ascii -U',
|
||||
args: '2>&1').should =~ /RuntimeError/
|
||||
args: '2>&1',
|
||||
exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,7 +21,7 @@ describe 'The -S command line option' do
|
|||
end
|
||||
|
||||
it "runs launcher found in PATH and sets the exit status to 1 if it fails" do
|
||||
result = ruby_exe(nil, options: '-S dash_s_fail', env: { 'PATH' => @path }, args: '2>&1')
|
||||
result = ruby_exe(nil, options: '-S dash_s_fail', env: { 'PATH' => @path }, args: '2>&1', exit_status: 1)
|
||||
result.should =~ /\bdie\b/
|
||||
$?.exitstatus.should == 1
|
||||
end
|
||||
|
|
|
@ -32,12 +32,14 @@ describe "ruby -U" do
|
|||
it "raises a RuntimeError if used with -Eext:int" do
|
||||
ruby_exe("p 1",
|
||||
options: '-U -Eascii:ascii',
|
||||
args: '2>&1').should =~ /RuntimeError/
|
||||
args: '2>&1',
|
||||
exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError if used with -E:int" do
|
||||
ruby_exe("p 1",
|
||||
options: '-U -E:ascii',
|
||||
args: '2>&1').should =~ /RuntimeError/
|
||||
args: '2>&1',
|
||||
exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,7 +9,7 @@ describe "The -x command line option" do
|
|||
|
||||
it "fails when /\#!.*ruby.*/-ish line in target file is not found" do
|
||||
bad_embedded_ruby = fixture __FILE__, "bin/bad_embedded_ruby.txt"
|
||||
result = ruby_exe(bad_embedded_ruby, options: '-x', args: '2>&1')
|
||||
result = ruby_exe(bad_embedded_ruby, options: '-x', args: '2>&1', exit_status: 1)
|
||||
result.should include "no Ruby script found in input"
|
||||
end
|
||||
|
||||
|
|
|
@ -2,10 +2,10 @@ require_relative '../spec_helper'
|
|||
|
||||
describe "The error message caused by an exception" do
|
||||
it "is not printed to stdout" do
|
||||
out = ruby_exe("this_does_not_exist", args: "2> #{File::NULL}")
|
||||
out = ruby_exe("this_does_not_exist", args: "2> #{File::NULL}", exit_status: 1)
|
||||
out.chomp.should.empty?
|
||||
|
||||
out = ruby_exe("end #syntax error", args: "2> #{File::NULL}")
|
||||
out = ruby_exe("end #syntax error", args: "2> #{File::NULL}", exit_status: 1)
|
||||
out.chomp.should.empty?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -87,101 +87,101 @@ describe "Processing RUBYOPT" do
|
|||
|
||||
it "raises a RuntimeError for '-a'" do
|
||||
ENV["RUBYOPT"] = '-a'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-p'" do
|
||||
ENV["RUBYOPT"] = '-p'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-n'" do
|
||||
ENV["RUBYOPT"] = '-n'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-y'" do
|
||||
ENV["RUBYOPT"] = '-y'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-c'" do
|
||||
ENV["RUBYOPT"] = '-c'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-s'" do
|
||||
ENV["RUBYOPT"] = '-s'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-h'" do
|
||||
ENV["RUBYOPT"] = '-h'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '--help'" do
|
||||
ENV["RUBYOPT"] = '--help'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-l'" do
|
||||
ENV["RUBYOPT"] = '-l'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-S'" do
|
||||
ENV["RUBYOPT"] = '-S irb'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-e'" do
|
||||
ENV["RUBYOPT"] = '-e0'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-i'" do
|
||||
ENV["RUBYOPT"] = '-i.bak'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-x'" do
|
||||
ENV["RUBYOPT"] = '-x'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-C'" do
|
||||
ENV["RUBYOPT"] = '-C'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-X'" do
|
||||
ENV["RUBYOPT"] = '-X.'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-F'" do
|
||||
ENV["RUBYOPT"] = '-F'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '-0'" do
|
||||
ENV["RUBYOPT"] = '-0'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '--copyright'" do
|
||||
ENV["RUBYOPT"] = '--copyright'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '--version'" do
|
||||
ENV["RUBYOPT"] = '--version'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
|
||||
it "raises a RuntimeError for '--yydebug'" do
|
||||
ENV["RUBYOPT"] = '--yydebug'
|
||||
ruby_exe("", args: '2>&1').should =~ /RuntimeError/
|
||||
ruby_exe("", args: '2>&1', exit_status: 1).should =~ /RuntimeError/
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,12 +2,12 @@ require_relative '../spec_helper'
|
|||
|
||||
describe "The interpreter" do
|
||||
it "prints an error when given a file with invalid syntax" do
|
||||
out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), args: "2>&1")
|
||||
out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), args: "2>&1", exit_status: 1)
|
||||
out.should include "syntax error"
|
||||
end
|
||||
|
||||
it "prints an error when given code via -e with invalid syntax" do
|
||||
out = ruby_exe(nil, args: "-e 'a{' 2>&1")
|
||||
out = ruby_exe(nil, args: "-e 'a{' 2>&1", exit_status: 1)
|
||||
out.should include "syntax error"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,6 +36,7 @@ describe "Array#[]=" do
|
|||
a[3, 2] = ['a', 'b', 'c', 'd']
|
||||
a.should == [2, 2, 3, "a", "b", "c", "d", 6]
|
||||
end
|
||||
|
||||
it "replaces the section defined by [start,length] with the given values" do
|
||||
a = [1, 2, 3, 4, 5, 6]
|
||||
a[3, 2] = 'a', 'b', 'c', 'd'
|
||||
|
@ -169,6 +170,7 @@ describe "Array#[]=" do
|
|||
ary[1...1] = []
|
||||
ary.should == [1, 2, 3]
|
||||
end
|
||||
|
||||
it "does nothing if the section defined by range has negative width and the rhs is an empty array" do
|
||||
ary = [1, 2, 3, 4, 5]
|
||||
ary[1...0] = []
|
||||
|
@ -284,6 +286,12 @@ describe "Array#[]= with [index, count]" do
|
|||
(a[2, 3] = [4, 5]).should == [4, 5]
|
||||
end
|
||||
|
||||
it "accepts a frozen String literal as RHS" do
|
||||
a = ['a', 'b', 'c']
|
||||
a[0, 2] = 'd'.freeze
|
||||
a.should == ['d', 'c']
|
||||
end
|
||||
|
||||
it "just sets the section defined by [start,length] to nil even if the rhs is nil" do
|
||||
a = ['a', 'b', 'c', 'd', 'e']
|
||||
a[1, 3] = nil
|
||||
|
|
|
@ -15,6 +15,8 @@ describe "Encoding#replicate" do
|
|||
name = @prefix + '-ASCII'
|
||||
e = Encoding::ASCII.replicate(name)
|
||||
e.name.should == name
|
||||
Encoding.find(name).should == e
|
||||
|
||||
"a".force_encoding(e).valid_encoding?.should be_true
|
||||
"\x80".force_encoding(e).valid_encoding?.should be_false
|
||||
end
|
||||
|
@ -23,6 +25,8 @@ describe "Encoding#replicate" do
|
|||
name = @prefix + 'UTF-8'
|
||||
e = Encoding::UTF_8.replicate(name)
|
||||
e.name.should == name
|
||||
Encoding.find(name).should == e
|
||||
|
||||
"a".force_encoding(e).valid_encoding?.should be_true
|
||||
"\u3042".force_encoding(e).valid_encoding?.should be_true
|
||||
"\x80".force_encoding(e).valid_encoding?.should be_false
|
||||
|
@ -32,6 +36,8 @@ describe "Encoding#replicate" do
|
|||
name = @prefix + 'UTF-16-BE'
|
||||
e = Encoding::UTF_16BE.replicate(name)
|
||||
e.name.should == name
|
||||
Encoding.find(name).should == e
|
||||
|
||||
"a".force_encoding(e).valid_encoding?.should be_false
|
||||
"\x30\x42".force_encoding(e).valid_encoding?.should be_true
|
||||
"\x80".force_encoding(e).valid_encoding?.should be_false
|
||||
|
@ -40,7 +46,22 @@ describe "Encoding#replicate" do
|
|||
it "returns a replica of ISO-2022-JP" do
|
||||
name = @prefix + 'ISO-2022-JP'
|
||||
e = Encoding::ISO_2022_JP.replicate(name)
|
||||
Encoding.find(name).should == e
|
||||
|
||||
e.name.should == name
|
||||
e.dummy?.should be_true
|
||||
end
|
||||
|
||||
# NOTE: it's unclear of the value of this (for the complexity cost of it),
|
||||
# but it is the current CRuby behavior.
|
||||
it "can be associated with a String" do
|
||||
name = @prefix + '-US-ASCII'
|
||||
e = Encoding::US_ASCII.replicate(name)
|
||||
e.name.should == name
|
||||
Encoding.find(name).should == e
|
||||
|
||||
s = "abc".force_encoding(e)
|
||||
s.encoding.should == e
|
||||
s.encoding.name.should == name
|
||||
end
|
||||
end
|
||||
|
|
16
spec/ruby/core/enumerator/lazy/filter_map_spec.rb
Normal file
16
spec/ruby/core/enumerator/lazy/filter_map_spec.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# -*- encoding: us-ascii -*-
|
||||
|
||||
require_relative '../../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "2.7" do
|
||||
describe "Enumerator::Lazy#filter_map" do
|
||||
it "maps only truthy results" do
|
||||
(1..Float::INFINITY).lazy.filter_map { |i| i if i.odd? }.first(4).should == [1, 3, 5, 7]
|
||||
end
|
||||
|
||||
it "does not map false results" do
|
||||
(1..Float::INFINITY).lazy.filter_map { |i| i.odd? ? i : false }.first(4).should == [1, 3, 5, 7]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -95,7 +95,7 @@ describe "SignalException" do
|
|||
|
||||
platform_is_not :windows do
|
||||
it "runs after at_exit" do
|
||||
output = ruby_exe(<<-RUBY)
|
||||
output = ruby_exe(<<-RUBY, exit_status: nil)
|
||||
at_exit do
|
||||
puts "hello"
|
||||
$stdout.flush
|
||||
|
@ -109,7 +109,7 @@ describe "SignalException" do
|
|||
end
|
||||
|
||||
it "cannot be trapped with Signal.trap" do
|
||||
ruby_exe(<<-RUBY)
|
||||
ruby_exe(<<-RUBY, exit_status: nil)
|
||||
Signal.trap("PROF") {}
|
||||
raise(SignalException, "PROF")
|
||||
RUBY
|
||||
|
@ -118,7 +118,7 @@ describe "SignalException" do
|
|||
end
|
||||
|
||||
it "self-signals for USR1" do
|
||||
ruby_exe("raise(SignalException, 'USR1')")
|
||||
ruby_exe("raise(SignalException, 'USR1')", exit_status: nil)
|
||||
$?.termsig.should == Signal.list.fetch('USR1')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,14 +3,14 @@ require_relative '../../spec_helper'
|
|||
describe "SystemExit" do
|
||||
it "sets the exit status and exits silently when raised" do
|
||||
code = 'raise SystemExit.new(7)'
|
||||
result = ruby_exe(code, args: "2>&1")
|
||||
result = ruby_exe(code, args: "2>&1", exit_status: 7)
|
||||
result.should == ""
|
||||
$?.exitstatus.should == 7
|
||||
end
|
||||
|
||||
it "sets the exit status and exits silently when raised when subclassed" do
|
||||
code = 'class CustomExit < SystemExit; end; raise CustomExit.new(8)'
|
||||
result = ruby_exe(code, args: "2>&1")
|
||||
result = ruby_exe(code, args: "2>&1", exit_status: 8)
|
||||
result.should == ""
|
||||
$?.exitstatus.should == 8
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ require_relative '../../spec_helper'
|
|||
|
||||
describe "An Exception reaching the top level" do
|
||||
it "is printed on STDERR" do
|
||||
ruby_exe('raise "foo"', args: "2>&1").should.include?("in `<main>': foo (RuntimeError)")
|
||||
ruby_exe('raise "foo"', args: "2>&1", exit_status: 1).should.include?("in `<main>': foo (RuntimeError)")
|
||||
end
|
||||
|
||||
ruby_version_is "2.6" do
|
||||
|
@ -20,7 +20,7 @@ describe "An Exception reaching the top level" do
|
|||
raise_wrapped
|
||||
end
|
||||
RUBY
|
||||
lines = ruby_exe(code, args: "2>&1").lines
|
||||
lines = ruby_exe(code, args: "2>&1", exit_status: 1).lines
|
||||
lines.reject! { |l| l.include?('rescue in') }
|
||||
lines.map! { |l| l.chomp[/:(in.+)/, 1] }
|
||||
lines.should == ["in `raise_wrapped': wrapped (RuntimeError)",
|
||||
|
@ -38,7 +38,7 @@ describe "An Exception reaching the top level" do
|
|||
"/dir/bar.rb:20:in `caller'",
|
||||
]
|
||||
RUBY
|
||||
ruby_exe(code, args: "2>&1").should == <<-EOS
|
||||
ruby_exe(code, args: "2>&1", exit_status: 1).should == <<-EOS
|
||||
/dir/foo.rb:10:in `raising': foo (RuntimeError)
|
||||
\tfrom /dir/bar.rb:20:in `caller'
|
||||
EOS
|
||||
|
|
|
@ -72,6 +72,26 @@ ruby_version_is "2.7" do
|
|||
-> { fiber.raise }.should raise_error
|
||||
-> { fiber.resume }.should raise_error(FiberError, /dead fiber called|attempt to resume a terminated fiber/)
|
||||
end
|
||||
|
||||
it "returns to calling fiber after raise" do
|
||||
fiber_one = Fiber.new do
|
||||
Fiber.yield :yield_one
|
||||
:unreachable
|
||||
end
|
||||
|
||||
fiber_two = Fiber.new do
|
||||
results = []
|
||||
results << fiber_one.resume
|
||||
begin
|
||||
fiber_one.raise
|
||||
rescue
|
||||
results << :rescued
|
||||
end
|
||||
results
|
||||
end
|
||||
|
||||
fiber_two.resume.should == [:yield_one, :rescued]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -16,23 +16,20 @@ describe "File.atime" do
|
|||
end
|
||||
|
||||
platform_is :linux, :windows do
|
||||
platform_is_not :"powerpc64le-linux" do # https://bugs.ruby-lang.org/issues/17926
|
||||
## NOTE also that some Linux systems disable atime (e.g. via mount params) for better filesystem speed.
|
||||
it "returns the last access time for the named file with microseconds" do
|
||||
supports_subseconds = Integer(`stat -c%x '#{__FILE__}'`[/\.(\d+)/, 1], 10)
|
||||
if supports_subseconds != 0
|
||||
expected_time = Time.at(Time.now.to_i + 0.123456)
|
||||
File.utime expected_time, 0, @file
|
||||
# FIXME: A random failing test on Travis ppc64le.
|
||||
# https://bugs.ruby-lang.org/issues/17926
|
||||
if ENV.key?('TRAVIS') && ENV['TRAVIS_CPU_ARCH'] == 'ppc64le'
|
||||
skip '[ruby-core:17926] A random failure on Travis ppc64le'
|
||||
end
|
||||
File.atime(@file).usec.should == expected_time.usec
|
||||
else
|
||||
File.atime(__FILE__).usec.should == 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an Errno::ENOENT exception if the file is not found" do
|
||||
-> { File.atime('a_fake_file') }.should raise_error(Errno::ENOENT)
|
||||
|
|
|
@ -164,5 +164,20 @@ describe "File.basename" do
|
|||
basename.encoding.should == Encoding::Windows_1250
|
||||
end
|
||||
|
||||
it "returns a new unfrozen String" do
|
||||
exts = [nil, '.rb', '.*', '.txt']
|
||||
['foo.rb','//', '/test/', 'test'].each do |example|
|
||||
exts.each do |ext|
|
||||
original = example.freeze
|
||||
result = if ext
|
||||
File.basename(original, ext)
|
||||
else
|
||||
File.basename(original)
|
||||
end
|
||||
result.should_not equal(original)
|
||||
result.frozen?.should == false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -59,6 +59,24 @@ describe "Hash#rehash" do
|
|||
h.keys.should == [a]
|
||||
end
|
||||
|
||||
it "removes duplicate keys for large hashes" do
|
||||
a = [1,2]
|
||||
b = [1]
|
||||
|
||||
h = {}
|
||||
h[a] = true
|
||||
h[b] = true
|
||||
100.times { |n| h[n] = true }
|
||||
b << 2
|
||||
h.size.should == 102
|
||||
h.keys.should.include? a
|
||||
h.keys.should.include? b
|
||||
h.rehash
|
||||
h.size.should == 101
|
||||
h.keys.should.include? a
|
||||
h.keys.should_not.include? [1]
|
||||
end
|
||||
|
||||
it "raises a FrozenError if called on a frozen instance" do
|
||||
-> { HashSpecs.frozen_hash.rehash }.should raise_error(FrozenError)
|
||||
-> { HashSpecs.empty_frozen_hash.rehash }.should raise_error(FrozenError)
|
||||
|
|
|
@ -57,4 +57,8 @@ describe "IO#binmode?" do
|
|||
@duped = @file.dup
|
||||
@duped.binmode?.should == @file.binmode?
|
||||
end
|
||||
|
||||
it "raises an IOError on closed stream" do
|
||||
-> { IOSpecs.closed_io.binmode? }.should raise_error(IOError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -84,4 +84,23 @@ end
|
|||
dup.close
|
||||
end
|
||||
end
|
||||
|
||||
it "always sets the autoclose flag for the new IO object" do
|
||||
@f.autoclose = true
|
||||
dup = @f.dup
|
||||
begin
|
||||
dup.should.autoclose?
|
||||
ensure
|
||||
dup.close
|
||||
end
|
||||
|
||||
@f.autoclose = false
|
||||
dup = @f.dup
|
||||
begin
|
||||
dup.should.autoclose?
|
||||
ensure
|
||||
dup.close
|
||||
@f.autoclose = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
describe :io_external_encoding_write, shared: true do
|
||||
describe "when Encoding.default_internal is nil" do
|
||||
|
@ -93,6 +94,10 @@ describe "IO#external_encoding" do
|
|||
rm_r @name
|
||||
end
|
||||
|
||||
it "raises an IOError on closed stream" do
|
||||
-> { IOSpecs.closed_io.external_encoding }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
describe "with 'r' mode" do
|
||||
describe "when Encoding.default_internal is nil" do
|
||||
before :each do
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
describe :io_internal_encoding, shared: true do
|
||||
describe "when Encoding.default_internal is not set" do
|
||||
|
@ -112,6 +113,10 @@ describe "IO#internal_encoding" do
|
|||
Encoding.default_internal = @internal
|
||||
end
|
||||
|
||||
it "raises an IOError on closed stream" do
|
||||
-> { IOSpecs.closed_io.internal_encoding }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
describe "with 'r' mode" do
|
||||
it_behaves_like :io_internal_encoding, nil, "r"
|
||||
end
|
||||
|
|
|
@ -14,6 +14,24 @@ describe "IO#lineno" do
|
|||
-> { IOSpecs.closed_io.lineno }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
it "raises an IOError on a write-only stream" do
|
||||
name = tmp("io_lineno.txt")
|
||||
begin
|
||||
File.open(name, 'w') do |f|
|
||||
-> { f.lineno }.should raise_error(IOError)
|
||||
end
|
||||
ensure
|
||||
rm_r name
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an IOError on a duplexed stream with the read side closed" do
|
||||
IO.popen('cat', 'r+') do |p|
|
||||
p.close_read
|
||||
-> { p.lineno }.should raise_error(IOError)
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the current line number" do
|
||||
@io.lineno.should == 0
|
||||
|
||||
|
@ -40,6 +58,24 @@ describe "IO#lineno=" do
|
|||
-> { IOSpecs.closed_io.lineno = 5 }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
it "raises an IOError on a write-only stream" do
|
||||
name = tmp("io_lineno.txt")
|
||||
begin
|
||||
File.open(name, 'w') do |f|
|
||||
-> { f.lineno = 0 }.should raise_error(IOError)
|
||||
end
|
||||
ensure
|
||||
rm_r name
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an IOError on a duplexed stream with the read side closed" do
|
||||
IO.popen('cat', 'r+') do |p|
|
||||
p.close_read
|
||||
-> { p.lineno = 0 }.should raise_error(IOError)
|
||||
end
|
||||
end
|
||||
|
||||
it "calls #to_int on a non-numeric argument" do
|
||||
obj = mock('123')
|
||||
obj.should_receive(:to_int).and_return(123)
|
||||
|
|
|
@ -34,6 +34,20 @@ describe "IO#set_encoding_by_bom" do
|
|||
@io.external_encoding.should == Encoding::UTF_16BE
|
||||
end
|
||||
|
||||
it "returns the result encoding if found BOM UTF_32LE sequence" do
|
||||
File.binwrite(@name, "\xFF\xFE\x00\x00abc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_32LE
|
||||
@io.external_encoding.should == Encoding::UTF_32LE
|
||||
end
|
||||
|
||||
it "returns the result encoding if found BOM UTF_32BE sequence" do
|
||||
File.binwrite(@name, "\x00\x00\xFE\xFFabc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_32BE
|
||||
@io.external_encoding.should == Encoding::UTF_32BE
|
||||
end
|
||||
|
||||
it "returns nil if found BOM sequence not provided" do
|
||||
File.write(@name, "abc")
|
||||
|
||||
|
|
|
@ -50,6 +50,11 @@ describe "IO#sysread on a file" do
|
|||
@file.sysread(5).should == "56789"
|
||||
end
|
||||
|
||||
it "raises an error when called after buffered reads" do
|
||||
@file.readline
|
||||
-> { @file.sysread(5) }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
it "reads normally even when called immediately after a buffered IO#read" do
|
||||
@file.read(15)
|
||||
@file.sysread(5).should == "56789"
|
||||
|
|
|
@ -26,6 +26,11 @@ describe "IO#sysseek" do
|
|||
-> { @io.sysseek(-5, IO::SEEK_CUR) }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
it "seeks normally even when called immediately after a buffered IO#read" do
|
||||
@io.read(15)
|
||||
@io.sysseek(-5, IO::SEEK_CUR).should == 10
|
||||
end
|
||||
|
||||
it "moves the read position relative to the start with SEEK_SET" do
|
||||
@io.sysseek(43, IO::SEEK_SET)
|
||||
@io.readline.should == "Aquí está la línea tres.\n"
|
||||
|
|
|
@ -33,31 +33,32 @@ describe "Kernel.at_exit" do
|
|||
end
|
||||
EOC
|
||||
|
||||
result = ruby_exe(code, args: "2>&1")
|
||||
result = ruby_exe(code, args: "2>&1", exit_status: 1)
|
||||
result.lines.should.include?("The exception matches: true (message=foo)\n")
|
||||
end
|
||||
|
||||
it "both exceptions in at_exit and in the main script are printed" do
|
||||
result = ruby_exe('at_exit { raise "at_exit_error" }; raise "main_script_error"', args: "2>&1")
|
||||
code = 'at_exit { raise "at_exit_error" }; raise "main_script_error"'
|
||||
result = ruby_exe(code, args: "2>&1", exit_status: 1)
|
||||
result.should.include?('at_exit_error (RuntimeError)')
|
||||
result.should.include?('main_script_error (RuntimeError)')
|
||||
end
|
||||
|
||||
it "decides the exit status if both at_exit and the main script raise SystemExit" do
|
||||
ruby_exe('at_exit { exit 43 }; exit 42', args: "2>&1")
|
||||
ruby_exe('at_exit { exit 43 }; exit 42', args: "2>&1", exit_status: 43)
|
||||
$?.exitstatus.should == 43
|
||||
end
|
||||
|
||||
it "runs all at_exit even if some raise exceptions" do
|
||||
code = 'at_exit { STDERR.puts "last" }; at_exit { exit 43 }; at_exit { STDERR.puts "first" }; exit 42'
|
||||
result = ruby_exe(code, args: "2>&1")
|
||||
result = ruby_exe(code, args: "2>&1", exit_status: 43)
|
||||
result.should == "first\nlast\n"
|
||||
$?.exitstatus.should == 43
|
||||
end
|
||||
|
||||
it "runs at_exit handlers even if the main script fails to parse" do
|
||||
script = fixture(__FILE__, "at_exit.rb")
|
||||
result = ruby_exe('{', options: "-r#{script}", args: "2>&1")
|
||||
result = ruby_exe('{', options: "-r#{script}", args: "2>&1", exit_status: 1)
|
||||
$?.should_not.success?
|
||||
result.should.include?("at_exit ran\n")
|
||||
result.should.include?("syntax error")
|
||||
|
|
|
@ -228,6 +228,17 @@ describe "Kernel#eval" do
|
|||
ruby_exe(code).chomp.should == "a,b,c,e,LocalJumpError,f"
|
||||
end
|
||||
|
||||
it "can be called with Method#call" do
|
||||
method(:eval).call("2 * 3").should == 6
|
||||
end
|
||||
|
||||
it "has the correct default definee when called through Method#call" do
|
||||
class EvalSpecs
|
||||
method(:eval).call("def eval_spec_method_call; end")
|
||||
EvalSpecs.should have_instance_method(:eval_spec_method_call)
|
||||
end
|
||||
end
|
||||
|
||||
# See language/magic_comment_spec.rb for more magic comments specs
|
||||
describe "with a magic encoding comment" do
|
||||
it "uses the magic comment encoding for the encoding of literal strings" do
|
||||
|
@ -374,6 +385,7 @@ CODE
|
|||
end
|
||||
end
|
||||
|
||||
describe 'with refinements' do
|
||||
it "activates refinements from the eval scope" do
|
||||
refinery = Module.new do
|
||||
refine EvalSpecs::A do
|
||||
|
@ -414,3 +426,4 @@ CODE
|
|||
result.should == "bar"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
# NOTE: most specs are in sprintf_spec.rb, this is just an alias
|
||||
describe "Kernel#format" do
|
||||
it "is a private method" do
|
||||
Kernel.should have_private_instance_method(:format)
|
||||
|
|
|
@ -30,4 +30,12 @@ describe "Kernel#inspect" do
|
|||
obj = Object.new
|
||||
obj.inspect.should =~ /^#<Object:0x[0-9a-f]+>$/
|
||||
end
|
||||
|
||||
it "returns a String for an object without #class method" do
|
||||
obj = Object.new
|
||||
class << obj
|
||||
undef_method :class
|
||||
end
|
||||
obj.inspect.should be_kind_of(String)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -342,6 +342,23 @@ describe :kernel_sprintf, shared: true do
|
|||
sub_string = long_string[8, 5]
|
||||
sprintf("%.#{1 * 3}s", sub_string).should == "hel"
|
||||
end
|
||||
|
||||
it "formats string with precision" do
|
||||
Kernel.format("%.3s", "hello").should == "hel"
|
||||
Kernel.format("%-3.3s", "hello").should == "hel"
|
||||
end
|
||||
|
||||
it "formats multibyte string with precision" do
|
||||
Kernel.format("%.2s", "été").should == "ét"
|
||||
end
|
||||
|
||||
it "preserves encoding of the format string" do
|
||||
str = format('%s'.encode(Encoding::UTF_8), 'foobar')
|
||||
str.encoding.should == Encoding::UTF_8
|
||||
|
||||
str = format('%s'.encode(Encoding::US_ASCII), 'foobar')
|
||||
str.encoding.should == Encoding::US_ASCII
|
||||
end
|
||||
end
|
||||
|
||||
describe "%" do
|
||||
|
|
|
@ -88,6 +88,23 @@ describe "Module#define_method when given an UnboundMethod" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "Module#define_method" do
|
||||
describe "when the default definee is not the same as the module" do
|
||||
it "sets the visibility of the method to public" do
|
||||
klass = Class.new
|
||||
class << klass
|
||||
private
|
||||
define_method(:meta) do
|
||||
define_method(:foo) { :foo }
|
||||
end
|
||||
end
|
||||
|
||||
klass.send :meta
|
||||
klass.new.foo.should == :foo
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Module#define_method when name is not a special private name" do
|
||||
describe "given an UnboundMethod" do
|
||||
describe "and called from the target module" do
|
||||
|
@ -491,7 +508,36 @@ describe "Module#define_method" do
|
|||
it "receives the value passed as the argument when passed one argument" do
|
||||
@klass.new.m(1).should == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "passed { |a,| } creates a method that" do
|
||||
before :each do
|
||||
@klass = Class.new do
|
||||
define_method(:m) { |a,| a }
|
||||
end
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when passed zero arguments" do
|
||||
-> { @klass.new.m }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when passed zero arguments and a block" do
|
||||
-> { @klass.new.m { :computed } }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when passed two arguments" do
|
||||
-> { @klass.new.m 1, 2 }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "receives the value passed as the argument when passed one argument" do
|
||||
@klass.new.m(1).should == 1
|
||||
end
|
||||
|
||||
it "does not destructure the passed argument" do
|
||||
@klass.new.m([1, 2]).should == [1, 2]
|
||||
# for comparison:
|
||||
proc { |a,| a }.call([1, 2]).should == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "passed { |*a| } creates a method that" do
|
||||
|
|
|
@ -234,6 +234,148 @@ describe "Module#include" do
|
|||
remove_const :C
|
||||
end
|
||||
end
|
||||
|
||||
it "updates the method when an included module is updated" do
|
||||
a_class = Class.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
|
||||
m_module = Module.new
|
||||
|
||||
b_class = Class.new(a_class) do
|
||||
include m_module
|
||||
end
|
||||
|
||||
b = b_class.new
|
||||
|
||||
foo = -> { b.foo }
|
||||
|
||||
foo.call.should == 'a'
|
||||
|
||||
m_module.module_eval do
|
||||
def foo
|
||||
'm'
|
||||
end
|
||||
end
|
||||
|
||||
foo.call.should == 'm'
|
||||
end
|
||||
|
||||
|
||||
it "updates the method when a module included after a call is later updated" do
|
||||
m_module = Module.new
|
||||
a_class = Class.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
b_class = Class.new(a_class)
|
||||
b = b_class.new
|
||||
foo = -> { b.foo }
|
||||
foo.call.should == 'a'
|
||||
|
||||
b_class.include m_module
|
||||
foo.call.should == 'a'
|
||||
|
||||
m_module.module_eval do
|
||||
def foo
|
||||
"m"
|
||||
end
|
||||
end
|
||||
foo.call.should == 'm'
|
||||
end
|
||||
|
||||
it "updates the method when a nested included module is updated" do
|
||||
a_class = Class.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
|
||||
n_module = Module.new
|
||||
|
||||
m_module = Module.new do
|
||||
include n_module
|
||||
end
|
||||
|
||||
b_class = Class.new(a_class) do
|
||||
include m_module
|
||||
end
|
||||
|
||||
b = b_class.new
|
||||
|
||||
foo = -> { b.foo }
|
||||
|
||||
foo.call.should == 'a'
|
||||
|
||||
n_module.module_eval do
|
||||
def foo
|
||||
'n'
|
||||
end
|
||||
end
|
||||
|
||||
foo.call.should == 'n'
|
||||
end
|
||||
|
||||
it "updates the method when a new module is included" do
|
||||
a_class = Class.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
|
||||
m_module = Module.new do
|
||||
def foo
|
||||
'm'
|
||||
end
|
||||
end
|
||||
|
||||
b_class = Class.new(a_class)
|
||||
b = b_class.new
|
||||
|
||||
foo = -> { b.foo }
|
||||
|
||||
foo.call.should == 'a'
|
||||
|
||||
b_class.class_eval do
|
||||
include m_module
|
||||
end
|
||||
|
||||
foo.call.should == 'm'
|
||||
end
|
||||
|
||||
it "updates the method when a new module with nested module is included" do
|
||||
a_class = Class.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
|
||||
n_module = Module.new do
|
||||
def foo
|
||||
'n'
|
||||
end
|
||||
end
|
||||
|
||||
m_module = Module.new do
|
||||
include n_module
|
||||
end
|
||||
|
||||
b_class = Class.new(a_class)
|
||||
b = b_class.new
|
||||
|
||||
foo = -> { b.foo }
|
||||
|
||||
foo.call.should == 'a'
|
||||
|
||||
b_class.class_eval do
|
||||
include m_module
|
||||
end
|
||||
|
||||
foo.call.should == 'n'
|
||||
end
|
||||
end
|
||||
|
||||
describe "Module#include?" do
|
||||
|
|
|
@ -36,6 +36,192 @@ describe "Module#prepend" do
|
|||
ScratchPad.recorded.should == [ [ m3, c], [ m2, c ], [ m, c ] ]
|
||||
end
|
||||
|
||||
it "updates the method when a module is prepended" do
|
||||
m_module = Module.new do
|
||||
def foo
|
||||
"m"
|
||||
end
|
||||
end
|
||||
a_class = Class.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
a = a_class.new
|
||||
foo = -> { a.foo }
|
||||
foo.call.should == 'a'
|
||||
a_class.class_eval do
|
||||
prepend m_module
|
||||
end
|
||||
foo.call.should == 'm'
|
||||
end
|
||||
|
||||
it "updates the method when a prepended module is updated" do
|
||||
m_module = Module.new
|
||||
a_class = Class.new do
|
||||
prepend m_module
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
a = a_class.new
|
||||
foo = -> { a.foo }
|
||||
foo.call.should == 'a'
|
||||
m_module.module_eval do
|
||||
def foo
|
||||
"m"
|
||||
end
|
||||
end
|
||||
foo.call.should == 'm'
|
||||
end
|
||||
|
||||
it "updates the method when there is a base included method and the prepended module overrides it" do
|
||||
base_module = Module.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
a_class = Class.new do
|
||||
include base_module
|
||||
end
|
||||
a = a_class.new
|
||||
foo = -> { a.foo }
|
||||
foo.call.should == 'a'
|
||||
|
||||
m_module = Module.new do
|
||||
def foo
|
||||
"m"
|
||||
end
|
||||
end
|
||||
a_class.prepend m_module
|
||||
foo.call.should == 'm'
|
||||
end
|
||||
|
||||
it "updates the method when there is a base included method and the prepended module is later updated" do
|
||||
base_module = Module.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
a_class = Class.new do
|
||||
include base_module
|
||||
end
|
||||
a = a_class.new
|
||||
foo = -> { a.foo }
|
||||
foo.call.should == 'a'
|
||||
|
||||
m_module = Module.new
|
||||
a_class.prepend m_module
|
||||
foo.call.should == 'a'
|
||||
|
||||
m_module.module_eval do
|
||||
def foo
|
||||
"m"
|
||||
end
|
||||
end
|
||||
foo.call.should == 'm'
|
||||
end
|
||||
|
||||
it "updates the method when a module prepended after a call is later updated" do
|
||||
m_module = Module.new
|
||||
a_class = Class.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
a = a_class.new
|
||||
foo = -> { a.foo }
|
||||
foo.call.should == 'a'
|
||||
|
||||
a_class.prepend m_module
|
||||
foo.call.should == 'a'
|
||||
|
||||
m_module.module_eval do
|
||||
def foo
|
||||
"m"
|
||||
end
|
||||
end
|
||||
foo.call.should == 'm'
|
||||
end
|
||||
|
||||
it "updates the method when a module is prepended after another and the method is defined later on that module" do
|
||||
m_module = Module.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
a_class = Class.new
|
||||
a_class.prepend m_module
|
||||
a = a_class.new
|
||||
foo = -> { a.foo }
|
||||
foo.call.should == 'a'
|
||||
|
||||
n_module = Module.new
|
||||
a_class.prepend n_module
|
||||
foo.call.should == 'a'
|
||||
|
||||
n_module.module_eval do
|
||||
def foo
|
||||
"n"
|
||||
end
|
||||
end
|
||||
foo.call.should == 'n'
|
||||
end
|
||||
|
||||
it "updates the method when a module is included in a prepended module and the method is defined later" do
|
||||
a_class = Class.new
|
||||
base_module = Module.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
a_class.prepend base_module
|
||||
a = a_class.new
|
||||
foo = -> { a.foo }
|
||||
foo.call.should == 'a'
|
||||
|
||||
m_module = Module.new
|
||||
n_module = Module.new
|
||||
m_module.include n_module
|
||||
a_class.prepend m_module
|
||||
|
||||
n_module.module_eval do
|
||||
def foo
|
||||
"n"
|
||||
end
|
||||
end
|
||||
foo.call.should == 'n'
|
||||
end
|
||||
|
||||
it "updates the method when a new module with an included module is prepended" do
|
||||
a_class = Class.new do
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
|
||||
n_module = Module.new do
|
||||
def foo
|
||||
'n'
|
||||
end
|
||||
end
|
||||
|
||||
m_module = Module.new do
|
||||
include n_module
|
||||
end
|
||||
|
||||
a = a_class.new
|
||||
foo = -> { a.foo }
|
||||
|
||||
foo.call.should == 'a'
|
||||
|
||||
a_class.class_eval do
|
||||
prepend m_module
|
||||
end
|
||||
|
||||
foo.call.should == 'n'
|
||||
end
|
||||
|
||||
it "raises a TypeError when the argument is not a Module" do
|
||||
-> { ModuleSpecs::Basic.prepend(Class.new) }.should raise_error(TypeError)
|
||||
end
|
||||
|
|
|
@ -43,6 +43,28 @@ describe "Module#remove_method" do
|
|||
x.method_to_remove.should == 1
|
||||
end
|
||||
|
||||
it "updates the method implementation" do
|
||||
m_module = Module.new do
|
||||
def foo
|
||||
'm'
|
||||
end
|
||||
end
|
||||
|
||||
a_class = Class.new do
|
||||
include m_module
|
||||
|
||||
def foo
|
||||
'a'
|
||||
end
|
||||
end
|
||||
|
||||
a = a_class.new
|
||||
foo = -> { a.foo }
|
||||
foo.call.should == 'a'
|
||||
a_class.remove_method(:foo)
|
||||
foo.call.should == 'm'
|
||||
end
|
||||
|
||||
it "removes multiple methods with 1 call" do
|
||||
klass = Class.new do
|
||||
def method_to_remove_1; 1; end
|
||||
|
|
|
@ -7,16 +7,43 @@ describe "ObjectSpace._id2ref" do
|
|||
r.should == s
|
||||
end
|
||||
|
||||
it "retrieves an Integer by object_id" do
|
||||
f = 1
|
||||
r = ObjectSpace._id2ref(f.object_id)
|
||||
r.should == f
|
||||
it "retrieves true by object_id" do
|
||||
ObjectSpace._id2ref(true.object_id).should == true
|
||||
end
|
||||
|
||||
it "retrieves false by object_id" do
|
||||
ObjectSpace._id2ref(false.object_id).should == false
|
||||
end
|
||||
|
||||
it "retrieves nil by object_id" do
|
||||
ObjectSpace._id2ref(nil.object_id).should == nil
|
||||
end
|
||||
|
||||
it "retrieves a small Integer by object_id" do
|
||||
ObjectSpace._id2ref(1.object_id).should == 1
|
||||
ObjectSpace._id2ref((-42).object_id).should == -42
|
||||
end
|
||||
|
||||
it "retrieves a large Integer by object_id" do
|
||||
obj = 1 << 88
|
||||
ObjectSpace._id2ref(obj.object_id).should.equal?(obj)
|
||||
end
|
||||
|
||||
it "retrieves a Symbol by object_id" do
|
||||
s = :sym
|
||||
r = ObjectSpace._id2ref(s.object_id)
|
||||
r.should == s
|
||||
ObjectSpace._id2ref(:sym.object_id).should.equal?(:sym)
|
||||
end
|
||||
|
||||
it "retrieves a String by object_id" do
|
||||
obj = "str"
|
||||
ObjectSpace._id2ref(obj.object_id).should.equal?(obj)
|
||||
end
|
||||
|
||||
it "retrieves a frozen literal String by object_id" do
|
||||
ObjectSpace._id2ref("frozen string literal _id2ref".freeze.object_id).should.equal?("frozen string literal _id2ref".freeze)
|
||||
end
|
||||
|
||||
it "retrieves an Encoding by object_id" do
|
||||
ObjectSpace._id2ref(Encoding::UTF_8.object_id).should.equal?(Encoding::UTF_8)
|
||||
end
|
||||
|
||||
it 'raises RangeError when an object could not be found' do
|
||||
|
|
|
@ -4,7 +4,7 @@ require_relative 'fixtures/classes'
|
|||
# Why do we not test that finalizers are run by the GC? The documentation
|
||||
# says that finalizers are never guaranteed to be run, so we can't
|
||||
# spec that they are. On some implementations of Ruby the finalizers may
|
||||
# run asyncronously, meaning that we can't predict when they'll run,
|
||||
# run asynchronously, meaning that we can't predict when they'll run,
|
||||
# even if they were guaranteed to do so. Even on MRI finalizers can be
|
||||
# very unpredictable, due to conservative stack scanning and references
|
||||
# left in unused memory.
|
||||
|
|
|
@ -2,13 +2,13 @@ require_relative '../../../spec_helper'
|
|||
|
||||
describe "Process::Status#==" do
|
||||
it "returns true when compared to the integer status of an exited child" do
|
||||
ruby_exe("exit(29)")
|
||||
ruby_exe("exit(29)", exit_status: 29)
|
||||
$?.to_i.should == $?
|
||||
$?.should == $?.to_i
|
||||
end
|
||||
|
||||
it "returns true when compared to the integer status of a terminated child" do
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(29)")
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(29)", exit_status: platform_is(:windows) ? 0 : nil)
|
||||
$?.to_i.should == $?
|
||||
$?.should == $?.to_i
|
||||
end
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
require_relative '../../../spec_helper'
|
||||
|
||||
describe "Process::Status#exited?" do
|
||||
|
||||
describe "for a child that exited normally" do
|
||||
|
||||
before :each do
|
||||
ruby_exe("exit(0)")
|
||||
end
|
||||
|
@ -15,9 +13,8 @@ describe "Process::Status#exited?" do
|
|||
|
||||
|
||||
describe "for a terminated child" do
|
||||
|
||||
before :each do
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)")
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)", exit_status: platform_is(:windows) ? 0 : nil)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
|
@ -31,7 +28,5 @@ describe "Process::Status#exited?" do
|
|||
$?.exited?.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ require_relative '../../../spec_helper'
|
|||
|
||||
describe "Process::Status#exitstatus" do
|
||||
before :each do
|
||||
ruby_exe("exit(42)")
|
||||
ruby_exe("exit(42)", exit_status: 42)
|
||||
end
|
||||
|
||||
it "returns the process exit code" do
|
||||
|
@ -11,7 +11,7 @@ describe "Process::Status#exitstatus" do
|
|||
|
||||
describe "for a child that raised SignalException" do
|
||||
before :each do
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)")
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)", exit_status: platform_is(:windows) ? 0 : nil)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
require_relative '../../../spec_helper'
|
||||
|
||||
describe "Process::Status#signaled?" do
|
||||
|
||||
describe "for a cleanly exited child" do
|
||||
|
||||
before :each do
|
||||
ruby_exe("exit(0)")
|
||||
end
|
||||
|
@ -14,9 +12,8 @@ describe "Process::Status#signaled?" do
|
|||
end
|
||||
|
||||
describe "for a terminated child" do
|
||||
|
||||
before :each do
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)")
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)", exit_status: platform_is(:windows) ? 0 : nil)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
|
@ -30,6 +27,5 @@ describe "Process::Status#signaled?" do
|
|||
$?.signaled?.should be_false
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
require_relative '../../../spec_helper'
|
||||
|
||||
describe "Process::Status#success?" do
|
||||
|
||||
describe "for a child that exited normally" do
|
||||
|
||||
before :each do
|
||||
ruby_exe("exit(0)")
|
||||
end
|
||||
|
@ -14,9 +12,8 @@ describe "Process::Status#success?" do
|
|||
end
|
||||
|
||||
describe "for a child that exited with a non zero status" do
|
||||
|
||||
before :each do
|
||||
ruby_exe("exit(42)")
|
||||
ruby_exe("exit(42)", exit_status: 42)
|
||||
end
|
||||
|
||||
it "returns false" do
|
||||
|
@ -25,27 +22,20 @@ describe "Process::Status#success?" do
|
|||
end
|
||||
|
||||
describe "for a child that was terminated" do
|
||||
|
||||
before :each do
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)")
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)", exit_status: platform_is(:windows) ? 0 : nil)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
|
||||
it "returns nil" do
|
||||
$?.success?.should be_nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
platform_is :windows do
|
||||
|
||||
it "always returns true" do
|
||||
$?.success?.should be_true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ describe "Process::Status#termsig" do
|
|||
|
||||
describe "for a child that raised SignalException" do
|
||||
before :each do
|
||||
ruby_exe("raise SignalException, 'SIGTERM'")
|
||||
ruby_exe("raise SignalException, 'SIGTERM'", exit_status: nil)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
|
@ -25,7 +25,7 @@ describe "Process::Status#termsig" do
|
|||
|
||||
describe "for a child that was sent a signal" do
|
||||
before :each do
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)")
|
||||
ruby_exe("Process.kill(:KILL, $$); exit(42)", exit_status: platform_is(:windows) ? 0 : nil)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
|
|
|
@ -2,12 +2,12 @@ require_relative '../../../spec_helper'
|
|||
|
||||
describe "Process::Status#to_i" do
|
||||
it "returns an integer when the child exits" do
|
||||
ruby_exe('exit 48')
|
||||
ruby_exe('exit 48', exit_status: 48)
|
||||
$?.to_i.should be_an_instance_of(Integer)
|
||||
end
|
||||
|
||||
it "returns an integer when the child is signaled" do
|
||||
ruby_exe('raise SignalException, "TERM"')
|
||||
ruby_exe('raise SignalException, "TERM"', exit_status: platform_is(:windows) ? 3 : nil)
|
||||
$?.to_i.should be_an_instance_of(Integer)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -207,11 +207,17 @@ describe "Range#step" do
|
|||
ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5])
|
||||
end
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
it "returns Float values of 'step * n + begin < end'" do
|
||||
(1.0...6.4).step(1.8) { |x| ScratchPad << x }
|
||||
ScratchPad.recorded.should eql([1.0, 2.8, 4.6])
|
||||
end
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
it "correctly handles values near the upper limit" do # https://bugs.ruby-lang.org/issues/16612
|
||||
(1.0...55.6).step(18.2) { |x| ScratchPad << x }
|
||||
ScratchPad.recorded.should eql([1.0, 2.8, 4.6, 1.0, 19.2, 37.4, 55.599999999999994])
|
||||
ScratchPad.recorded.should eql([1.0, 19.2, 37.4, 55.599999999999994])
|
||||
|
||||
(1.0...55.6).step(18.2).size.should == 4
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -459,7 +465,6 @@ describe "Range#step" do
|
|||
(-1.0...1.0).step(0.5).size.should == 4
|
||||
end
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
it "returns the range size when there's no step_size" do
|
||||
(-2..2).step.size.should == 5
|
||||
(-2.0..2.0).step.size.should == 5
|
||||
|
@ -472,8 +477,6 @@ describe "Range#step" do
|
|||
(-2...2.0).step.size.should == 4
|
||||
(-2.0...2).step.size.should == 4
|
||||
(1.0...6.4).step(1.8).size.should == 3
|
||||
(1.0...55.6).step(18.2).size.should == 4
|
||||
end
|
||||
end
|
||||
|
||||
it "returns nil with begin and end are String" do
|
||||
|
|
|
@ -254,7 +254,7 @@ describe "Signal.trap" do
|
|||
r.close
|
||||
loop { w.write("a"*1024) }
|
||||
RUBY
|
||||
out = ruby_exe(code)
|
||||
out = ruby_exe(code, exit_status: nil)
|
||||
status = $?
|
||||
out.should == "nil\n"
|
||||
status.should.signaled?
|
||||
|
|
|
@ -502,5 +502,11 @@ describe "String#inspect" do
|
|||
"\u{3042}".encode("EUC-JP").inspect.should == '"\\x{A4A2}"'
|
||||
end
|
||||
end
|
||||
|
||||
describe "and the string has both ASCII-compatible and ASCII-incompatible chars" do
|
||||
it "returns a string with the non-ASCII characters replaced by \\u notation" do
|
||||
"hello привет".encode("utf-16le").inspect.should == '"hello \\u043F\\u0440\\u0438\\u0432\\u0435\\u0442"'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,6 +11,19 @@ describe "String#rpartition with String" do
|
|||
"hello".rpartition("hello").should == ["", "hello", ""]
|
||||
end
|
||||
|
||||
it "returns original string if regexp doesn't match" do
|
||||
"hello".rpartition("/x/").should == ["", "", "hello"]
|
||||
end
|
||||
|
||||
it "returns new object if doesn't match" do
|
||||
str = "hello"
|
||||
str.rpartition("/no_match/").last.should_not.equal?(str)
|
||||
end
|
||||
|
||||
it "handles multibyte string correctly" do
|
||||
"ユーザ@ドメイン".rpartition(/@/).should == ["ユーザ", "@", "ドメイン"]
|
||||
end
|
||||
|
||||
it "accepts regexp" do
|
||||
"hello!".rpartition(/l./).should == ["hel", "lo", "!"]
|
||||
end
|
||||
|
|
|
@ -461,6 +461,16 @@ describe "String#split with Regexp" do
|
|||
->{ broken_str.split(/\r\n|\r|\n/) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
# See https://bugs.ruby-lang.org/issues/12689 and https://github.com/jruby/jruby/issues/4868
|
||||
it "allows concurrent Regexp calls in a shared context" do
|
||||
str = 'a,b,c,d,e'
|
||||
|
||||
p = proc { str.split(/,/) }
|
||||
results = 10.times.map { Thread.new { x = nil; 100.times { x = p.call }; x } }.map(&:value)
|
||||
|
||||
results.should == [%w[a b c d e]] * 10
|
||||
end
|
||||
|
||||
ruby_version_is "2.6" do
|
||||
context "when a block is given" do
|
||||
it "yields each split substring with default pattern" do
|
||||
|
|
|
@ -10,6 +10,16 @@ describe "Struct#dig" do
|
|||
@instance.dig(:a, :a).should == { b: [1, 2, 3] }
|
||||
end
|
||||
|
||||
it "accepts String keys" do
|
||||
@instance.dig('a', 'a').should == { b: [1, 2, 3] }
|
||||
end
|
||||
|
||||
it "returns the value by the index" do
|
||||
instance = Struct.new(:a, :b).new(:one, :two)
|
||||
instance.dig(0).should == :one
|
||||
instance.dig(1).should == :two
|
||||
end
|
||||
|
||||
it "returns the nested value specified if the sequence includes an index" do
|
||||
@instance.dig(:a, :a, :b, 0).should == 1
|
||||
end
|
||||
|
|
|
@ -101,20 +101,16 @@ module ReturnSpecs
|
|||
# return value will go into val before we run the ensure.
|
||||
#
|
||||
# If lamb's return keeps unwinding incorrectly, val will still
|
||||
# have it's old value.
|
||||
# have its old value.
|
||||
#
|
||||
# We can therefore use val to figure out what happened.
|
||||
begin
|
||||
val = foo()
|
||||
ensure
|
||||
if val != :good
|
||||
return :bad
|
||||
end
|
||||
end
|
||||
|
||||
return val
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class MethodWithBlock
|
||||
def method1
|
||||
|
|
|
@ -48,6 +48,21 @@ describe "Hash literal" do
|
|||
}.should complain(/key :foo is duplicated|duplicated key/)
|
||||
@h.keys.size.should == 1
|
||||
@h.should == {foo: :foo}
|
||||
-> {
|
||||
@h = eval "{%q{a} => :bar, %q{a} => :foo}"
|
||||
}.should complain(/key "a" is duplicated|duplicated key/)
|
||||
@h.keys.size.should == 1
|
||||
@h.should == {%q{a} => :foo}
|
||||
-> {
|
||||
@h = eval "{1000 => :bar, 1000 => :foo}"
|
||||
}.should complain(/key 1000 is duplicated|duplicated key/)
|
||||
@h.keys.size.should == 1
|
||||
@h.should == {1000 => :foo}
|
||||
-> {
|
||||
@h = eval "{1.0 => :bar, 1.0 => :foo}"
|
||||
}.should complain(/key 1.0 is duplicated|duplicated key/)
|
||||
@h.keys.size.should == 1
|
||||
@h.should == {1.0 => :foo}
|
||||
end
|
||||
|
||||
it "accepts a hanging comma" do
|
||||
|
|
|
@ -29,7 +29,7 @@ describe "Source files" do
|
|||
|
||||
touch(path, "wb") { |f| f.write source }
|
||||
begin
|
||||
ruby_exe(path, args: "2>&1").should =~ /invalid multibyte char/
|
||||
ruby_exe(path, args: "2>&1", exit_status: 1).should =~ /invalid multibyte char/
|
||||
ensure
|
||||
rm_r path
|
||||
end
|
||||
|
@ -51,7 +51,7 @@ describe "Source files" do
|
|||
|
||||
touch(path, "wb") { |f| f.write source }
|
||||
begin
|
||||
ruby_exe(path, args: "2>&1").should =~ /invalid multibyte char/
|
||||
ruby_exe(path, args: "2>&1", exit_status: 1).should =~ /invalid multibyte char/
|
||||
ensure
|
||||
rm_r path
|
||||
end
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
require_relative '../../spec_helper'
|
||||
require 'date'
|
||||
require_relative '../../shared/time/strftime_for_date'
|
||||
require_relative '../../shared/time/strftime_for_time'
|
||||
|
|
|
@ -22,6 +22,12 @@ describe 'RbConfig::CONFIG' do
|
|||
File.directory?(archdir).should == true
|
||||
File.should.exist?("#{archdir}/etc.#{RbConfig::CONFIG['DLEXT']}")
|
||||
end
|
||||
|
||||
it "['sitelibdir'] is set and is part of $LOAD_PATH" do
|
||||
sitelibdir = RbConfig::CONFIG['sitelibdir']
|
||||
sitelibdir.should be_kind_of String
|
||||
$LOAD_PATH.should.include? sitelibdir
|
||||
end
|
||||
end
|
||||
|
||||
it "contains no frozen strings even with --enable-frozen-string-literal" do
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
require_relative '../../../spec_helper'
|
||||
require 'rubygems'
|
||||
|
||||
describe "Gem.load_path_insert_index" do
|
||||
guard -> { RbConfig::TOPDIR } do
|
||||
it "is set for an installed an installed Ruby" do
|
||||
Gem.load_path_insert_index.should be_kind_of Integer
|
||||
end
|
||||
end
|
||||
end
|
|
@ -36,6 +36,13 @@ describe "CApiWrappedStruct" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "rb_check_type" do
|
||||
it "does not raise an exception when checking data objects" do
|
||||
a = @s.wrap_struct(1024)
|
||||
@s.rb_check_type(a, a).should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe "DATA_PTR" do
|
||||
it "returns the struct data" do
|
||||
a = @s.wrap_struct(1024)
|
||||
|
|
|
@ -66,6 +66,11 @@ VALUE sws_change_struct(VALUE self, VALUE obj, VALUE new_val) {
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE sws_rb_check_type(VALUE self, VALUE obj, VALUE other) {
|
||||
rb_check_type(obj, TYPE(other));
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
void Init_data_spec(void) {
|
||||
VALUE cls = rb_define_class("CApiAllocSpecs", rb_cObject);
|
||||
rb_define_alloc_func(cls, sdaf_alloc_func);
|
||||
|
@ -76,6 +81,7 @@ void Init_data_spec(void) {
|
|||
rb_define_method(cls, "get_struct_rdata", sws_get_struct_rdata, 1);
|
||||
rb_define_method(cls, "get_struct_data_ptr", sws_get_struct_data_ptr, 1);
|
||||
rb_define_method(cls, "change_struct", sws_change_struct, 2);
|
||||
rb_define_method(cls, "rb_check_type", sws_rb_check_type, 2);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -189,6 +189,11 @@ static VALUE object_spec_RTEST(VALUE self, VALUE value) {
|
|||
return RTEST(value) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
||||
static VALUE so_check_type(VALUE self, VALUE obj, VALUE other) {
|
||||
rb_check_type(obj, TYPE(other));
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
static VALUE so_is_type_nil(VALUE self, VALUE obj) {
|
||||
if(TYPE(obj) == T_NIL) {
|
||||
return Qtrue;
|
||||
|
@ -434,6 +439,7 @@ void Init_object_spec(void) {
|
|||
|
||||
rb_define_method(cls, "rb_to_id", so_to_id, 1);
|
||||
rb_define_method(cls, "RTEST", object_spec_RTEST, 1);
|
||||
rb_define_method(cls, "rb_check_type", so_check_type, 2);
|
||||
rb_define_method(cls, "rb_is_type_nil", so_is_type_nil, 1);
|
||||
rb_define_method(cls, "rb_is_type_object", so_is_type_object, 1);
|
||||
rb_define_method(cls, "rb_is_type_array", so_is_type_array, 1);
|
||||
|
|
|
@ -148,6 +148,11 @@ VALUE sws_typed_change_struct(VALUE self, VALUE obj, VALUE new_val) {
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE sws_typed_rb_check_type(VALUE self, VALUE obj, VALUE other) {
|
||||
rb_check_type(obj, TYPE(other));
|
||||
return Qtrue;
|
||||
}
|
||||
|
||||
VALUE sws_typed_rb_check_typeddata_same_type(VALUE self, VALUE obj) {
|
||||
return rb_check_typeddata(obj, &sample_typed_wrapped_struct_data_type) == DATA_PTR(obj) ? Qtrue : Qfalse;
|
||||
}
|
||||
|
@ -172,6 +177,7 @@ void Init_typed_data_spec(void) {
|
|||
rb_define_method(cls, "typed_get_struct_rdata", sws_typed_get_struct_rdata, 1);
|
||||
rb_define_method(cls, "typed_get_struct_data_ptr", sws_typed_get_struct_data_ptr, 1);
|
||||
rb_define_method(cls, "typed_change_struct", sws_typed_change_struct, 2);
|
||||
rb_define_method(cls, "rb_check_type", sws_typed_rb_check_type, 2);
|
||||
rb_define_method(cls, "rb_check_typeddata_same_type", sws_typed_rb_check_typeddata_same_type, 1);
|
||||
rb_define_method(cls, "rb_check_typeddata_same_type_parent", sws_typed_rb_check_typeddata_same_type_parent, 1);
|
||||
rb_define_method(cls, "rb_check_typeddata_different_type", sws_typed_rb_check_typeddata_different_type, 1);
|
||||
|
|
|
@ -499,20 +499,43 @@ describe "CApiObject" do
|
|||
@o.rb_is_type_array([]).should == true
|
||||
@o.rb_is_type_array(DescArray.new).should == true
|
||||
@o.rb_is_type_module(ObjectTest).should == false
|
||||
@o.rb_is_type_module(Module.new).should == true
|
||||
@o.rb_is_type_class(ObjectTest).should == true
|
||||
@o.rb_is_type_data(Time.now).should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_check_type" do
|
||||
it "checks if the object is of the given type" do
|
||||
@o.rb_check_type(nil, nil).should == true
|
||||
@o.rb_check_type(ObjectTest.new, Object.new).should == true
|
||||
@o.rb_check_type([], []).should == true
|
||||
@o.rb_check_type(Class.new(Array).new, []).should == true
|
||||
@o.rb_check_type(ObjectTest, Object).should == true
|
||||
end
|
||||
|
||||
it "raises an exception if the object is not of the expected type" do
|
||||
-> {
|
||||
@o.rb_check_type([], Object.new)
|
||||
}.should raise_error(TypeError, 'wrong argument type Array (expected Object)')
|
||||
|
||||
-> {
|
||||
@o.rb_check_type(ObjectTest, Module.new)
|
||||
}.should raise_error(TypeError, 'wrong argument type Class (expected Module)')
|
||||
|
||||
-> {
|
||||
@o.rb_check_type(nil, "string")
|
||||
}.should raise_error(TypeError, 'wrong argument type nil (expected String)')
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_type_p" do
|
||||
it "returns whether object is of the given type" do
|
||||
class DescArray < Array
|
||||
end
|
||||
@o.rb_is_rb_type_p_nil(nil).should == true
|
||||
@o.rb_is_rb_type_p_object([]).should == false
|
||||
@o.rb_is_rb_type_p_object(ObjectTest.new).should == true
|
||||
@o.rb_is_rb_type_p_array([]).should == true
|
||||
@o.rb_is_rb_type_p_array(DescArray.new).should == true
|
||||
@o.rb_is_rb_type_p_array(Class.new(Array).new).should == true
|
||||
@o.rb_is_rb_type_p_module(ObjectTest).should == false
|
||||
@o.rb_is_rb_type_p_class(ObjectTest).should == true
|
||||
@o.rb_is_rb_type_p_data(Time.now).should == true
|
||||
|
@ -521,12 +544,10 @@ describe "CApiObject" do
|
|||
|
||||
describe "BUILTIN_TYPE" do
|
||||
it "returns the type constant for the object" do
|
||||
class DescArray < Array
|
||||
end
|
||||
@o.rb_is_builtin_type_object([]).should == false
|
||||
@o.rb_is_builtin_type_object(ObjectTest.new).should == true
|
||||
@o.rb_is_builtin_type_array([]).should == true
|
||||
@o.rb_is_builtin_type_array(DescArray.new).should == true
|
||||
@o.rb_is_builtin_type_array(Class.new(Array).new).should == true
|
||||
@o.rb_is_builtin_type_module(ObjectTest).should == false
|
||||
@o.rb_is_builtin_type_class(ObjectTest).should == true
|
||||
@o.rb_is_builtin_type_data(Time.now).should == true
|
||||
|
|
|
@ -58,6 +58,17 @@ describe "CApiWrappedTypedStruct" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "rb_check_type" do
|
||||
it "raises an exception when checking typed data objects" do
|
||||
-> {
|
||||
a = @s.typed_wrap_struct(1024)
|
||||
@s.rb_check_type(a, a)
|
||||
}.should raise_error(TypeError) { |e|
|
||||
e.message.should == 'wrong argument type Object (expected Data)'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_check_typeddata" do
|
||||
it "returns data pointer when the struct has the given type" do
|
||||
a = @s.typed_wrap_struct(1024)
|
||||
|
|
|
@ -75,25 +75,25 @@ end
|
|||
|
||||
describe :process_exit!, shared: true do
|
||||
it "exits with the given status" do
|
||||
out = ruby_exe("#{@object}.send(:exit!, 21)", args: '2>&1')
|
||||
out = ruby_exe("#{@object}.send(:exit!, 21)", args: '2>&1', exit_status: 21)
|
||||
out.should == ""
|
||||
$?.exitstatus.should == 21
|
||||
end
|
||||
|
||||
it "exits when called from a thread" do
|
||||
out = ruby_exe("Thread.new { #{@object}.send(:exit!, 21) }.join; sleep", args: '2>&1')
|
||||
out = ruby_exe("Thread.new { #{@object}.send(:exit!, 21) }.join; sleep", args: '2>&1', exit_status: 21)
|
||||
out.should == ""
|
||||
$?.exitstatus.should == 21
|
||||
end
|
||||
|
||||
it "exits when called from a fiber" do
|
||||
out = ruby_exe("Fiber.new { #{@object}.send(:exit!, 21) }.resume", args: '2>&1')
|
||||
out = ruby_exe("Fiber.new { #{@object}.send(:exit!, 21) }.resume", args: '2>&1', exit_status: 21)
|
||||
out.should == ""
|
||||
$?.exitstatus.should == 21
|
||||
end
|
||||
|
||||
it "skips at_exit handlers" do
|
||||
out = ruby_exe("at_exit { STDERR.puts 'at_exit' }; #{@object}.send(:exit!, 21)", args: '2>&1')
|
||||
out = ruby_exe("at_exit { STDERR.puts 'at_exit' }; #{@object}.send(:exit!, 21)", args: '2>&1', exit_status: 21)
|
||||
out.should == ""
|
||||
$?.exitstatus.should == 21
|
||||
end
|
||||
|
@ -107,7 +107,7 @@ describe :process_exit!, shared: true do
|
|||
end
|
||||
raise 'original error'
|
||||
RUBY
|
||||
out = ruby_exe(code, args: '2>&1')
|
||||
out = ruby_exe(code, args: '2>&1', exit_status: 21)
|
||||
out.should == "in at_exit\n$! is RuntimeError:original error\n"
|
||||
$?.exitstatus.should == 21
|
||||
end
|
||||
|
|
|
@ -170,4 +170,12 @@ describe :strftime_time, shared: true do
|
|||
time.strftime("%-k%p").should == "8AM"
|
||||
time.strftime("%-l%p").should == "8AM"
|
||||
end
|
||||
|
||||
it "should be able to show default Logger format" do
|
||||
default_logger_format = "%Y-%m-%dT%H:%M:%S.%6N "
|
||||
@new_time[2001, 2, 3, 4, 5, 6].strftime(default_logger_format).should == "2001-02-03T04:05:06.000000 "
|
||||
@new_time[2001, 12, 3, 4, 5, 6 + 1/10r].strftime(default_logger_format).should == "2001-12-03T04:05:06.100000 "
|
||||
@new_time[2001, 2, 13, 4, 5, 6 + 1/100r].strftime(default_logger_format).should == "2001-02-13T04:05:06.010000 "
|
||||
@new_time[2001, 2, 3, 14, 5, 6 + 1/1000r].strftime(default_logger_format).should == "2001-02-03T14:05:06.001000 "
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue