mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@ccf0d85
This commit is contained in:
parent
afcbb501ac
commit
b9f34062f0
28 changed files with 692 additions and 31 deletions
|
@ -92,6 +92,7 @@ module DirSpecs
|
|||
special/|
|
||||
|
||||
special/こんにちは.txt
|
||||
special/\a
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -80,6 +80,10 @@ describe :dir_glob, shared: true do
|
|||
it "matches regexp special |" do
|
||||
Dir.send(@method, 'special/|').should == ['special/|']
|
||||
end
|
||||
|
||||
it "matches files with backslashes in their name" do
|
||||
Dir.glob('special/\\\\{a,b}').should == ['special/\a']
|
||||
end
|
||||
end
|
||||
|
||||
it "matches regexp special ^" do
|
||||
|
|
|
@ -17,6 +17,14 @@ describe "Encoding.default_external" do
|
|||
Encoding.default_external = Encoding::SHIFT_JIS
|
||||
Encoding.default_external.should == Encoding::SHIFT_JIS
|
||||
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
|
||||
|
||||
describe "Encoding.default_external=" do
|
||||
|
|
|
@ -89,5 +89,19 @@ describe :enumerable_collect, shared: true do
|
|||
end.should raise_error(ArgumentError)
|
||||
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
|
||||
end
|
||||
|
|
|
@ -70,6 +70,15 @@ describe "File.utime" do
|
|||
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 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
|
||||
|
|
|
@ -320,6 +320,10 @@ describe :kernel_sprintf, shared: true do
|
|||
@method.call("%s", "abc").should == "abc"
|
||||
end
|
||||
|
||||
it "substitutes '' for nil" do
|
||||
@method.call("%s", nil).should == ""
|
||||
end
|
||||
|
||||
it "converts argument to string with to_s" do
|
||||
obj = mock("string")
|
||||
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"
|
||||
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
|
||||
Kernel.format("%.2s", "été").should == "ét"
|
||||
end
|
||||
|
|
|
@ -97,8 +97,8 @@ describe :marshal_load, shared: true do
|
|||
:b, :c, 2, a, false, "ant", ["hi", 10, "hi", "hi", st, [:a, :b, :c]],
|
||||
]
|
||||
|
||||
arr.each do |obj|
|
||||
obj.should.frozen?
|
||||
arr.each do |v|
|
||||
v.should.frozen?
|
||||
end
|
||||
|
||||
Struct.send(:remove_const, :Brittle)
|
||||
|
|
|
@ -6,8 +6,8 @@ describe "ObjectSpace.garbage_collect" do
|
|||
-> { ObjectSpace.garbage_collect }.should_not raise_error
|
||||
end
|
||||
|
||||
it "doesn't accept any arguments" do
|
||||
-> { ObjectSpace.garbage_collect(1) }.should raise_error(ArgumentError)
|
||||
it "accepts keyword arguments" do
|
||||
ObjectSpace.garbage_collect(full_mark: true, immediate_sweep: true).should == nil
|
||||
end
|
||||
|
||||
it "ignores the supplied block" do
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
require_relative 'shared/strip'
|
||||
|
||||
describe "String#lstrip" do
|
||||
it_behaves_like :string_strip, :lstrip
|
||||
|
||||
it "returns a copy of self with leading whitespace removed" do
|
||||
" hello ".lstrip.should == "hello "
|
||||
" hello world ".lstrip.should == "hello world "
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
require_relative 'shared/partition'
|
||||
|
||||
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
|
||||
"hello world".partition("o").should == ["hell", "o", " world"]
|
||||
end
|
||||
|
|
|
@ -10,6 +10,22 @@ describe "String#reverse" do
|
|||
"".reverse.should == ""
|
||||
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
|
||||
it "taints the result if self is tainted" do
|
||||
"".taint.reverse.should.tainted?
|
||||
|
@ -20,7 +36,6 @@ describe "String#reverse" do
|
|||
it "reverses a string with multi byte characters" do
|
||||
"微軟正黑體".reverse.should == "體黑正軟微"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "String#reverse!" do
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
require_relative 'shared/partition'
|
||||
|
||||
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
|
||||
"hello world".rpartition("o").should == ["hello w", "o", "rld"]
|
||||
end
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
require_relative 'shared/strip'
|
||||
|
||||
describe "String#rstrip" do
|
||||
it_behaves_like :string_strip, :rstrip
|
||||
|
||||
it "returns a copy of self with trailing whitespace removed" do
|
||||
" hello ".rstrip.should == " hello"
|
||||
" hello world ".rstrip.should == " hello world"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
describe "String#scrub with a default replacement" do
|
||||
it "returns self for valid strings" do
|
||||
|
@ -19,12 +20,25 @@ describe "String#scrub with a default replacement" do
|
|||
input.scrub.should == "foo"
|
||||
end
|
||||
|
||||
|
||||
it "replaces invalid byte sequences when using ASCII as the input encoding" do
|
||||
xE3x80 = [0xE3, 0x80].pack('CC').force_encoding 'utf-8'
|
||||
input = "abc\u3042#{xE3x80}".force_encoding('ASCII')
|
||||
input.scrub.should == "abc?????"
|
||||
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
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
describe "String#scrub with a block" do
|
||||
|
@ -89,6 +111,14 @@ describe "String#scrub with a block" do
|
|||
|
||||
replaced.should == "€€"
|
||||
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
|
||||
|
||||
describe "String#scrub!" do
|
||||
|
|
36
spec/ruby/core/string/shared/partition.rb
Normal file
36
spec/ruby/core/string/shared/partition.rb
Normal 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
|
20
spec/ruby/core/string/shared/strip.rb
Normal file
20
spec/ruby/core/string/shared/strip.rb
Normal 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
|
|
@ -1,7 +1,10 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
require_relative 'shared/strip'
|
||||
|
||||
describe "String#strip" do
|
||||
it_behaves_like :string_strip, :strip
|
||||
|
||||
it "returns a new string with leading and trailing whitespace removed" do
|
||||
" hello ".strip.should == "hello"
|
||||
" hello world ".strip.should == "hello world"
|
||||
|
|
|
@ -5,21 +5,25 @@ describe "The defined? keyword for literals" do
|
|||
it "returns 'self' for self" do
|
||||
ret = defined?(self)
|
||||
ret.should == "self"
|
||||
ret.frozen?.should == true
|
||||
end
|
||||
|
||||
it "returns 'nil' for nil" do
|
||||
ret = defined?(nil)
|
||||
ret.should == "nil"
|
||||
ret.frozen?.should == true
|
||||
end
|
||||
|
||||
it "returns 'true' for true" do
|
||||
ret = defined?(true)
|
||||
ret.should == "true"
|
||||
ret.frozen?.should == true
|
||||
end
|
||||
|
||||
it "returns 'false' for false" do
|
||||
ret = defined?(false)
|
||||
ret.should == "false"
|
||||
ret.frozen?.should == true
|
||||
end
|
||||
|
||||
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
|
||||
ret = defined?([Object, Array])
|
||||
ret.should == "expression"
|
||||
ret.frozen?.should == true
|
||||
end
|
||||
|
||||
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 "without a receiver" 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
|
||||
|
||||
it "returns nil if the method is not defined" do
|
||||
|
@ -167,7 +174,9 @@ describe "The defined? keyword for an expression" do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
it "returns 'assignment' for assigning an instance variable" do
|
||||
|
@ -470,7 +479,9 @@ end
|
|||
|
||||
describe "The defined? keyword for variables" 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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
# 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?'.
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
it "returns 'constant' when the constant is defined" do
|
||||
defined?(DefinedSpecs).should == "constant"
|
||||
ret = defined?(DefinedSpecs)
|
||||
ret.should == "constant"
|
||||
ret.frozen?.should == true
|
||||
end
|
||||
|
||||
it "returns nil when the constant is not defined" do
|
||||
|
@ -941,12 +960,26 @@ describe "The defined? keyword for yield" do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
it "returns 'yield' if a block is passed to a method taking a block parameter" do
|
||||
DefinedSpecs::Basic.new.yield_block_parameter.should == "yield"
|
||||
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
|
||||
|
||||
describe "The defined? keyword for super" do
|
||||
|
@ -972,7 +1005,9 @@ describe "The defined? keyword for super" do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
it "returns 'super' from a block when a superclass method exists" do
|
||||
|
|
|
@ -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
|
||||
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).
|
||||
|
@ -1116,9 +1118,55 @@ SCRIPT_LINES__ Hash If a constant SCRIPT_LINES__ is defined and ref
|
|||
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
|
||||
|
||||
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
|
||||
Object.const_defined?(:STDIN).should == true
|
||||
end
|
||||
|
@ -1146,7 +1194,6 @@ describe "The predefined global constants" do
|
|||
it "includes TOPLEVEL_BINDING" do
|
||||
Object.const_defined?(:TOPLEVEL_BINDING).should == true
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "The predefined global constant" do
|
||||
|
|
|
@ -11,29 +11,23 @@ module NetHTTPSpecs
|
|||
class SmallHTTPServer
|
||||
def initialize(bind_address)
|
||||
@server = TCPServer.new(bind_address, 0)
|
||||
@running = Mutex.new
|
||||
@thread = Thread.new {
|
||||
Thread.current.abort_on_exception = true
|
||||
listen
|
||||
}
|
||||
end
|
||||
|
||||
def ip
|
||||
@server.addr[3]
|
||||
end
|
||||
|
||||
def port
|
||||
@server.addr[1]
|
||||
end
|
||||
|
||||
def listen
|
||||
loop do
|
||||
begin
|
||||
client = @server.accept
|
||||
rescue IOError => e
|
||||
if @running.locked? # close
|
||||
break
|
||||
else
|
||||
raise e
|
||||
end
|
||||
end
|
||||
|
||||
until @server.closed?
|
||||
client = @server.accept
|
||||
handle_client(client)
|
||||
end
|
||||
end
|
||||
|
@ -43,6 +37,10 @@ module NetHTTPSpecs
|
|||
until client.closed?
|
||||
request = client.gets("\r\n\r\n")
|
||||
break unless request
|
||||
if request == "CLOSE"
|
||||
@server.close
|
||||
break
|
||||
end
|
||||
handle_request(client, request)
|
||||
end
|
||||
ensure
|
||||
|
@ -95,8 +93,9 @@ module NetHTTPSpecs
|
|||
end
|
||||
|
||||
def close
|
||||
@running.lock
|
||||
@server.close
|
||||
TCPSocket.open(ip, port) do |socket|
|
||||
socket.write "CLOSE"
|
||||
end
|
||||
@thread.join
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,6 +42,17 @@ describe 'RbConfig::CONFIG' do
|
|||
RUBY
|
||||
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
|
||||
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' :
|
||||
|
|
10
spec/ruby/library/socket/basicsocket/local_address_spec.rb
Normal file
10
spec/ruby/library/socket/basicsocket/local_address_spec.rb
Normal 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
|
10
spec/ruby/library/socket/basicsocket/remote_address_spec.rb
Normal file
10
spec/ruby/library/socket/basicsocket/remote_address_spec.rb
Normal 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
|
249
spec/ruby/library/socket/shared/address.rb
Normal file
249
spec/ruby/library/socket/shared/address.rb
Normal 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
|
|
@ -1,6 +1,42 @@
|
|||
# frozen_string_literal: false
|
||||
require_relative '../../spec_helper'
|
||||
require 'stringio'
|
||||
|
||||
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
|
||||
|
|
|
@ -13,4 +13,15 @@ describe "StringScanner#check" do
|
|||
@s.check(/is/).should == nil
|
||||
@s.matched.should == nil
|
||||
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
|
||||
|
|
|
@ -471,6 +471,32 @@ static VALUE string_spec_rb_sprintf4(VALUE self, VALUE 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);
|
||||
static VALUE string_spec_rb_vsprintf_worker(char* fmt, ...) {
|
||||
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_sprintf3", string_spec_rb_sprintf3, 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_str_equal", string_spec_rb_str_equal, 2);
|
||||
rb_define_method(cls, "rb_usascii_str_new", string_spec_rb_usascii_str_new, 2);
|
||||
|
|
|
@ -1055,6 +1055,51 @@ end
|
|||
s = 'Result: true.'
|
||||
@s.rb_sprintf4(true.class).should == s
|
||||
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
|
||||
|
||||
describe "rb_vsprintf" do
|
||||
|
|
Loading…
Add table
Reference in a new issue