зеркало из https://github.com/github/ruby.git
Update to ruby/spec@1d9d5c6
This commit is contained in:
Родитель
5a1ab740fc
Коммит
31cf1bb525
|
@ -161,6 +161,9 @@ Lint/Debugger:
|
|||
Lint/Loop:
|
||||
Enabled: false
|
||||
|
||||
Style/BlockComments:
|
||||
Enabled: true
|
||||
|
||||
Style/Lambda:
|
||||
Enabled: true
|
||||
EnforcedStyle: literal
|
||||
|
|
|
@ -20,12 +20,18 @@ describe "BasicObject#instance_eval" do
|
|||
a.instance_eval('self').equal?(a).should be_true
|
||||
end
|
||||
|
||||
it "expects a block with no arguments" do
|
||||
-> { "hola".instance_eval }.should raise_error(ArgumentError)
|
||||
it "raises an ArgumentError when no arguments and no block are given" do
|
||||
-> { "hola".instance_eval }.should raise_error(ArgumentError, "wrong number of arguments (given 0, expected 1..3)")
|
||||
end
|
||||
|
||||
it "takes no arguments with a block" do
|
||||
-> { "hola".instance_eval(4, 5) {|a,b| a + b } }.should raise_error(ArgumentError)
|
||||
it "raises an ArgumentError when a block and normal arguments are given" do
|
||||
-> { "hola".instance_eval(4, 5) {|a,b| a + b } }.should raise_error(ArgumentError, "wrong number of arguments (given 2, expected 0)")
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when more than 3 arguments are given" do
|
||||
-> {
|
||||
"hola".instance_eval("1 + 1", "some file", 0, "bogus")
|
||||
}.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 1..3)")
|
||||
end
|
||||
|
||||
it "yields the object to the block" do
|
||||
|
@ -185,4 +191,58 @@ end
|
|||
|
||||
x.should == :value
|
||||
end
|
||||
|
||||
it "converts string argument with #to_str method" do
|
||||
source_code = Object.new
|
||||
def source_code.to_str() "1" end
|
||||
|
||||
a = BasicObject.new
|
||||
a.instance_eval(source_code).should == 1
|
||||
end
|
||||
|
||||
it "raises ArgumentError if returned value is not String" do
|
||||
source_code = Object.new
|
||||
def source_code.to_str() :symbol end
|
||||
|
||||
a = BasicObject.new
|
||||
-> { a.instance_eval(source_code) }.should raise_error(TypeError, /can't convert Object to String/)
|
||||
end
|
||||
|
||||
it "converts filename argument with #to_str method" do
|
||||
filename = Object.new
|
||||
def filename.to_str() "file.rb" end
|
||||
|
||||
err = begin
|
||||
Object.new.instance_eval("raise", filename)
|
||||
rescue => e
|
||||
e
|
||||
end
|
||||
err.backtrace.first.split(":")[0].should == "file.rb"
|
||||
end
|
||||
|
||||
it "raises ArgumentError if returned value is not String" do
|
||||
filename = Object.new
|
||||
def filename.to_str() :symbol end
|
||||
|
||||
-> { Object.new.instance_eval("raise", filename) }.should raise_error(TypeError, /can't convert Object to String/)
|
||||
end
|
||||
|
||||
it "converts lineno argument with #to_int method" do
|
||||
lineno = Object.new
|
||||
def lineno.to_int() 15 end
|
||||
|
||||
err = begin
|
||||
Object.new.instance_eval("raise", "file.rb", lineno)
|
||||
rescue => e
|
||||
e
|
||||
end
|
||||
err.backtrace.first.split(":")[1].should == "15"
|
||||
end
|
||||
|
||||
it "raises ArgumentError if returned value is not Integer" do
|
||||
lineno = Object.new
|
||||
def lineno.to_int() :symbol end
|
||||
|
||||
-> { Object.new.instance_eval("raise", "file.rb", lineno) }.should raise_error(TypeError, /can't convert Object to Integer/)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,10 +22,23 @@ describe 'Enumerable#sum' do
|
|||
@enum.sum.should == 5/3r
|
||||
end
|
||||
|
||||
it 'takes a block to transform the elements' do
|
||||
context 'with a block' do
|
||||
it 'transforms the elements' do
|
||||
@enum.sum { |element| element * 2 }.should == 10/3r
|
||||
end
|
||||
|
||||
it 'does not destructure array elements' do
|
||||
class << @enum
|
||||
def each
|
||||
yield [1,2]
|
||||
yield [3]
|
||||
end
|
||||
end
|
||||
|
||||
@enum.sum(&:last).should == 5
|
||||
end
|
||||
end
|
||||
|
||||
# https://bugs.ruby-lang.org/issues/12217
|
||||
# https://github.com/ruby/ruby/blob/master/doc/ChangeLog-2.4.0#L6208-L6214
|
||||
it "uses Kahan's compensated summation algorithm for precise sum of float numbers" do
|
||||
|
|
|
@ -213,6 +213,8 @@ describe "IO#gets" do
|
|||
|
||||
it "returns empty string when 0 passed as a limit" do
|
||||
@io.gets(0).should == ""
|
||||
@io.gets(nil, 0).should == ""
|
||||
@io.gets("", 0).should == ""
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,16 +3,27 @@ require_relative 'fixtures/classes'
|
|||
|
||||
describe "IO#print" do
|
||||
before :each do
|
||||
@old_separator = $\
|
||||
suppress_warning {$\ = '->'}
|
||||
@old_record_separator = $\
|
||||
@old_field_separator = $,
|
||||
suppress_warning {
|
||||
$\ = '->'
|
||||
$, = '^^'
|
||||
}
|
||||
@name = tmp("io_print")
|
||||
end
|
||||
|
||||
after :each do
|
||||
suppress_warning {$\ = @old_separator}
|
||||
suppress_warning {
|
||||
$\ = @old_record_separator
|
||||
$, = @old_field_separator
|
||||
}
|
||||
rm_r @name
|
||||
end
|
||||
|
||||
it "returns nil" do
|
||||
touch(@name) { |f| f.print.should be_nil }
|
||||
end
|
||||
|
||||
it "writes $_.to_s followed by $\\ (if any) to the stream if no arguments given" do
|
||||
o = mock('o')
|
||||
o.should_receive(:to_s).and_return("mockmockmock")
|
||||
|
@ -38,13 +49,15 @@ describe "IO#print" do
|
|||
IO.read(@name).should == "hello#{$\}"
|
||||
end
|
||||
|
||||
it "writes each obj.to_s to the stream and appends $\\ (if any) given multiple objects" do
|
||||
it "writes each obj.to_s to the stream separated by $, (if any) and appends $\\ (if any) given multiple objects" do
|
||||
o, o2 = Object.new, Object.new
|
||||
def o.to_s(); 'o'; end
|
||||
def o2.to_s(); 'o2'; end
|
||||
|
||||
suppress_warning {
|
||||
touch(@name) { |f| f.print(o, o2) }
|
||||
IO.read(@name).should == "#{o.to_s}#{o2.to_s}#{$\}"
|
||||
}
|
||||
IO.read(@name).should == "#{o.to_s}#{$,}#{o2.to_s}#{$\}"
|
||||
end
|
||||
|
||||
it "raises IOError on closed stream" do
|
||||
|
|
|
@ -55,6 +55,27 @@ describe "IO#read_nonblock" do
|
|||
@read.read_nonblock(4).should == "hell"
|
||||
end
|
||||
|
||||
it "reads after ungetc with data in the buffer" do
|
||||
@write.write("foobar")
|
||||
@read.set_encoding(
|
||||
'utf-8', universal_newline: false
|
||||
)
|
||||
c = @read.getc
|
||||
@read.ungetc(c)
|
||||
@read.read_nonblock(3).should == "foo"
|
||||
@read.read_nonblock(3).should == "bar"
|
||||
end
|
||||
|
||||
it "raises an exception after ungetc with data in the buffer and character conversion enabled" do
|
||||
@write.write("foobar")
|
||||
@read.set_encoding(
|
||||
'utf-8', universal_newline: true
|
||||
)
|
||||
c = @read.getc
|
||||
@read.ungetc(c)
|
||||
-> { @read.read_nonblock(3).should == "foo" }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
it "returns less data if that is all that is available" do
|
||||
@write << "hello"
|
||||
@read.read_nonblock(10).should == "hello"
|
||||
|
@ -70,6 +91,10 @@ describe "IO#read_nonblock" do
|
|||
@read.read_nonblock(1).should == "1"
|
||||
end
|
||||
|
||||
it "raises ArgumentError when length is less than 0" do
|
||||
-> { @read.read_nonblock(-1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "reads into the passed buffer" do
|
||||
buffer = ""
|
||||
@write.write("1")
|
||||
|
@ -84,6 +109,21 @@ describe "IO#read_nonblock" do
|
|||
output.should equal(buffer)
|
||||
end
|
||||
|
||||
it "discards the existing buffer content upon successful read" do
|
||||
buffer = "existing content"
|
||||
@write.write("hello world")
|
||||
@write.close
|
||||
@read.read_nonblock(11, buffer)
|
||||
buffer.should == "hello world"
|
||||
end
|
||||
|
||||
it "discards the existing buffer content upon error" do
|
||||
buffer = "existing content"
|
||||
@write.close
|
||||
-> { @read.read_nonblock(1, buffer) }.should raise_error(EOFError)
|
||||
buffer.should be_empty
|
||||
end
|
||||
|
||||
it "raises IOError on closed stream" do
|
||||
-> { IOSpecs.closed_io.read_nonblock(5) }.should raise_error(IOError)
|
||||
end
|
||||
|
@ -96,4 +136,13 @@ describe "IO#read_nonblock" do
|
|||
|
||||
-> { @read.read_nonblock(5) }.should raise_error(EOFError)
|
||||
end
|
||||
|
||||
it "preserves the encoding of the given buffer" do
|
||||
buffer = ''.encode(Encoding::ISO_8859_1)
|
||||
@write.write("abc")
|
||||
@write.close
|
||||
@read.read_nonblock(10, buffer)
|
||||
|
||||
buffer.encoding.should == Encoding::ISO_8859_1
|
||||
end
|
||||
end
|
||||
|
|
|
@ -270,6 +270,13 @@ describe "IO#read" do
|
|||
@io.read(nil, buf).should equal buf
|
||||
end
|
||||
|
||||
it "returns the given buffer when there is nothing to read" do
|
||||
buf = ""
|
||||
|
||||
@io.read
|
||||
@io.read(nil, buf).should equal buf
|
||||
end
|
||||
|
||||
it "coerces the second argument to string and uses it as a buffer" do
|
||||
buf = "ABCDE"
|
||||
obj = mock("buff")
|
||||
|
@ -312,6 +319,9 @@ describe "IO#read" do
|
|||
-> { IOSpecs.closed_io.read }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
it "raises ArgumentError when length is less than 0" do
|
||||
-> { @io.read(-1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
it "raises IOError when stream is closed by another thread" do
|
||||
|
|
|
@ -1,6 +1,16 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
describe :io_readchar_internal_encoding, shared: true do
|
||||
it "returns a transcoded String" do
|
||||
@io.readchar.should == "あ"
|
||||
end
|
||||
|
||||
it "sets the String encoding to the internal encoding" do
|
||||
@io.readchar.encoding.should equal(Encoding::UTF_8)
|
||||
end
|
||||
end
|
||||
|
||||
describe "IO#readchar" do
|
||||
before :each do
|
||||
@io = IOSpecs.io_fixture "lines.txt"
|
||||
|
@ -29,6 +39,62 @@ describe "IO#readchar" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "IO#readchar with internal encoding" do
|
||||
after :each do
|
||||
@io.close if @io
|
||||
end
|
||||
|
||||
describe "not specified" do
|
||||
before :each do
|
||||
@io = IOSpecs.io_fixture "read_euc_jp.txt", "r:euc-jp"
|
||||
end
|
||||
|
||||
it "does not transcode the String" do
|
||||
@io.readchar.should == ("あ").encode(Encoding::EUC_JP)
|
||||
end
|
||||
|
||||
it "sets the String encoding to the external encoding" do
|
||||
@io.readchar.encoding.should equal(Encoding::EUC_JP)
|
||||
end
|
||||
end
|
||||
|
||||
describe "specified by open mode" do
|
||||
before :each do
|
||||
@io = IOSpecs.io_fixture "read_euc_jp.txt", "r:euc-jp:utf-8"
|
||||
end
|
||||
|
||||
it_behaves_like :io_readchar_internal_encoding, nil
|
||||
end
|
||||
|
||||
describe "specified by mode: option" do
|
||||
before :each do
|
||||
@io = IOSpecs.io_fixture "read_euc_jp.txt", mode: "r:euc-jp:utf-8"
|
||||
end
|
||||
|
||||
it_behaves_like :io_readchar_internal_encoding, nil
|
||||
end
|
||||
|
||||
describe "specified by internal_encoding: option" do
|
||||
before :each do
|
||||
options = { mode: "r",
|
||||
internal_encoding: "utf-8",
|
||||
external_encoding: "euc-jp" }
|
||||
@io = IOSpecs.io_fixture "read_euc_jp.txt", options
|
||||
end
|
||||
|
||||
it_behaves_like :io_readchar_internal_encoding, nil
|
||||
end
|
||||
|
||||
describe "specified by encoding: option" do
|
||||
before :each do
|
||||
options = { mode: "r", encoding: "euc-jp:utf-8" }
|
||||
@io = IOSpecs.io_fixture "read_euc_jp.txt", options
|
||||
end
|
||||
|
||||
it_behaves_like :io_readchar_internal_encoding, nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "IO#readchar" do
|
||||
before :each do
|
||||
@io = IOSpecs.io_fixture "empty.txt"
|
||||
|
|
|
@ -59,7 +59,7 @@ describe "IO#readpartial" do
|
|||
end
|
||||
|
||||
it "discards the existing buffer content upon successful read" do
|
||||
buffer = "existing"
|
||||
buffer = "existing content"
|
||||
@wr.write("hello world")
|
||||
@wr.close
|
||||
@rd.readpartial(11, buffer)
|
||||
|
@ -93,4 +93,17 @@ describe "IO#readpartial" do
|
|||
@rd.readpartial(0).should == ""
|
||||
end
|
||||
|
||||
it "clears and returns the given buffer if the length argument is 0" do
|
||||
buffer = "existing content"
|
||||
@rd.readpartial(0, buffer).should == buffer
|
||||
buffer.should == ""
|
||||
end
|
||||
|
||||
it "preserves the encoding of the given buffer" do
|
||||
buffer = ''.encode(Encoding::ISO_8859_1)
|
||||
@wr.write("abc")
|
||||
@wr.close
|
||||
@rd.readpartial(10, buffer)
|
||||
buffer.encoding.should == Encoding::ISO_8859_1
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,6 +18,17 @@ describe "IO#rewind" do
|
|||
@io.readline.should == "Voici la ligne une.\n"
|
||||
end
|
||||
|
||||
it "positions the instance to the beginning of output for write-only IO" do
|
||||
name = tmp("io_rewind_spec")
|
||||
io = File.open(name, "w")
|
||||
io.write("Voici la ligne une.\n")
|
||||
io.rewind
|
||||
io.pos.should == 0
|
||||
ensure
|
||||
io.close
|
||||
rm_r name
|
||||
end
|
||||
|
||||
it "positions the instance to the beginning of input and clears EOF" do
|
||||
value = @io.read
|
||||
@io.rewind
|
||||
|
@ -32,6 +43,10 @@ describe "IO#rewind" do
|
|||
@io.lineno.should == 0
|
||||
end
|
||||
|
||||
it "returns 0" do
|
||||
@io.rewind.should == 0
|
||||
end
|
||||
|
||||
it "raises IOError on closed stream" do
|
||||
-> { IOSpecs.closed_io.rewind }.should raise_error(IOError)
|
||||
end
|
||||
|
|
|
@ -12,45 +12,232 @@ describe "IO#set_encoding_by_bom" do
|
|||
rm_r @name
|
||||
end
|
||||
|
||||
it "returns nil if not readable" do
|
||||
not_readable_io = new_io(@name, 'wb')
|
||||
|
||||
not_readable_io.set_encoding_by_bom.should be_nil
|
||||
not_readable_io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
ensure
|
||||
not_readable_io.close
|
||||
end
|
||||
|
||||
it "returns the result encoding if found BOM UTF-8 sequence" do
|
||||
File.binwrite(@name, "\u{FEFF}")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_8
|
||||
@io.external_encoding.should == Encoding::UTF_8
|
||||
@io.read.b.should == "".b
|
||||
@io.rewind
|
||||
@io.set_encoding(Encoding::ASCII_8BIT)
|
||||
|
||||
File.binwrite(@name, "\u{FEFF}abc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_8
|
||||
@io.external_encoding.should == Encoding::UTF_8
|
||||
@io.read.b.should == "abc".b
|
||||
end
|
||||
|
||||
it "returns the result encoding if found BOM UTF_16LE sequence" do
|
||||
File.binwrite(@name, "\xFF\xFE")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_16LE
|
||||
@io.external_encoding.should == Encoding::UTF_16LE
|
||||
@io.read.b.should == "".b
|
||||
@io.rewind
|
||||
@io.set_encoding(Encoding::ASCII_8BIT)
|
||||
|
||||
File.binwrite(@name, "\xFF\xFEabc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_16LE
|
||||
@io.external_encoding.should == Encoding::UTF_16LE
|
||||
@io.read.b.should == "abc".b
|
||||
end
|
||||
|
||||
it "returns the result encoding if found BOM UTF_16BE sequence" do
|
||||
File.binwrite(@name, "\xFE\xFF")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_16BE
|
||||
@io.external_encoding.should == Encoding::UTF_16BE
|
||||
@io.read.b.should == "".b
|
||||
@io.rewind
|
||||
@io.set_encoding(Encoding::ASCII_8BIT)
|
||||
|
||||
File.binwrite(@name, "\xFE\xFFabc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_16BE
|
||||
@io.external_encoding.should == Encoding::UTF_16BE
|
||||
@io.read.b.should == "abc".b
|
||||
end
|
||||
|
||||
it "returns the result encoding if found BOM UTF_32LE sequence" do
|
||||
File.binwrite(@name, "\xFF\xFE\x00\x00")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_32LE
|
||||
@io.external_encoding.should == Encoding::UTF_32LE
|
||||
@io.read.b.should == "".b
|
||||
@io.rewind
|
||||
@io.set_encoding(Encoding::ASCII_8BIT)
|
||||
|
||||
File.binwrite(@name, "\xFF\xFE\x00\x00abc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_32LE
|
||||
@io.external_encoding.should == Encoding::UTF_32LE
|
||||
@io.read.b.should == "abc".b
|
||||
end
|
||||
|
||||
it "returns the result encoding if found BOM UTF_32BE sequence" do
|
||||
File.binwrite(@name, "\x00\x00\xFE\xFF")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_32BE
|
||||
@io.external_encoding.should == Encoding::UTF_32BE
|
||||
@io.read.b.should == "".b
|
||||
@io.rewind
|
||||
@io.set_encoding(Encoding::ASCII_8BIT)
|
||||
|
||||
File.binwrite(@name, "\x00\x00\xFE\xFFabc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_32BE
|
||||
@io.external_encoding.should == Encoding::UTF_32BE
|
||||
@io.read.b.should == "abc".b
|
||||
end
|
||||
|
||||
it "returns nil if io is empty" do
|
||||
@io.set_encoding_by_bom.should be_nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
end
|
||||
|
||||
it "returns nil if UTF-8 BOM sequence is incomplete" do
|
||||
File.write(@name, "\xEF")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\xEF".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\xEFa")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\xEFa".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\xEF\xBB")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\xEF\xBB".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\xEF\xBBa")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\xEF\xBBa".b
|
||||
end
|
||||
|
||||
it "returns nil if UTF-16BE BOM sequence is incomplete" do
|
||||
File.write(@name, "\xFE")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\xFE".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\xFEa")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\xFEa".b
|
||||
end
|
||||
|
||||
it "returns nil if UTF-16LE/UTF-32LE BOM sequence is incomplete" do
|
||||
File.write(@name, "\xFF")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\xFF".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\xFFa")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\xFFa".b
|
||||
end
|
||||
|
||||
it "returns UTF-16LE if UTF-32LE BOM sequence is incomplete" do
|
||||
File.write(@name, "\xFF\xFE")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_16LE
|
||||
@io.external_encoding.should == Encoding::UTF_16LE
|
||||
@io.read.b.should == "".b
|
||||
@io.rewind
|
||||
@io.set_encoding(Encoding::ASCII_8BIT)
|
||||
|
||||
File.write(@name, "\xFF\xFE\x00")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_16LE
|
||||
@io.external_encoding.should == Encoding::UTF_16LE
|
||||
@io.read.b.should == "\x00".b
|
||||
@io.rewind
|
||||
@io.set_encoding(Encoding::ASCII_8BIT)
|
||||
|
||||
File.write(@name, "\xFF\xFE\x00a")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_16LE
|
||||
@io.external_encoding.should == Encoding::UTF_16LE
|
||||
@io.read.b.should == "\x00a".b
|
||||
end
|
||||
|
||||
it "returns nil if UTF-32BE BOM sequence is incomplete" do
|
||||
File.write(@name, "\x00")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\x00".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\x00a")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\x00a".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\x00\x00")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\x00\x00".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\x00\x00a")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\x00\x00a".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\x00\x00\xFE")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\x00\x00\xFE".b
|
||||
@io.rewind
|
||||
|
||||
File.write(@name, "\x00\x00\xFEa")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read.b.should == "\x00\x00\xFEa".b
|
||||
end
|
||||
|
||||
it "returns nil if found BOM sequence not provided" do
|
||||
File.write(@name, "abc")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
@io.external_encoding.should == Encoding::ASCII_8BIT
|
||||
@io.read(3).should == "abc".b
|
||||
end
|
||||
|
||||
it 'returns exception if io not in binary mode' do
|
||||
|
|
|
@ -188,4 +188,21 @@ describe "IO#set_encoding" do
|
|||
@io.external_encoding.should == Encoding::UTF_8
|
||||
@io.internal_encoding.should == Encoding::UTF_16BE
|
||||
end
|
||||
|
||||
it "saves encoding options passed as a hash in the last argument" do
|
||||
File.write(@name, "\xff")
|
||||
io = File.open(@name)
|
||||
io.set_encoding(Encoding::EUC_JP, Encoding::SHIFT_JIS, invalid: :replace, replace: ".")
|
||||
io.read.should == "."
|
||||
ensure
|
||||
io.close
|
||||
end
|
||||
|
||||
it "raises ArgumentError when no arguments are given" do
|
||||
-> { @io.set_encoding() }.should raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "raises ArgumentError when too many arguments are given" do
|
||||
-> { @io.set_encoding(1, 2, 3) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -113,6 +113,13 @@ describe :io_each, shared: true do
|
|||
@io.send(@method, "") { |s| ScratchPad << s }
|
||||
ScratchPad.recorded.should == IOSpecs.paragraphs
|
||||
end
|
||||
|
||||
it "discards leading newlines" do
|
||||
@io.readline
|
||||
@io.readline
|
||||
@io.send(@method, "") { |s| ScratchPad << s }
|
||||
ScratchPad.recorded.should == IOSpecs.paragraphs[1..-1]
|
||||
end
|
||||
end
|
||||
|
||||
describe "with both separator and limit" do
|
||||
|
@ -152,6 +159,13 @@ describe :io_each, shared: true do
|
|||
@io.send(@method, "", 1024) { |s| ScratchPad << s }
|
||||
ScratchPad.recorded.should == IOSpecs.paragraphs
|
||||
end
|
||||
|
||||
it "discards leading newlines" do
|
||||
@io.readline
|
||||
@io.readline
|
||||
@io.send(@method, "", 1024) { |s| ScratchPad << s }
|
||||
ScratchPad.recorded.should == IOSpecs.paragraphs[1..-1]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -220,6 +234,14 @@ describe :io_each, shared: true do
|
|||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passed too many arguments" do
|
||||
it "raises ArgumentError" do
|
||||
-> {
|
||||
@io.send(@method, "", 1, "excess argument", chomp: true) {}
|
||||
}.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :io_each_default_separator, shared: true do
|
||||
|
|
|
@ -69,16 +69,6 @@ describe :io_write, shared: true do
|
|||
-> { IOSpecs.closed_io.send(@method, "hello") }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
it "does not modify the passed argument" do
|
||||
File.open(@filename, "w") do |f|
|
||||
f.set_encoding(Encoding::IBM437)
|
||||
# A character whose codepoint differs between UTF-8 and IBM437
|
||||
f.write "ƒ".freeze
|
||||
end
|
||||
|
||||
File.binread(@filename).bytes.should == [159]
|
||||
end
|
||||
|
||||
describe "on a pipe" do
|
||||
before :each do
|
||||
@r, @w = IO.pipe
|
||||
|
|
|
@ -6,7 +6,7 @@ describe "IO#sysread on a file" do
|
|||
@file_name = tmp("IO_sysread_file") + $$.to_s
|
||||
File.open(@file_name, "w") do |f|
|
||||
# write some stuff
|
||||
f.write("012345678901234567890123456789")
|
||||
f.write("012345678901234567890123456789\nabcdef")
|
||||
end
|
||||
@file = File.open(@file_name, "r+")
|
||||
end
|
||||
|
@ -84,6 +84,29 @@ describe "IO#sysread on a file" do
|
|||
it "raises IOError on closed stream" do
|
||||
-> { IOSpecs.closed_io.sysread(5) }.should raise_error(IOError)
|
||||
end
|
||||
|
||||
it "immediately returns an empty string if the length argument is 0" do
|
||||
@file.sysread(0).should == ""
|
||||
end
|
||||
|
||||
it "immediately returns the given buffer if the length argument is 0" do
|
||||
buffer = "existing content"
|
||||
@file.sysread(0, buffer).should == buffer
|
||||
buffer.should == "existing content"
|
||||
end
|
||||
|
||||
it "discards the existing buffer content upon successful read" do
|
||||
buffer = "existing content"
|
||||
@file.sysread(11, buffer)
|
||||
buffer.should == "01234567890"
|
||||
end
|
||||
|
||||
it "discards the existing buffer content upon error" do
|
||||
buffer = "existing content"
|
||||
@file.seek(0, :END)
|
||||
-> { @file.sysread(1, buffer) }.should raise_error(EOFError)
|
||||
buffer.should be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe "IO#sysread" do
|
||||
|
@ -100,4 +123,10 @@ describe "IO#sysread" do
|
|||
@write.syswrite "ab"
|
||||
@read.sysread(3).should == "ab"
|
||||
end
|
||||
|
||||
guard_not -> { platform_is :windows and ruby_version_is ""..."3.2" } do # https://bugs.ruby-lang.org/issues/18880
|
||||
it "raises ArgumentError when length is less than 0" do
|
||||
-> { @read.sysread(-1) }.should raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,6 +29,16 @@ describe "IO#syswrite on a file" do
|
|||
end
|
||||
end
|
||||
|
||||
it "does not modify the passed argument" do
|
||||
File.open(@filename, "w") do |f|
|
||||
f.set_encoding(Encoding::IBM437)
|
||||
# A character whose codepoint differs between UTF-8 and IBM437
|
||||
f.syswrite("ƒ".freeze)
|
||||
end
|
||||
|
||||
File.binread(@filename).bytes.should == [198, 146]
|
||||
end
|
||||
|
||||
it "warns if called immediately after a buffered IO#write" do
|
||||
@file.write("abcde")
|
||||
-> { @file.syswrite("fghij") }.should complain(/syswrite/)
|
||||
|
|
|
@ -31,6 +31,16 @@ platform_is_not :windows do
|
|||
end
|
||||
end
|
||||
|
||||
it "does not modify the passed argument" do
|
||||
File.open(@filename, "w") do |f|
|
||||
f.set_encoding(Encoding::IBM437)
|
||||
# A character whose codepoint differs between UTF-8 and IBM437
|
||||
f.write_nonblock("ƒ".freeze)
|
||||
end
|
||||
|
||||
File.binread(@filename).bytes.should == [198, 146]
|
||||
end
|
||||
|
||||
it "checks if the file is writable if writing zero bytes" do
|
||||
-> {
|
||||
@readonly_file.write_nonblock("")
|
||||
|
|
|
@ -44,6 +44,16 @@ describe "IO#write on a file" do
|
|||
@file.write("hellø").should == 6
|
||||
end
|
||||
|
||||
it "does not modify the passed argument" do
|
||||
File.open(@filename, "w") do |f|
|
||||
f.set_encoding(Encoding::IBM437)
|
||||
# A character whose codepoint differs between UTF-8 and IBM437
|
||||
f.write("ƒ".freeze)
|
||||
end
|
||||
|
||||
File.binread(@filename).bytes.should == [159]
|
||||
end
|
||||
|
||||
it "uses the encoding from the given option for non-ascii encoding" do
|
||||
File.open(@filename, "w", encoding: Encoding::UTF_32LE) do |file|
|
||||
file.write("hi").should == 8
|
||||
|
|
|
@ -76,10 +76,8 @@ describe "Kernel#p" do
|
|||
-> { p(*[]) }.should output("")
|
||||
end
|
||||
|
||||
=begin Not sure how to spec this, but wanted to note the behavior here
|
||||
it "does not flush if receiver is not a TTY or a File" do
|
||||
end
|
||||
=end
|
||||
# Not sure how to spec this, but wanted to note the behavior here
|
||||
it "does not flush if receiver is not a TTY or a File"
|
||||
end
|
||||
|
||||
describe "Kernel.p" do
|
||||
|
|
|
@ -213,4 +213,28 @@ module MethodSpecs
|
|||
n * m
|
||||
end
|
||||
end
|
||||
|
||||
module InheritedMethods
|
||||
module A
|
||||
private
|
||||
def derp(message)
|
||||
'A'
|
||||
end
|
||||
end
|
||||
|
||||
module B
|
||||
private
|
||||
def derp
|
||||
'B' + super('superclass')
|
||||
end
|
||||
end
|
||||
|
||||
class C
|
||||
include A
|
||||
include B
|
||||
|
||||
public :derp
|
||||
alias_method :meow, :derp
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,4 +42,32 @@ describe "Method#super_method" do
|
|||
|
||||
method.super_method.should == nil
|
||||
end
|
||||
|
||||
# https://github.com/jruby/jruby/issues/7240
|
||||
context "after changing an inherited methods visibility" do
|
||||
it "calls the proper super method" do
|
||||
MethodSpecs::InheritedMethods::C.new.derp.should == 'BA'
|
||||
end
|
||||
|
||||
ruby_version_is ""..."3.2" do
|
||||
it "returns the expected super_method" do
|
||||
method = MethodSpecs::InheritedMethods::C.new.method(:derp)
|
||||
method.super_method.owner.should == MethodSpecs::InheritedMethods::A
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "3.2" do
|
||||
it "returns the expected super_method" do
|
||||
method = MethodSpecs::InheritedMethods::C.new.method(:derp)
|
||||
method.super_method.owner.should == MethodSpecs::InheritedMethods::B
|
||||
end
|
||||
end
|
||||
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
|
||||
|
|
|
@ -17,11 +17,16 @@ describe "Module#const_defined?" do
|
|||
ConstantSpecs::ContainerA::ChildA.const_defined?(:CS_CONST4).should be_true
|
||||
end
|
||||
|
||||
it "returns true if the constant is defined in a mixed-in module of the receiver" do
|
||||
it "returns true if the constant is defined in a mixed-in module of the receiver's parent" do
|
||||
# CS_CONST10 is defined in a module included by ChildA
|
||||
ConstantSpecs::ContainerA::ChildA.const_defined?(:CS_CONST10).should be_true
|
||||
end
|
||||
|
||||
it "returns true if the constant is defined in a mixed-in module (with prepends) of the receiver" do
|
||||
# CS_CONST11 is defined in the module included by ContainerPrepend
|
||||
ConstantSpecs::ContainerPrepend.const_defined?(:CS_CONST11).should be_true
|
||||
end
|
||||
|
||||
it "returns true if the constant is defined in Object and the receiver is a module" do
|
||||
# CS_CONST1 is defined in Object
|
||||
ConstantSpecs::ModuleA.const_defined?(:CS_CONST1).should be_true
|
||||
|
|
|
@ -219,18 +219,55 @@ describe "Module#define_method" do
|
|||
o.block_test2.should == o
|
||||
end
|
||||
|
||||
it "raises TypeError if name cannot converted to String" do
|
||||
-> {
|
||||
Class.new { define_method(1001, -> {}) }
|
||||
}.should raise_error(TypeError, /is not a symbol nor a string/)
|
||||
|
||||
-> {
|
||||
Class.new { define_method([], -> {}) }
|
||||
}.should raise_error(TypeError, /is not a symbol nor a string/)
|
||||
end
|
||||
|
||||
it "converts non-String name to String with #to_str" do
|
||||
obj = Object.new
|
||||
def obj.to_str() "foo" end
|
||||
|
||||
new_class = Class.new { define_method(obj, -> { :called }) }
|
||||
new_class.new.foo.should == :called
|
||||
end
|
||||
|
||||
it "raises TypeError when #to_str called on non-String name returns non-String value" do
|
||||
obj = Object.new
|
||||
def obj.to_str() [] end
|
||||
|
||||
-> {
|
||||
Class.new { define_method(obj, -> {}) }
|
||||
}.should raise_error(TypeError, /can't convert Object to String/)
|
||||
end
|
||||
|
||||
it "raises a TypeError when the given method is no Method/Proc" do
|
||||
-> {
|
||||
Class.new { define_method(:test, "self") }
|
||||
}.should raise_error(TypeError)
|
||||
}.should raise_error(TypeError, "wrong argument type String (expected Proc/Method/UnboundMethod)")
|
||||
|
||||
-> {
|
||||
Class.new { define_method(:test, 1234) }
|
||||
}.should raise_error(TypeError)
|
||||
}.should raise_error(TypeError, "wrong argument type Integer (expected Proc/Method/UnboundMethod)")
|
||||
|
||||
-> {
|
||||
Class.new { define_method(:test, nil) }
|
||||
}.should raise_error(TypeError)
|
||||
}.should raise_error(TypeError, "wrong argument type NilClass (expected Proc/Method/UnboundMethod)")
|
||||
end
|
||||
|
||||
it "uses provided Method/Proc even if block is specified" do
|
||||
new_class = Class.new do
|
||||
define_method(:test, -> { :method_is_called }) do
|
||||
:block_is_called
|
||||
end
|
||||
end
|
||||
|
||||
new_class.new.test.should == :method_is_called
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when no block is given" do
|
||||
|
|
|
@ -42,6 +42,14 @@ module ModuleSpecs
|
|||
class LookupChild < Lookup
|
||||
end
|
||||
|
||||
module ModuleWithPrepend
|
||||
prepend LookupMod
|
||||
end
|
||||
|
||||
class WithPrependedModule
|
||||
include ModuleWithPrepend
|
||||
end
|
||||
|
||||
class Parent
|
||||
# For private_class_method spec
|
||||
def self.private_method; end
|
||||
|
|
|
@ -4,9 +4,11 @@ require_relative 'fixtures/classes'
|
|||
describe "Module#included_modules" do
|
||||
it "returns a list of modules included in self" do
|
||||
ModuleSpecs.included_modules.should == []
|
||||
|
||||
ModuleSpecs::Child.included_modules.should include(ModuleSpecs::Super, ModuleSpecs::Basic, Kernel)
|
||||
ModuleSpecs::Parent.included_modules.should include(Kernel)
|
||||
ModuleSpecs::Basic.included_modules.should == []
|
||||
ModuleSpecs::Super.included_modules.should include(ModuleSpecs::Basic)
|
||||
ModuleSpecs::WithPrependedModule.included_modules.should include(ModuleSpecs::ModuleWithPrepend)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,14 +51,36 @@ describe "Module#instance_method" do
|
|||
@mod_um.inspect.should =~ /\bModuleSpecs::InstanceMethChild\b/
|
||||
end
|
||||
|
||||
it "raises a TypeError if not passed a symbol" do
|
||||
-> { Object.instance_method([]) }.should raise_error(TypeError)
|
||||
-> { Object.instance_method(0) }.should raise_error(TypeError)
|
||||
it "raises a TypeError if the given name is not a String/Symbol" do
|
||||
-> { Object.instance_method([]) }.should raise_error(TypeError, /is not a symbol nor a string/)
|
||||
-> { Object.instance_method(0) }.should raise_error(TypeError, /is not a symbol nor a string/)
|
||||
-> { Object.instance_method(nil) }.should raise_error(TypeError, /is not a symbol nor a string/)
|
||||
-> { Object.instance_method(mock('x')) }.should raise_error(TypeError, /is not a symbol nor a string/)
|
||||
end
|
||||
|
||||
it "raises a TypeError if the given name is not a string/symbol" do
|
||||
-> { Object.instance_method(nil) }.should raise_error(TypeError)
|
||||
-> { Object.instance_method(mock('x')) }.should raise_error(TypeError)
|
||||
it "accepts String name argument" do
|
||||
method = ModuleSpecs::InstanceMeth.instance_method(:foo)
|
||||
method.should be_kind_of(UnboundMethod)
|
||||
end
|
||||
|
||||
it "accepts Symbol name argument" do
|
||||
method = ModuleSpecs::InstanceMeth.instance_method("foo")
|
||||
method.should be_kind_of(UnboundMethod)
|
||||
end
|
||||
|
||||
it "converts non-String name by calling #to_str method" do
|
||||
obj = Object.new
|
||||
def obj.to_str() "foo" end
|
||||
|
||||
method = ModuleSpecs::InstanceMeth.instance_method(obj)
|
||||
method.should be_kind_of(UnboundMethod)
|
||||
end
|
||||
|
||||
it "raises TypeError when passed non-String name and #to_str returns non-String value" do
|
||||
obj = Object.new
|
||||
def obj.to_str() [] end
|
||||
|
||||
-> { ModuleSpecs::InstanceMeth.instance_method(obj) }.should raise_error(TypeError, /can't convert Object to String/)
|
||||
end
|
||||
|
||||
it "raises a NameError if the method has been undefined" do
|
||||
|
|
|
@ -55,40 +55,49 @@ describe :module_class_eval, shared: true do
|
|||
it "converts a non-string filename to a string using to_str" do
|
||||
(file = mock(__FILE__)).should_receive(:to_str).and_return(__FILE__)
|
||||
ModuleSpecs.send(@method, "1+1", file)
|
||||
|
||||
(file = mock(__FILE__)).should_receive(:to_str).and_return(__FILE__)
|
||||
ModuleSpecs.send(@method, "1+1", file, 15)
|
||||
end
|
||||
|
||||
it "raises a TypeError when the given filename can't be converted to string using to_str" do
|
||||
(file = mock('123')).should_receive(:to_str).and_return(123)
|
||||
-> { ModuleSpecs.send(@method, "1+1", file) }.should raise_error(TypeError)
|
||||
-> { ModuleSpecs.send(@method, "1+1", file) }.should raise_error(TypeError, /can't convert MockObject to String/)
|
||||
end
|
||||
|
||||
it "converts non string eval-string to string using to_str" do
|
||||
(o = mock('1 + 1')).should_receive(:to_str).and_return("1 + 1")
|
||||
ModuleSpecs.send(@method, o).should == 2
|
||||
|
||||
(o = mock('1 + 1')).should_receive(:to_str).and_return("1 + 1")
|
||||
ModuleSpecs.send(@method, o, "file.rb").should == 2
|
||||
|
||||
(o = mock('1 + 1')).should_receive(:to_str).and_return("1 + 1")
|
||||
ModuleSpecs.send(@method, o, "file.rb", 15).should == 2
|
||||
end
|
||||
|
||||
it "raises a TypeError when the given eval-string can't be converted to string using to_str" do
|
||||
o = mock('x')
|
||||
-> { ModuleSpecs.send(@method, o) }.should raise_error(TypeError)
|
||||
-> { ModuleSpecs.send(@method, o) }.should raise_error(TypeError, "no implicit conversion of MockObject into String")
|
||||
|
||||
(o = mock('123')).should_receive(:to_str).and_return(123)
|
||||
-> { ModuleSpecs.send(@method, o) }.should raise_error(TypeError)
|
||||
-> { ModuleSpecs.send(@method, o) }.should raise_error(TypeError, /can't convert MockObject to String/)
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when no arguments and no block are given" do
|
||||
-> { ModuleSpecs.send(@method) }.should raise_error(ArgumentError)
|
||||
-> { ModuleSpecs.send(@method) }.should raise_error(ArgumentError, "wrong number of arguments (given 0, expected 1..3)")
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when more than 3 arguments are given" do
|
||||
-> {
|
||||
ModuleSpecs.send(@method, "1 + 1", "some file", 0, "bogus")
|
||||
}.should raise_error(ArgumentError)
|
||||
}.should raise_error(ArgumentError, "wrong number of arguments (given 4, expected 1..3)")
|
||||
end
|
||||
|
||||
it "raises an ArgumentError when a block and normal arguments are given" do
|
||||
-> {
|
||||
ModuleSpecs.send(@method, "1 + 1") { 1 + 1 }
|
||||
}.should raise_error(ArgumentError)
|
||||
}.should raise_error(ArgumentError, "wrong number of arguments (given 1, expected 0)")
|
||||
end
|
||||
|
||||
# This case was found because Rubinius was caching the compiled
|
||||
|
|
|
@ -29,9 +29,35 @@ describe "String#split with String" do
|
|||
"1,2,,3,4,,".split(',').should == ["1", "2", "", "3", "4"]
|
||||
"1,2,,3,4,,".split(',', 0).should == ["1", "2", "", "3", "4"]
|
||||
" a b c\nd ".split(" ").should == ["", "a", "b", "c\nd"]
|
||||
" a あ c\nd ".split(" ").should == ["", "a", "あ", "c\nd"]
|
||||
"hai".split("hai").should == []
|
||||
",".split(",").should == []
|
||||
",".split(",", 0).should == []
|
||||
"あ".split("あ").should == []
|
||||
"あ".split("あ", 0).should == []
|
||||
end
|
||||
|
||||
it "does not suppress trailing empty fields when a positive limit is given" do
|
||||
" 1 2 ".split(" ", 2).should == ["1", "2 "]
|
||||
" 1 2 ".split(" ", 3).should == ["1", "2", ""]
|
||||
" 1 2 ".split(" ", 4).should == ["1", "2", ""]
|
||||
" 1 あ ".split(" ", 2).should == ["1", "あ "]
|
||||
" 1 あ ".split(" ", 3).should == ["1", "あ", ""]
|
||||
" 1 あ ".split(" ", 4).should == ["1", "あ", ""]
|
||||
|
||||
"1,2,".split(',', 2).should == ["1", "2,"]
|
||||
"1,2,".split(',', 3).should == ["1", "2", ""]
|
||||
"1,2,".split(',', 4).should == ["1", "2", ""]
|
||||
"1,あ,".split(',', 2).should == ["1", "あ,"]
|
||||
"1,あ,".split(',', 3).should == ["1", "あ", ""]
|
||||
"1,あ,".split(',', 4).should == ["1", "あ", ""]
|
||||
|
||||
"1 2 ".split(/ /, 2).should == ["1", "2 "]
|
||||
"1 2 ".split(/ /, 3).should == ["1", "2", ""]
|
||||
"1 2 ".split(/ /, 4).should == ["1", "2", ""]
|
||||
"1 あ ".split(/ /, 2).should == ["1", "あ "]
|
||||
"1 あ ".split(/ /, 3).should == ["1", "あ", ""]
|
||||
"1 あ ".split(/ /, 4).should == ["1", "あ", ""]
|
||||
end
|
||||
|
||||
it "returns an array with one entry if limit is 1: the original string" do
|
||||
|
|
|
@ -17,6 +17,15 @@ describe 'Thread::Backtrace::Location#absolute_path' do
|
|||
end
|
||||
end
|
||||
|
||||
it 'returns the correct absolute path when using a relative main script path and changing CWD' do
|
||||
script = fixture(__FILE__, 'subdir/absolute_path_main_chdir.rb')
|
||||
sibling = fixture(__FILE__, 'subdir/sibling.rb')
|
||||
subdir = File.dirname script
|
||||
Dir.chdir(fixture(__FILE__)) do
|
||||
ruby_exe('subdir/absolute_path_main_chdir.rb').should == "subdir/absolute_path_main_chdir.rb\n#{subdir}\n#{subdir}\n#{script}\n#{sibling}\n"
|
||||
end
|
||||
end
|
||||
|
||||
context "when used in eval with a given filename" do
|
||||
code = "caller_locations(0)[0].absolute_path"
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
puts __FILE__
|
||||
puts __dir__
|
||||
Dir.chdir __dir__
|
||||
|
||||
# Check __dir__ is still correct after chdir
|
||||
puts __dir__
|
||||
|
||||
puts caller_locations(0)[0].absolute_path
|
||||
|
||||
# require_relative also needs to know the absolute path of the current file so we test it here too
|
||||
require_relative 'sibling'
|
|
@ -0,0 +1 @@
|
|||
puts __FILE__
|
|
@ -84,4 +84,14 @@ module UnboundMethodSpecs
|
|||
class C < B
|
||||
def overridden; end
|
||||
end
|
||||
|
||||
module HashSpecs
|
||||
class SuperClass
|
||||
def foo
|
||||
end
|
||||
end
|
||||
|
||||
class SubClass < SuperClass
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,4 +12,11 @@ describe "UnboundMethod#hash" do
|
|||
to_s, inspect = Array.instance_method(:to_s), Array.instance_method(:inspect)
|
||||
to_s.hash.should == inspect.hash
|
||||
end
|
||||
|
||||
it "equals a hash of the same method in the superclass" do
|
||||
foo_in_superclass = UnboundMethodSpecs::HashSpecs::SuperClass.instance_method(:foo)
|
||||
foo = UnboundMethodSpecs::HashSpecs::SubClass.instance_method(:foo)
|
||||
|
||||
foo.hash.should == foo_in_superclass.hash
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
require_relative '../method/fixtures/classes'
|
||||
|
||||
describe "UnboundMethod#super_method" do
|
||||
it "returns the method that would be called by super in the method" do
|
||||
|
@ -25,4 +26,28 @@ describe "UnboundMethod#super_method" do
|
|||
|
||||
method.super_method.should == nil
|
||||
end
|
||||
|
||||
# https://github.com/jruby/jruby/issues/7240
|
||||
context "after changing an inherited methods visibility" do
|
||||
ruby_version_is ""..."3.2" do
|
||||
it "returns the expected super_method" do
|
||||
method = MethodSpecs::InheritedMethods::C.instance_method(:derp)
|
||||
method.super_method.owner.should == MethodSpecs::InheritedMethods::A
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "3.2" do
|
||||
it "returns the expected super_method" do
|
||||
method = MethodSpecs::InheritedMethods::C.instance_method(:derp)
|
||||
method.super_method.owner.should == MethodSpecs::InheritedMethods::B
|
||||
end
|
||||
end
|
||||
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
|
||||
|
|
|
@ -75,6 +75,13 @@ module ConstantSpecs
|
|||
CS_CONST10 = :const10_8
|
||||
end
|
||||
|
||||
# Included in ContainerA
|
||||
module ModuleIncludePrepended
|
||||
prepend ModuleD
|
||||
|
||||
CS_CONST11 = :const11_8
|
||||
end
|
||||
|
||||
# The following classes/modules have all the constants set "statically".
|
||||
# Contrast with the classes below where the constants are set as the specs
|
||||
# are run.
|
||||
|
@ -169,6 +176,10 @@ module ConstantSpecs
|
|||
def const10; CS_CONST10; end
|
||||
end
|
||||
|
||||
class ContainerPrepend
|
||||
include ModuleIncludePrepended
|
||||
end
|
||||
|
||||
class ContainerA::ChildA
|
||||
def self.const23; CS_CONST23; end
|
||||
end
|
||||
|
|
|
@ -14,46 +14,44 @@ require_relative 'fixtures/precedence'
|
|||
# the level below (as well as showing associativity within
|
||||
# the precedence level).
|
||||
|
||||
=begin
|
||||
Excerpted from 'Programming Ruby: The Pragmatic Programmer's Guide'
|
||||
Second Edition by Dave Thomas, Chad Fowler, and Andy Hunt, page 324
|
||||
|
||||
Table 22.4. Ruby operators (high to low precedence)
|
||||
Method Operator Description
|
||||
-----------------------------------------------------------------------
|
||||
:: .
|
||||
x* [ ] [ ]= Element reference, element set
|
||||
x ** Exponentiation
|
||||
x ! ~ + - Not, complement, unary plus and minus
|
||||
(method names for the last two are +@ and -@)
|
||||
x * / % Multiply, divide, and modulo
|
||||
x + - Plus and minus
|
||||
x >> << Right and left shift
|
||||
x & “And” (bitwise for integers)
|
||||
x ^ | Exclusive “or” and regular “or” (bitwise for integers)
|
||||
x <= < > >= Comparison operators
|
||||
x <=> == === != =~ !~ Equality and pattern match operators (!=
|
||||
and !~ may not be defined as methods)
|
||||
&& Logical “and”
|
||||
|| Logical “or”
|
||||
.. ... Range (inclusive and exclusive)
|
||||
? : Ternary if-then-else
|
||||
= %= /= -= += |= &= Assignment
|
||||
>>= <<= *= &&= ||= **=
|
||||
defined? Check if symbol defined
|
||||
not Logical negation
|
||||
or and Logical composition
|
||||
if unless while until Expression modifiers
|
||||
begin/end Block expression
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
* Operators marked with 'x' in the Method column are implemented as methods
|
||||
and can be overridden (except != and !~ as noted). (But see the specs
|
||||
below for implementations that define != and !~ as methods.)
|
||||
|
||||
** These are not included in the excerpted table but are shown here for
|
||||
completeness.
|
||||
=end
|
||||
# Excerpted from 'Programming Ruby: The Pragmatic Programmer's Guide'
|
||||
# Second Edition by Dave Thomas, Chad Fowler, and Andy Hunt, page 324
|
||||
#
|
||||
# Table 22.4. Ruby operators (high to low precedence)
|
||||
# Method Operator Description
|
||||
# -----------------------------------------------------------------------
|
||||
# :: .
|
||||
# x* [ ] [ ]= Element reference, element set
|
||||
# x ** Exponentiation
|
||||
# x ! ~ + - Not, complement, unary plus and minus
|
||||
# (method names for the last two are +@ and -@)
|
||||
# x * / % Multiply, divide, and modulo
|
||||
# x + - Plus and minus
|
||||
# x >> << Right and left shift
|
||||
# x & “And” (bitwise for integers)
|
||||
# x ^ | Exclusive “or” and regular “or” (bitwise for integers)
|
||||
# x <= < > >= Comparison operators
|
||||
# x <=> == === != =~ !~ Equality and pattern match operators (!=
|
||||
# and !~ may not be defined as methods)
|
||||
# && Logical “and”
|
||||
# || Logical “or”
|
||||
# .. ... Range (inclusive and exclusive)
|
||||
# ? : Ternary if-then-else
|
||||
# = %= /= -= += |= &= Assignment
|
||||
# >>= <<= *= &&= ||= **=
|
||||
# defined? Check if symbol defined
|
||||
# not Logical negation
|
||||
# or and Logical composition
|
||||
# if unless while until Expression modifiers
|
||||
# begin/end Block expression
|
||||
# -----------------------------------------------------------------------
|
||||
#
|
||||
# * Operators marked with 'x' in the Method column are implemented as methods
|
||||
# and can be overridden (except != and !~ as noted). (But see the specs
|
||||
# below for implementations that define != and !~ as methods.)
|
||||
#
|
||||
# ** These are not included in the excerpted table but are shown here for
|
||||
# completeness.
|
||||
|
||||
# -----------------------------------------------------------------------
|
||||
# It seems that this table is not correct anymore
|
||||
|
|
|
@ -7,37 +7,33 @@ require 'stringio'
|
|||
# Entries marked [r/o] are read-only and an error will be raised of the program attempts to
|
||||
# modify them. Entries marked [thread] are thread local.
|
||||
|
||||
=begin
|
||||
Exception Information
|
||||
---------------------------------------------------------------------------------------------------
|
||||
# Exception Information
|
||||
# ---------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# $! Exception The exception object passed to raise. [thread]
|
||||
# $@ Array The stack backtrace generated by the last exception. [thread]
|
||||
|
||||
$! Exception The exception object passed to raise. [thread]
|
||||
$@ Array The stack backtrace generated by the last exception. [thread]
|
||||
=end
|
||||
|
||||
=begin
|
||||
Pattern Matching Variables
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
These variables are set to nil after an unsuccessful pattern match.
|
||||
|
||||
$& String The string matched (following a successful pattern match). This variable is
|
||||
local to the current scope. [r/o, thread]
|
||||
$+ String The contents of the highest-numbered group matched following a successful
|
||||
pattern match. Thus, in "cat" =~/(c|a)(t|z)/, $+ will be set to “t”. This
|
||||
variable is local to the current scope. [r/o, thread]
|
||||
$` String The string preceding the match in a successful pattern match. This variable
|
||||
is local to the current scope. [r/o, thread]
|
||||
$' String The string following the match in a successful pattern match. This variable
|
||||
is local to the current scope. [r/o, thread]
|
||||
$1 to $<N> String The contents of successive groups matched in a successful pattern match. In
|
||||
"cat" =~/(c|a)(t|z)/, $1 will be set to “a” and $2 to “t”. This variable
|
||||
is local to the current scope. [r/o, thread]
|
||||
$~ MatchData An object that encapsulates the results of a successful pattern match. The
|
||||
variables $&, $`, $', and $1 to $<N> are all derived from $~. Assigning to $~
|
||||
changes the values of these derived variables. This variable is local to the
|
||||
current scope. [thread]
|
||||
=end
|
||||
# Pattern Matching Variables
|
||||
# ---------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# These variables are set to nil after an unsuccessful pattern match.
|
||||
#
|
||||
# $& String The string matched (following a successful pattern match). This variable is
|
||||
# local to the current scope. [r/o, thread]
|
||||
# $+ String The contents of the highest-numbered group matched following a successful
|
||||
# pattern match. Thus, in "cat" =~/(c|a)(t|z)/, $+ will be set to “t”. This
|
||||
# variable is local to the current scope. [r/o, thread]
|
||||
# $` String The string preceding the match in a successful pattern match. This variable
|
||||
# is local to the current scope. [r/o, thread]
|
||||
# $' String The string following the match in a successful pattern match. This variable
|
||||
# is local to the current scope. [r/o, thread]
|
||||
# $1 to $<N> String The contents of successive groups matched in a successful pattern match. In
|
||||
# "cat" =~/(c|a)(t|z)/, $1 will be set to “a” and $2 to “t”. This variable
|
||||
# is local to the current scope. [r/o, thread]
|
||||
# $~ MatchData An object that encapsulates the results of a successful pattern match. The
|
||||
# variables $&, $`, $', and $1 to $<N> are all derived from $~. Assigning to $~
|
||||
# changes the values of these derived variables. This variable is local to the
|
||||
# current scope. [thread]
|
||||
|
||||
|
||||
describe "Predefined global $~" do
|
||||
|
@ -506,41 +502,39 @@ describe "Predefined global $!" do
|
|||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
Input/Output Variables
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
$/ String The input record separator (newline by default). This is the value that rou-
|
||||
tines such as Kernel#gets use to determine record boundaries. If set to
|
||||
nil, gets will read the entire file.
|
||||
$-0 String Synonym for $/.
|
||||
$\ String The string appended to the output of every call to methods such as
|
||||
Kernel#print and IO#write. The default value is nil.
|
||||
$, String The separator string output between the parameters to methods such as
|
||||
Kernel#print and Array#join. Defaults to nil, which adds no text.
|
||||
$. Integer The number of the last line read from the current input file.
|
||||
$; String The default separator pattern used by String#split. May be set from the
|
||||
command line using the -F flag.
|
||||
$< Object An object that provides access to the concatenation of the contents of all
|
||||
the files given as command-line arguments or $stdin (in the case where
|
||||
there are no arguments). $< supports methods similar to a File object:
|
||||
binmode, close, closed?, each, each_byte, each_line, eof, eof?,
|
||||
file, filename, fileno, getc, gets, lineno, lineno=, path, pos, pos=,
|
||||
read, readchar, readline, readlines, rewind, seek, skip, tell, to_a,
|
||||
to_i, to_io, to_s, along with the methods in Enumerable. The method
|
||||
file returns a File object for the file currently being read. This may change
|
||||
as $< reads through the files on the command line. [r/o]
|
||||
$> IO The destination of output for Kernel#print and Kernel#printf. The
|
||||
default value is $stdout.
|
||||
$_ String The last line read by Kernel#gets or Kernel#readline. Many string-
|
||||
related functions in the Kernel module operate on $_ by default. The vari-
|
||||
able is local to the current scope. [thread]
|
||||
$-F String Synonym for $;.
|
||||
$stderr IO The current standard error output.
|
||||
$stdin IO The current standard input.
|
||||
$stdout IO The current standard output. Assignment to $stdout is deprecated: use
|
||||
$stdout.reopen instead.
|
||||
=end
|
||||
# Input/Output Variables
|
||||
# ---------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# $/ String The input record separator (newline by default). This is the value that rou-
|
||||
# tines such as Kernel#gets use to determine record boundaries. If set to
|
||||
# nil, gets will read the entire file.
|
||||
# $-0 String Synonym for $/.
|
||||
# $\ String The string appended to the output of every call to methods such as
|
||||
# Kernel#print and IO#write. The default value is nil.
|
||||
# $, String The separator string output between the parameters to methods such as
|
||||
# Kernel#print and Array#join. Defaults to nil, which adds no text.
|
||||
# $. Integer The number of the last line read from the current input file.
|
||||
# $; String The default separator pattern used by String#split. May be set from the
|
||||
# command line using the -F flag.
|
||||
# $< Object An object that provides access to the concatenation of the contents of all
|
||||
# the files given as command-line arguments or $stdin (in the case where
|
||||
# there are no arguments). $< supports methods similar to a File object:
|
||||
# binmode, close, closed?, each, each_byte, each_line, eof, eof?,
|
||||
# file, filename, fileno, getc, gets, lineno, lineno=, path, pos, pos=,
|
||||
# read, readchar, readline, readlines, rewind, seek, skip, tell, to_a,
|
||||
# to_i, to_io, to_s, along with the methods in Enumerable. The method
|
||||
# file returns a File object for the file currently being read. This may change
|
||||
# as $< reads through the files on the command line. [r/o]
|
||||
# $> IO The destination of output for Kernel#print and Kernel#printf. The
|
||||
# default value is $stdout.
|
||||
# $_ String The last line read by Kernel#gets or Kernel#readline. Many string-
|
||||
# related functions in the Kernel module operate on $_ by default. The vari-
|
||||
# able is local to the current scope. [thread]
|
||||
# $-F String Synonym for $;.
|
||||
# $stderr IO The current standard error output.
|
||||
# $stdin IO The current standard input.
|
||||
# $stdout IO The current standard output. Assignment to $stdout is deprecated: use
|
||||
# $stdout.reopen instead.
|
||||
|
||||
describe "Predefined global $/" do
|
||||
before :each do
|
||||
|
@ -803,54 +797,52 @@ describe "Predefined global $_" do
|
|||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
Execution Environment Variables
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
$0 String The name of the top-level Ruby program being executed. Typically this will
|
||||
be the program’s filename. On some operating systems, assigning to this
|
||||
variable will change the name of the process reported (for example) by the
|
||||
ps(1) command.
|
||||
$* Array An array of strings containing the command-line options from the invoca-
|
||||
tion of the program. Options used by the Ruby interpreter will have been
|
||||
removed. [r/o]
|
||||
$" Array An array containing the filenames of modules loaded by require. [r/o]
|
||||
$$ Integer The process number of the program being executed. [r/o]
|
||||
$? Process::Status The exit status of the last child process to terminate. [r/o, thread]
|
||||
$: Array An array of strings, where each string specifies a directory to be searched for
|
||||
Ruby scripts and binary extensions used by the load and require methods.
|
||||
The initial value is the value of the arguments passed via the -I command-
|
||||
line option, followed by an installation-defined standard library location, fol-
|
||||
lowed by the current directory (“.”). This variable may be set from within a
|
||||
program to alter the default search path; typically, programs use $: << dir
|
||||
to append dir to the path. [r/o]
|
||||
$-a Object True if the -a option is specified on the command line. [r/o]
|
||||
$-d Object Synonym for $DEBUG.
|
||||
$DEBUG Object Set to true if the -d command-line option is specified.
|
||||
__FILE__ String The name of the current source file. [r/o]
|
||||
$F Array The array that receives the split input line if the -a command-line option is
|
||||
used.
|
||||
$FILENAME String The name of the current input file. Equivalent to $<.filename. [r/o]
|
||||
$-i String If in-place edit mode is enabled (perhaps using the -i command-line
|
||||
option), $-i holds the extension used when creating the backup file. If you
|
||||
set a value into $-i, enables in-place edit mode.
|
||||
$-I Array Synonym for $:. [r/o]
|
||||
$-K String Sets the multibyte coding system for strings and regular expressions. Equiv-
|
||||
alent to the -K command-line option.
|
||||
$-l Object Set to true if the -l option (which enables line-end processing) is present
|
||||
on the command line. [r/o]
|
||||
__LINE__ String The current line number in the source file. [r/o]
|
||||
$LOAD_PATH Array A synonym for $:. [r/o]
|
||||
$-p Object Set to true if the -p option (which puts an implicit while gets . . . end
|
||||
loop around your program) is present on the command line. [r/o]
|
||||
$VERBOSE Object Set to true if the -v, --version, -W, or -w option is specified on the com-
|
||||
mand line. Set to false if no option, or -W1 is given. Set to nil if -W0
|
||||
was specified. Setting this option to true causes the interpreter and some
|
||||
library routines to report additional information. Setting to nil suppresses
|
||||
all warnings (including the output of Kernel.warn).
|
||||
$-v Object Synonym for $VERBOSE.
|
||||
$-w Object Synonym for $VERBOSE.
|
||||
=end
|
||||
# Execution Environment Variables
|
||||
# ---------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# $0 String The name of the top-level Ruby program being executed. Typically this will
|
||||
# be the program’s filename. On some operating systems, assigning to this
|
||||
# variable will change the name of the process reported (for example) by the
|
||||
# ps(1) command.
|
||||
# $* Array An array of strings containing the command-line options from the invoca-
|
||||
# tion of the program. Options used by the Ruby interpreter will have been
|
||||
# removed. [r/o]
|
||||
# $" Array An array containing the filenames of modules loaded by require. [r/o]
|
||||
# $$ Integer The process number of the program being executed. [r/o]
|
||||
# $? Process::Status The exit status of the last child process to terminate. [r/o, thread]
|
||||
# $: Array An array of strings, where each string specifies a directory to be searched for
|
||||
# Ruby scripts and binary extensions used by the load and require methods.
|
||||
# The initial value is the value of the arguments passed via the -I command-
|
||||
# line option, followed by an installation-defined standard library location, fol-
|
||||
# lowed by the current directory (“.”). This variable may be set from within a
|
||||
# program to alter the default search path; typically, programs use $: << dir
|
||||
# to append dir to the path. [r/o]
|
||||
# $-a Object True if the -a option is specified on the command line. [r/o]
|
||||
# $-d Object Synonym for $DEBUG.
|
||||
# $DEBUG Object Set to true if the -d command-line option is specified.
|
||||
# __FILE__ String The name of the current source file. [r/o]
|
||||
# $F Array The array that receives the split input line if the -a command-line option is
|
||||
# used.
|
||||
# $FILENAME String The name of the current input file. Equivalent to $<.filename. [r/o]
|
||||
# $-i String If in-place edit mode is enabled (perhaps using the -i command-line
|
||||
# option), $-i holds the extension used when creating the backup file. If you
|
||||
# set a value into $-i, enables in-place edit mode.
|
||||
# $-I Array Synonym for $:. [r/o]
|
||||
# $-K String Sets the multibyte coding system for strings and regular expressions. Equiv-
|
||||
# alent to the -K command-line option.
|
||||
# $-l Object Set to true if the -l option (which enables line-end processing) is present
|
||||
# on the command line. [r/o]
|
||||
# __LINE__ String The current line number in the source file. [r/o]
|
||||
# $LOAD_PATH Array A synonym for $:. [r/o]
|
||||
# $-p Object Set to true if the -p option (which puts an implicit while gets . . . end
|
||||
# loop around your program) is present on the command line. [r/o]
|
||||
# $VERBOSE Object Set to true if the -v, --version, -W, or -w option is specified on the com-
|
||||
# mand line. Set to false if no option, or -W1 is given. Set to nil if -W0
|
||||
# was specified. Setting this option to true causes the interpreter and some
|
||||
# library routines to report additional information. Setting to nil suppresses
|
||||
# all warnings (including the output of Kernel.warn).
|
||||
# $-v Object Synonym for $VERBOSE.
|
||||
# $-w Object Synonym for $VERBOSE.
|
||||
describe "Execution variable $:" do
|
||||
it "is initialized to an array of strings" do
|
||||
$:.is_a?(Array).should == true
|
||||
|
@ -1068,22 +1060,20 @@ describe "Global variable $0" do
|
|||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
Standard Objects
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
ARGF Object A synonym for $<.
|
||||
ARGV Array A synonym for $*.
|
||||
ENV Object A hash-like object containing the program’s environment variables. An
|
||||
instance of class Object, ENV implements the full set of Hash methods. Used
|
||||
to query and set the value of an environment variable, as in ENV["PATH"]
|
||||
and ENV["term"]="ansi".
|
||||
false FalseClass Singleton instance of class FalseClass. [r/o]
|
||||
nil NilClass The singleton instance of class NilClass. The value of uninitialized
|
||||
instance and global variables. [r/o]
|
||||
self Object The receiver (object) of the current method. [r/o]
|
||||
true TrueClass Singleton instance of class TrueClass. [r/o]
|
||||
=end
|
||||
# Standard Objects
|
||||
# ---------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# ARGF Object A synonym for $<.
|
||||
# ARGV Array A synonym for $*.
|
||||
# ENV Object A hash-like object containing the program’s environment variables. An
|
||||
# instance of class Object, ENV implements the full set of Hash methods. Used
|
||||
# to query and set the value of an environment variable, as in ENV["PATH"]
|
||||
# and ENV["term"]="ansi".
|
||||
# false FalseClass Singleton instance of class FalseClass. [r/o]
|
||||
# nil NilClass The singleton instance of class NilClass. The value of uninitialized
|
||||
# instance and global variables. [r/o]
|
||||
# self Object The receiver (object) of the current method. [r/o]
|
||||
# true TrueClass Singleton instance of class TrueClass. [r/o]
|
||||
|
||||
describe "The predefined standard objects" do
|
||||
it "includes ARGF" do
|
||||
|
@ -1136,36 +1126,34 @@ describe "The self pseudo-variable" do
|
|||
end
|
||||
end
|
||||
|
||||
=begin
|
||||
Global Constants
|
||||
---------------------------------------------------------------------------------------------------
|
||||
|
||||
The following constants are defined by the Ruby interpreter.
|
||||
|
||||
DATA IO If the main program file contains the directive __END__, then
|
||||
the constant DATA will be initialized so that reading from it will
|
||||
return lines following __END__ from the source file.
|
||||
FALSE FalseClass Synonym for false (deprecated, removed in Ruby 3).
|
||||
NIL NilClass Synonym for nil (deprecated, removed in Ruby 3).
|
||||
RUBY_PLATFORM String The identifier of the platform running this program. This string
|
||||
is in the same form as the platform identifier used by the GNU
|
||||
configure utility (which is not a coincidence).
|
||||
RUBY_RELEASE_DATE String The date of this release.
|
||||
RUBY_VERSION String The version number of the interpreter.
|
||||
STDERR IO The actual standard error stream for the program. The initial
|
||||
value of $stderr.
|
||||
STDIN IO The actual standard input stream for the program. The initial
|
||||
value of $stdin.
|
||||
STDOUT IO The actual standard output stream for the program. The initial
|
||||
value of $stdout.
|
||||
SCRIPT_LINES__ Hash If a constant SCRIPT_LINES__ is defined and references a Hash,
|
||||
Ruby will store an entry containing the contents of each file it
|
||||
parses, with the file’s name as the key and an array of strings as
|
||||
the value.
|
||||
TOPLEVEL_BINDING Binding A Binding object representing the binding at Ruby’s top level—
|
||||
the level where programs are initially executed.
|
||||
TRUE TrueClass Synonym for true (deprecated, removed in Ruby 3).
|
||||
=end
|
||||
# Global Constants
|
||||
# ---------------------------------------------------------------------------------------------------
|
||||
#
|
||||
# The following constants are defined by the Ruby interpreter.
|
||||
#
|
||||
# DATA IO If the main program file contains the directive __END__, then
|
||||
# the constant DATA will be initialized so that reading from it will
|
||||
# return lines following __END__ from the source file.
|
||||
# FALSE FalseClass Synonym for false (deprecated, removed in Ruby 3).
|
||||
# NIL NilClass Synonym for nil (deprecated, removed in Ruby 3).
|
||||
# RUBY_PLATFORM String The identifier of the platform running this program. This string
|
||||
# is in the same form as the platform identifier used by the GNU
|
||||
# configure utility (which is not a coincidence).
|
||||
# RUBY_RELEASE_DATE String The date of this release.
|
||||
# RUBY_VERSION String The version number of the interpreter.
|
||||
# STDERR IO The actual standard error stream for the program. The initial
|
||||
# value of $stderr.
|
||||
# STDIN IO The actual standard input stream for the program. The initial
|
||||
# value of $stdin.
|
||||
# STDOUT IO The actual standard output stream for the program. The initial
|
||||
# value of $stdout.
|
||||
# SCRIPT_LINES__ Hash If a constant SCRIPT_LINES__ is defined and references a Hash,
|
||||
# Ruby will store an entry containing the contents of each file it
|
||||
# parses, with the file’s name as the key and an array of strings as
|
||||
# the value.
|
||||
# TOPLEVEL_BINDING Binding A Binding object representing the binding at Ruby’s top level—
|
||||
# the level where programs are initially executed.
|
||||
# TRUE TrueClass Synonym for true (deprecated, removed in Ruby 3).
|
||||
|
||||
describe "The predefined global constants" do
|
||||
describe "TRUE" do
|
||||
|
|
|
@ -18,17 +18,6 @@ describe "BigDecimal#exponent" do
|
|||
BigDecimal("1234567E10").exponent.should == 17
|
||||
end
|
||||
|
||||
# commenting this spec out after discussion with Defiler, since it seems to be an MRI bug, not a real feature
|
||||
=begin
|
||||
platform_is wordsize: 32 do
|
||||
# TODO: write specs for both 32 and 64 bit
|
||||
it "returns 0 if exponent can't be represented as Integer" do
|
||||
BigDecimal("2E1000000000000000").exponent.should == 0
|
||||
BigDecimal("-5E-999999999999999").exponent.should == 0
|
||||
end
|
||||
end
|
||||
=end
|
||||
|
||||
it "returns 0 if self is 0" do
|
||||
BigDecimal("0").exponent.should == 0
|
||||
BigDecimal("+0").exponent.should == 0
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
require_relative '../../../spec_helper'
|
||||
require 'fiddle'
|
||||
|
||||
describe "Fiddle::Handle#initialize" do
|
||||
it "raises Fiddle::DLError if the library cannot be found" do
|
||||
-> {
|
||||
Fiddle::Handle.new("doesnotexist.doesnotexist")
|
||||
}.should raise_error(Fiddle::DLError)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,25 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
require 'io/wait'
|
||||
|
||||
describe "IO#wait_readable" do
|
||||
before :each do
|
||||
@io = File.new(__FILE__ )
|
||||
end
|
||||
|
||||
after :each do
|
||||
@io.close
|
||||
end
|
||||
|
||||
it "waits for the IO to become readable with no timeout" do
|
||||
@io.wait_readable.should == @io
|
||||
end
|
||||
|
||||
it "waits for the IO to become readable with the given timeout" do
|
||||
@io.wait_readable(1).should == @io
|
||||
end
|
||||
|
||||
it "waits for the IO to become readable with the given large timeout" do
|
||||
@io.wait_readable(365 * 24 * 60 * 60).should == @io
|
||||
end
|
||||
end
|
|
@ -0,0 +1,18 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
require 'io/wait'
|
||||
|
||||
describe "IO#wait_writable" do
|
||||
it "waits for the IO to become writable with no timeout" do
|
||||
STDOUT.wait_writable.should == STDOUT
|
||||
end
|
||||
|
||||
it "waits for the IO to become writable with the given timeout" do
|
||||
STDOUT.wait_writable(1).should == STDOUT
|
||||
end
|
||||
|
||||
it "waits for the IO to become writable with the given large timeout" do
|
||||
# Represents one year and is larger than a 32-bit int
|
||||
STDOUT.wait_writable(365 * 24 * 60 * 60).should == STDOUT
|
||||
end
|
||||
end
|
|
@ -91,7 +91,7 @@ describe "Addrinfo#initialize" do
|
|||
@addrinfo.afamily.should == Socket::AF_INET6
|
||||
end
|
||||
|
||||
it "returns the 0 socket type" do
|
||||
it "returns the specified socket type" do
|
||||
@addrinfo.socktype.should == Socket::SOCK_STREAM
|
||||
end
|
||||
|
||||
|
|
|
@ -19,6 +19,11 @@ describe :socket_pack_sockaddr_in, shared: true do
|
|||
Socket.unpack_sockaddr_in(sockaddr_in).should == [0, '127.0.0.1']
|
||||
end
|
||||
|
||||
it 'resolves the service name to a port' do
|
||||
sockaddr_in = Socket.public_send(@method, 'http', '127.0.0.1')
|
||||
Socket.unpack_sockaddr_in(sockaddr_in).should == [80, '127.0.0.1']
|
||||
end
|
||||
|
||||
describe 'using an IPv4 address' do
|
||||
it 'returns a String of 16 bytes' do
|
||||
str = Socket.public_send(@method, 80, '127.0.0.1')
|
||||
|
|
|
@ -204,6 +204,10 @@ describe "C-API Class function" do
|
|||
it "returns a string for an anonymous class" do
|
||||
@s.rb_class2name(Class.new).should be_kind_of(String)
|
||||
end
|
||||
|
||||
it "returns a string beginning with # for an anonymous class" do
|
||||
@s.rb_class2name(Struct.new(:x, :y).new(1, 2).class).should.start_with?('#')
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_class_path" do
|
||||
|
|
|
@ -112,6 +112,10 @@ VALUE kernel_spec_rb_eval_string(VALUE self, VALUE str) {
|
|||
return rb_eval_string(RSTRING_PTR(str));
|
||||
}
|
||||
|
||||
VALUE kernel_spec_rb_eval_cmd_kw(VALUE self, VALUE cmd, VALUE args, VALUE kw_splat) {
|
||||
return rb_eval_cmd_kw(cmd, args, NUM2INT(kw_splat));
|
||||
}
|
||||
|
||||
VALUE kernel_spec_rb_raise(VALUE self, VALUE hash) {
|
||||
rb_hash_aset(hash, ID2SYM(rb_intern("stage")), ID2SYM(rb_intern("before")));
|
||||
if (self != Qundef)
|
||||
|
@ -361,6 +365,7 @@ void Init_kernel_spec(void) {
|
|||
rb_define_method(cls, "rb_frame_this_func_test_again", kernel_spec_rb_frame_this_func, 0);
|
||||
rb_define_method(cls, "rb_ensure", kernel_spec_rb_ensure, 4);
|
||||
rb_define_method(cls, "rb_eval_string", kernel_spec_rb_eval_string, 1);
|
||||
rb_define_method(cls, "rb_eval_cmd_kw", kernel_spec_rb_eval_cmd_kw, 3);
|
||||
rb_define_method(cls, "rb_raise", kernel_spec_rb_raise, 1);
|
||||
rb_define_method(cls, "rb_throw", kernel_spec_rb_throw, 1);
|
||||
rb_define_method(cls, "rb_throw_obj", kernel_spec_rb_throw_obj, 2);
|
||||
|
|
|
@ -393,6 +393,18 @@ static VALUE object_spec_rb_class_inherited_p(VALUE self, VALUE mod, VALUE arg)
|
|||
return rb_class_inherited_p(mod, arg);
|
||||
}
|
||||
|
||||
static int foreach_f(ID key, VALUE val, VALUE ary) {
|
||||
rb_ary_push(ary, ID2SYM(key));
|
||||
rb_ary_push(ary, val);
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
static VALUE object_spec_rb_ivar_foreach(VALUE self, VALUE obj) {
|
||||
VALUE ary = rb_ary_new();
|
||||
rb_ivar_foreach(obj, foreach_f, ary);
|
||||
return ary;
|
||||
}
|
||||
|
||||
static VALUE speced_allocator(VALUE klass) {
|
||||
VALUE flags = 0;
|
||||
VALUE instance;
|
||||
|
@ -508,6 +520,7 @@ void Init_object_spec(void) {
|
|||
rb_define_method(cls, "speced_allocator?", speced_allocator_p, 1);
|
||||
rb_define_method(cls, "custom_alloc_func?", custom_alloc_func_p, 1);
|
||||
rb_define_method(cls, "not_implemented_method", rb_f_notimplement, -1);
|
||||
rb_define_method(cls, "rb_ivar_foreach", object_spec_rb_ivar_foreach, 1);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
class CApiObjectSpecs
|
||||
class IVars
|
||||
def initialize
|
||||
@a = 3
|
||||
@b = 7
|
||||
@c = 4
|
||||
end
|
||||
|
||||
def self.set_class_variables
|
||||
@@foo = :a
|
||||
@@bar = :b
|
||||
@@baz = :c
|
||||
end
|
||||
end
|
||||
|
||||
module MVars
|
||||
@@mvar = :foo
|
||||
@@mvar2 = :bar
|
||||
|
||||
@ivar = :baz
|
||||
end
|
||||
|
||||
module CVars
|
||||
@@cvar = :foo
|
||||
@@cvar2 = :bar
|
||||
|
||||
@ivar = :baz
|
||||
end
|
||||
end
|
|
@ -504,6 +504,25 @@ describe "C-API Kernel function" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "rb_eval_cmd_kw" do
|
||||
it "evaluates a string of ruby code" do
|
||||
@s.rb_eval_cmd_kw("1+1", [], 0).should == 2
|
||||
end
|
||||
|
||||
it "calls a proc with the supplied arguments" do
|
||||
@s.rb_eval_cmd_kw(-> *x { x.map { |i| i + 1 } }, [1, 3, 7], 0).should == [2, 4, 8]
|
||||
end
|
||||
|
||||
it "calls a proc with keyword arguments if kw_splat is non zero" do
|
||||
a_proc = -> *x, **y {
|
||||
res = x.map { |i| i + 1 }
|
||||
y.each { |k, v| res << k; res << v }
|
||||
res
|
||||
}
|
||||
@s.rb_eval_cmd_kw(a_proc, [1, 3, 7, {a: 1, b: 2, c: 3}], 1).should == [2, 4, 8, :a, 1, :b, 2, :c, 3]
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_block_proc" do
|
||||
it "converts the implicit block into a proc" do
|
||||
proc = @s.rb_block_proc { 1+1 }
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require_relative 'spec_helper'
|
||||
require_relative 'fixtures/object'
|
||||
|
||||
load_extension("object")
|
||||
|
||||
|
@ -983,5 +984,24 @@ describe "CApiObject" do
|
|||
@o.speced_allocator?(parent).should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_ivar_foreach" do
|
||||
it "calls the callback function for each instance variable on an object" do
|
||||
o = CApiObjectSpecs::IVars.new
|
||||
ary = @o.rb_ivar_foreach(o)
|
||||
ary.should == [:@a, 3, :@b, 7, :@c, 4]
|
||||
end
|
||||
|
||||
it "calls the callback function for each cvar and ivar on a class" do
|
||||
ary = @o.rb_ivar_foreach(CApiObjectSpecs::CVars)
|
||||
ary.should == [:__classpath__, 'CApiObjectSpecs::CVars', :@@cvar, :foo, :@@cvar2, :bar, :@ivar, :baz]
|
||||
end
|
||||
|
||||
it "calls the callback function for each cvar and ivar on a module" do
|
||||
ary = @o.rb_ivar_foreach(CApiObjectSpecs::MVars)
|
||||
ary.should == [:__classpath__, 'CApiObjectSpecs::MVars', :@@mvar, :foo, :@@mvar2, :bar, :@ivar, :baz]
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,9 +8,16 @@ describe :rbasic, shared: true do
|
|||
|
||||
it "reports the appropriate FREEZE flag for the object when reading" do
|
||||
obj, _ = @data.call
|
||||
(@specs.get_flags(obj) & @freeze).should == 0
|
||||
initial = @specs.get_flags(obj)
|
||||
obj.freeze
|
||||
(@specs.get_flags(obj) & @freeze).should == @freeze
|
||||
@specs.get_flags(obj).should == @freeze | initial
|
||||
end
|
||||
|
||||
it "supports setting the FREEZE flag" do
|
||||
obj, _ = @data.call
|
||||
initial = @specs.get_flags(obj)
|
||||
@specs.set_flags(obj, @freeze | initial).should == @freeze | initial
|
||||
obj.should.frozen?
|
||||
end
|
||||
|
||||
it "supports retrieving the (meta)class" do
|
||||
|
|
|
@ -27,7 +27,8 @@ unless ENV['MSPEC_RUNNER'] # Running directly with ruby some_spec.rb
|
|||
end
|
||||
end
|
||||
|
||||
ruby_version_is ""..."2.7" do
|
||||
# Compare with SpecVersion directly here so it works even with --unguarded
|
||||
if VersionGuard::FULL_RUBY_VERSION < SpecVersion.new('2.7')
|
||||
abort "This version of ruby/spec requires Ruby 2.7+"
|
||||
end
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче