summaryrefslogtreecommitdiff
path: root/spec/ruby/core
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core')
-rw-r--r--spec/ruby/core/argf/readpartial_spec.rb2
-rw-r--r--spec/ruby/core/array/bsearch_index_spec.rb4
-rw-r--r--spec/ruby/core/dir/glob_spec.rb10
-rw-r--r--spec/ruby/core/exception/detailed_message_spec.rb12
-rw-r--r--spec/ruby/core/exception/full_message_spec.rb40
-rw-r--r--spec/ruby/core/file/flock_spec.rb4
-rw-r--r--spec/ruby/core/file/new_spec.rb6
-rw-r--r--spec/ruby/core/file/shared/fnmatch.rb47
-rw-r--r--spec/ruby/core/io/copy_stream_spec.rb33
-rw-r--r--spec/ruby/core/io/gets_spec.rb6
-rw-r--r--spec/ruby/core/io/new_spec.rb6
-rw-r--r--spec/ruby/core/io/open_spec.rb13
-rw-r--r--spec/ruby/core/io/pread_spec.rb77
-rw-r--r--spec/ruby/core/io/pwrite_spec.rb30
-rw-r--r--spec/ruby/core/io/read_spec.rb18
-rw-r--r--spec/ruby/core/io/shared/each.rb4
-rw-r--r--spec/ruby/core/kernel/exec_spec.rb4
-rw-r--r--spec/ruby/core/kernel/printf_spec.rb7
-rw-r--r--spec/ruby/core/kernel/shared/load.rb38
-rw-r--r--spec/ruby/core/kernel/shared/require.rb28
-rw-r--r--spec/ruby/core/kernel/sleep_spec.rb1
-rw-r--r--spec/ruby/core/kernel/sprintf_spec.rb16
-rw-r--r--spec/ruby/core/matchdata/values_at_spec.rb4
-rw-r--r--spec/ruby/core/method/super_method_spec.rb10
-rw-r--r--spec/ruby/core/module/define_method_spec.rb8
-rw-r--r--spec/ruby/core/process/constants_spec.rb8
-rw-r--r--spec/ruby/core/process/exec_spec.rb42
-rw-r--r--spec/ruby/core/regexp/union_spec.rb51
-rw-r--r--spec/ruby/core/signal/signame_spec.rb12
-rw-r--r--spec/ruby/core/signal/trap_spec.rb19
-rw-r--r--spec/ruby/core/string/start_with_spec.rb9
-rw-r--r--spec/ruby/core/string/uplus_spec.rb3
-rw-r--r--spec/ruby/core/unboundmethod/super_method_spec.rb10
-rw-r--r--spec/ruby/core/warning/element_reference_spec.rb8
34 files changed, 480 insertions, 110 deletions
diff --git a/spec/ruby/core/argf/readpartial_spec.rb b/spec/ruby/core/argf/readpartial_spec.rb
index 5e284b3423..bbc8831131 100644
--- a/spec/ruby/core/argf/readpartial_spec.rb
+++ b/spec/ruby/core/argf/readpartial_spec.rb
@@ -69,7 +69,7 @@ describe "ARGF.readpartial" do
print ARGF.readpartial(#{@stdin.size})
ARGF.readpartial(1) rescue print $!.class
STR
- stdin = ruby_exe(ruby_str, args: "< #{@stdin_name}", escape: true)
+ stdin = ruby_exe(ruby_str, args: "< #{@stdin_name}")
stdin.should == @stdin + "EOFError"
end
end
diff --git a/spec/ruby/core/array/bsearch_index_spec.rb b/spec/ruby/core/array/bsearch_index_spec.rb
index df2c7c098e..94d85b37f3 100644
--- a/spec/ruby/core/array/bsearch_index_spec.rb
+++ b/spec/ruby/core/array/bsearch_index_spec.rb
@@ -63,10 +63,6 @@ describe "Array#bsearch_index" do
@array.bsearch_index { |x| -1 }.should be_nil
end
- it "returns the middle element when block always returns zero" do
- @array.bsearch_index { |x| 0 }.should == 2
- end
-
context "magnitude does not effect the result" do
it "returns the index of any matched elements where element is between 4n <= xn < 8n" do
[1, 2].should include(@array.bsearch_index { |x| (1 - x / 4) * (2**100) })
diff --git a/spec/ruby/core/dir/glob_spec.rb b/spec/ruby/core/dir/glob_spec.rb
index 61115b5eec..32f515c81d 100644
--- a/spec/ruby/core/dir/glob_spec.rb
+++ b/spec/ruby/core/dir/glob_spec.rb
@@ -106,11 +106,11 @@ describe "Dir.glob" do
ruby_version_is '3.1' do
it "recursively matches files and directories in nested dot subdirectory except . with 'nested/**/*' from the current directory and option File::FNM_DOTMATCH" do
expected = %w[
- nested/.
- nested/.dotsubir
- nested/.dotsubir/.dotfile
- nested/.dotsubir/nondotfile
- ]
+ nested/.
+ nested/.dotsubir
+ nested/.dotsubir/.dotfile
+ nested/.dotsubir/nondotfile
+ ]
Dir.glob('nested/**/*', File::FNM_DOTMATCH).sort.should == expected.sort
end
diff --git a/spec/ruby/core/exception/detailed_message_spec.rb b/spec/ruby/core/exception/detailed_message_spec.rb
index bd85927dbe..fbe4443daa 100644
--- a/spec/ruby/core/exception/detailed_message_spec.rb
+++ b/spec/ruby/core/exception/detailed_message_spec.rb
@@ -7,6 +7,14 @@ describe "Exception#detailed_message" do
RuntimeError.new("new error").detailed_message.should == "new error (RuntimeError)"
end
+ it "is called by #full_message to allow message customization" do
+ exception = Exception.new("new error")
+ def exception.detailed_message(**)
+ "<prefix>#{message}<suffix>"
+ end
+ exception.full_message(highlight: false).should.include? "<prefix>new error<suffix>"
+ end
+
it "accepts highlight keyword argument and adds escape control sequences" do
RuntimeError.new("new error").detailed_message(highlight: true).should == "\e[1mnew error (\e[1;4mRuntimeError\e[m\e[1m)\e[m"
end
@@ -23,13 +31,13 @@ describe "Exception#detailed_message" do
RuntimeError.new("").detailed_message.should == "unhandled exception"
end
- it "returns just class name for an instance of RuntimeError sublass with empty message" do
+ it "returns just class name for an instance of RuntimeError subclass with empty message" do
DetailedMessageSpec::C.new("").detailed_message.should == "DetailedMessageSpec::C"
end
it "returns a generated class name for an instance of RuntimeError anonymous subclass with empty message" do
klass = Class.new(RuntimeError)
- klass.new("").detailed_message.should =~ /\A#<Class:0x\h+>\z/
+ klass.new("").detailed_message.should =~ /\A#<Class:0x\h+>\z/
end
end
end
diff --git a/spec/ruby/core/exception/full_message_spec.rb b/spec/ruby/core/exception/full_message_spec.rb
index ee66582022..e15649ca75 100644
--- a/spec/ruby/core/exception/full_message_spec.rb
+++ b/spec/ruby/core/exception/full_message_spec.rb
@@ -107,21 +107,49 @@ describe "Exception#full_message" do
ruby_version_is "3.2" do
it "relies on #detailed_message" do
e = RuntimeError.new("new error")
- e.define_singleton_method(:detailed_message) { |**opt| "DETAILED MESSAGE" }
+ e.define_singleton_method(:detailed_message) { |**| "DETAILED MESSAGE" }
e.full_message.lines.first.should =~ /DETAILED MESSAGE/
end
- it "passes all its own keyword arguments to #detailed_message" do
+ it "passes all its own keyword arguments (with :highlight default value and without :order default value) to #detailed_message" do
e = RuntimeError.new("new error")
- opt_ = nil
- e.define_singleton_method(:detailed_message) do |**opt|
- opt_ = opt
+ options_passed = nil
+ e.define_singleton_method(:detailed_message) do |**options|
+ options_passed = options
"DETAILED MESSAGE"
end
e.full_message(foo: "bar")
- opt_.should == { foo: "bar", highlight: Exception.to_tty? }
+ options_passed.should == { foo: "bar", highlight: Exception.to_tty? }
+ end
+
+ it "converts #detailed_message returned value to String if it isn't a String" do
+ message = Object.new
+ def message.to_str; "DETAILED MESSAGE"; end
+
+ e = RuntimeError.new("new error")
+ e.define_singleton_method(:detailed_message) { |**| message }
+
+ e.full_message.lines.first.should =~ /DETAILED MESSAGE/
+ end
+
+ it "uses class name if #detailed_message returns nil" do
+ e = RuntimeError.new("new error")
+ e.define_singleton_method(:detailed_message) { |**| nil }
+
+ e.full_message(highlight: false).lines.first.should =~ /RuntimeError/
+ e.full_message(highlight: true).lines.first.should =~ /#{Regexp.escape("\e[1;4mRuntimeError\e[m")}/
+ end
+
+ it "uses class name if exception object doesn't respond to #detailed_message" do
+ e = RuntimeError.new("new error")
+ class << e
+ undef :detailed_message
+ end
+
+ e.full_message(highlight: false).lines.first.should =~ /RuntimeError/
+ e.full_message(highlight: true).lines.first.should =~ /#{Regexp.escape("\e[1;4mRuntimeError\e[m")}/
end
end
end
diff --git a/spec/ruby/core/file/flock_spec.rb b/spec/ruby/core/file/flock_spec.rb
index 751e99d994..070d830bc4 100644
--- a/spec/ruby/core/file/flock_spec.rb
+++ b/spec/ruby/core/file/flock_spec.rb
@@ -30,7 +30,7 @@ describe "File#flock" do
it "returns false if trying to lock an exclusively locked file" do
@file.flock File::LOCK_EX
- ruby_exe(<<-END_OF_CODE, escape: true).should == "false"
+ ruby_exe(<<-END_OF_CODE).should == "false"
File.open('#{@name}', "w") do |f2|
print f2.flock(File::LOCK_EX | File::LOCK_NB).to_s
end
@@ -40,7 +40,7 @@ describe "File#flock" do
it "blocks if trying to lock an exclusively locked file" do
@file.flock File::LOCK_EX
- out = ruby_exe(<<-END_OF_CODE, escape: true)
+ out = ruby_exe(<<-END_OF_CODE)
running = false
t = Thread.new do
diff --git a/spec/ruby/core/file/new_spec.rb b/spec/ruby/core/file/new_spec.rb
index 715ac1aaf3..3e2641aed3 100644
--- a/spec/ruby/core/file/new_spec.rb
+++ b/spec/ruby/core/file/new_spec.rb
@@ -188,6 +188,12 @@ describe "File.new" do
}.should raise_error(Errno::EEXIST, /File exists/)
end
+ it "does not use the given block and warns to use File::open" do
+ -> {
+ @fh = File.new(@file) { raise }
+ }.should complain(/warning: File::new\(\) does not take block; use File::open\(\) instead/)
+ end
+
it "raises a TypeError if the first parameter can't be coerced to a string" do
-> { File.new(true) }.should raise_error(TypeError)
-> { File.new(false) }.should raise_error(TypeError)
diff --git a/spec/ruby/core/file/shared/fnmatch.rb b/spec/ruby/core/file/shared/fnmatch.rb
index 94f22144b0..db4b5c5d8c 100644
--- a/spec/ruby/core/file/shared/fnmatch.rb
+++ b/spec/ruby/core/file/shared/fnmatch.rb
@@ -102,6 +102,7 @@ describe :file_fnmatch, shared: true do
it "matches ranges of characters using exclusive bracket expression (e.g. [^t] or [!t])" do
File.send(@method, 'ca[^t]', 'cat').should == false
+ File.send(@method, 'ca[^t]', 'cas').should == true
File.send(@method, 'ca[!t]', 'cat').should == false
end
@@ -125,6 +126,13 @@ describe :file_fnmatch, shared: true do
end
end
+ it "matches wildcard with characters when flags includes FNM_PATHNAME" do
+ File.send(@method, '*a', 'aa', File::FNM_PATHNAME).should == true
+ File.send(@method, 'a*', 'aa', File::FNM_PATHNAME).should == true
+ File.send(@method, 'a*', 'aaa', File::FNM_PATHNAME).should == true
+ File.send(@method, '*a', 'aaa', File::FNM_PATHNAME).should == true
+ end
+
it "does not match '/' characters with ? or * when flags includes FNM_PATHNAME" do
File.send(@method, '?', '/', File::FNM_PATHNAME).should == false
File.send(@method, '*', '/', File::FNM_PATHNAME).should == false
@@ -165,9 +173,19 @@ describe :file_fnmatch, shared: true do
File.should_not.send(@method, '*/*', 'dave/.profile', File::FNM_PATHNAME)
end
- it "matches patterns with leading periods to dotfiles by default" do
+ it "matches patterns with leading periods to dotfiles" do
File.send(@method, '.*', '.profile').should == true
+ File.send(@method, '.*', '.profile', File::FNM_PATHNAME).should == true
File.send(@method, ".*file", "nondotfile").should == false
+ File.send(@method, ".*file", "nondotfile", File::FNM_PATHNAME).should == false
+ end
+
+ it "does not match directories with leading periods by default with FNM_PATHNAME" do
+ File.send(@method, '.*', '.directory/nondotfile', File::FNM_PATHNAME).should == false
+ File.send(@method, '.*', '.directory/.profile', File::FNM_PATHNAME).should == false
+ File.send(@method, '.*', 'foo/.directory/nondotfile', File::FNM_PATHNAME).should == false
+ File.send(@method, '.*', 'foo/.directory/.profile', File::FNM_PATHNAME).should == false
+ File.send(@method, '**/.dotfile', '.dotsubdir/.dotfile', File::FNM_PATHNAME).should == false
end
it "matches leading periods in filenames when flags includes FNM_DOTMATCH" do
@@ -221,6 +239,33 @@ describe :file_fnmatch, shared: true do
File.send(@method, pattern, 'a/.b/c/foo', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
end
+ it "has special handling for ./ when using * and FNM_PATHNAME" do
+ File.send(@method, './*', '.', File::FNM_PATHNAME).should be_false
+ File.send(@method, './*', './', File::FNM_PATHNAME).should be_true
+ File.send(@method, './*/', './', File::FNM_PATHNAME).should be_false
+ File.send(@method, './**', './', File::FNM_PATHNAME).should be_true
+ File.send(@method, './**/', './', File::FNM_PATHNAME).should be_true
+ File.send(@method, './*', '.', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_false
+ File.send(@method, './*', './', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
+ File.send(@method, './*/', './', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_false
+ File.send(@method, './**', './', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
+ File.send(@method, './**/', './', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
+ end
+
+ it "matches **/* with FNM_PATHNAME to recurse directories" do
+ File.send(@method, 'nested/**/*', 'nested/subdir', File::FNM_PATHNAME).should be_true
+ File.send(@method, 'nested/**/*', 'nested/subdir/file', File::FNM_PATHNAME).should be_true
+ File.send(@method, 'nested/**/*', 'nested/.dotsubdir', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
+ File.send(@method, 'nested/**/*', 'nested/.dotsubir/.dotfile', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
+ end
+
+ it "matches ** with FNM_PATHNAME only in current directory" do
+ File.send(@method, 'nested/**', 'nested/subdir', File::FNM_PATHNAME).should be_true
+ File.send(@method, 'nested/**', 'nested/subdir/file', File::FNM_PATHNAME).should be_false
+ File.send(@method, 'nested/**', 'nested/.dotsubdir', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_true
+ File.send(@method, 'nested/**', 'nested/.dotsubir/.dotfile', File::FNM_PATHNAME | File::FNM_DOTMATCH).should be_false
+ end
+
it "accepts an object that has a #to_path method" do
File.send(@method, '\*', mock_to_path('a')).should == false
end
diff --git a/spec/ruby/core/io/copy_stream_spec.rb b/spec/ruby/core/io/copy_stream_spec.rb
index df9c5c7390..ffa2ea992c 100644
--- a/spec/ruby/core/io/copy_stream_spec.rb
+++ b/spec/ruby/core/io/copy_stream_spec.rb
@@ -69,9 +69,12 @@ describe :io_copy_stream_to_io, shared: true do
end
it "raises an IOError if the destination IO is not open for writing" do
- @to_io.close
- @to_io = new_io @to_name, "r"
- -> { IO.copy_stream @object.from, @to_io }.should raise_error(IOError)
+ to_io = new_io __FILE__, "r"
+ begin
+ -> { IO.copy_stream @object.from, to_io }.should raise_error(IOError)
+ ensure
+ to_io.close
+ end
end
it "does not close the destination IO" do
@@ -109,7 +112,8 @@ describe "IO.copy_stream" do
end
after :each do
- rm_r @to_name, @from_bigfile
+ rm_r @to_name if @to_name
+ rm_r @from_bigfile
end
describe "from an IO" do
@@ -164,6 +168,25 @@ describe "IO.copy_stream" do
it_behaves_like :io_copy_stream_to_io, nil, IOSpecs::CopyStream
it_behaves_like :io_copy_stream_to_io_with_offset, nil, IOSpecs::CopyStream
end
+
+ describe "to a Tempfile" do
+ before :all do
+ require 'tempfile'
+ end
+
+ before :each do
+ @to_io = Tempfile.new("rubyspec_copy_stream", encoding: Encoding::BINARY, mode: File::RDONLY)
+ @to_name = @to_io.path
+ end
+
+ after :each do
+ @to_io.close!
+ @to_name = nil # do not rm_r it, already done by Tempfile#close!
+ end
+
+ it_behaves_like :io_copy_stream_to_io, nil, IOSpecs::CopyStream
+ it_behaves_like :io_copy_stream_to_io_with_offset, nil, IOSpecs::CopyStream
+ end
end
describe "from a file name" do
@@ -277,10 +300,8 @@ describe "IO.copy_stream" do
@io.should_not_receive(:pos)
IO.copy_stream(@io, @to_name)
end
-
end
-
describe "with a destination that does partial reads" do
before do
@from_out, @from_in = IO.pipe
diff --git a/spec/ruby/core/io/gets_spec.rb b/spec/ruby/core/io/gets_spec.rb
index 73d76b3abd..ca64bf860e 100644
--- a/spec/ruby/core/io/gets_spec.rb
+++ b/spec/ruby/core/io/gets_spec.rb
@@ -24,6 +24,12 @@ describe "IO#gets" do
end
end
+ it "sets $_ to nil after the last line has been read" do
+ while @io.gets
+ end
+ $_.should be_nil
+ end
+
it "returns nil if called at the end of the stream" do
IOSpecs.lines.length.times { @io.gets }
@io.gets.should == nil
diff --git a/spec/ruby/core/io/new_spec.rb b/spec/ruby/core/io/new_spec.rb
index 9d14ec18ad..979ac0efcb 100644
--- a/spec/ruby/core/io/new_spec.rb
+++ b/spec/ruby/core/io/new_spec.rb
@@ -5,6 +5,12 @@ require_relative 'shared/new'
describe "IO.new" do
it_behaves_like :io_new, :new
+
+ it "does not use the given block and warns to use IO::open" do
+ -> {
+ @io = IO.send(@method, @fd) { raise }
+ }.should complain(/warning: IO::new\(\) does not take block; use IO::open\(\) instead/)
+ end
end
describe "IO.new" do
diff --git a/spec/ruby/core/io/open_spec.rb b/spec/ruby/core/io/open_spec.rb
index d3a3961df7..d151da9ce5 100644
--- a/spec/ruby/core/io/open_spec.rb
+++ b/spec/ruby/core/io/open_spec.rb
@@ -37,6 +37,19 @@ describe "IO.open" do
ScratchPad.recorded.should == :called
end
+ it "propagate an exception in the block after calling #close" do
+ -> do
+ IO.open(@fd, "w") do |io|
+ IOSpecs.io_mock(io, :close) do
+ super()
+ ScratchPad.record :called
+ end
+ raise Exception
+ end
+ end.should raise_error(Exception)
+ ScratchPad.recorded.should == :called
+ end
+
it "propagates an exception raised by #close that is not a StandardError" do
-> do
IO.open(@fd, "w") do |io|
diff --git a/spec/ruby/core/io/pread_spec.rb b/spec/ruby/core/io/pread_spec.rb
index fb0645dec6..aa496ee803 100644
--- a/spec/ruby/core/io/pread_spec.rb
+++ b/spec/ruby/core/io/pread_spec.rb
@@ -26,11 +26,88 @@ guard -> { platform_is_not :windows or ruby_version_is "3.3" } do
buffer.should == "567"
end
+ it "shrinks the buffer in case of less bytes read" do
+ buffer = "foo"
+ @file.pread(1, 0, buffer)
+ buffer.should == "1"
+ end
+
+ it "grows the buffer in case of more bytes read" do
+ buffer = "foo"
+ @file.pread(5, 0, buffer)
+ buffer.should == "12345"
+ end
+
it "does not advance the file pointer" do
@file.pread(4, 0).should == "1234"
@file.read.should == "1234567890"
end
+ it "ignores the current offset" do
+ @file.pos = 3
+ @file.pread(4, 0).should == "1234"
+ end
+
+ it "returns an empty string for maxlen = 0" do
+ @file.pread(0, 4).should == ""
+ end
+
+ it "ignores the offset for maxlen = 0, even if it is out of file bounds" do
+ @file.pread(0, 400).should == ""
+ end
+
+ it "does not reset the buffer when reading with maxlen = 0" do
+ buffer = "foo"
+ @file.pread(0, 4, buffer)
+ buffer.should == "foo"
+
+ @file.pread(0, 400, buffer)
+ buffer.should == "foo"
+ end
+
+ it "converts maxlen to Integer using #to_int" do
+ maxlen = mock('maxlen')
+ maxlen.should_receive(:to_int).and_return(4)
+ @file.pread(maxlen, 0).should == "1234"
+ end
+
+ it "converts offset to Integer using #to_int" do
+ offset = mock('offset')
+ offset.should_receive(:to_int).and_return(0)
+ @file.pread(4, offset).should == "1234"
+ end
+
+ it "converts a buffer to String using to_str" do
+ buffer = mock('buffer')
+ buffer.should_receive(:to_str).at_least(1).and_return("foo")
+ @file.pread(4, 0, buffer)
+ buffer.should_not.is_a?(String)
+ buffer.to_str.should == "1234"
+ end
+
+ it "raises TypeError if maxlen is not an Integer and cannot be coerced into Integer" do
+ maxlen = Object.new
+ -> { @file.pread(maxlen, 0) }.should raise_error(TypeError, 'no implicit conversion of Object into Integer')
+ end
+
+ it "raises TypeError if offset is not an Integer and cannot be coerced into Integer" do
+ offset = Object.new
+ -> { @file.pread(4, offset) }.should raise_error(TypeError, 'no implicit conversion of Object into Integer')
+ end
+
+ it "raises ArgumentError for negative values of maxlen" do
+ -> { @file.pread(-4, 0) }.should raise_error(ArgumentError, 'negative string size (or size too big)')
+ end
+
+ it "raised Errno::EINVAL for negative values of offset" do
+ -> { @file.pread(4, -1) }.should raise_error(Errno::EINVAL, /Invalid argument/)
+ end
+
+ it "raises TypeError if the buffer is not a String and cannot be coerced into String" do
+ buffer = Object.new
+ -> { @file.pread(4, 0, buffer) }.should raise_error(TypeError, 'no implicit conversion of Object into String')
+ end
+
it "raises EOFError if end-of-file is reached" do
-> { @file.pread(1, 10) }.should raise_error(EOFError)
end
diff --git a/spec/ruby/core/io/pwrite_spec.rb b/spec/ruby/core/io/pwrite_spec.rb
index c10578a8eb..00d40db28d 100644
--- a/spec/ruby/core/io/pwrite_spec.rb
+++ b/spec/ruby/core/io/pwrite_spec.rb
@@ -28,16 +28,42 @@ guard -> { platform_is_not :windows or ruby_version_is "3.3" } do
@file.pread(6, 0).should == "foobar"
end
+ it "calls #to_s on the object to be written" do
+ object = mock("to_s")
+ object.should_receive(:to_s).and_return("foo")
+ @file.pwrite(object, 0)
+ @file.pread(3, 0).should == "foo"
+ end
+
+ it "calls #to_int on the offset" do
+ offset = mock("to_int")
+ offset.should_receive(:to_int).and_return(2)
+ @file.pwrite("foo", offset)
+ @file.pread(3, 2).should == "foo"
+ end
+
it "raises IOError when file is not open in write mode" do
File.open(@fname, "r") do |file|
- -> { file.pwrite("foo", 1) }.should raise_error(IOError)
+ -> { file.pwrite("foo", 1) }.should raise_error(IOError, "not opened for writing")
end
end
it "raises IOError when file is closed" do
file = File.open(@fname, "w+")
file.close
- -> { file.pwrite("foo", 1) }.should raise_error(IOError)
+ -> { file.pwrite("foo", 1) }.should raise_error(IOError, "closed stream")
+ end
+
+ it "raises a NoMethodError if object does not respond to #to_s" do
+ -> {
+ @file.pwrite(BasicObject.new, 0)
+ }.should raise_error(NoMethodError, /undefined method `to_s'/)
+ end
+
+ it "raises a TypeError if the offset cannot be converted to an Integer" do
+ -> {
+ @file.pwrite("foo", Object.new)
+ }.should raise_error(TypeError, "no implicit conversion of Object into Integer")
end
end
end
diff --git a/spec/ruby/core/io/read_spec.rb b/spec/ruby/core/io/read_spec.rb
index bd22fb6d6e..996f70bf20 100644
--- a/spec/ruby/core/io/read_spec.rb
+++ b/spec/ruby/core/io/read_spec.rb
@@ -113,6 +113,15 @@ describe "IO.read" do
IO.read(@fname, 1, 10).should == nil
end
+ it "returns an empty string when reading zero bytes" do
+ IO.read(@fname, 0).should == ''
+ end
+
+ it "returns a String in BINARY when passed a size" do
+ IO.read(@fname, 1).encoding.should == Encoding::BINARY
+ IO.read(@fname, 0).encoding.should == Encoding::BINARY
+ end
+
it "raises an Errno::ENOENT when the requested file does not exist" do
rm_r @fname
-> { IO.read @fname }.should raise_error(Errno::ENOENT)
@@ -274,6 +283,14 @@ describe "IO#read" do
@io.read(4).should == '7890'
end
+ it "treats first nil argument as no length limit" do
+ @io.read(nil).should == @contents
+ end
+
+ it "raises an ArgumentError when not passed a valid length" do
+ -> { @io.read(-1) }.should raise_error(ArgumentError)
+ end
+
it "clears the output buffer if there is nothing to read" do
@io.pos = 10
@@ -565,6 +582,7 @@ describe :io_read_size_internal_encoding, shared: true do
it "returns a String in BINARY when passed a size" do
@io.read(4).encoding.should equal(Encoding::BINARY)
+ @io.read(0).encoding.should equal(Encoding::BINARY)
end
it "does not change the buffer's encoding when passed a limit" do
diff --git a/spec/ruby/core/io/shared/each.rb b/spec/ruby/core/io/shared/each.rb
index dbc0178dd6..aca622834f 100644
--- a/spec/ruby/core/io/shared/each.rb
+++ b/spec/ruby/core/io/shared/each.rb
@@ -33,10 +33,6 @@ describe :io_each, shared: true do
$_.should == "test"
end
- it "returns self" do
- @io.send(@method) { |l| l }.should equal(@io)
- end
-
it "raises an IOError when self is not readable" do
-> { IOSpecs.closed_io.send(@method) {} }.should raise_error(IOError)
end
diff --git a/spec/ruby/core/kernel/exec_spec.rb b/spec/ruby/core/kernel/exec_spec.rb
index 1b4a7ae6f4..3d9520ad67 100644
--- a/spec/ruby/core/kernel/exec_spec.rb
+++ b/spec/ruby/core/kernel/exec_spec.rb
@@ -7,12 +7,12 @@ describe "Kernel#exec" do
end
it "runs the specified command, replacing current process" do
- ruby_exe('exec "echo hello"; puts "fail"', escape: true).should == "hello\n"
+ ruby_exe('exec "echo hello"; puts "fail"').should == "hello\n"
end
end
describe "Kernel.exec" do
it "runs the specified command, replacing current process" do
- ruby_exe('Kernel.exec "echo hello"; puts "fail"', escape: true).should == "hello\n"
+ ruby_exe('Kernel.exec "echo hello"; puts "fail"').should == "hello\n"
end
end
diff --git a/spec/ruby/core/kernel/printf_spec.rb b/spec/ruby/core/kernel/printf_spec.rb
index d8f93ce429..61bf955c25 100644
--- a/spec/ruby/core/kernel/printf_spec.rb
+++ b/spec/ruby/core/kernel/printf_spec.rb
@@ -31,6 +31,13 @@ describe "Kernel.printf" do
object.should_receive(:write).with("string")
Kernel.printf(object, "%s", "string")
end
+
+ it "calls #to_str to convert the format object to a String" do
+ object = mock('format string')
+ object.should_receive(:to_str).and_return("to_str: %i")
+ $stdout.should_receive(:write).with("to_str: 42")
+ Kernel.printf($stdout, object, 42)
+ end
end
describe "Kernel.printf" do
diff --git a/spec/ruby/core/kernel/shared/load.rb b/spec/ruby/core/kernel/shared/load.rb
index 5c41c19bf6..0fe2d5ce16 100644
--- a/spec/ruby/core/kernel/shared/load.rb
+++ b/spec/ruby/core/kernel/shared/load.rb
@@ -1,5 +1,6 @@
main = self
+# The big difference is Kernel#load does not attempt to add an extension to the passed path, unlike Kernel#require
describe :kernel_load, shared: true do
before :each do
CodeLoadingSpecs.spec_setup
@@ -10,22 +11,31 @@ describe :kernel_load, shared: true do
CodeLoadingSpecs.spec_cleanup
end
- it "loads a non-extensioned file as a Ruby source file" do
- path = File.expand_path "load_fixture", CODE_LOADING_DIR
- @object.load(path).should be_true
- ScratchPad.recorded.should == [:no_ext]
- end
+ describe "(path resolution)" do
+ # This behavior is specific to Kernel#load, it differs for Kernel#require
+ it "loads a non-extensioned file as a Ruby source file" do
+ path = File.expand_path "load_fixture", CODE_LOADING_DIR
+ @object.load(path).should be_true
+ ScratchPad.recorded.should == [:no_ext]
+ end
- it "loads a non .rb extensioned file as a Ruby source file" do
- path = File.expand_path "load_fixture.ext", CODE_LOADING_DIR
- @object.load(path).should be_true
- ScratchPad.recorded.should == [:no_rb_ext]
- end
+ it "loads a non .rb extensioned file as a Ruby source file" do
+ path = File.expand_path "load_fixture.ext", CODE_LOADING_DIR
+ @object.load(path).should be_true
+ ScratchPad.recorded.should == [:no_rb_ext]
+ end
- it "loads from the current working directory" do
- Dir.chdir CODE_LOADING_DIR do
- @object.load("load_fixture.rb").should be_true
- ScratchPad.recorded.should == [:loaded]
+ it "loads from the current working directory" do
+ Dir.chdir CODE_LOADING_DIR do
+ @object.load("load_fixture.rb").should be_true
+ ScratchPad.recorded.should == [:loaded]
+ end
+ end
+
+ # This behavior is specific to Kernel#load, it differs for Kernel#require
+ it "does not look for a c-extension file when passed a path without extension (when no .rb is present)" do
+ path = File.join CODE_LOADING_DIR, "a", "load_fixture"
+ -> { @object.send(@method, path) }.should raise_error(LoadError)
end
end
diff --git a/spec/ruby/core/kernel/shared/require.rb b/spec/ruby/core/kernel/shared/require.rb
index 61081b200c..250813191b 100644
--- a/spec/ruby/core/kernel/shared/require.rb
+++ b/spec/ruby/core/kernel/shared/require.rb
@@ -212,6 +212,34 @@ end
describe :kernel_require, shared: true do
describe "(path resolution)" do
+ it "loads .rb file when passed absolute path without extension" do
+ path = File.expand_path "load_fixture", CODE_LOADING_DIR
+ @object.send(@method, path).should be_true
+ # This should _not_ be [:no_ext]
+ ScratchPad.recorded.should == [:loaded]
+ end
+
+ platform_is :linux, :darwin do
+ it "loads c-extension file when passed absolute path without extension when no .rb is present" do
+ # the error message is specific to what dlerror() returns
+ path = File.join CODE_LOADING_DIR, "a", "load_fixture"
+ -> { @object.send(@method, path) }.should raise_error(Exception, /file too short|not a mach-o file/)
+ end
+ end
+
+ platform_is :darwin do
+ it "loads .bundle file when passed absolute path with .so" do
+ # the error message is specific to what dlerror() returns
+ path = File.join CODE_LOADING_DIR, "a", "load_fixture.so"
+ -> { @object.send(@method, path) }.should raise_error(Exception, /load_fixture\.bundle.+(file too short|not a mach-o file)/)
+ end
+ end
+
+ it "does not try an extra .rb if the path already ends in .rb" do
+ path = File.join CODE_LOADING_DIR, "d", "load_fixture.rb"
+ -> { @object.send(@method, path) }.should raise_error(LoadError)
+ end
+
# For reference see [ruby-core:24155] in which matz confirms this feature is
# intentional for security reasons.
it "does not load a bare filename unless the current working directory is in $LOAD_PATH" do
diff --git a/spec/ruby/core/kernel/sleep_spec.rb b/spec/ruby/core/kernel/sleep_spec.rb
index 44b417a92e..0570629723 100644
--- a/spec/ruby/core/kernel/sleep_spec.rb
+++ b/spec/ruby/core/kernel/sleep_spec.rb
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
-require_relative 'fixtures/classes'
describe "Kernel#sleep" do
it "is a private method" do
diff --git a/spec/ruby/core/kernel/sprintf_spec.rb b/spec/ruby/core/kernel/sprintf_spec.rb
index 7adf71be76..9ef7f86f16 100644
--- a/spec/ruby/core/kernel/sprintf_spec.rb
+++ b/spec/ruby/core/kernel/sprintf_spec.rb
@@ -3,6 +3,14 @@ require_relative 'fixtures/classes'
require_relative 'shared/sprintf'
require_relative 'shared/sprintf_encoding'
+describe :kernel_sprintf_to_str, shared: true do
+ it "calls #to_str to convert the format object to a String" do
+ obj = mock('format string')
+ obj.should_receive(:to_str).and_return("to_str: %i")
+ @method.call(obj, 42).should == "to_str: 42"
+ end
+end
+
describe "Kernel#sprintf" do
it_behaves_like :kernel_sprintf, -> format, *args {
sprintf(format, *args)
@@ -11,6 +19,10 @@ describe "Kernel#sprintf" do
it_behaves_like :kernel_sprintf_encoding, -> format, *args {
sprintf(format, *args)
}
+
+ it_behaves_like :kernel_sprintf_to_str, -> format, *args {
+ sprintf(format, *args)
+ }
end
describe "Kernel.sprintf" do
@@ -21,4 +33,8 @@ describe "Kernel.sprintf" do
it_behaves_like :kernel_sprintf_encoding, -> format, *args {
Kernel.sprintf(format, *args)
}
+
+ it_behaves_like :kernel_sprintf_to_str, -> format, *args {
+ Kernel.sprintf(format, *args)
+ }
end
diff --git a/spec/ruby/core/matchdata/values_at_spec.rb b/spec/ruby/core/matchdata/values_at_spec.rb
index 4fd0bfc42a..535719a2ee 100644
--- a/spec/ruby/core/matchdata/values_at_spec.rb
+++ b/spec/ruby/core/matchdata/values_at_spec.rb
@@ -1,6 +1,6 @@
require_relative '../../spec_helper'
-describe "Struct#values_at" do
+describe "MatchData#values_at" do
# Should be synchronized with core/array/values_at_spec.rb and core/struct/values_at_spec.rb
#
# /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").to_a # => ["HX1138", "H", "X", "113", "8"]
@@ -34,7 +34,7 @@ describe "Struct#values_at" do
end
it "supports beginningless Range" do
- /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(0..2).should == ["HX1138", "H", "X"]
+ /(.)(.)(\d+)(\d)/.match("THX1138: The Movie").values_at(..2).should == ["HX1138", "H", "X"]
end
it "returns an empty Array when Range is empty" do
diff --git a/spec/ruby/core/method/super_method_spec.rb b/spec/ruby/core/method/super_method_spec.rb
index f9a18f3878..c63a7aaa0f 100644
--- a/spec/ruby/core/method/super_method_spec.rb
+++ b/spec/ruby/core/method/super_method_spec.rb
@@ -55,12 +55,10 @@ describe "Method#super_method" do
end
end
- ruby_version_is "2.7.3" do
- context "after aliasing an inherited method" do
- it "returns the expected super_method" do
- method = MethodSpecs::InheritedMethods::C.new.method(:meow)
- method.super_method.owner.should == MethodSpecs::InheritedMethods::A
- end
+ context "after aliasing an inherited method" do
+ it "returns the expected super_method" do
+ method = MethodSpecs::InheritedMethods::C.new.method(:meow)
+ method.super_method.owner.should == MethodSpecs::InheritedMethods::A
end
end
end
diff --git a/spec/ruby/core/module/define_method_spec.rb b/spec/ruby/core/module/define_method_spec.rb
index d742ece6bc..e04bb87ceb 100644
--- a/spec/ruby/core/module/define_method_spec.rb
+++ b/spec/ruby/core/module/define_method_spec.rb
@@ -724,7 +724,7 @@ describe "Module#define_method" do
end
end
-describe "Method#define_method when passed a Method object" do
+describe "Module#define_method when passed a Method object" do
before :each do
@klass = Class.new do
def m(a, b, *c)
@@ -749,7 +749,7 @@ describe "Method#define_method when passed a Method object" do
end
end
-describe "Method#define_method when passed an UnboundMethod object" do
+describe "Module#define_method when passed an UnboundMethod object" do
before :each do
@klass = Class.new do
def m(a, b, *c)
@@ -774,7 +774,7 @@ describe "Method#define_method when passed an UnboundMethod object" do
end
end
-describe "Method#define_method when passed a Proc object" do
+describe "Module#define_method when passed a Proc object" do
describe "and a method is defined inside" do
it "defines the nested method in the default definee where the Proc was created" do
prc = nil
@@ -799,7 +799,7 @@ describe "Method#define_method when passed a Proc object" do
end
end
-describe "Method#define_method when passed a block" do
+describe "Module#define_method when passed a block" do
describe "behaves exactly like a lambda" do
it "for return" do
Class.new do
diff --git a/spec/ruby/core/process/constants_spec.rb b/spec/ruby/core/process/constants_spec.rb
index 4130bb58a5..616c54b8e1 100644
--- a/spec/ruby/core/process/constants_spec.rb
+++ b/spec/ruby/core/process/constants_spec.rb
@@ -56,12 +56,18 @@ describe "Process::Constants" do
end
platform_is :netbsd, :freebsd do
- it "Process::RLIMIT_SBSIZE" do
+ it "has the correct constant values on NetBSD and FreeBSD" do
Process::RLIMIT_SBSIZE.should == 9 # FIXME: what's it equal?
Process::RLIMIT_AS.should == 10
end
end
+ platform_is :freebsd do
+ it "has the correct constant values on FreeBSD" do
+ Process::RLIMIT_NPTS.should == 11
+ end
+ end
+
platform_is :windows do
it "does not define RLIMIT constants" do
%i[
diff --git a/spec/ruby/core/process/exec_spec.rb b/spec/ruby/core/process/exec_spec.rb
index 2fa8b08975..0f371b39c8 100644
--- a/spec/ruby/core/process/exec_spec.rb
+++ b/spec/ruby/core/process/exec_spec.rb
@@ -34,16 +34,16 @@ describe "Process.exec" do
end
it "runs the specified command, replacing current process" do
- ruby_exe('Process.exec "echo hello"; puts "fail"', escape: true).should == "hello\n"
+ ruby_exe('Process.exec "echo hello"; puts "fail"').should == "hello\n"
end
it "sets the current directory when given the :chdir option" do
tmpdir = tmp("")[0..-2]
platform_is_not :windows do
- ruby_exe("Process.exec(\"pwd\", chdir: #{tmpdir.inspect})", escape: true).should == "#{tmpdir}\n"
+ ruby_exe("Process.exec(\"pwd\", chdir: #{tmpdir.inspect})").should == "#{tmpdir}\n"
end
platform_is :windows do
- ruby_exe("Process.exec(\"cd\", chdir: #{tmpdir.inspect})", escape: true).tr('\\', '/').should == "#{tmpdir}\n"
+ ruby_exe("Process.exec(\"cd\", chdir: #{tmpdir.inspect})").tr('\\', '/').should == "#{tmpdir}\n"
end
end
@@ -73,13 +73,13 @@ describe "Process.exec" do
platform_is_not :windows do
it "subjects the specified command to shell expansion" do
result = Dir.chdir(@dir) do
- ruby_exe('Process.exec "echo *"', escape: true)
+ ruby_exe('Process.exec "echo *"')
end
result.chomp.should == @name
end
it "creates an argument array with shell parsing semantics for whitespace" do
- ruby_exe('Process.exec "echo a b c d"', escape: true).should == "a b c d\n"
+ ruby_exe('Process.exec "echo a b c d"').should == "a b c d\n"
end
end
@@ -87,13 +87,13 @@ describe "Process.exec" do
# There is no shell expansion on Windows
it "does not subject the specified command to shell expansion on Windows" do
result = Dir.chdir(@dir) do
- ruby_exe('Process.exec "echo *"', escape: true)
+ ruby_exe('Process.exec "echo *"')
end
result.should == "*\n"
end
it "does not create an argument array with shell parsing semantics for whitespace on Windows" do
- ruby_exe('Process.exec "echo a b c d"', escape: true).should == "a b c d\n"
+ ruby_exe('Process.exec "echo a b c d"').should == "a b c d\n"
end
end
@@ -105,7 +105,7 @@ describe "Process.exec" do
platform_is :windows do
cmd = '"cmd.exe", "/C", "echo", "*"'
end
- ruby_exe("Process.exec #{cmd}", escape: true).should == "*\n"
+ ruby_exe("Process.exec #{cmd}").should == "*\n"
end
end
@@ -124,29 +124,29 @@ describe "Process.exec" do
end
it "sets environment variables in the child environment" do
- ruby_exe('Process.exec({"FOO" => "BAR"}, "echo ' + var + '")', escape: true).should == "BAR\n"
+ ruby_exe('Process.exec({"FOO" => "BAR"}, "echo ' + var + '")').should == "BAR\n"
end
it "unsets environment variables whose value is nil" do
platform_is_not :windows do
- ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")', escape: true).should == "\n"
+ ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")').should == "\n"
end
platform_is :windows do
# On Windows, echo-ing a non-existent env var is treated as echo-ing any other string of text
- ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")', escape: true).should == var + "\n"
+ ruby_exe('Process.exec({"FOO" => nil}, "echo ' + var + '")').should == var + "\n"
end
end
it "coerces environment argument using to_hash" do
- ruby_exe('o = Object.new; def o.to_hash; {"FOO" => "BAR"}; end; Process.exec(o, "echo ' + var + '")', escape: true).should == "BAR\n"
+ ruby_exe('o = Object.new; def o.to_hash; {"FOO" => "BAR"}; end; Process.exec(o, "echo ' + var + '")').should == "BAR\n"
end
it "unsets other environment variables when given a true :unsetenv_others option" do
platform_is_not :windows do
- ruby_exe('Process.exec("echo ' + var + '", unsetenv_others: true)', escape: true).should == "\n"
+ ruby_exe('Process.exec("echo ' + var + '", unsetenv_others: true)').should == "\n"
end
platform_is :windows do
- ruby_exe('Process.exec("' + ENV['COMSPEC'].gsub('\\', '\\\\\\') + ' /C echo ' + var + '", unsetenv_others: true)', escape: true).should == var + "\n"
+ ruby_exe('Process.exec("' + ENV['COMSPEC'].gsub('\\', '\\\\\\') + ' /C echo ' + var + '", unsetenv_others: true)').should == var + "\n"
end
end
end
@@ -154,19 +154,19 @@ describe "Process.exec" do
describe "with a command array" do
it "uses the first element as the command name and the second as the argv[0] value" do
platform_is_not :windows do
- ruby_exe('Process.exec(["/bin/sh", "argv_zero"], "-c", "echo $0")', escape: true).should == "argv_zero\n"
+ ruby_exe('Process.exec(["/bin/sh", "argv_zero"], "-c", "echo $0")').should == "argv_zero\n"
end
platform_is :windows do
- ruby_exe('Process.exec(["cmd.exe", "/C"], "/C", "echo", "argv_zero")', escape: true).should == "argv_zero\n"
+ ruby_exe('Process.exec(["cmd.exe", "/C"], "/C", "echo", "argv_zero")').should == "argv_zero\n"
end
end
it "coerces the argument using to_ary" do
platform_is_not :windows do
- ruby_exe('o = Object.new; def o.to_ary; ["/bin/sh", "argv_zero"]; end; Process.exec(o, "-c", "echo $0")', escape: true).should == "argv_zero\n"
+ ruby_exe('o = Object.new; def o.to_ary; ["/bin/sh", "argv_zero"]; end; Process.exec(o, "-c", "echo $0")').should == "argv_zero\n"
end
platform_is :windows do
- ruby_exe('o = Object.new; def o.to_ary; ["cmd.exe", "/C"]; end; Process.exec(o, "/C", "echo", "argv_zero")', escape: true).should == "argv_zero\n"
+ ruby_exe('o = Object.new; def o.to_ary; ["cmd.exe", "/C"]; end; Process.exec(o, "/C", "echo", "argv_zero")').should == "argv_zero\n"
end
end
@@ -200,7 +200,7 @@ describe "Process.exec" do
end
EOC
- ruby_exe(cmd, escape: true)
+ ruby_exe(cmd)
child_fd = IO.read(@child_fd_file).to_i
child_fd.to_i.should > STDERR.fileno
@@ -216,7 +216,7 @@ describe "Process.exec" do
Process.exec("#{ruby_cmd(map_fd_fixture)} \#{f.fileno}", f.fileno => f.fileno)
EOC
- output = ruby_exe(cmd, escape: true)
+ output = ruby_exe(cmd)
child_fd, close_on_exec = output.split
child_fd.to_i.should > STDERR.fileno
@@ -232,7 +232,7 @@ describe "Process.exec" do
puts(f.close_on_exec?)
EOC
- output = ruby_exe(cmd, escape: true)
+ output = ruby_exe(cmd)
output.split.should == ['true', 'false']
end
end
diff --git a/spec/ruby/core/regexp/union_spec.rb b/spec/ruby/core/regexp/union_spec.rb
index 8076836471..ea5a5053f7 100644
--- a/spec/ruby/core/regexp/union_spec.rb
+++ b/spec/ruby/core/regexp/union_spec.rb
@@ -43,6 +43,27 @@ describe "Regexp.union" do
Regexp.union("\u00A9".encode("ISO-8859-1"), "a".encode("UTF-8")).encoding.should == Encoding::ISO_8859_1
end
+ it "returns ASCII-8BIT if the regexp encodings are ASCII-8BIT and at least one has non-ASCII characters" do
+ us_ascii_implicit, us_ascii_explicit, binary = /abc/, /[\x00-\x7f]/n, /[\x80-\xBF]/n
+ us_ascii_implicit.encoding.should == Encoding::US_ASCII
+ us_ascii_explicit.encoding.should == Encoding::US_ASCII
+ binary.encoding.should == Encoding::BINARY
+
+ Regexp.union(us_ascii_implicit, us_ascii_explicit, binary).encoding.should == Encoding::BINARY
+ Regexp.union(us_ascii_implicit, binary, us_ascii_explicit).encoding.should == Encoding::BINARY
+ Regexp.union(us_ascii_explicit, us_ascii_implicit, binary).encoding.should == Encoding::BINARY
+ Regexp.union(us_ascii_explicit, binary, us_ascii_implicit).encoding.should == Encoding::BINARY
+ Regexp.union(binary, us_ascii_implicit, us_ascii_explicit).encoding.should == Encoding::BINARY
+ Regexp.union(binary, us_ascii_explicit, us_ascii_implicit).encoding.should == Encoding::BINARY
+ end
+
+ it "return US-ASCII if all patterns are ASCII-only" do
+ Regexp.union(/abc/e, /def/e).encoding.should == Encoding::US_ASCII
+ Regexp.union(/abc/n, /def/n).encoding.should == Encoding::US_ASCII
+ Regexp.union(/abc/s, /def/s).encoding.should == Encoding::US_ASCII
+ Regexp.union(/abc/u, /def/u).encoding.should == Encoding::US_ASCII
+ end
+
it "returns a Regexp with UTF-8 if one part is UTF-8" do
Regexp.union(/probl[éeè]me/i, /help/i).encoding.should == Encoding::UTF_8
end
@@ -54,83 +75,83 @@ describe "Regexp.union" do
it "raises ArgumentError if the arguments include conflicting ASCII-incompatible Strings" do
-> {
Regexp.union("a".encode("UTF-16LE"), "b".encode("UTF-16BE"))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and UTF-16BE')
end
it "raises ArgumentError if the arguments include conflicting ASCII-incompatible Regexps" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")),
Regexp.new("b".encode("UTF-16BE")))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and UTF-16BE')
end
it "raises ArgumentError if the arguments include conflicting fixed encoding Regexps" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-8"), Regexp::FIXEDENCODING),
Regexp.new("b".encode("US-ASCII"), Regexp::FIXEDENCODING))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, 'incompatible encodings: UTF-8 and US-ASCII')
end
it "raises ArgumentError if the arguments include a fixed encoding Regexp and a String containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-8"), Regexp::FIXEDENCODING),
"\u00A9".encode("ISO-8859-1"))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, 'incompatible encodings: UTF-8 and ISO-8859-1')
end
it "raises ArgumentError if the arguments include a String containing non-ASCII-compatible characters and a fixed encoding Regexp in a different encoding" do
-> {
Regexp.union("\u00A9".encode("ISO-8859-1"),
Regexp.new("a".encode("UTF-8"), Regexp::FIXEDENCODING))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, 'incompatible encodings: ISO-8859-1 and UTF-8')
end
it "raises ArgumentError if the arguments include an ASCII-incompatible String and an ASCII-only String" do
-> {
Regexp.union("a".encode("UTF-16LE"), "b".encode("UTF-8"))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, /ASCII incompatible encoding: UTF-16LE|incompatible encodings: UTF-16LE and US-ASCII/)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible Regexp and an ASCII-only String" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")), "b".encode("UTF-8"))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, /ASCII incompatible encoding: UTF-16LE|incompatible encodings: UTF-16LE and US-ASCII/)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible String and an ASCII-only Regexp" do
-> {
Regexp.union("a".encode("UTF-16LE"), Regexp.new("b".encode("UTF-8")))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, /ASCII incompatible encoding: UTF-16LE|incompatible encodings: UTF-16LE and US-ASCII/)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible Regexp and an ASCII-only Regexp" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")), Regexp.new("b".encode("UTF-8")))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, /ASCII incompatible encoding: UTF-16LE|incompatible encodings: UTF-16LE and US-ASCII/)
end
it "raises ArgumentError if the arguments include an ASCII-incompatible String and a String containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union("a".encode("UTF-16LE"), "\u00A9".encode("ISO-8859-1"))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and ISO-8859-1')
end
it "raises ArgumentError if the arguments include an ASCII-incompatible Regexp and a String containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")), "\u00A9".encode("ISO-8859-1"))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and ISO-8859-1')
end
it "raises ArgumentError if the arguments include an ASCII-incompatible String and a Regexp containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union("a".encode("UTF-16LE"), Regexp.new("\u00A9".encode("ISO-8859-1")))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and ISO-8859-1')
end
it "raises ArgumentError if the arguments include an ASCII-incompatible Regexp and a Regexp containing non-ASCII-compatible characters in a different encoding" do
-> {
Regexp.union(Regexp.new("a".encode("UTF-16LE")), Regexp.new("\u00A9".encode("ISO-8859-1")))
- }.should raise_error(ArgumentError)
+ }.should raise_error(ArgumentError, 'incompatible encodings: UTF-16LE and ISO-8859-1')
end
it "uses to_str to convert arguments (if not Regexp)" do
@@ -154,6 +175,8 @@ describe "Regexp.union" do
not_supported_on :opal do
Regexp.union([/dogs/, /cats/i]).should == /(?-mix:dogs)|(?i-mx:cats)/
end
- ->{Regexp.union(["skiing", "sledding"], [/dogs/, /cats/i])}.should raise_error(TypeError)
+ -> {
+ Regexp.union(["skiing", "sledding"], [/dogs/, /cats/i])
+ }.should raise_error(TypeError, 'no implicit conversion of Array into String')
end
end
diff --git a/spec/ruby/core/signal/signame_spec.rb b/spec/ruby/core/signal/signame_spec.rb
index b66de9fc85..adfe895d97 100644
--- a/spec/ruby/core/signal/signame_spec.rb
+++ b/spec/ruby/core/signal/signame_spec.rb
@@ -9,10 +9,22 @@ describe "Signal.signame" do
Signal.signame(-1).should == nil
end
+ it "calls #to_int on an object to convert to an Integer" do
+ obj = mock('signal')
+ obj.should_receive(:to_int).and_return(0)
+ Signal.signame(obj).should == "EXIT"
+ end
+
it "raises a TypeError when the passed argument can't be coerced to Integer" do
-> { Signal.signame("hello") }.should raise_error(TypeError)
end
+ it "raises a TypeError when the passed argument responds to #to_int but does not return an Integer" do
+ obj = mock('signal')
+ obj.should_receive(:to_int).and_return('not an int')
+ -> { Signal.signame(obj) }.should raise_error(TypeError)
+ end
+
platform_is_not :windows do
it "the original should take precedence over alias when looked up by number" do
Signal.signame(Signal.list["ABRT"]).should == "ABRT"
diff --git a/spec/ruby/core/signal/trap_spec.rb b/spec/ruby/core/signal/trap_spec.rb
index 10e122e072..b3186cda92 100644
--- a/spec/ruby/core/signal/trap_spec.rb
+++ b/spec/ruby/core/signal/trap_spec.rb
@@ -221,6 +221,25 @@ describe "Signal.trap" do
Signal.trap(:HUP, @saved_trap).should equal(@proc)
end
+ it "calls #to_str on an object to convert to a String" do
+ obj = mock("signal")
+ obj.should_receive(:to_str).exactly(2).times.and_return("HUP")
+ Signal.trap obj, @proc
+ Signal.trap(obj, @saved_trap).should equal(@proc)
+ end
+
+ it "accepts Integer values" do
+ hup = Signal.list["HUP"]
+ Signal.trap hup, @proc
+ Signal.trap(hup, @saved_trap).should equal(@proc)
+ end
+
+ it "does not call #to_int on an object to convert to an Integer" do
+ obj = mock("signal")
+ obj.should_not_receive(:to_int)
+ -> { Signal.trap obj, @proc }.should raise_error(ArgumentError, /bad signal type/)
+ end
+
it "raises ArgumentError when passed unknown signal" do
-> { Signal.trap(300) { } }.should raise_error(ArgumentError, "invalid signal number (300)")
-> { Signal.trap("USR10") { } }.should raise_error(ArgumentError, "unsupported signal `SIGUSR10'")
diff --git a/spec/ruby/core/string/start_with_spec.rb b/spec/ruby/core/string/start_with_spec.rb
index 81eed47f96..35e33b46a6 100644
--- a/spec/ruby/core/string/start_with_spec.rb
+++ b/spec/ruby/core/string/start_with_spec.rb
@@ -11,7 +11,14 @@ describe "String#start_with?" do
"\xA9".should.start_with?("\xA9") # A9 is not a character head for UTF-8
end
- ruby_bug "#19784", ""..."3.3" do
+ ruby_version_is ""..."3.3" do
+ it "does not check we are matching only part of a character" do
+ "\xe3\x81\x82".size.should == 1
+ "\xe3\x81\x82".should.start_with?("\xe3")
+ end
+ end
+
+ ruby_version_is "3.3" do # #19784
it "checks we are matching only part of a character" do
"\xe3\x81\x82".size.should == 1
"\xe3\x81\x82".should_not.start_with?("\xe3")
diff --git a/spec/ruby/core/string/uplus_spec.rb b/spec/ruby/core/string/uplus_spec.rb
index 038b283c90..65b66260dd 100644
--- a/spec/ruby/core/string/uplus_spec.rb
+++ b/spec/ruby/core/string/uplus_spec.rb
@@ -7,6 +7,9 @@ describe 'String#+@' do
output.should_not.frozen?
output.should == 'foo'
+
+ output << 'bar'
+ output.should == 'foobar'
end
it 'returns self if the String is not frozen' do
diff --git a/spec/ruby/core/unboundmethod/super_method_spec.rb b/spec/ruby/core/unboundmethod/super_method_spec.rb
index 101c83b8b3..aa7c129377 100644
--- a/spec/ruby/core/unboundmethod/super_method_spec.rb
+++ b/spec/ruby/core/unboundmethod/super_method_spec.rb
@@ -40,12 +40,10 @@ describe "UnboundMethod#super_method" do
end
end
- ruby_version_is "2.7.3" do
- context "after aliasing an inherited method" do
- it "returns the expected super_method" do
- method = MethodSpecs::InheritedMethods::C.instance_method(:meow)
- method.super_method.owner.should == MethodSpecs::InheritedMethods::A
- end
+ context "after aliasing an inherited method" do
+ it "returns the expected super_method" do
+ method = MethodSpecs::InheritedMethods::C.instance_method(:meow)
+ method.super_method.owner.should == MethodSpecs::InheritedMethods::A
end
end
end
diff --git a/spec/ruby/core/warning/element_reference_spec.rb b/spec/ruby/core/warning/element_reference_spec.rb
index bd024d19b4..8cb4018c20 100644
--- a/spec/ruby/core/warning/element_reference_spec.rb
+++ b/spec/ruby/core/warning/element_reference_spec.rb
@@ -1,11 +1,9 @@
require_relative '../../spec_helper'
describe "Warning.[]" do
- ruby_version_is '2.7.2' do
- it "returns default values for categories :deprecated and :experimental" do
- ruby_exe('p [Warning[:deprecated], Warning[:experimental]]').chomp.should == "[false, true]"
- ruby_exe('p [Warning[:deprecated], Warning[:experimental]]', options: "-w").chomp.should == "[true, true]"
- end
+ it "returns default values for categories :deprecated and :experimental" do
+ ruby_exe('p [Warning[:deprecated], Warning[:experimental]]').chomp.should == "[false, true]"
+ ruby_exe('p [Warning[:deprecated], Warning[:experimental]]', options: "-w").chomp.should == "[true, true]"
end
ruby_version_is '3.3' do