1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
This commit is contained in:
Benoit Daloze 2021-10-05 19:41:44 +02:00
parent afcbb501ac
commit b9f34062f0
28 changed files with 692 additions and 31 deletions

View file

@ -92,6 +92,7 @@ module DirSpecs
special/| special/|
special/.txt special/.txt
special/\a
] ]
end end
end end

View file

@ -80,6 +80,10 @@ describe :dir_glob, shared: true do
it "matches regexp special |" do it "matches regexp special |" do
Dir.send(@method, 'special/|').should == ['special/|'] Dir.send(@method, 'special/|').should == ['special/|']
end end
it "matches files with backslashes in their name" do
Dir.glob('special/\\\\{a,b}').should == ['special/\a']
end
end end
it "matches regexp special ^" do it "matches regexp special ^" do

View file

@ -17,6 +17,14 @@ describe "Encoding.default_external" do
Encoding.default_external = Encoding::SHIFT_JIS Encoding.default_external = Encoding::SHIFT_JIS
Encoding.default_external.should == Encoding::SHIFT_JIS Encoding.default_external.should == Encoding::SHIFT_JIS
end end
ruby_version_is "3.0" do
platform_is :windows do
it 'is UTF-8 by default on Windows' do
Encoding.default_external.should == Encoding::UTF_8
end
end
end
end end
describe "Encoding.default_external=" do describe "Encoding.default_external=" do

View file

@ -89,5 +89,19 @@ describe :enumerable_collect, shared: true do
end.should raise_error(ArgumentError) end.should raise_error(ArgumentError)
end end
it "calls the each method on sub-classes" do
c = Class.new(Hash) do
def each
ScratchPad << 'in each'
super
end
end
h = c.new
h[1] = 'a'
ScratchPad.record []
h.send(@method) { |k,v| v }
ScratchPad.recorded.should == ['in each']
end
it_should_behave_like :enumerable_enumeratorized_with_origin_size it_should_behave_like :enumerable_enumeratorized_with_origin_size
end end

View file

@ -70,6 +70,15 @@ describe "File.utime" do
end end
end end
platform_is_not :windows do
it "sets nanosecond precision" do
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r)
File.utime(t, t, @file1)
File.atime(@file1).nsec.should == 123456789
File.mtime(@file1).nsec.should == 123456789
end
end
platform_is :linux do platform_is :linux do
platform_is wordsize: 64 do platform_is wordsize: 64 do
it "allows Time instances in the far future to set mtime and atime (but some filesystems limit it up to 2446-05-10 or 2038-01-19)" do it "allows Time instances in the far future to set mtime and atime (but some filesystems limit it up to 2446-05-10 or 2038-01-19)" do

View file

@ -320,6 +320,10 @@ describe :kernel_sprintf, shared: true do
@method.call("%s", "abc").should == "abc" @method.call("%s", "abc").should == "abc"
end end
it "substitutes '' for nil" do
@method.call("%s", nil).should == ""
end
it "converts argument to string with to_s" do it "converts argument to string with to_s" do
obj = mock("string") obj = mock("string")
obj.should_receive(:to_s).and_return("abc") obj.should_receive(:to_s).and_return("abc")
@ -348,6 +352,28 @@ describe :kernel_sprintf, shared: true do
Kernel.format("%-3.3s", "hello").should == "hel" Kernel.format("%-3.3s", "hello").should == "hel"
end end
it "formats string with width" do
@method.call("%6s", "abc").should == " abc"
@method.call("%6s", "abcdefg").should == "abcdefg"
end
it "formats string with width and precision" do
@method.call("%4.6s", "abc").should == " abc"
@method.call("%4.6s", "abcdefg").should == "abcdef"
end
it "formats nli with width" do
@method.call("%6s", nil).should == " "
end
it "formats nli with precision" do
@method.call("%.6s", nil).should == ""
end
it "formats nil with width and precision" do
@method.call("%4.6s", nil).should == " "
end
it "formats multibyte string with precision" do it "formats multibyte string with precision" do
Kernel.format("%.2s", "été").should == "ét" Kernel.format("%.2s", "été").should == "ét"
end end

View file

@ -97,8 +97,8 @@ describe :marshal_load, shared: true do
:b, :c, 2, a, false, "ant", ["hi", 10, "hi", "hi", st, [:a, :b, :c]], :b, :c, 2, a, false, "ant", ["hi", 10, "hi", "hi", st, [:a, :b, :c]],
] ]
arr.each do |obj| arr.each do |v|
obj.should.frozen? v.should.frozen?
end end
Struct.send(:remove_const, :Brittle) Struct.send(:remove_const, :Brittle)

View file

@ -6,8 +6,8 @@ describe "ObjectSpace.garbage_collect" do
-> { ObjectSpace.garbage_collect }.should_not raise_error -> { ObjectSpace.garbage_collect }.should_not raise_error
end end
it "doesn't accept any arguments" do it "accepts keyword arguments" do
-> { ObjectSpace.garbage_collect(1) }.should raise_error(ArgumentError) ObjectSpace.garbage_collect(full_mark: true, immediate_sweep: true).should == nil
end end
it "ignores the supplied block" do it "ignores the supplied block" do

View file

@ -1,7 +1,10 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
require_relative 'shared/strip'
describe "String#lstrip" do describe "String#lstrip" do
it_behaves_like :string_strip, :lstrip
it "returns a copy of self with leading whitespace removed" do it "returns a copy of self with leading whitespace removed" do
" hello ".lstrip.should == "hello " " hello ".lstrip.should == "hello "
" hello world ".lstrip.should == "hello world " " hello world ".lstrip.should == "hello world "

View file

@ -1,7 +1,10 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
require_relative 'shared/partition'
describe "String#partition with String" do describe "String#partition with String" do
it_behaves_like :string_partition, :partition
it "returns an array of substrings based on splitting on the given string" do it "returns an array of substrings based on splitting on the given string" do
"hello world".partition("o").should == ["hell", "o", " world"] "hello world".partition("o").should == ["hell", "o", " world"]
end end

View file

@ -10,6 +10,22 @@ describe "String#reverse" do
"".reverse.should == "" "".reverse.should == ""
end end
ruby_version_is '3.0' do
it "returns String instances when called on a subclass" do
StringSpecs::MyString.new("stressed").reverse.should be_an_instance_of(String)
StringSpecs::MyString.new("m").reverse.should be_an_instance_of(String)
StringSpecs::MyString.new("").reverse.should be_an_instance_of(String)
end
end
ruby_version_is ''...'3.0' do
it "returns subclass instances when called on a subclass" do
StringSpecs::MyString.new("stressed").reverse.should be_an_instance_of(StringSpecs::MyString)
StringSpecs::MyString.new("m").reverse.should be_an_instance_of(StringSpecs::MyString)
StringSpecs::MyString.new("").reverse.should be_an_instance_of(StringSpecs::MyString)
end
end
ruby_version_is ''...'2.7' do ruby_version_is ''...'2.7' do
it "taints the result if self is tainted" do it "taints the result if self is tainted" do
"".taint.reverse.should.tainted? "".taint.reverse.should.tainted?
@ -20,7 +36,6 @@ describe "String#reverse" do
it "reverses a string with multi byte characters" do it "reverses a string with multi byte characters" do
"微軟正黑體".reverse.should == "體黑正軟微" "微軟正黑體".reverse.should == "體黑正軟微"
end end
end end
describe "String#reverse!" do describe "String#reverse!" do

View file

@ -1,7 +1,10 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
require_relative 'shared/partition'
describe "String#rpartition with String" do describe "String#rpartition with String" do
it_behaves_like :string_partition, :rpartition
it "returns an array of substrings based on splitting on the given string" do it "returns an array of substrings based on splitting on the given string" do
"hello world".rpartition("o").should == ["hello w", "o", "rld"] "hello world".rpartition("o").should == ["hello w", "o", "rld"]
end end

View file

@ -1,7 +1,10 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
require_relative 'shared/strip'
describe "String#rstrip" do describe "String#rstrip" do
it_behaves_like :string_strip, :rstrip
it "returns a copy of self with trailing whitespace removed" do it "returns a copy of self with trailing whitespace removed" do
" hello ".rstrip.should == " hello" " hello ".rstrip.should == " hello"
" hello world ".rstrip.should == " hello world" " hello world ".rstrip.should == " hello world"

View file

@ -1,5 +1,6 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "String#scrub with a default replacement" do describe "String#scrub with a default replacement" do
it "returns self for valid strings" do it "returns self for valid strings" do
@ -19,12 +20,25 @@ describe "String#scrub with a default replacement" do
input.scrub.should == "foo" input.scrub.should == "foo"
end end
it "replaces invalid byte sequences when using ASCII as the input encoding" do it "replaces invalid byte sequences when using ASCII as the input encoding" do
xE3x80 = [0xE3, 0x80].pack('CC').force_encoding 'utf-8' xE3x80 = [0xE3, 0x80].pack('CC').force_encoding 'utf-8'
input = "abc\u3042#{xE3x80}".force_encoding('ASCII') input = "abc\u3042#{xE3x80}".force_encoding('ASCII')
input.scrub.should == "abc?????" input.scrub.should == "abc?????"
end end
ruby_version_is '3.0' do
it "returns String instances when called on a subclass" do
StringSpecs::MyString.new("foo").scrub.should be_an_instance_of(String)
input = [0x81].pack('C').force_encoding('utf-8')
StringSpecs::MyString.new(input).scrub.should be_an_instance_of(String)
end
end
ruby_version_is ''...'3.0' do
it "returns subclass instances when called on a subclass" do
StringSpecs::MyString.new("foo").scrub.should be_an_instance_of(StringSpecs::MyString)
end
end
end end
describe "String#scrub with a custom replacement" do describe "String#scrub with a custom replacement" do
@ -65,6 +79,14 @@ describe "String#scrub with a custom replacement" do
block.should raise_error(TypeError) block.should raise_error(TypeError)
end end
ruby_version_is '3.0' do
it "returns String instances when called on a subclass" do
StringSpecs::MyString.new("foo").scrub("*").should be_an_instance_of(String)
input = [0x81].pack('C').force_encoding('utf-8')
StringSpecs::MyString.new(input).scrub("*").should be_an_instance_of(String)
end
end
end end
describe "String#scrub with a block" do describe "String#scrub with a block" do
@ -89,6 +111,14 @@ describe "String#scrub with a block" do
replaced.should == "€€" replaced.should == "€€"
end end
ruby_version_is '3.0' do
it "returns String instances when called on a subclass" do
StringSpecs::MyString.new("foo").scrub { |b| "*" }.should be_an_instance_of(String)
input = [0x81].pack('C').force_encoding('utf-8')
StringSpecs::MyString.new(input).scrub { |b| "<#{b.unpack("H*")[0]}>" }.should be_an_instance_of(String)
end
end
end end
describe "String#scrub!" do describe "String#scrub!" do

View file

@ -0,0 +1,36 @@
require_relative '../../../spec_helper'
require_relative '../fixtures/classes'
describe :string_partition, shared: true do
ruby_version_is '3.0' do
it "returns String instances when called on a subclass" do
StringSpecs::MyString.new("hello").send(@method, "l").each do |item|
item.should be_an_instance_of(String)
end
StringSpecs::MyString.new("hello").send(@method, "x").each do |item|
item.should be_an_instance_of(String)
end
StringSpecs::MyString.new("hello").send(@method, /l./).each do |item|
item.should be_an_instance_of(String)
end
end
end
ruby_version_is ''...'3.0' do
it "returns subclass instances when called on a subclass" do
StringSpecs::MyString.new("hello").send(@method, StringSpecs::MyString.new("l")).each do |item|
item.should be_an_instance_of(StringSpecs::MyString)
end
StringSpecs::MyString.new("hello").send(@method, "x").each do |item|
item.should be_an_instance_of(StringSpecs::MyString)
end
StringSpecs::MyString.new("hello").send(@method, /l./).each do |item|
item.should be_an_instance_of(StringSpecs::MyString)
end
end
end
end

View file

@ -0,0 +1,20 @@
require_relative '../../../spec_helper'
require_relative '../fixtures/classes'
describe :string_strip, shared: true do
ruby_version_is '3.0' do
it "returns String instances when called on a subclass" do
StringSpecs::MyString.new(" hello ").send(@method).should be_an_instance_of(String)
StringSpecs::MyString.new(" ").send(@method).should be_an_instance_of(String)
StringSpecs::MyString.new("").send(@method).should be_an_instance_of(String)
end
end
ruby_version_is ''...'3.0' do
it "returns subclass instances when called on a subclass" do
StringSpecs::MyString.new(" hello ").send(@method).should be_an_instance_of(StringSpecs::MyString)
StringSpecs::MyString.new(" ").send(@method).should be_an_instance_of(StringSpecs::MyString)
StringSpecs::MyString.new("").send(@method).should be_an_instance_of(StringSpecs::MyString)
end
end
end

View file

@ -1,7 +1,10 @@
require_relative '../../spec_helper' require_relative '../../spec_helper'
require_relative 'fixtures/classes' require_relative 'fixtures/classes'
require_relative 'shared/strip'
describe "String#strip" do describe "String#strip" do
it_behaves_like :string_strip, :strip
it "returns a new string with leading and trailing whitespace removed" do it "returns a new string with leading and trailing whitespace removed" do
" hello ".strip.should == "hello" " hello ".strip.should == "hello"
" hello world ".strip.should == "hello world" " hello world ".strip.should == "hello world"

View file

@ -5,21 +5,25 @@ describe "The defined? keyword for literals" do
it "returns 'self' for self" do it "returns 'self' for self" do
ret = defined?(self) ret = defined?(self)
ret.should == "self" ret.should == "self"
ret.frozen?.should == true
end end
it "returns 'nil' for nil" do it "returns 'nil' for nil" do
ret = defined?(nil) ret = defined?(nil)
ret.should == "nil" ret.should == "nil"
ret.frozen?.should == true
end end
it "returns 'true' for true" do it "returns 'true' for true" do
ret = defined?(true) ret = defined?(true)
ret.should == "true" ret.should == "true"
ret.frozen?.should == true
end end
it "returns 'false' for false" do it "returns 'false' for false" do
ret = defined?(false) ret = defined?(false)
ret.should == "false" ret.should == "false"
ret.frozen?.should == true
end end
describe "for a literal Array" do describe "for a literal Array" do
@ -27,6 +31,7 @@ describe "The defined? keyword for literals" do
it "returns 'expression' if each element is defined" do it "returns 'expression' if each element is defined" do
ret = defined?([Object, Array]) ret = defined?([Object, Array])
ret.should == "expression" ret.should == "expression"
ret.frozen?.should == true
end end
it "returns nil if one element is not defined" do it "returns nil if one element is not defined" do
@ -45,7 +50,9 @@ end
describe "The defined? keyword when called with a method name" do describe "The defined? keyword when called with a method name" do
describe "without a receiver" do describe "without a receiver" do
it "returns 'method' if the method is defined" do it "returns 'method' if the method is defined" do
defined?(puts).should == "method" ret = defined?(puts)
ret.should == "method"
ret.frozen?.should == true
end end
it "returns nil if the method is not defined" do it "returns nil if the method is not defined" do
@ -167,7 +174,9 @@ describe "The defined? keyword for an expression" do
end end
it "returns 'assignment' for assigning a local variable" do it "returns 'assignment' for assigning a local variable" do
defined?(x = 2).should == "assignment" ret = defined?(x = 2)
ret.should == "assignment"
ret.frozen?.should == true
end end
it "returns 'assignment' for assigning an instance variable" do it "returns 'assignment' for assigning an instance variable" do
@ -470,7 +479,9 @@ end
describe "The defined? keyword for variables" do describe "The defined? keyword for variables" do
it "returns 'local-variable' when called with the name of a local variable" do it "returns 'local-variable' when called with the name of a local variable" do
DefinedSpecs::Basic.new.local_variable_defined.should == "local-variable" ret = DefinedSpecs::Basic.new.local_variable_defined
ret.should == "local-variable"
ret.frozen?.should == true
end end
it "returns 'local-variable' when called with the name of a local variable assigned to nil" do it "returns 'local-variable' when called with the name of a local variable assigned to nil" do
@ -486,7 +497,9 @@ describe "The defined? keyword for variables" do
end end
it "returns 'instance-variable' for an instance variable that has been assigned" do it "returns 'instance-variable' for an instance variable that has been assigned" do
DefinedSpecs::Basic.new.instance_variable_defined.should == "instance-variable" ret = DefinedSpecs::Basic.new.instance_variable_defined
ret.should == "instance-variable"
ret.frozen?.should == true
end end
it "returns 'instance-variable' for an instance variable that has been assigned to nil" do it "returns 'instance-variable' for an instance variable that has been assigned to nil" do
@ -502,7 +515,9 @@ describe "The defined? keyword for variables" do
end end
it "returns 'global-variable' for a global variable that has been assigned nil" do it "returns 'global-variable' for a global variable that has been assigned nil" do
DefinedSpecs::Basic.new.global_variable_defined_as_nil.should == "global-variable" ret = DefinedSpecs::Basic.new.global_variable_defined_as_nil
ret.should == "global-variable"
ret.frozen?.should == true
end end
# MRI appears to special case defined? for $! and $~ in that it returns # MRI appears to special case defined? for $! and $~ in that it returns
@ -674,7 +689,9 @@ describe "The defined? keyword for variables" do
# get to the defined? call so it really has nothing to do with 'defined?'. # get to the defined? call so it really has nothing to do with 'defined?'.
it "returns 'class variable' when called with the name of a class variable" do it "returns 'class variable' when called with the name of a class variable" do
DefinedSpecs::Basic.new.class_variable_defined.should == "class variable" ret = DefinedSpecs::Basic.new.class_variable_defined
ret.should == "class variable"
ret.frozen?.should == true
end end
it "returns 'local-variable' when called with the name of a block local" do it "returns 'local-variable' when called with the name of a block local" do
@ -685,7 +702,9 @@ end
describe "The defined? keyword for a simple constant" do describe "The defined? keyword for a simple constant" do
it "returns 'constant' when the constant is defined" do it "returns 'constant' when the constant is defined" do
defined?(DefinedSpecs).should == "constant" ret = defined?(DefinedSpecs)
ret.should == "constant"
ret.frozen?.should == true
end end
it "returns nil when the constant is not defined" do it "returns nil when the constant is not defined" do
@ -941,12 +960,26 @@ describe "The defined? keyword for yield" do
end end
it "returns 'yield' if a block is passed to a method not taking a block parameter" do it "returns 'yield' if a block is passed to a method not taking a block parameter" do
DefinedSpecs::Basic.new.yield_block.should == "yield" ret = DefinedSpecs::Basic.new.yield_block
ret.should == "yield"
ret.frozen?.should == true
end end
it "returns 'yield' if a block is passed to a method taking a block parameter" do it "returns 'yield' if a block is passed to a method taking a block parameter" do
DefinedSpecs::Basic.new.yield_block_parameter.should == "yield" DefinedSpecs::Basic.new.yield_block_parameter.should == "yield"
end end
it "returns 'yield' when called within a block" do
def yielder
yield
end
def call_defined
yielder { defined?(yield) }
end
call_defined() { }.should == "yield"
end
end end
describe "The defined? keyword for super" do describe "The defined? keyword for super" do
@ -972,7 +1005,9 @@ describe "The defined? keyword for super" do
end end
it "returns 'super' when a superclass method exists" do it "returns 'super' when a superclass method exists" do
DefinedSpecs::Super.new.method_no_args.should == "super" ret = DefinedSpecs::Super.new.method_no_args
ret.should == "super"
ret.frozen?.should == true
end end
it "returns 'super' from a block when a superclass method exists" do it "returns 'super' from a block when a superclass method exists" do

View file

@ -1099,6 +1099,8 @@ The following constants are defined by the Ruby interpreter.
DATA IO If the main program file contains the directive __END__, then DATA IO If the main program file contains the directive __END__, then
the constant DATA will be initialized so that reading from it will the constant DATA will be initialized so that reading from it will
return lines following __END__ from the source file. 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 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 is in the same form as the platform identifier used by the GNU
configure utility (which is not a coincidence). configure utility (which is not a coincidence).
@ -1116,9 +1118,55 @@ SCRIPT_LINES__ Hash If a constant SCRIPT_LINES__ is defined and ref
the value. the value.
TOPLEVEL_BINDING Binding A Binding object representing the binding at Rubys top level TOPLEVEL_BINDING Binding A Binding object representing the binding at Rubys top level
the level where programs are initially executed. the level where programs are initially executed.
TRUE TrueClass Synonym for true (deprecated, removed in Ruby 3).
=end =end
describe "The predefined global constants" do describe "The predefined global constants" do
describe "TRUE" do
ruby_version_is "3.0" do
it "is no longer defined" do
Object.const_defined?(:TRUE).should == false
end
end
ruby_version_is ""..."3.0" do
it "includes TRUE" do
Object.const_defined?(:TRUE).should == true
-> { TRUE }.should complain(/constant ::TRUE is deprecated/)
end
end
end
describe "FALSE" do
ruby_version_is "3.0" do
it "is no longer defined" do
Object.const_defined?(:FALSE).should == false
end
end
ruby_version_is ""..."3.0" do
it "includes FALSE" do
Object.const_defined?(:FALSE).should == true
-> { FALSE }.should complain(/constant ::FALSE is deprecated/)
end
end
end
describe "NIL" do
ruby_version_is "3.0" do
it "is no longer defined" do
Object.const_defined?(:NIL).should == false
end
end
ruby_version_is ""..."3.0" do
it "includes NIL" do
Object.const_defined?(:NIL).should == true
-> { NIL }.should complain(/constant ::NIL is deprecated/)
end
end
end
it "includes STDIN" do it "includes STDIN" do
Object.const_defined?(:STDIN).should == true Object.const_defined?(:STDIN).should == true
end end
@ -1146,7 +1194,6 @@ describe "The predefined global constants" do
it "includes TOPLEVEL_BINDING" do it "includes TOPLEVEL_BINDING" do
Object.const_defined?(:TOPLEVEL_BINDING).should == true Object.const_defined?(:TOPLEVEL_BINDING).should == true
end end
end end
describe "The predefined global constant" do describe "The predefined global constant" do

View file

@ -11,29 +11,23 @@ module NetHTTPSpecs
class SmallHTTPServer class SmallHTTPServer
def initialize(bind_address) def initialize(bind_address)
@server = TCPServer.new(bind_address, 0) @server = TCPServer.new(bind_address, 0)
@running = Mutex.new
@thread = Thread.new { @thread = Thread.new {
Thread.current.abort_on_exception = true Thread.current.abort_on_exception = true
listen listen
} }
end end
def ip
@server.addr[3]
end
def port def port
@server.addr[1] @server.addr[1]
end end
def listen def listen
loop do until @server.closed?
begin client = @server.accept
client = @server.accept
rescue IOError => e
if @running.locked? # close
break
else
raise e
end
end
handle_client(client) handle_client(client)
end end
end end
@ -43,6 +37,10 @@ module NetHTTPSpecs
until client.closed? until client.closed?
request = client.gets("\r\n\r\n") request = client.gets("\r\n\r\n")
break unless request break unless request
if request == "CLOSE"
@server.close
break
end
handle_request(client, request) handle_request(client, request)
end end
ensure ensure
@ -95,8 +93,9 @@ module NetHTTPSpecs
end end
def close def close
@running.lock TCPSocket.open(ip, port) do |socket|
@server.close socket.write "CLOSE"
end
@thread.join @thread.join
end end
end end

View file

@ -42,6 +42,17 @@ describe 'RbConfig::CONFIG' do
RUBY RUBY
end end
platform_is_not :windows do
it "['LIBRUBY'] is the same as LIBRUBY_SO if and only if ENABLE_SHARED" do
case RbConfig::CONFIG['ENABLE_SHARED']
when 'yes'
RbConfig::CONFIG['LIBRUBY'].should == RbConfig::CONFIG['LIBRUBY_SO']
when 'no'
RbConfig::CONFIG['LIBRUBY'].should_not == RbConfig::CONFIG['LIBRUBY_SO']
end
end
end
guard -> { RbConfig::TOPDIR } do guard -> { RbConfig::TOPDIR } do
it "libdir/LIBRUBY_SO is the path to libruby and it exists if and only if ENABLE_SHARED" do it "libdir/LIBRUBY_SO is the path to libruby and it exists if and only if ENABLE_SHARED" do
libdirname = RbConfig::CONFIG['LIBPATHENV'] == 'PATH' ? 'bindir' : libdirname = RbConfig::CONFIG['LIBPATHENV'] == 'PATH' ? 'bindir' :

View file

@ -0,0 +1,10 @@
require_relative '../spec_helper'
require_relative '../shared/address'
describe 'BasicSocket#local_address' do
it_behaves_like :socket_local_remote_address, :local_address, -> socket {
a2 = BasicSocket.for_fd(socket.fileno)
a2.autoclose = false
a2.local_address
}
end

View file

@ -0,0 +1,10 @@
require_relative '../spec_helper'
require_relative '../shared/address'
describe 'BasicSocket#remote_address' do
it_behaves_like :socket_local_remote_address, :remote_address, -> socket {
a2 = BasicSocket.for_fd(socket.fileno)
a2.autoclose = false
a2.remote_address
}
end

View file

@ -0,0 +1,249 @@
require_relative '../fixtures/classes'
describe :socket_local_remote_address, shared: true do
describe 'using TCPSocket' do
before :each do
@s = TCPServer.new('127.0.0.1', 0)
@a = TCPSocket.new('127.0.0.1', @s.addr[1])
@b = @s.accept
@addr = @object.call(@a)
end
after :each do
[@b, @a, @s].each(&:close)
end
it 'uses AF_INET as the address family' do
@addr.afamily.should == Socket::AF_INET
end
it 'uses PF_INET as the protocol family' do
@addr.pfamily.should == Socket::PF_INET
end
it 'uses SOCK_STREAM as the socket type' do
@addr.socktype.should == Socket::SOCK_STREAM
end
it 'uses the correct IP address' do
@addr.ip_address.should == '127.0.0.1'
end
it 'uses the correct port' do
if @method == :local_address
@addr.ip_port.should != @s.addr[1]
else
@addr.ip_port.should == @s.addr[1]
end
end
it 'equals address of peer socket' do
if @method == :local_address
@addr.to_s.should == @b.remote_address.to_s
else
@addr.to_s.should == @b.local_address.to_s
end
end
it 'returns an Addrinfo' do
@addr.should be_an_instance_of(Addrinfo)
end
it 'uses 0 as the protocol' do
@addr.protocol.should == 0
end
it 'can be used to connect to the server' do
skip if @method == :local_address
b = @addr.connect
begin
b.remote_address.to_s.should == @addr.to_s
ensure
b.close
end
end
end
guard -> { SocketSpecs.ipv6_available? } do
describe 'using IPv6' do
before :each do
@s = TCPServer.new('::1', 0)
@a = TCPSocket.new('::1', @s.addr[1])
@b = @s.accept
@addr = @object.call(@a)
end
after :each do
[@b, @a, @s].each(&:close)
end
it 'uses AF_INET6 as the address family' do
@addr.afamily.should == Socket::AF_INET6
end
it 'uses PF_INET6 as the protocol family' do
@addr.pfamily.should == Socket::PF_INET6
end
it 'uses SOCK_STREAM as the socket type' do
@addr.socktype.should == Socket::SOCK_STREAM
end
it 'uses the correct IP address' do
@addr.ip_address.should == '::1'
end
it 'uses the correct port' do
if @method == :local_address
@addr.ip_port.should != @s.addr[1]
else
@addr.ip_port.should == @s.addr[1]
end
end
it 'equals address of peer socket' do
if @method == :local_address
@addr.to_s.should == @b.remote_address.to_s
else
@addr.to_s.should == @b.local_address.to_s
end
end
it 'returns an Addrinfo' do
@addr.should be_an_instance_of(Addrinfo)
end
it 'uses 0 as the protocol' do
@addr.protocol.should == 0
end
it 'can be used to connect to the server' do
skip if @method == :local_address
b = @addr.connect
begin
b.remote_address.to_s.should == @addr.to_s
ensure
b.close
end
end
end
end
with_feature :unix_socket do
describe 'using UNIXSocket' do
before :each do
@path = SocketSpecs.socket_path
@s = UNIXServer.new(@path)
@a = UNIXSocket.new(@path)
@b = @s.accept
@addr = @object.call(@a)
end
after :each do
[@b, @a, @s].each(&:close)
rm_r(@path)
end
it 'uses AF_UNIX as the address family' do
@addr.afamily.should == Socket::AF_UNIX
end
it 'uses PF_UNIX as the protocol family' do
@addr.pfamily.should == Socket::PF_UNIX
end
it 'uses SOCK_STREAM as the socket type' do
@addr.socktype.should == Socket::SOCK_STREAM
end
it 'uses the correct socket path' do
if @method == :local_address
@addr.unix_path.should == ""
else
@addr.unix_path.should == @path
end
end
it 'equals address of peer socket' do
if @method == :local_address
@addr.to_s.should == @b.remote_address.to_s
else
@addr.to_s.should == @b.local_address.to_s
end
end
it 'returns an Addrinfo' do
@addr.should be_an_instance_of(Addrinfo)
end
it 'uses 0 as the protocol' do
@addr.protocol.should == 0
end
it 'can be used to connect to the server' do
skip if @method == :local_address
b = @addr.connect
begin
b.remote_address.to_s.should == @addr.to_s
ensure
b.close
end
end
end
end
describe 'using UDPSocket' do
before :each do
@s = UDPSocket.new
@s.bind("127.0.0.1", 0)
@a = UDPSocket.new
@a.connect("127.0.0.1", @s.addr[1])
@addr = @object.call(@a)
end
after :each do
[@a, @s].each(&:close)
end
it 'uses the correct address family' do
@addr.afamily.should == Socket::AF_INET
end
it 'uses the correct protocol family' do
@addr.pfamily.should == Socket::PF_INET
end
it 'uses SOCK_DGRAM as the socket type' do
@addr.socktype.should == Socket::SOCK_DGRAM
end
it 'uses the correct IP address' do
@addr.ip_address.should == '127.0.0.1'
end
it 'uses the correct port' do
if @method == :local_address
@addr.ip_port.should != @s.addr[1]
else
@addr.ip_port.should == @s.addr[1]
end
end
it 'returns an Addrinfo' do
@addr.should be_an_instance_of(Addrinfo)
end
it 'uses 0 as the protocol' do
@addr.protocol.should == 0
end
it 'can be used to connect to the peer' do
b = @addr.connect
begin
b.remote_address.to_s.should == @addr.to_s
ensure
b.close
end
end
end
end

View file

@ -1,6 +1,42 @@
# frozen_string_literal: false
require_relative '../../spec_helper' require_relative '../../spec_helper'
require 'stringio' require 'stringio'
describe "StringIO#ungetbyte" do describe "StringIO#ungetbyte" do
it "needs to be reviewed for spec completeness" it "ungets a single byte from a string starting with a single byte character" do
str = 'This is a simple string.'
io = StringIO.new("#{str}")
c = io.getc
c.should == 'T'
io.ungetbyte(83)
io.string.should == 'Shis is a simple string.'
end
it "ungets a single byte from a string in the middle of a multibyte characte" do
str = "\u01a9"
io = StringIO.new(str)
b = io.getbyte
b.should == 0xc6 # First byte of UTF-8 encoding of \u01a9
io.ungetbyte(0xce) # First byte of UTF-8 encoding of \u03a9
io.string.should == "\u03a9"
end
it "constrains the value of a numeric argument to a single byte" do
str = 'This is a simple string.'
io = StringIO.new("#{str}")
c = io.getc
c.should == 'T'
io.ungetbyte(83 | 0xff00)
io.string.should == 'Shis is a simple string.'
end
it "ungets the bytes of a string if given a string as an arugment" do
str = "\u01a9"
io = StringIO.new(str)
b = io.getbyte
b.should == 0xc6 # First byte of UTF-8 encoding of \u01a9
io.ungetbyte("\u01a9")
io.string.bytes.should == [198, 169, 169]
end
end end

View file

@ -13,4 +13,15 @@ describe "StringScanner#check" do
@s.check(/is/).should == nil @s.check(/is/).should == nil
@s.matched.should == nil @s.matched.should == nil
end end
ruby_version_is "2.7" do
it "treats String as the pattern itself" do
@s.check("This").should == "This"
@s.matched.should == "This"
@s.pos.should == 0
@s.check(/is/).should == nil
@s.matched.should == nil
end
end
end end

View file

@ -471,6 +471,32 @@ static VALUE string_spec_rb_sprintf4(VALUE self, VALUE str) {
return rb_sprintf("Result: %+" PRIsVALUE ".", str); return rb_sprintf("Result: %+" PRIsVALUE ".", str);
} }
static VALUE string_spec_rb_sprintf5(VALUE self, VALUE width, VALUE precision, VALUE str) {
return rb_sprintf("Result: %*.*s.", FIX2INT(width), FIX2INT(precision), RSTRING_PTR(str));
}
static VALUE string_spec_rb_sprintf6(VALUE self, VALUE width, VALUE precision, VALUE str) {
return rb_sprintf("Result: %*.*" PRIsVALUE ".", FIX2INT(width), FIX2INT(precision), str);
}
static VALUE string_spec_rb_sprintf7(VALUE self, VALUE str, VALUE obj) {
VALUE results = rb_ary_new();
rb_ary_push(results, rb_sprintf(RSTRING_PTR(str), obj));
char cstr[256];
int len = snprintf(cstr, 256, RSTRING_PTR(str), obj);
rb_ary_push(results, rb_str_new(cstr, len));
return results;
}
static VALUE string_spec_rb_sprintf8(VALUE self, VALUE str, VALUE num) {
VALUE results = rb_ary_new();
rb_ary_push(results, rb_sprintf(RSTRING_PTR(str), FIX2LONG(num)));
char cstr[256];
int len = snprintf(cstr, 256, RSTRING_PTR(str), FIX2LONG(num));
rb_ary_push(results, rb_str_new(cstr, len));
return results;
}
PRINTF_ARGS(static VALUE string_spec_rb_vsprintf_worker(char* fmt, ...), 1, 2); PRINTF_ARGS(static VALUE string_spec_rb_vsprintf_worker(char* fmt, ...), 1, 2);
static VALUE string_spec_rb_vsprintf_worker(char* fmt, ...) { static VALUE string_spec_rb_vsprintf_worker(char* fmt, ...) {
va_list varargs; va_list varargs;
@ -628,6 +654,10 @@ void Init_string_spec(void) {
rb_define_method(cls, "rb_sprintf2", string_spec_rb_sprintf2, 3); rb_define_method(cls, "rb_sprintf2", string_spec_rb_sprintf2, 3);
rb_define_method(cls, "rb_sprintf3", string_spec_rb_sprintf3, 1); rb_define_method(cls, "rb_sprintf3", string_spec_rb_sprintf3, 1);
rb_define_method(cls, "rb_sprintf4", string_spec_rb_sprintf4, 1); rb_define_method(cls, "rb_sprintf4", string_spec_rb_sprintf4, 1);
rb_define_method(cls, "rb_sprintf5", string_spec_rb_sprintf5, 3);
rb_define_method(cls, "rb_sprintf6", string_spec_rb_sprintf6, 3);
rb_define_method(cls, "rb_sprintf7", string_spec_rb_sprintf7, 2);
rb_define_method(cls, "rb_sprintf8", string_spec_rb_sprintf8, 2);
rb_define_method(cls, "rb_vsprintf", string_spec_rb_vsprintf, 4); rb_define_method(cls, "rb_vsprintf", string_spec_rb_vsprintf, 4);
rb_define_method(cls, "rb_str_equal", string_spec_rb_str_equal, 2); rb_define_method(cls, "rb_str_equal", string_spec_rb_str_equal, 2);
rb_define_method(cls, "rb_usascii_str_new", string_spec_rb_usascii_str_new, 2); rb_define_method(cls, "rb_usascii_str_new", string_spec_rb_usascii_str_new, 2);

View file

@ -1055,6 +1055,51 @@ end
s = 'Result: true.' s = 'Result: true.'
@s.rb_sprintf4(true.class).should == s @s.rb_sprintf4(true.class).should == s
end end
it "truncates a string to a supplied precision if that is shorter than the string" do
s = 'Result: Hel.'
@s.rb_sprintf5(0, 3, "Hello").should == s
end
it "does not truncates a string to a supplied precision if that is longer than the string" do
s = 'Result: Hello.'
@s.rb_sprintf5(0, 8, "Hello").should == s
end
it "pads a string to a supplied width if that is longer than the string" do
s = 'Result: Hello.'
@s.rb_sprintf5(8, 5, "Hello").should == s
end
it "truncates a VALUE string to a supplied precision if that is shorter than the VALUE string" do
s = 'Result: Hel.'
@s.rb_sprintf6(0, 3, "Hello").should == s
end
it "does not truncates a VALUE string to a supplied precision if that is longer than the VALUE string" do
s = 'Result: Hello.'
@s.rb_sprintf6(0, 8, "Hello").should == s
end
it "pads a VALUE string to a supplied width if that is longer than the VALUE string" do
s = 'Result: Hello.'
@s.rb_sprintf6(8, 5, "Hello").should == s
end
it "can format a nil VALUE as a pointer and gives the same output as sprintf in C" do
res = @s.rb_sprintf7("%p", nil);
res[0].should == res[1]
end
it "can format a string VALUE as a pointer and gives the same output as sprintf in C" do
res = @s.rb_sprintf7("%p", "Hello")
res[0].should == res[1]
end
it "can format a raw number a pointer and gives the same output as sprintf in C" do
res = @s.rb_sprintf7("%p", 0x223643);
res[0].should == res[1]
end
end end
describe "rb_vsprintf" do describe "rb_vsprintf" do