mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@82cd3a3
This commit is contained in:
parent
1dc6bed0ca
commit
3b21818db1
16 changed files with 213 additions and 72 deletions
|
@ -73,6 +73,7 @@ EvalBindingProcA
|
|||
Exception2MessageMapper
|
||||
ExceptionForMatrix
|
||||
Fcntl
|
||||
Fiddle
|
||||
FileStat
|
||||
FileUtils
|
||||
Find
|
||||
|
|
|
@ -3,9 +3,10 @@ require_relative 'fixtures/classes'
|
|||
require_relative 'shared/enumeratorize'
|
||||
require_relative '../enumerable/shared/enumeratorized'
|
||||
|
||||
# Modifying a collection while the contents are being iterated
|
||||
# gives undefined behavior. See
|
||||
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/23633
|
||||
# Mutating the array while it is being iterated is discouraged as it can result in confusing behavior.
|
||||
# Yet a Ruby implementation must not crash in such a case, and following the simple CRuby behavior makes sense.
|
||||
# CRuby simply reads the array storage and checks the size for every iteration;
|
||||
# like `i = 0; while i < size; yield self[i]; end`
|
||||
|
||||
describe "Array#each" do
|
||||
it "yields each element to the block" do
|
||||
|
@ -15,6 +16,34 @@ describe "Array#each" do
|
|||
a.should == [1, 2, 3]
|
||||
end
|
||||
|
||||
it "yields each element to the block even if the array is changed during iteration" do
|
||||
a = [1, 2, 3, 4, 5]
|
||||
iterated = []
|
||||
a.each { |x| iterated << x; a << x+5 if x.even? }
|
||||
iterated.should == [1, 2, 3, 4, 5, 7, 9]
|
||||
end
|
||||
|
||||
it "yields only elements that are still in the array" do
|
||||
a = [0, 1, 2, 3, 4]
|
||||
iterated = []
|
||||
a.each { |x| iterated << x; a.pop if x.even? }
|
||||
iterated.should == [0, 1, 2]
|
||||
end
|
||||
|
||||
it "yields elements based on an internal index" do
|
||||
a = [0, 1, 2, 3, 4]
|
||||
iterated = []
|
||||
a.each { |x| iterated << x; a.shift if x.even? }
|
||||
iterated.should == [0, 2, 4]
|
||||
end
|
||||
|
||||
it "yields the same element multiple times if inserting while iterating" do
|
||||
a = [1, 2]
|
||||
iterated = []
|
||||
a.each { |x| iterated << x; a.unshift(0) if a.size == 2 }
|
||||
iterated.should == [1, 1, 2]
|
||||
end
|
||||
|
||||
it "yields each element to a block that takes multiple arguments" do
|
||||
a = [[1, 2], :a, [3, 4]]
|
||||
b = []
|
||||
|
|
|
@ -101,12 +101,30 @@ module DirSpecs
|
|||
@mock_dir_files
|
||||
end
|
||||
|
||||
def self.mock_dir_links
|
||||
unless @mock_dir_links
|
||||
@mock_dir_links = []
|
||||
platform_is_not :windows do
|
||||
@mock_dir_links += [
|
||||
['special/ln', 'subdir_one']
|
||||
]
|
||||
end
|
||||
end
|
||||
@mock_dir_links
|
||||
end
|
||||
|
||||
def self.create_mock_dirs
|
||||
mock_dir_files.each do |name|
|
||||
file = File.join mock_dir, name
|
||||
mkdir_p File.dirname(file)
|
||||
touch file
|
||||
end
|
||||
mock_dir_links.each do |link, target|
|
||||
full_link = File.join mock_dir, link
|
||||
full_target = File.join mock_dir, target
|
||||
|
||||
File.symlink full_target, full_link
|
||||
end
|
||||
end
|
||||
|
||||
def self.delete_mock_dirs
|
||||
|
|
|
@ -222,5 +222,30 @@ describe "Dir.glob" do
|
|||
Dir.rmdir('no_permission')
|
||||
end
|
||||
end
|
||||
|
||||
it "will follow symlinks when processing a `*/` pattern." do
|
||||
expected = ['special/ln/nondotfile']
|
||||
Dir.glob('special/*/nondotfile').should == expected
|
||||
end
|
||||
|
||||
it "will not follow symlinks when recursively traversing directories" do
|
||||
expected = %w[
|
||||
deeply/nondotfile
|
||||
nondotfile
|
||||
subdir_one/nondotfile
|
||||
subdir_two/nondotfile
|
||||
]
|
||||
Dir.glob('**/nondotfile').sort.should == expected
|
||||
end
|
||||
|
||||
it "will follow symlinks when testing directory after recursive directory in pattern" do
|
||||
expected = %w[
|
||||
deeply/nondotfile
|
||||
special/ln/nondotfile
|
||||
subdir_one/nondotfile
|
||||
subdir_two/nondotfile
|
||||
]
|
||||
Dir.glob('**/*/nondotfile').sort.should == expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,16 +54,16 @@ describe "Dir#read" do
|
|||
old_external_encoding = Encoding::default_external
|
||||
Encoding.default_internal = Encoding::UTF_8
|
||||
Encoding.default_external = Encoding::SHIFT_JIS
|
||||
dir = Dir.open(File.join(DirSpecs.mock_dir, 'special'))
|
||||
shift_jis_entries = []
|
||||
begin
|
||||
Dir.open(File.join(DirSpecs.mock_dir, 'special')) do |d|
|
||||
-> {
|
||||
while entry = dir.read
|
||||
while entry = d.read
|
||||
shift_jis_entries << entry
|
||||
end
|
||||
}.should_not raise_error
|
||||
end
|
||||
ensure
|
||||
dir.close
|
||||
Encoding.default_internal = old_internal_encoding
|
||||
Encoding.default_external = old_external_encoding
|
||||
end
|
||||
|
|
|
@ -48,4 +48,13 @@ describe "Interrupt" do
|
|||
RUBY
|
||||
out.should == "Interrupt: #{Signal.list["INT"]}\n"
|
||||
end
|
||||
|
||||
platform_is_not :windows do
|
||||
it "shows the backtrace and has a signaled exit status" do
|
||||
err = IO.popen([*ruby_exe, '-e', 'Process.kill :INT, Process.pid; sleep'], err: [:child, :out], &:read)
|
||||
$?.termsig.should == Signal.list.fetch('INT')
|
||||
err.should.include? ': Interrupt'
|
||||
err.should.include? "from -e:1:in `<main>'"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,6 +44,12 @@ describe "IO#close" do
|
|||
@io.close.should be_nil
|
||||
end
|
||||
|
||||
it "does not call the #flush method but flushes the stream internally" do
|
||||
@io.should_not_receive(:flush)
|
||||
@io.close
|
||||
@io.should.closed?
|
||||
end
|
||||
|
||||
it 'raises an IOError with a clear message' do
|
||||
matching_exception = nil
|
||||
|
||||
|
|
|
@ -1,7 +1,51 @@
|
|||
require_relative '../../shared/rational/minus'
|
||||
require_relative '../../spec_helper'
|
||||
require_relative '../../shared/rational/arithmetic_exception_in_coerce'
|
||||
|
||||
describe "Rational#-" do
|
||||
it_behaves_like :rational_minus, :-
|
||||
it_behaves_like :rational_arithmetic_exception_in_coerce, :-
|
||||
|
||||
it "calls #coerce on the passed argument with self" do
|
||||
rational = Rational(3, 4)
|
||||
obj = mock("Object")
|
||||
obj.should_receive(:coerce).with(rational).and_return([1, 2])
|
||||
|
||||
rational - obj
|
||||
end
|
||||
|
||||
it "calls #- on the coerced Rational with the coerced Object" do
|
||||
rational = Rational(3, 4)
|
||||
|
||||
coerced_rational = mock("Coerced Rational")
|
||||
coerced_rational.should_receive(:-).and_return(:result)
|
||||
|
||||
coerced_obj = mock("Coerced Object")
|
||||
|
||||
obj = mock("Object")
|
||||
obj.should_receive(:coerce).and_return([coerced_rational, coerced_obj])
|
||||
|
||||
(rational - obj).should == :result
|
||||
end
|
||||
end
|
||||
|
||||
describe "Rational#- passed a Rational" do
|
||||
it "returns the result of subtracting other from self as a Rational" do
|
||||
(Rational(3, 4) - Rational(0, 1)).should eql(Rational(3, 4))
|
||||
(Rational(3, 4) - Rational(1, 4)).should eql(Rational(1, 2))
|
||||
|
||||
(Rational(3, 4) - Rational(2, 1)).should eql(Rational(-5, 4))
|
||||
end
|
||||
end
|
||||
|
||||
describe "Rational#- passed a Float" do
|
||||
it "returns the result of subtracting other from self as a Float" do
|
||||
(Rational(3, 4) - 0.2).should eql(0.55)
|
||||
(Rational(3, 4) - 2.5).should eql(-1.75)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Rational#- passed an Integer" do
|
||||
it "returns the result of subtracting other from self as a Rational" do
|
||||
(Rational(3, 4) - 1).should eql(Rational(-1, 4))
|
||||
(Rational(3, 4) - 2).should eql(Rational(-5, 4))
|
||||
end
|
||||
end
|
||||
|
|
|
@ -53,6 +53,15 @@ describe :string_to_sym, shared: true do
|
|||
sym.to_s.should == binary_string
|
||||
end
|
||||
|
||||
it "ignores exising symbols with different encoding" do
|
||||
source = "fée"
|
||||
|
||||
iso_symbol = source.force_encoding(Encoding::ISO_8859_1).send(@method)
|
||||
iso_symbol.encoding.should == Encoding::ISO_8859_1
|
||||
binary_symbol = source.force_encoding(Encoding::BINARY).send(@method)
|
||||
binary_symbol.encoding.should == Encoding::BINARY
|
||||
end
|
||||
|
||||
it "raises an EncodingError for UTF-8 String containing invalid bytes" do
|
||||
invalid_utf8 = "\xC3"
|
||||
invalid_utf8.should_not.valid_encoding?
|
||||
|
|
|
@ -60,6 +60,27 @@ describe "Thread#report_on_exception=" do
|
|||
t.join
|
||||
}.should raise_error(RuntimeError, "Thread#report_on_exception specs")
|
||||
end
|
||||
|
||||
it "prints the backtrace even if the thread was killed just after Thread#raise" do
|
||||
t = nil
|
||||
ready = false
|
||||
-> {
|
||||
t = Thread.new {
|
||||
Thread.current.report_on_exception = true
|
||||
ready = true
|
||||
sleep
|
||||
}
|
||||
|
||||
Thread.pass until ready and t.stop?
|
||||
t.raise RuntimeError, "Thread#report_on_exception before kill spec"
|
||||
t.kill
|
||||
Thread.pass while t.alive?
|
||||
}.should output("", /Thread.+terminated with exception.+Thread#report_on_exception before kill spec/m)
|
||||
|
||||
-> {
|
||||
t.join
|
||||
}.should raise_error(RuntimeError, "Thread#report_on_exception before kill spec")
|
||||
end
|
||||
end
|
||||
|
||||
describe "when set to false" do
|
||||
|
|
|
@ -12,18 +12,10 @@ describe "The __FILE__ pseudo-variable" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "The __FILE__ pseudo-variable" do
|
||||
it_behaves_like :language___FILE__, :require, CodeLoadingSpecs::Method.new
|
||||
end
|
||||
|
||||
describe "The __FILE__ pseudo-variable" do
|
||||
describe "The __FILE__ pseudo-variable with require" do
|
||||
it_behaves_like :language___FILE__, :require, Kernel
|
||||
end
|
||||
|
||||
describe "The __FILE__ pseudo-variable" do
|
||||
it_behaves_like :language___FILE__, :load, CodeLoadingSpecs::Method.new
|
||||
end
|
||||
|
||||
describe "The __FILE__ pseudo-variable" do
|
||||
describe "The __FILE__ pseudo-variable with load" do
|
||||
it_behaves_like :language___FILE__, :load, Kernel
|
||||
end
|
||||
|
|
|
@ -835,6 +835,8 @@ describe "Execution variable $:" do
|
|||
it "can be changed via <<" do
|
||||
$: << "foo"
|
||||
$:.should include("foo")
|
||||
ensure
|
||||
$:.delete("foo")
|
||||
end
|
||||
|
||||
it "is read-only" do
|
||||
|
@ -850,6 +852,14 @@ describe "Execution variable $:" do
|
|||
$-I = []
|
||||
}.should raise_error(NameError)
|
||||
end
|
||||
|
||||
it "default $LOAD_PATH entries until sitelibdir included have @gem_prelude_index set" do
|
||||
$:.should.include?(RbConfig::CONFIG['sitelibdir'])
|
||||
idx = $:.index(RbConfig::CONFIG['sitelibdir'])
|
||||
|
||||
$:[idx..-1].all? { |p| p.instance_variable_defined?(:@gem_prelude_index) }.should be_true
|
||||
$:[0...idx].all? { |p| !p.instance_variable_defined?(:@gem_prelude_index) }.should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe "Global variable $\"" do
|
||||
|
|
|
@ -118,11 +118,14 @@ static VALUE so_rb_obj_call_init(VALUE self, VALUE object,
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE so_rb_obj_class(VALUE self, VALUE obj) {
|
||||
return rb_obj_class(obj);
|
||||
}
|
||||
|
||||
static VALUE so_rbobjclassname(VALUE self, VALUE obj) {
|
||||
return rb_str_new2(rb_obj_classname(obj));
|
||||
}
|
||||
|
||||
|
||||
static VALUE object_spec_rb_obj_freeze(VALUE self, VALUE obj) {
|
||||
return rb_obj_freeze(obj);
|
||||
}
|
||||
|
@ -442,6 +445,7 @@ void Init_object_spec(void) {
|
|||
rb_define_method(cls, "rb_obj_alloc", so_rb_obj_alloc, 1);
|
||||
rb_define_method(cls, "rb_obj_dup", so_rb_obj_dup, 1);
|
||||
rb_define_method(cls, "rb_obj_call_init", so_rb_obj_call_init, 3);
|
||||
rb_define_method(cls, "rb_obj_class", so_rb_obj_class, 1);
|
||||
rb_define_method(cls, "rb_obj_classname", so_rbobjclassname, 1);
|
||||
rb_define_method(cls, "rb_obj_freeze", object_spec_rb_obj_freeze, 1);
|
||||
rb_define_method(cls, "rb_obj_frozen_p", object_spec_rb_obj_frozen_p, 1);
|
||||
|
|
|
@ -480,12 +480,31 @@ describe "CApiObject" do
|
|||
end
|
||||
end
|
||||
|
||||
describe "rb_obj_class" do
|
||||
it "returns the class of an object" do
|
||||
@o.rb_obj_class(nil).should == NilClass
|
||||
@o.rb_obj_class(0).should == Integer
|
||||
@o.rb_obj_class(0.1).should == Float
|
||||
@o.rb_obj_class(ObjectTest.new).should == ObjectTest
|
||||
end
|
||||
|
||||
it "does not return the singleton class if it exists" do
|
||||
o = ObjectTest.new
|
||||
o.singleton_class
|
||||
@o.rb_obj_class(o).should equal ObjectTest
|
||||
end
|
||||
end
|
||||
|
||||
describe "rb_obj_classname" do
|
||||
it "returns the class name of an object" do
|
||||
@o.rb_obj_classname(nil).should == 'NilClass'
|
||||
@o.rb_obj_classname(0).should == 'Integer'
|
||||
@o.rb_obj_classname(0.1).should == 'Float'
|
||||
@o.rb_obj_classname(ObjectTest.new).should == 'ObjectTest'
|
||||
|
||||
o = ObjectTest.new
|
||||
o.singleton_class
|
||||
@o.rb_obj_classname(o).should == 'ObjectTest'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -611,7 +611,9 @@ describe "C-API String function" do
|
|||
filename = fixture(__FILE__, "read.txt")
|
||||
str = ""
|
||||
capacities = @s.RSTRING_PTR_read(str, filename)
|
||||
capacities.should == [30, 53]
|
||||
capacities[0].should >= 30
|
||||
capacities[1].should >= 53
|
||||
capacities[0].should < capacities[1]
|
||||
str.should == "fixture file contents to test read() with RSTRING_PTR"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
describe :rational_minus_rat, shared: true do
|
||||
it "returns the result of subtracting other from self as a Rational" do
|
||||
(Rational(3, 4) - Rational(0, 1)).should eql(Rational(3, 4))
|
||||
(Rational(3, 4) - Rational(1, 4)).should eql(Rational(1, 2))
|
||||
|
||||
(Rational(3, 4) - Rational(2, 1)).should eql(Rational(-5, 4))
|
||||
end
|
||||
end
|
||||
|
||||
describe :rational_minus_int, shared: true do
|
||||
it "returns the result of subtracting other from self as a Rational" do
|
||||
(Rational(3, 4) - 1).should eql(Rational(-1, 4))
|
||||
(Rational(3, 4) - 2).should eql(Rational(-5, 4))
|
||||
end
|
||||
end
|
||||
|
||||
describe :rational_minus_float, shared: true do
|
||||
it "returns the result of subtracting other from self as a Float" do
|
||||
(Rational(3, 4) - 0.2).should eql(0.55)
|
||||
(Rational(3, 4) - 2.5).should eql(-1.75)
|
||||
end
|
||||
end
|
||||
|
||||
describe :rational_minus, shared: true do
|
||||
it "calls #coerce on the passed argument with self" do
|
||||
rational = Rational(3, 4)
|
||||
obj = mock("Object")
|
||||
obj.should_receive(:coerce).with(rational).and_return([1, 2])
|
||||
|
||||
rational - obj
|
||||
end
|
||||
|
||||
it "calls #- on the coerced Rational with the coerced Object" do
|
||||
rational = Rational(3, 4)
|
||||
|
||||
coerced_rational = mock("Coerced Rational")
|
||||
coerced_rational.should_receive(:-).and_return(:result)
|
||||
|
||||
coerced_obj = mock("Coerced Object")
|
||||
|
||||
obj = mock("Object")
|
||||
obj.should_receive(:coerce).and_return([coerced_rational, coerced_obj])
|
||||
|
||||
(rational - obj).should == :result
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue