diff options
author | Benoit Daloze <[email protected]> | 2022-03-03 14:43:14 +0100 |
---|---|---|
committer | Benoit Daloze <[email protected]> | 2022-03-03 14:43:14 +0100 |
commit | 3b21818db1fac0c22f16364eab2d8cc0067abd63 (patch) | |
tree | 6776a6bfe92db4e35da1ff01e09c40d4c4c20351 /spec/ruby | |
parent | 1dc6bed0ca6ca379f1c4b2e9fc0dee72dbf1e205 (diff) |
Update to ruby/spec@82cd3a3
Diffstat (limited to 'spec/ruby')
-rw-r--r-- | spec/ruby/.mspec.constants | 1 | ||||
-rw-r--r-- | spec/ruby/core/array/each_spec.rb | 35 | ||||
-rw-r--r-- | spec/ruby/core/dir/fixtures/common.rb | 18 | ||||
-rw-r--r-- | spec/ruby/core/dir/glob_spec.rb | 25 | ||||
-rw-r--r-- | spec/ruby/core/dir/read_spec.rb | 14 | ||||
-rw-r--r-- | spec/ruby/core/exception/interrupt_spec.rb | 9 | ||||
-rw-r--r-- | spec/ruby/core/io/close_spec.rb | 6 | ||||
-rw-r--r-- | spec/ruby/core/rational/minus_spec.rb | 48 | ||||
-rw-r--r-- | spec/ruby/core/string/shared/to_sym.rb | 9 | ||||
-rw-r--r-- | spec/ruby/core/thread/report_on_exception_spec.rb | 21 | ||||
-rw-r--r-- | spec/ruby/language/file_spec.rb | 12 | ||||
-rw-r--r-- | spec/ruby/language/predefined_spec.rb | 10 | ||||
-rw-r--r-- | spec/ruby/optional/capi/ext/object_spec.c | 6 | ||||
-rw-r--r-- | spec/ruby/optional/capi/object_spec.rb | 19 | ||||
-rw-r--r-- | spec/ruby/optional/capi/string_spec.rb | 4 | ||||
-rw-r--r-- | spec/ruby/shared/rational/minus.rb | 48 |
16 files changed, 213 insertions, 72 deletions
diff --git a/spec/ruby/.mspec.constants b/spec/ruby/.mspec.constants index 6b70274c52..c070e35496 100644 --- a/spec/ruby/.mspec.constants +++ b/spec/ruby/.mspec.constants @@ -73,6 +73,7 @@ EvalBindingProcA Exception2MessageMapper ExceptionForMatrix Fcntl +Fiddle FileStat FileUtils Find diff --git a/spec/ruby/core/array/each_spec.rb b/spec/ruby/core/array/each_spec.rb index 256647d61e..cf8e9da6d8 100644 --- a/spec/ruby/core/array/each_spec.rb +++ b/spec/ruby/core/array/each_spec.rb @@ -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 = [] diff --git a/spec/ruby/core/dir/fixtures/common.rb b/spec/ruby/core/dir/fixtures/common.rb index 637fe93e2f..a8d6e69c44 100644 --- a/spec/ruby/core/dir/fixtures/common.rb +++ b/spec/ruby/core/dir/fixtures/common.rb @@ -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 diff --git a/spec/ruby/core/dir/glob_spec.rb b/spec/ruby/core/dir/glob_spec.rb index 295a7ab920..43dac73eee 100644 --- a/spec/ruby/core/dir/glob_spec.rb +++ b/spec/ruby/core/dir/glob_spec.rb @@ -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 diff --git a/spec/ruby/core/dir/read_spec.rb b/spec/ruby/core/dir/read_spec.rb index 2953aad72f..276930c6b7 100644 --- a/spec/ruby/core/dir/read_spec.rb +++ b/spec/ruby/core/dir/read_spec.rb @@ -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 - -> { - while entry = dir.read - shift_jis_entries << entry - end - }.should_not raise_error + Dir.open(File.join(DirSpecs.mock_dir, 'special')) do |d| + -> { + 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 diff --git a/spec/ruby/core/exception/interrupt_spec.rb b/spec/ruby/core/exception/interrupt_spec.rb index a7501efadc..299b5b81f3 100644 --- a/spec/ruby/core/exception/interrupt_spec.rb +++ b/spec/ruby/core/exception/interrupt_spec.rb @@ -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 diff --git a/spec/ruby/core/io/close_spec.rb b/spec/ruby/core/io/close_spec.rb index eb560eaf67..3a44cc8b17 100644 --- a/spec/ruby/core/io/close_spec.rb +++ b/spec/ruby/core/io/close_spec.rb @@ -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 diff --git a/spec/ruby/core/rational/minus_spec.rb b/spec/ruby/core/rational/minus_spec.rb index 9e0f81556b..a61b62ebe6 100644 --- a/spec/ruby/core/rational/minus_spec.rb +++ b/spec/ruby/core/rational/minus_spec.rb @@ -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 diff --git a/spec/ruby/core/string/shared/to_sym.rb b/spec/ruby/core/string/shared/to_sym.rb index 416f302aef..7bd3a0510c 100644 --- a/spec/ruby/core/string/shared/to_sym.rb +++ b/spec/ruby/core/string/shared/to_sym.rb @@ -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? diff --git a/spec/ruby/core/thread/report_on_exception_spec.rb b/spec/ruby/core/thread/report_on_exception_spec.rb index bf50a167df..e7f400819a 100644 --- a/spec/ruby/core/thread/report_on_exception_spec.rb +++ b/spec/ruby/core/thread/report_on_exception_spec.rb @@ -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 diff --git a/spec/ruby/language/file_spec.rb b/spec/ruby/language/file_spec.rb index 729dee1008..136b262d07 100644 --- a/spec/ruby/language/file_spec.rb +++ b/spec/ruby/language/file_spec.rb @@ -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 diff --git a/spec/ruby/language/predefined_spec.rb b/spec/ruby/language/predefined_spec.rb index 732e66b9e7..8eb7511c0e 100644 --- a/spec/ruby/language/predefined_spec.rb +++ b/spec/ruby/language/predefined_spec.rb @@ -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 diff --git a/spec/ruby/optional/capi/ext/object_spec.c b/spec/ruby/optional/capi/ext/object_spec.c index 6c4b66fc06..2670f24661 100644 --- a/spec/ruby/optional/capi/ext/object_spec.c +++ b/spec/ruby/optional/capi/ext/object_spec.c @@ -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); diff --git a/spec/ruby/optional/capi/object_spec.rb b/spec/ruby/optional/capi/object_spec.rb index ab11367060..8791a4bc76 100644 --- a/spec/ruby/optional/capi/object_spec.rb +++ b/spec/ruby/optional/capi/object_spec.rb @@ -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 diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb index 0cf22e0287..9291630ace 100644 --- a/spec/ruby/optional/capi/string_spec.rb +++ b/spec/ruby/optional/capi/string_spec.rb @@ -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 diff --git a/spec/ruby/shared/rational/minus.rb b/spec/ruby/shared/rational/minus.rb deleted file mode 100644 index 0a0946fdb9..0000000000 --- a/spec/ruby/shared/rational/minus.rb +++ /dev/null @@ -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 |