summaryrefslogtreecommitdiff
path: root/spec/ruby/core
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2021-06-02 14:34:07 +0200
committerBenoit Daloze <eregontp@gmail.com>2021-06-02 14:34:07 +0200
commit22e2a6a999b958efe5d84d9c7314e450fda82254 (patch)
treeb2dc946cf2fe2c250d0583675e548c67dca3e71a /spec/ruby/core
parenta4fbc7e2884ba694278adea3b32ddb8c2ac10efe (diff)
Update to ruby/spec@a0b7d0d
Diffstat (limited to 'spec/ruby/core')
-rw-r--r--spec/ruby/core/array/element_set_spec.rb8
-rw-r--r--spec/ruby/core/encoding/replicate_spec.rb21
-rw-r--r--spec/ruby/core/enumerator/lazy/filter_map_spec.rb16
-rw-r--r--spec/ruby/core/exception/signal_exception_spec.rb6
-rw-r--r--spec/ruby/core/exception/system_exit_spec.rb4
-rw-r--r--spec/ruby/core/exception/top_level_spec.rb6
-rw-r--r--spec/ruby/core/fiber/raise_spec.rb20
-rw-r--r--spec/ruby/core/file/atime_spec.rb23
-rw-r--r--spec/ruby/core/file/basename_spec.rb15
-rw-r--r--spec/ruby/core/hash/rehash_spec.rb18
-rw-r--r--spec/ruby/core/io/binmode_spec.rb4
-rw-r--r--spec/ruby/core/io/dup_spec.rb19
-rw-r--r--spec/ruby/core/io/external_encoding_spec.rb5
-rw-r--r--spec/ruby/core/io/internal_encoding_spec.rb5
-rw-r--r--spec/ruby/core/io/lineno_spec.rb36
-rw-r--r--spec/ruby/core/io/set_encoding_by_bom_spec.rb14
-rw-r--r--spec/ruby/core/io/sysread_spec.rb5
-rw-r--r--spec/ruby/core/io/sysseek_spec.rb5
-rw-r--r--spec/ruby/core/kernel/at_exit_spec.rb11
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb65
-rw-r--r--spec/ruby/core/kernel/format_spec.rb1
-rw-r--r--spec/ruby/core/kernel/inspect_spec.rb8
-rw-r--r--spec/ruby/core/kernel/shared/sprintf.rb17
-rw-r--r--spec/ruby/core/module/define_method_spec.rb46
-rw-r--r--spec/ruby/core/module/include_spec.rb142
-rw-r--r--spec/ruby/core/module/prepend_spec.rb186
-rw-r--r--spec/ruby/core/module/remove_method_spec.rb22
-rw-r--r--spec/ruby/core/objectspace/_id2ref_spec.rb41
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb2
-rw-r--r--spec/ruby/core/process/status/equal_value_spec.rb4
-rw-r--r--spec/ruby/core/process/status/exited_spec.rb7
-rw-r--r--spec/ruby/core/process/status/exitstatus_spec.rb4
-rw-r--r--spec/ruby/core/process/status/signaled_spec.rb6
-rw-r--r--spec/ruby/core/process/status/success_spec.rb14
-rw-r--r--spec/ruby/core/process/status/termsig_spec.rb4
-rw-r--r--spec/ruby/core/process/status/to_i_spec.rb4
-rw-r--r--spec/ruby/core/range/step_spec.rb39
-rw-r--r--spec/ruby/core/signal/trap_spec.rb2
-rw-r--r--spec/ruby/core/string/inspect_spec.rb6
-rw-r--r--spec/ruby/core/string/rpartition_spec.rb13
-rw-r--r--spec/ruby/core/string/split_spec.rb10
-rw-r--r--spec/ruby/core/struct/dig_spec.rb10
42 files changed, 784 insertions, 110 deletions
diff --git a/spec/ruby/core/array/element_set_spec.rb b/spec/ruby/core/array/element_set_spec.rb
index 1c143f3e37..07c64b919e 100644
--- a/spec/ruby/core/array/element_set_spec.rb
+++ b/spec/ruby/core/array/element_set_spec.rb
@@ -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
diff --git a/spec/ruby/core/encoding/replicate_spec.rb b/spec/ruby/core/encoding/replicate_spec.rb
index 717e9cea72..45727a5c0d 100644
--- a/spec/ruby/core/encoding/replicate_spec.rb
+++ b/spec/ruby/core/encoding/replicate_spec.rb
@@ -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
diff --git a/spec/ruby/core/enumerator/lazy/filter_map_spec.rb b/spec/ruby/core/enumerator/lazy/filter_map_spec.rb
new file mode 100644
index 0000000000..3480af0865
--- /dev/null
+++ b/spec/ruby/core/enumerator/lazy/filter_map_spec.rb
@@ -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
diff --git a/spec/ruby/core/exception/signal_exception_spec.rb b/spec/ruby/core/exception/signal_exception_spec.rb
index e494e18cde..2d2179a628 100644
--- a/spec/ruby/core/exception/signal_exception_spec.rb
+++ b/spec/ruby/core/exception/signal_exception_spec.rb
@@ -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
diff --git a/spec/ruby/core/exception/system_exit_spec.rb b/spec/ruby/core/exception/system_exit_spec.rb
index 5c6116576b..eef9faf271 100644
--- a/spec/ruby/core/exception/system_exit_spec.rb
+++ b/spec/ruby/core/exception/system_exit_spec.rb
@@ -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
diff --git a/spec/ruby/core/exception/top_level_spec.rb b/spec/ruby/core/exception/top_level_spec.rb
index 501c7253c3..5c4514f694 100644
--- a/spec/ruby/core/exception/top_level_spec.rb
+++ b/spec/ruby/core/exception/top_level_spec.rb
@@ -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
diff --git a/spec/ruby/core/fiber/raise_spec.rb b/spec/ruby/core/fiber/raise_spec.rb
index f56219e565..2a465c8bfa 100644
--- a/spec/ruby/core/fiber/raise_spec.rb
+++ b/spec/ruby/core/fiber/raise_spec.rb
@@ -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
diff --git a/spec/ruby/core/file/atime_spec.rb b/spec/ruby/core/file/atime_spec.rb
index 047bb0e10e..cef07ba010 100644
--- a/spec/ruby/core/file/atime_spec.rb
+++ b/spec/ruby/core/file/atime_spec.rb
@@ -16,20 +16,17 @@ describe "File.atime" do
end
platform_is :linux, :windows do
- ## 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'
+ 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
+ File.atime(@file).usec.should == expected_time.usec
+ else
+ File.atime(__FILE__).usec.should == 0
end
- File.atime(@file).usec.should == expected_time.usec
- else
- File.atime(__FILE__).usec.should == 0
end
end
end
diff --git a/spec/ruby/core/file/basename_spec.rb b/spec/ruby/core/file/basename_spec.rb
index 6d7e432086..989409d76b 100644
--- a/spec/ruby/core/file/basename_spec.rb
+++ b/spec/ruby/core/file/basename_spec.rb
@@ -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
diff --git a/spec/ruby/core/hash/rehash_spec.rb b/spec/ruby/core/hash/rehash_spec.rb
index ff7b644786..0049080456 100644
--- a/spec/ruby/core/hash/rehash_spec.rb
+++ b/spec/ruby/core/hash/rehash_spec.rb
@@ -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)
diff --git a/spec/ruby/core/io/binmode_spec.rb b/spec/ruby/core/io/binmode_spec.rb
index b698777cad..342cac2a9b 100644
--- a/spec/ruby/core/io/binmode_spec.rb
+++ b/spec/ruby/core/io/binmode_spec.rb
@@ -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
diff --git a/spec/ruby/core/io/dup_spec.rb b/spec/ruby/core/io/dup_spec.rb
index 8cadaee118..68d538377f 100644
--- a/spec/ruby/core/io/dup_spec.rb
+++ b/spec/ruby/core/io/dup_spec.rb
@@ -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
diff --git a/spec/ruby/core/io/external_encoding_spec.rb b/spec/ruby/core/io/external_encoding_spec.rb
index 9666974647..c1b727d930 100644
--- a/spec/ruby/core/io/external_encoding_spec.rb
+++ b/spec/ruby/core/io/external_encoding_spec.rb
@@ -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
diff --git a/spec/ruby/core/io/internal_encoding_spec.rb b/spec/ruby/core/io/internal_encoding_spec.rb
index 10ebf28707..210e969c7b 100644
--- a/spec/ruby/core/io/internal_encoding_spec.rb
+++ b/spec/ruby/core/io/internal_encoding_spec.rb
@@ -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
diff --git a/spec/ruby/core/io/lineno_spec.rb b/spec/ruby/core/io/lineno_spec.rb
index 3d1b2275cc..99266ecca1 100644
--- a/spec/ruby/core/io/lineno_spec.rb
+++ b/spec/ruby/core/io/lineno_spec.rb
@@ -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)
diff --git a/spec/ruby/core/io/set_encoding_by_bom_spec.rb b/spec/ruby/core/io/set_encoding_by_bom_spec.rb
index b8e4eedcb9..c551042bee 100644
--- a/spec/ruby/core/io/set_encoding_by_bom_spec.rb
+++ b/spec/ruby/core/io/set_encoding_by_bom_spec.rb
@@ -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")
diff --git a/spec/ruby/core/io/sysread_spec.rb b/spec/ruby/core/io/sysread_spec.rb
index 024200efea..8201ad47ca 100644
--- a/spec/ruby/core/io/sysread_spec.rb
+++ b/spec/ruby/core/io/sysread_spec.rb
@@ -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"
diff --git a/spec/ruby/core/io/sysseek_spec.rb b/spec/ruby/core/io/sysseek_spec.rb
index df894734e3..e631939bce 100644
--- a/spec/ruby/core/io/sysseek_spec.rb
+++ b/spec/ruby/core/io/sysseek_spec.rb
@@ -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"
diff --git a/spec/ruby/core/kernel/at_exit_spec.rb b/spec/ruby/core/kernel/at_exit_spec.rb
index 7bdb5391fe..a784c1ae17 100644
--- a/spec/ruby/core/kernel/at_exit_spec.rb
+++ b/spec/ruby/core/kernel/at_exit_spec.rb
@@ -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")
diff --git a/spec/ruby/core/kernel/eval_spec.rb b/spec/ruby/core/kernel/eval_spec.rb
index c53e51e430..1e2764a4de 100644
--- a/spec/ruby/core/kernel/eval_spec.rb
+++ b/spec/ruby/core/kernel/eval_spec.rb
@@ -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,43 +385,45 @@ CODE
end
end
- it "activates refinements from the eval scope" do
- refinery = Module.new do
- refine EvalSpecs::A do
- def foo
- "bar"
+ describe 'with refinements' do
+ it "activates refinements from the eval scope" do
+ refinery = Module.new do
+ refine EvalSpecs::A do
+ def foo
+ "bar"
+ end
end
end
- end
- result = nil
+ result = nil
- Module.new do
- using refinery
+ Module.new do
+ using refinery
- result = eval "EvalSpecs::A.new.foo"
- end
+ result = eval "EvalSpecs::A.new.foo"
+ end
- result.should == "bar"
- end
+ result.should == "bar"
+ end
- it "activates refinements from the binding" do
- refinery = Module.new do
- refine EvalSpecs::A do
- def foo
- "bar"
+ it "activates refinements from the binding" do
+ refinery = Module.new do
+ refine EvalSpecs::A do
+ def foo
+ "bar"
+ end
end
end
- end
- b = nil
- m = Module.new do
- using refinery
- b = binding
- end
+ b = nil
+ m = Module.new do
+ using refinery
+ b = binding
+ end
- result = eval "EvalSpecs::A.new.foo", b
+ result = eval "EvalSpecs::A.new.foo", b
- result.should == "bar"
+ result.should == "bar"
+ end
end
end
diff --git a/spec/ruby/core/kernel/format_spec.rb b/spec/ruby/core/kernel/format_spec.rb
index 72fd40b952..e8b031e480 100644
--- a/spec/ruby/core/kernel/format_spec.rb
+++ b/spec/ruby/core/kernel/format_spec.rb
@@ -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)
diff --git a/spec/ruby/core/kernel/inspect_spec.rb b/spec/ruby/core/kernel/inspect_spec.rb
index a946d032db..e6fca8bf6f 100644
--- a/spec/ruby/core/kernel/inspect_spec.rb
+++ b/spec/ruby/core/kernel/inspect_spec.rb
@@ -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
diff --git a/spec/ruby/core/kernel/shared/sprintf.rb b/spec/ruby/core/kernel/shared/sprintf.rb
index ca1e6bb2ed..6d62a65f7c 100644
--- a/spec/ruby/core/kernel/shared/sprintf.rb
+++ b/spec/ruby/core/kernel/shared/sprintf.rb
@@ -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
diff --git a/spec/ruby/core/module/define_method_spec.rb b/spec/ruby/core/module/define_method_spec.rb
index 49472c18e1..0cb2ab140c 100644
--- a/spec/ruby/core/module/define_method_spec.rb
+++ b/spec/ruby/core/module/define_method_spec.rb
@@ -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
diff --git a/spec/ruby/core/module/include_spec.rb b/spec/ruby/core/module/include_spec.rb
index e7f99a5981..c7ead1079c 100644
--- a/spec/ruby/core/module/include_spec.rb
+++ b/spec/ruby/core/module/include_spec.rb
@@ -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
diff --git a/spec/ruby/core/module/prepend_spec.rb b/spec/ruby/core/module/prepend_spec.rb
index a501b5e50c..f11ca1b8b6 100644
--- a/spec/ruby/core/module/prepend_spec.rb
+++ b/spec/ruby/core/module/prepend_spec.rb
@@ -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
diff --git a/spec/ruby/core/module/remove_method_spec.rb b/spec/ruby/core/module/remove_method_spec.rb
index b6ae02078f..94b255df62 100644
--- a/spec/ruby/core/module/remove_method_spec.rb
+++ b/spec/ruby/core/module/remove_method_spec.rb
@@ -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
diff --git a/spec/ruby/core/objectspace/_id2ref_spec.rb b/spec/ruby/core/objectspace/_id2ref_spec.rb
index 6e8828348e..c088ae2743 100644
--- a/spec/ruby/core/objectspace/_id2ref_spec.rb
+++ b/spec/ruby/core/objectspace/_id2ref_spec.rb
@@ -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
diff --git a/spec/ruby/core/objectspace/define_finalizer_spec.rb b/spec/ruby/core/objectspace/define_finalizer_spec.rb
index ed021b7131..281785b0a4 100644
--- a/spec/ruby/core/objectspace/define_finalizer_spec.rb
+++ b/spec/ruby/core/objectspace/define_finalizer_spec.rb
@@ -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.
diff --git a/spec/ruby/core/process/status/equal_value_spec.rb b/spec/ruby/core/process/status/equal_value_spec.rb
index 444ce1775b..d85bb22214 100644
--- a/spec/ruby/core/process/status/equal_value_spec.rb
+++ b/spec/ruby/core/process/status/equal_value_spec.rb
@@ -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
diff --git a/spec/ruby/core/process/status/exited_spec.rb b/spec/ruby/core/process/status/exited_spec.rb
index 0ae3f9e7ae..059cd5b1aa 100644
--- a/spec/ruby/core/process/status/exited_spec.rb
+++ b/spec/ruby/core/process/status/exited_spec.rb
@@ -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
diff --git a/spec/ruby/core/process/status/exitstatus_spec.rb b/spec/ruby/core/process/status/exitstatus_spec.rb
index d6c6965b9e..3087bd619e 100644
--- a/spec/ruby/core/process/status/exitstatus_spec.rb
+++ b/spec/ruby/core/process/status/exitstatus_spec.rb
@@ -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
diff --git a/spec/ruby/core/process/status/signaled_spec.rb b/spec/ruby/core/process/status/signaled_spec.rb
index f23c95025f..389092a533 100644
--- a/spec/ruby/core/process/status/signaled_spec.rb
+++ b/spec/ruby/core/process/status/signaled_spec.rb
@@ -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
diff --git a/spec/ruby/core/process/status/success_spec.rb b/spec/ruby/core/process/status/success_spec.rb
index 28a1721800..c531121f08 100644
--- a/spec/ruby/core/process/status/success_spec.rb
+++ b/spec/ruby/core/process/status/success_spec.rb
@@ -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
diff --git a/spec/ruby/core/process/status/termsig_spec.rb b/spec/ruby/core/process/status/termsig_spec.rb
index 204708bc1b..1c87a6f455 100644
--- a/spec/ruby/core/process/status/termsig_spec.rb
+++ b/spec/ruby/core/process/status/termsig_spec.rb
@@ -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
diff --git a/spec/ruby/core/process/status/to_i_spec.rb b/spec/ruby/core/process/status/to_i_spec.rb
index a284f64f86..7cde9b915b 100644
--- a/spec/ruby/core/process/status/to_i_spec.rb
+++ b/spec/ruby/core/process/status/to_i_spec.rb
@@ -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
diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb
index 1c2e30742c..be4b482654 100644
--- a/spec/ruby/core/range/step_spec.rb
+++ b/spec/ruby/core/range/step_spec.rb
@@ -207,11 +207,17 @@ describe "Range#step" do
ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5])
end
+ 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 "returns Float values of 'step * n + begin < end'" do
- (1.0...6.4).step(1.8) { |x| ScratchPad << x }
+ 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,21 +465,18 @@ 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
- (-2..2.0).step.size.should == 5
- (-2.0..2).step.size.should == 5
- (1.0..6.4).step(1.8).size.should == 4
- (1.0..12.7).step(1.3).size.should == 10
- (-2...2).step.size.should == 4
- (-2.0...2.0).step.size.should == 4
- (-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
+ 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
+ (-2..2.0).step.size.should == 5
+ (-2.0..2).step.size.should == 5
+ (1.0..6.4).step(1.8).size.should == 4
+ (1.0..12.7).step(1.3).size.should == 10
+ (-2...2).step.size.should == 4
+ (-2.0...2.0).step.size.should == 4
+ (-2...2.0).step.size.should == 4
+ (-2.0...2).step.size.should == 4
+ (1.0...6.4).step(1.8).size.should == 3
end
it "returns nil with begin and end are String" do
diff --git a/spec/ruby/core/signal/trap_spec.rb b/spec/ruby/core/signal/trap_spec.rb
index 61d39cfa93..3c78922694 100644
--- a/spec/ruby/core/signal/trap_spec.rb
+++ b/spec/ruby/core/signal/trap_spec.rb
@@ -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?
diff --git a/spec/ruby/core/string/inspect_spec.rb b/spec/ruby/core/string/inspect_spec.rb
index 9818796c83..98b5b32b61 100644
--- a/spec/ruby/core/string/inspect_spec.rb
+++ b/spec/ruby/core/string/inspect_spec.rb
@@ -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
diff --git a/spec/ruby/core/string/rpartition_spec.rb b/spec/ruby/core/string/rpartition_spec.rb
index c6428636f6..fc37f8b427 100644
--- a/spec/ruby/core/string/rpartition_spec.rb
+++ b/spec/ruby/core/string/rpartition_spec.rb
@@ -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
diff --git a/spec/ruby/core/string/split_spec.rb b/spec/ruby/core/string/split_spec.rb
index 2ebfe1e353..e3641b33e0 100644
--- a/spec/ruby/core/string/split_spec.rb
+++ b/spec/ruby/core/string/split_spec.rb
@@ -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
diff --git a/spec/ruby/core/struct/dig_spec.rb b/spec/ruby/core/struct/dig_spec.rb
index 4e39e5a4ef..93a52dbbe1 100644
--- a/spec/ruby/core/struct/dig_spec.rb
+++ b/spec/ruby/core/struct/dig_spec.rb
@@ -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