diff options
author | Benoit Daloze <[email protected]> | 2021-07-29 22:11:21 +0200 |
---|---|---|
committer | Benoit Daloze <[email protected]> | 2021-07-29 22:11:21 +0200 |
commit | 6998d758248d778fa95b008c78d05473e48b8428 (patch) | |
tree | 8abc6926f647ea5f374a5b34c3a4820c5861e32e | |
parent | 15d05f8120745a121b93fab9fd2addf5f094e8d2 (diff) |
Update to ruby/spec@b65d01f
186 files changed, 3865 insertions, 3248 deletions
diff --git a/spec/ruby/.rubocop.yml b/spec/ruby/.rubocop.yml index 60b42cff7f..eab4c3c4a6 100644 --- a/spec/ruby/.rubocop.yml +++ b/spec/ruby/.rubocop.yml @@ -1,7 +1,7 @@ inherit_from: .rubocop_todo.yml AllCops: - TargetRubyVersion: 2.5 + TargetRubyVersion: 2.6 DisplayCopNames: true Exclude: - command_line/fixtures/bad_syntax.rb diff --git a/spec/ruby/CONTRIBUTING.md b/spec/ruby/CONTRIBUTING.md index e470a811ff..30941677e0 100644 --- a/spec/ruby/CONTRIBUTING.md +++ b/spec/ruby/CONTRIBUTING.md @@ -178,7 +178,7 @@ First, file a bug at https://bugs.ruby-lang.org/. It is better to use a `ruby_version_is` guard if there was a release with the fix. ```ruby -ruby_bug '#13669', ''...'2.5' do +ruby_bug '#13669', ''...'2.7' do it "works like this" do # Specify the expected behavior here, not the bug end diff --git a/spec/ruby/README.md b/spec/ruby/README.md index c5b7d6fb6a..a12cc3f7d8 100644 --- a/spec/ruby/README.md +++ b/spec/ruby/README.md @@ -29,8 +29,8 @@ ruby/spec is known to be tested in these implementations for every commit: * [TruffleRuby](https://github.com/oracle/truffleruby/tree/master/spec/ruby) * [Opal](https://github.com/opal/opal/tree/master/spec) -ruby/spec describes the behavior of Ruby 2.5 and more recent Ruby versions. -More precisely, every latest stable MRI release should [pass](https://github.com/ruby/spec/actions/workflows/ci.yml) all specs of ruby/spec (2.5.x, 2.6.x, 2.7.x, etc), and those are tested in CI. +ruby/spec describes the behavior of Ruby 2.6 and more recent Ruby versions. +More precisely, every latest stable MRI release should [pass](https://github.com/ruby/spec/actions/workflows/ci.yml) all specs of ruby/spec (2.6.x, 2.7.x, 3.0.x, etc), and those are tested in CI. ### Synchronization with Ruby Implementations @@ -57,6 +57,7 @@ For older specs try these commits: * Ruby 2.2.10 - [Suite](https://github.com/ruby/spec/commit/cbaa0e412270c944df0c2532fc500c920dba0e92) using [MSpec](https://github.com/ruby/mspec/commit/d84d7668449e96856c5f6bac8cb1526b6d357ce3) * Ruby 2.3.8 - [Suite](https://github.com/ruby/spec/commit/dc733114d8ae66a3368ba3a98422c50147a76ba5) using [MSpec](https://github.com/ruby/mspec/commit/4599bc195fb109f2a482a01c32a7d659518369ea) * Ruby 2.4.10 - [Suite](https://github.com/ruby/spec/commit/bce4f2b81d6c31db67cf4d023a0625ceadde59bd) using [MSpec](https://github.com/ruby/mspec/commit/e7eb8aa4c26495b7b461e687d950b96eb08b3ff2) +* Ruby 2.5.9 - [Suite](https://github.com/ruby/spec/commit/c503335d3d9f6ec6ef24de60a0716c34af69b64f) using [MSpec](https://github.com/ruby/mspec/commit/0091e8a62e954717cd54641f935eaf1403692041) ### Running the specs diff --git a/spec/ruby/command_line/feature_spec.rb b/spec/ruby/command_line/feature_spec.rb index 16e106b37d..1a9ea925c9 100644 --- a/spec/ruby/command_line/feature_spec.rb +++ b/spec/ruby/command_line/feature_spec.rb @@ -1,6 +1,12 @@ require_relative '../spec_helper' describe "The --enable and --disable flags" do + before :all do + # Since some specs disable reading RUBYOPT, we instead pass its contents as :options for those specs + rubyopt = [ENV["RUBYOPT"]] + rubyopt << ENV["#{RUBY_ENGINE.upcase}OPT"] unless RUBY_ENGINE == 'ruby' + @rubyopt = RUBY_ENGINE == "ruby" ? "" : rubyopt.compact.join(" ") + end it "can be used with gems" do ruby_exe("p defined?(Gem)", options: "--enable=gems").chomp.should == "\"constant\"" @@ -25,9 +31,9 @@ describe "The --enable and --disable flags" do it "can be used with rubyopt" do ruby_exe("p $VERBOSE", options: "--enable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "true" - ruby_exe("p $VERBOSE", options: "--disable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false" + ruby_exe("p $VERBOSE", options: "#{@rubyopt} --disable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false" ruby_exe("p $VERBOSE", options: "--enable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "true" - ruby_exe("p $VERBOSE", options: "--disable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false" + ruby_exe("p $VERBOSE", options: "#{@rubyopt} --disable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false" end it "can be used with frozen-string-literal" do @@ -49,8 +55,8 @@ describe "The --enable and --disable flags" do it "can be used with all for disable" do e = "p [defined?(Gem), defined?(DidYouMean), $VERBOSE, 'foo'.frozen?]" env = {'RUBYOPT' => '-w'} - ruby_exe(e, options: "--disable=all", env: env).chomp.should == "[nil, nil, false, false]" - ruby_exe(e, options: "--disable-all", env: env).chomp.should == "[nil, nil, false, false]" + ruby_exe(e, options: "#{@rubyopt} --disable=all", env: env).chomp.should == "[nil, nil, false, false]" + ruby_exe(e, options: "#{@rubyopt} --disable-all", env: env).chomp.should == "[nil, nil, false, false]" end it "prints a warning for unknown features" do diff --git a/spec/ruby/core/array/difference_spec.rb b/spec/ruby/core/array/difference_spec.rb index a357657967..9f7d4c4a1a 100644 --- a/spec/ruby/core/array/difference_spec.rb +++ b/spec/ruby/core/array/difference_spec.rb @@ -2,23 +2,21 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative 'shared/difference' -ruby_version_is "2.6" do - describe "Array#difference" do - it_behaves_like :array_binary_difference, :difference +describe "Array#difference" do + it_behaves_like :array_binary_difference, :difference - it "returns a copy when called without any parameter" do - x = [1, 2, 3, 2] - x.difference.should == x - x.difference.should_not equal x - end + it "returns a copy when called without any parameter" do + x = [1, 2, 3, 2] + x.difference.should == x + x.difference.should_not equal x + end - it "does not return subclass instances for Array subclasses" do - ArraySpecs::MyArray[1, 2, 3].difference.should be_an_instance_of(Array) - end + it "does not return subclass instances for Array subclasses" do + ArraySpecs::MyArray[1, 2, 3].difference.should be_an_instance_of(Array) + end - it "accepts multiple arguments" do - x = [1, 2, 3, 1] - x.difference([], [0, 1], [3, 4], [3]).should == [2] - end + it "accepts multiple arguments" do + x = [1, 2, 3, 1] + x.difference([], [0, 1], [3, 4], [3]).should == [2] end end diff --git a/spec/ruby/core/array/element_set_spec.rb b/spec/ruby/core/array/element_set_spec.rb index 07c64b919e..1e192c100f 100644 --- a/spec/ruby/core/array/element_set_spec.rb +++ b/spec/ruby/core/array/element_set_spec.rb @@ -445,41 +445,39 @@ describe "Array#[]= with [m..n]" do end end -ruby_version_is "2.6" do - describe "Array#[]= with [m..]" do - it "just sets the section defined by range to nil even if the rhs is nil" do - a = [1, 2, 3, 4, 5] - a[eval("(2..)")] = nil - a.should == [1, 2, nil] - end +describe "Array#[]= with [m..]" do + it "just sets the section defined by range to nil even if the rhs is nil" do + a = [1, 2, 3, 4, 5] + a[eval("(2..)")] = nil + a.should == [1, 2, nil] + end - it "just sets the section defined by range to nil if m and n < 0 and the rhs is nil" do - a = [1, 2, 3, 4, 5] - a[eval("(-3..)")] = nil - a.should == [1, 2, nil] - end + it "just sets the section defined by range to nil if m and n < 0 and the rhs is nil" do + a = [1, 2, 3, 4, 5] + a[eval("(-3..)")] = nil + a.should == [1, 2, nil] + end - it "replaces the section defined by range" do - a = [6, 5, 4, 3, 2, 1] - a[eval("(3...)")] = 9 - a.should == [6, 5, 4, 9] - a[eval("(2..)")] = [7, 7, 7] - a.should == [6, 5, 7, 7, 7] - end + it "replaces the section defined by range" do + a = [6, 5, 4, 3, 2, 1] + a[eval("(3...)")] = 9 + a.should == [6, 5, 4, 9] + a[eval("(2..)")] = [7, 7, 7] + a.should == [6, 5, 7, 7, 7] + end - it "replaces the section if m and n < 0" do - a = [1, 2, 3, 4, 5] - a[eval("(-3..)")] = [7, 8, 9] - a.should == [1, 2, 7, 8, 9] - end + it "replaces the section if m and n < 0" do + a = [1, 2, 3, 4, 5] + a[eval("(-3..)")] = [7, 8, 9] + a.should == [1, 2, 7, 8, 9] + end - it "inserts at the end if m > the array size" do - a = [1, 2, 3] - a[eval("(3..)")] = [4] - a.should == [1, 2, 3, 4] - a[eval("(5..)")] = [6] - a.should == [1, 2, 3, 4, nil, 6] - end + it "inserts at the end if m > the array size" do + a = [1, 2, 3] + a[eval("(3..)")] = [4] + a.should == [1, 2, 3, 4] + a[eval("(5..)")] = [6] + a.should == [1, 2, 3, 4, nil, 6] end end diff --git a/spec/ruby/core/array/fill_spec.rb b/spec/ruby/core/array/fill_spec.rb index 8f0814a5da..bfa8db551b 100644 --- a/spec/ruby/core/array/fill_spec.rb +++ b/spec/ruby/core/array/fill_spec.rb @@ -316,13 +316,11 @@ describe "Array#fill with (filler, range)" do -> { [].fill('a', obj..obj) }.should raise_error(TypeError) end - ruby_version_is "2.6" do - it "works with endless ranges" do - [1, 2, 3, 4].fill('x', eval("(1..)")).should == [1, 'x', 'x', 'x'] - [1, 2, 3, 4].fill('x', eval("(3...)")).should == [1, 2, 3, 'x'] - [1, 2, 3, 4].fill(eval("(1..)")) { |x| x + 2 }.should == [1, 3, 4, 5] - [1, 2, 3, 4].fill(eval("(3...)")) { |x| x + 2 }.should == [1, 2, 3, 5] - end + it "works with endless ranges" do + [1, 2, 3, 4].fill('x', eval("(1..)")).should == [1, 'x', 'x', 'x'] + [1, 2, 3, 4].fill('x', eval("(3...)")).should == [1, 2, 3, 'x'] + [1, 2, 3, 4].fill(eval("(1..)")) { |x| x + 2 }.should == [1, 3, 4, 5] + [1, 2, 3, 4].fill(eval("(3...)")) { |x| x + 2 }.should == [1, 2, 3, 5] end ruby_version_is "2.7" do diff --git a/spec/ruby/core/array/filter_spec.rb b/spec/ruby/core/array/filter_spec.rb index ee4f71ca28..156ad14f9c 100644 --- a/spec/ruby/core/array/filter_spec.rb +++ b/spec/ruby/core/array/filter_spec.rb @@ -1,16 +1,14 @@ require_relative '../../spec_helper' require_relative 'shared/select' -ruby_version_is "2.6" do - describe "Array#filter" do - it_behaves_like :array_select, :filter - end - - describe "Array#filter!" do - it "returns nil if no changes were made in the array" do - [1, 2, 3].filter! { true }.should be_nil - end +describe "Array#filter" do + it_behaves_like :array_select, :filter +end - it_behaves_like :keep_if, :filter! +describe "Array#filter!" do + it "returns nil if no changes were made in the array" do + [1, 2, 3].filter! { true }.should be_nil end + + it_behaves_like :keep_if, :filter! end diff --git a/spec/ruby/core/array/shared/slice.rb b/spec/ruby/core/array/shared/slice.rb index 6818badeda..19e1a3ee2b 100644 --- a/spec/ruby/core/array/shared/slice.rb +++ b/spec/ruby/core/array/shared/slice.rb @@ -521,18 +521,16 @@ describe :array_slice, shared: true do -> { "hello".send(@method, 0..bignum_value) }.should raise_error(RangeError) end - ruby_version_is "2.6" do - it "can accept endless ranges" do - a = [0, 1, 2, 3, 4, 5] - a.send(@method, eval("(2..)")).should == [2, 3, 4, 5] - a.send(@method, eval("(2...)")).should == [2, 3, 4, 5] - a.send(@method, eval("(-2..)")).should == [4, 5] - a.send(@method, eval("(-2...)")).should == [4, 5] - a.send(@method, eval("(9..)")).should == nil - a.send(@method, eval("(9...)")).should == nil - a.send(@method, eval("(-9..)")).should == nil - a.send(@method, eval("(-9...)")).should == nil - end + it "can accept endless ranges" do + a = [0, 1, 2, 3, 4, 5] + a.send(@method, eval("(2..)")).should == [2, 3, 4, 5] + a.send(@method, eval("(2...)")).should == [2, 3, 4, 5] + a.send(@method, eval("(-2..)")).should == [4, 5] + a.send(@method, eval("(-2...)")).should == [4, 5] + a.send(@method, eval("(9..)")).should == nil + a.send(@method, eval("(9...)")).should == nil + a.send(@method, eval("(-9..)")).should == nil + a.send(@method, eval("(-9...)")).should == nil end ruby_version_is "2.7" do diff --git a/spec/ruby/core/array/slice_spec.rb b/spec/ruby/core/array/slice_spec.rb index 2f98df9488..8c276f9084 100644 --- a/spec/ruby/core/array/slice_spec.rb +++ b/spec/ruby/core/array/slice_spec.rb @@ -154,24 +154,22 @@ describe "Array#slice!" do -> { ArraySpecs.frozen_array.slice!(0, 0) }.should raise_error(FrozenError) end - ruby_version_is "2.6" do - it "works with endless ranges" do - a = [1, 2, 3] - a.slice!(eval("(1..)")).should == [2, 3] - a.should == [1] - - a = [1, 2, 3] - a.slice!(eval("(2...)")).should == [3] - a.should == [1, 2] - - a = [1, 2, 3] - a.slice!(eval("(-2..)")).should == [2, 3] - a.should == [1] - - a = [1, 2, 3] - a.slice!(eval("(-1...)")).should == [3] - a.should == [1, 2] - end + it "works with endless ranges" do + a = [1, 2, 3] + a.slice!(eval("(1..)")).should == [2, 3] + a.should == [1] + + a = [1, 2, 3] + a.slice!(eval("(2...)")).should == [3] + a.should == [1, 2] + + a = [1, 2, 3] + a.slice!(eval("(-2..)")).should == [2, 3] + a.should == [1] + + a = [1, 2, 3] + a.slice!(eval("(-1...)")).should == [3] + a.should == [1, 2] end ruby_version_is "2.7" do diff --git a/spec/ruby/core/array/to_h_spec.rb b/spec/ruby/core/array/to_h_spec.rb index 46a79ba58b..f5a7e546e6 100644 --- a/spec/ruby/core/array/to_h_spec.rb +++ b/spec/ruby/core/array/to_h_spec.rb @@ -39,43 +39,41 @@ describe "Array#to_h" do [[:a, 1], [:b, 2]].to_h[:c].should be_nil end - ruby_version_is "2.6" do - context "with block" do - it "converts [key, value] pairs returned by the block to a Hash" do - [:a, :b].to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' } - end - - it "raises ArgumentError if block returns longer or shorter array" do - -> do - [:a, :b].to_h { |k| [k, k.to_s, 1] } - end.should raise_error(ArgumentError, /wrong array length at 0/) - - -> do - [:a, :b].to_h { |k| [k] } - end.should raise_error(ArgumentError, /wrong array length at 0/) - end - - it "raises TypeError if block returns something other than Array" do - -> do - [:a, :b].to_h { |k| "not-array" } - end.should raise_error(TypeError, /wrong element type String at 0/) - end - - it "coerces returned pair to Array with #to_ary" do - x = mock('x') - x.stub!(:to_ary).and_return([:b, 'b']) - - [:a].to_h { |k| x }.should == { :b => 'b' } - end - - it "does not coerce returned pair to Array with #to_a" do - x = mock('x') - x.stub!(:to_a).and_return([:b, 'b']) - - -> do - [:a].to_h { |k| x } - end.should raise_error(TypeError, /wrong element type MockObject at 0/) - end + context "with block" do + it "converts [key, value] pairs returned by the block to a Hash" do + [:a, :b].to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' } + end + + it "raises ArgumentError if block returns longer or shorter array" do + -> do + [:a, :b].to_h { |k| [k, k.to_s, 1] } + end.should raise_error(ArgumentError, /wrong array length at 0/) + + -> do + [:a, :b].to_h { |k| [k] } + end.should raise_error(ArgumentError, /wrong array length at 0/) + end + + it "raises TypeError if block returns something other than Array" do + -> do + [:a, :b].to_h { |k| "not-array" } + end.should raise_error(TypeError, /wrong element type String at 0/) + end + + it "coerces returned pair to Array with #to_ary" do + x = mock('x') + x.stub!(:to_ary).and_return([:b, 'b']) + + [:a].to_h { |k| x }.should == { :b => 'b' } + end + + it "does not coerce returned pair to Array with #to_a" do + x = mock('x') + x.stub!(:to_a).and_return([:b, 'b']) + + -> do + [:a].to_h { |k| x } + end.should raise_error(TypeError, /wrong element type MockObject at 0/) end end end diff --git a/spec/ruby/core/array/union_spec.rb b/spec/ruby/core/array/union_spec.rb index 1dca47696d..ba2cc0d6b7 100644 --- a/spec/ruby/core/array/union_spec.rb +++ b/spec/ruby/core/array/union_spec.rb @@ -6,22 +6,20 @@ describe "Array#|" do it_behaves_like :array_binary_union, :| end -ruby_version_is "2.6" do - describe "Array#union" do - it_behaves_like :array_binary_union, :union +describe "Array#union" do + it_behaves_like :array_binary_union, :union - it "returns unique elements when given no argument" do - x = [1, 2, 3, 2] - x.union.should == [1, 2, 3] - end + it "returns unique elements when given no argument" do + x = [1, 2, 3, 2] + x.union.should == [1, 2, 3] + end - it "does not return subclass instances for Array subclasses" do - ArraySpecs::MyArray[1, 2, 3].union.should be_an_instance_of(Array) - end + it "does not return subclass instances for Array subclasses" do + ArraySpecs::MyArray[1, 2, 3].union.should be_an_instance_of(Array) + end - it "accepts multiple arguments" do - x = [1, 2, 3] - x.union(x, x, x, x, [3, 4], x).should == [1, 2, 3, 4] - end + it "accepts multiple arguments" do + x = [1, 2, 3] + x.union(x, x, x, x, [3, 4], x).should == [1, 2, 3, 4] end end diff --git a/spec/ruby/core/array/values_at_spec.rb b/spec/ruby/core/array/values_at_spec.rb index 019152c51c..f1522e0bfe 100644 --- a/spec/ruby/core/array/values_at_spec.rb +++ b/spec/ruby/core/array/values_at_spec.rb @@ -61,11 +61,9 @@ describe "Array#values_at" do ArraySpecs::MyArray[1, 2, 3].values_at(0, 1..2, 1).should be_an_instance_of(Array) end - ruby_version_is "2.6" do - it "works when given endless ranges" do - [1, 2, 3, 4].values_at(eval("(1..)")).should == [2, 3, 4] - [1, 2, 3, 4].values_at(eval("(3...)")).should == [4] - end + it "works when given endless ranges" do + [1, 2, 3, 4].values_at(eval("(1..)")).should == [2, 3, 4] + [1, 2, 3, 4].values_at(eval("(3...)")).should == [4] end ruby_version_is "2.7" do diff --git a/spec/ruby/core/binding/source_location_spec.rb b/spec/ruby/core/binding/source_location_spec.rb index e562bc65c8..d439c3e399 100644 --- a/spec/ruby/core/binding/source_location_spec.rb +++ b/spec/ruby/core/binding/source_location_spec.rb @@ -1,11 +1,9 @@ require_relative '../../spec_helper' require_relative 'fixtures/location' -ruby_version_is "2.6" do - describe "Binding#source_location" do - it "returns an [file, line] pair" do - b = BindingSpecs::LocationMethod::TEST_BINDING - b.source_location.should == [BindingSpecs::LocationMethod::FILE_PATH, 4] - end +describe "Binding#source_location" do + it "returns an [file, line] pair" do + b = BindingSpecs::LocationMethod::TEST_BINDING + b.source_location.should == [BindingSpecs::LocationMethod::FILE_PATH, 4] end end diff --git a/spec/ruby/core/dir/children_spec.rb b/spec/ruby/core/dir/children_spec.rb index f890f54eb4..986c8f38c0 100644 --- a/spec/ruby/core/dir/children_spec.rb +++ b/spec/ruby/core/dir/children_spec.rb @@ -69,76 +69,74 @@ describe "Dir.children" do end end -ruby_version_is "2.6" do - describe "Dir#children" do - before :all do - DirSpecs.create_mock_dirs - end +describe "Dir#children" do + before :all do + DirSpecs.create_mock_dirs + end - before :each do - @internal = Encoding.default_internal - end + before :each do + @internal = Encoding.default_internal + end - after :all do - DirSpecs.delete_mock_dirs - end + after :all do + DirSpecs.delete_mock_dirs + end - after :each do - Encoding.default_internal = @internal - @dir.close if @dir - end + after :each do + Encoding.default_internal = @internal + @dir.close if @dir + end - it "returns an Array of filenames in an existing directory including dotfiles" do - @dir = Dir.new(DirSpecs.mock_dir) - a = @dir.children.sort - @dir.close + it "returns an Array of filenames in an existing directory including dotfiles" do + @dir = Dir.new(DirSpecs.mock_dir) + a = @dir.children.sort + @dir.close - a.should == DirSpecs.expected_paths - %w[. ..] + a.should == DirSpecs.expected_paths - %w[. ..] - @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested") - a = @dir.children.sort - a.should == %w|.dotfile.ext directory| - end + @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested") + a = @dir.children.sort + a.should == %w|.dotfile.ext directory| + end - it "accepts an encoding keyword for the encoding of the entries" do - @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8") - dirs = @dir.to_a.sort - dirs.each { |d| d.encoding.should == Encoding::UTF_8 } - end + it "accepts an encoding keyword for the encoding of the entries" do + @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8") + dirs = @dir.to_a.sort + dirs.each { |d| d.encoding.should == Encoding::UTF_8 } + end - ruby_version_is ""..."2.7" do - it "accepts nil options" do - @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested", nil) - dirs = @dir.to_a.sort - dirs.each { |d| d.encoding.should == Encoding.find("filesystem") } - end + ruby_version_is ""..."2.7" do + it "accepts nil options" do + @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested", nil) + dirs = @dir.to_a.sort + dirs.each { |d| d.encoding.should == Encoding.find("filesystem") } end + end - it "returns children encoded with the filesystem encoding by default" do - # This spec depends on the locale not being US-ASCII because if it is, the - # children that are not ascii_only? will be BINARY encoded. - @dir = Dir.new(File.join(DirSpecs.mock_dir, 'special')) - children = @dir.children.sort - encoding = Encoding.find("filesystem") - encoding = Encoding::BINARY if encoding == Encoding::US_ASCII - platform_is_not :windows do - children.should include("こんにちは.txt".force_encoding(encoding)) - end - children.first.encoding.should equal(Encoding.find("filesystem")) + it "returns children encoded with the filesystem encoding by default" do + # This spec depends on the locale not being US-ASCII because if it is, the + # children that are not ascii_only? will be BINARY encoded. + @dir = Dir.new(File.join(DirSpecs.mock_dir, 'special')) + children = @dir.children.sort + encoding = Encoding.find("filesystem") + encoding = Encoding::BINARY if encoding == Encoding::US_ASCII + platform_is_not :windows do + children.should include("こんにちは.txt".force_encoding(encoding)) end + children.first.encoding.should equal(Encoding.find("filesystem")) + end - it "returns children encoded with the specified encoding" do - path = File.join(DirSpecs.mock_dir, 'special') - @dir = Dir.new(path, encoding: "euc-jp") - children = @dir.children.sort - children.first.encoding.should equal(Encoding::EUC_JP) - end + it "returns children encoded with the specified encoding" do + path = File.join(DirSpecs.mock_dir, 'special') + @dir = Dir.new(path, encoding: "euc-jp") + children = @dir.children.sort + children.first.encoding.should equal(Encoding::EUC_JP) + end - it "returns children transcoded to the default internal encoding" do - Encoding.default_internal = Encoding::EUC_KR - @dir = Dir.new(File.join(DirSpecs.mock_dir, 'special')) - children = @dir.children.sort - children.first.encoding.should equal(Encoding::EUC_KR) - end + it "returns children transcoded to the default internal encoding" do + Encoding.default_internal = Encoding::EUC_KR + @dir = Dir.new(File.join(DirSpecs.mock_dir, 'special')) + children = @dir.children.sort + children.first.encoding.should equal(Encoding::EUC_KR) end end diff --git a/spec/ruby/core/dir/each_child_spec.rb b/spec/ruby/core/dir/each_child_spec.rb index 684f42acc0..f7980991e5 100644 --- a/spec/ruby/core/dir/each_child_spec.rb +++ b/spec/ruby/core/dir/each_child_spec.rb @@ -62,52 +62,50 @@ describe "Dir.each_child" do end end -ruby_version_is "2.6" do - describe "Dir#each_child" do - before :all do - DirSpecs.create_mock_dirs - end +describe "Dir#each_child" do + before :all do + DirSpecs.create_mock_dirs + end - after :all do - DirSpecs.delete_mock_dirs - end + after :all do + DirSpecs.delete_mock_dirs + end - after :each do - @dir.close if @dir - end + after :each do + @dir.close if @dir + end - it "yields all names in an existing directory to the provided block" do - a, b = [], [] - @dir = Dir.new(DirSpecs.mock_dir) - @dir2 = Dir.new("#{DirSpecs.mock_dir}/deeply/nested") + it "yields all names in an existing directory to the provided block" do + a, b = [], [] + @dir = Dir.new(DirSpecs.mock_dir) + @dir2 = Dir.new("#{DirSpecs.mock_dir}/deeply/nested") - @dir.each_child { |f| a << f } - @dir2.each_child { |f| b << f } - @dir2.close + @dir.each_child { |f| a << f } + @dir2.each_child { |f| b << f } + @dir2.close - a.sort.should == DirSpecs.expected_paths - %w|. ..| - b.sort.should == %w|.dotfile.ext directory| - end + a.sort.should == DirSpecs.expected_paths - %w|. ..| + b.sort.should == %w|.dotfile.ext directory| + end - it "returns self when successful" do - @dir = Dir.new(DirSpecs.mock_dir) - @dir.each_child { |f| f }.should == @dir - end + it "returns self when successful" do + @dir = Dir.new(DirSpecs.mock_dir) + @dir.each_child { |f| f }.should == @dir + end - describe "when no block is given" do - it "returns an Enumerator" do - @dir = Dir.new(DirSpecs.mock_dir) + describe "when no block is given" do + it "returns an Enumerator" do + @dir = Dir.new(DirSpecs.mock_dir) - @dir.each_child.should be_an_instance_of(Enumerator) - @dir.each_child.to_a.sort.should == DirSpecs.expected_paths - %w|. ..| - end + @dir.each_child.should be_an_instance_of(Enumerator) + @dir.each_child.to_a.sort.should == DirSpecs.expected_paths - %w|. ..| + end - describe "returned Enumerator" do - describe "size" do - it "should return nil" do - @dir = Dir.new(DirSpecs.mock_dir) - @dir.each_child.size.should == nil - end + describe "returned Enumerator" do + describe "size" do + it "should return nil" do + @dir = Dir.new(DirSpecs.mock_dir) + @dir.each_child.size.should == nil end end end diff --git a/spec/ruby/core/dir/glob_spec.rb b/spec/ruby/core/dir/glob_spec.rb index 61553ab0b1..6533c9b65a 100644 --- a/spec/ruby/core/dir/glob_spec.rb +++ b/spec/ruby/core/dir/glob_spec.rb @@ -29,6 +29,23 @@ describe "Dir.glob" do %w!file_one.ext file_two.ext! end + it 'returns matching file paths when supplied :base keyword argument' do + dir = tmp('dir_glob_base') + file_1 = "#{dir}/lib/bloop.rb" + file_2 = "#{dir}/lib/soup.rb" + file_3 = "#{dir}/lib/mismatched_file_type.txt" + file_4 = "#{dir}/mismatched_directory.rb" + + touch file_1 + touch file_2 + touch file_3 + touch file_4 + + Dir.glob('**/*.rb', base: "#{dir}/lib").sort.should == ["bloop.rb", "soup.rb"].sort + ensure + rm_r dir + end + it "calls #to_path to convert multiple patterns" do pat1 = mock('file_one.ext') pat1.should_receive(:to_path).and_return('file_one.ext') @@ -133,6 +150,14 @@ describe "Dir.glob" do Dir.glob('{deeply/**/,subdir_two/*}').sort.should == expected end + it "preserves multiple /s before a **" do + expected = %w[ + deeply//nested/directory/structure + ] + + Dir.glob('{deeply//**/structure}').sort.should == expected + end + it "accepts a block and yields it with each elements" do ary = [] ret = Dir.glob(["file_o*", "file_t*"]) { |t| ary << t } diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb index c35f7d71ca..ae5c2a114b 100644 --- a/spec/ruby/core/dir/shared/glob.rb +++ b/spec/ruby/core/dir/shared/glob.rb @@ -23,14 +23,7 @@ describe :dir_glob, shared: true do Dir.send(@method, obj).should == %w[file_one.ext] end - ruby_version_is ""..."2.6" do - it "splits the string on \\0 if there is only one string given" do - Dir.send(@method, "file_o*\0file_t*").should == - %w!file_one.ext file_two.ext! - end - end - - ruby_version_is "2.6"..."2.7" do + ruby_version_is ""..."2.7" do it "splits the string on \\0 if there is only one string given and warns" do -> { Dir.send(@method, "file_o*\0file_t*").should == @@ -205,6 +198,14 @@ describe :dir_glob, shared: true do Dir.send(@method, '**/').sort.should == expected end + it "recursively matches any subdirectories except './' or '../' with '**/' from the base directory if that is specified" do + expected = %w[ + nested/directory + ] + + Dir.send(@method, '**/*ory', base: 'deeply').sort.should == expected + end + ruby_version_is ''...'3.1' do it "recursively matches any subdirectories including ./ and ../ with '.**/'" do Dir.chdir("#{DirSpecs.mock_dir}/subdir_one") do diff --git a/spec/ruby/core/enumerable/all_spec.rb b/spec/ruby/core/enumerable/all_spec.rb index 7e9726fe87..b782f94a3e 100644 --- a/spec/ruby/core/enumerable/all_spec.rb +++ b/spec/ruby/core/enumerable/all_spec.rb @@ -132,14 +132,6 @@ describe "Enumerable#all?" do end # may raise an exception in future versions - ruby_version_is ""..."2.6" do - it "ignores block" do - @enum2.all?(NilClass) { raise }.should == false - [1, 2, nil].all?(NilClass) { raise }.should == false - {a: 1}.all?(Array) { raise }.should == true - end - end - it "always returns true on empty enumeration" do @empty.all?(Integer).should == true [].all?(Integer).should == true diff --git a/spec/ruby/core/enumerable/any_spec.rb b/spec/ruby/core/enumerable/any_spec.rb index 64e3159963..636b1fa450 100644 --- a/spec/ruby/core/enumerable/any_spec.rb +++ b/spec/ruby/core/enumerable/any_spec.rb @@ -146,14 +146,6 @@ describe "Enumerable#any?" do end # may raise an exception in future versions - ruby_version_is ""..."2.6" do - it "ignores block" do - @enum2.any?(NilClass) { raise }.should == true - [1, 2, nil].any?(NilClass) { raise }.should == true - {a: 1}.any?(Array) { raise }.should == true - end - end - it "always returns false on empty enumeration" do @empty.any?(Integer).should == false [].any?(Integer).should == false diff --git a/spec/ruby/core/enumerable/chain_spec.rb b/spec/ruby/core/enumerable/chain_spec.rb index 85c0c03603..5e2105d294 100644 --- a/spec/ruby/core/enumerable/chain_spec.rb +++ b/spec/ruby/core/enumerable/chain_spec.rb @@ -1,25 +1,23 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' -ruby_version_is "2.6" do - describe "Enumerable#chain" do - before :each do - ScratchPad.record [] - end +describe "Enumerable#chain" do + before :each do + ScratchPad.record [] + end - it "returns a chain of self and provided enumerables" do - one = EnumerableSpecs::Numerous.new(1) - two = EnumerableSpecs::Numerous.new(2, 3) - three = EnumerableSpecs::Numerous.new(4, 5, 6) + it "returns a chain of self and provided enumerables" do + one = EnumerableSpecs::Numerous.new(1) + two = EnumerableSpecs::Numerous.new(2, 3) + three = EnumerableSpecs::Numerous.new(4, 5, 6) - chain = one.chain(two, three) + chain = one.chain(two, three) - chain.each { |item| ScratchPad << item } - ScratchPad.recorded.should == [1, 2, 3, 4, 5, 6] - end + chain.each { |item| ScratchPad << item } + ScratchPad.recorded.should == [1, 2, 3, 4, 5, 6] + end - it "returns an Enumerator::Chain if given a block" do - EnumerableSpecs::Numerous.new.chain.should be_an_instance_of(Enumerator::Chain) - end + it "returns an Enumerator::Chain if given a block" do + EnumerableSpecs::Numerous.new.chain.should be_an_instance_of(Enumerator::Chain) end end diff --git a/spec/ruby/core/enumerable/filter_spec.rb b/spec/ruby/core/enumerable/filter_spec.rb index f2dc7a7b71..7e4f8c0b50 100644 --- a/spec/ruby/core/enumerable/filter_spec.rb +++ b/spec/ruby/core/enumerable/filter_spec.rb @@ -2,8 +2,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative 'shared/find_all' -ruby_version_is "2.6" do - describe "Enumerable#filter" do - it_behaves_like(:enumerable_find_all , :filter) - end +describe "Enumerable#filter" do + it_behaves_like(:enumerable_find_all , :filter) end diff --git a/spec/ruby/core/enumerable/none_spec.rb b/spec/ruby/core/enumerable/none_spec.rb index ec48eaf0a7..b898d00063 100644 --- a/spec/ruby/core/enumerable/none_spec.rb +++ b/spec/ruby/core/enumerable/none_spec.rb @@ -101,14 +101,6 @@ describe "Enumerable#none?" do end # may raise an exception in future versions - ruby_version_is ""..."2.6" do - it "ignores block" do - @enum2.none?(Integer) { raise }.should == true - [1, 2, nil].none?(TrueClass) { raise }.should == true - {a: 1}.none?(Hash) { raise }.should == true - end - end - it "always returns true on empty enumeration" do @empty.none?(Integer).should == true [].none?(Integer).should == true diff --git a/spec/ruby/core/enumerable/one_spec.rb b/spec/ruby/core/enumerable/one_spec.rb index 6489c84742..d54dd4a527 100644 --- a/spec/ruby/core/enumerable/one_spec.rb +++ b/spec/ruby/core/enumerable/one_spec.rb @@ -92,14 +92,6 @@ describe "Enumerable#one?" do end # may raise an exception in future versions - ruby_version_is ""..."2.6" do - it "ignores block" do - @enum2.one?(NilClass) { raise }.should == true - [1, 2, nil].one?(NilClass) { raise }.should == true - {a: 1}.one?(Array) { raise }.should == true - end - end - it "always returns false on empty enumeration" do @empty.one?(Integer).should == false [].one?(Integer).should == false diff --git a/spec/ruby/core/enumerable/to_h_spec.rb b/spec/ruby/core/enumerable/to_h_spec.rb index 63bfdf19af..0489134552 100644 --- a/spec/ruby/core/enumerable/to_h_spec.rb +++ b/spec/ruby/core/enumerable/to_h_spec.rb @@ -44,47 +44,45 @@ describe "Enumerable#to_h" do -> { enum.to_h }.should raise_error(ArgumentError) end - ruby_version_is "2.6" do - context "with block" do - before do - @enum = EnumerableSpecs::EachDefiner.new(:a, :b) - end - - it "converts [key, value] pairs returned by the block to a hash" do - @enum.to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' } - end - - it "raises ArgumentError if block returns longer or shorter array" do - -> do - @enum.to_h { |k| [k, k.to_s, 1] } - end.should raise_error(ArgumentError, /element has wrong array length/) - - -> do - @enum.to_h { |k| [k] } - end.should raise_error(ArgumentError, /element has wrong array length/) - end - - it "raises TypeError if block returns something other than Array" do - -> do - @enum.to_h { |k| "not-array" } - end.should raise_error(TypeError, /wrong element type String/) - end - - it "coerces returned pair to Array with #to_ary" do - x = mock('x') - x.stub!(:to_ary).and_return([:b, 'b']) - - @enum.to_h { |k| x }.should == { :b => 'b' } - end - - it "does not coerce returned pair to Array with #to_a" do - x = mock('x') - x.stub!(:to_a).and_return([:b, 'b']) - - -> do - @enum.to_h { |k| x } - end.should raise_error(TypeError, /wrong element type MockObject/) - end + context "with block" do + before do + @enum = EnumerableSpecs::EachDefiner.new(:a, :b) + end + + it "converts [key, value] pairs returned by the block to a hash" do + @enum.to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' } + end + + it "raises ArgumentError if block returns longer or shorter array" do + -> do + @enum.to_h { |k| [k, k.to_s, 1] } + end.should raise_error(ArgumentError, /element has wrong array length/) + + -> do + @enum.to_h { |k| [k] } + end.should raise_error(ArgumentError, /element has wrong array length/) + end + + it "raises TypeError if block returns something other than Array" do + -> do + @enum.to_h { |k| "not-array" } + end.should raise_error(TypeError, /wrong element type String/) + end + + it "coerces returned pair to Array with #to_ary" do + x = mock('x') + x.stub!(:to_ary).and_return([:b, 'b']) + + @enum.to_h { |k| x }.should == { :b => 'b' } + end + + it "does not coerce returned pair to Array with #to_a" do + x = mock('x') + x.stub!(:to_a).and_return([:b, 'b']) + + -> do + @enum.to_h { |k| x } + end.should raise_error(TypeError, /wrong element type MockObject/) end end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb index c8d91ebaec..bed30c546d 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/begin_spec.rb @@ -1,11 +1,9 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#begin" do - it "returns the begin of the sequence" do - 1.step(10).begin.should == 1 - (1..10).step.begin.should == 1 - (1...10).step.begin.should == 1 - end +describe "Enumerator::ArithmeticSequence#begin" do + it "returns the begin of the sequence" do + 1.step(10).begin.should == 1 + (1..10).step.begin.should == 1 + (1...10).step.begin.should == 1 end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/each_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/each_spec.rb index d7edf3a21f..d4fff3e01f 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/each_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/each_spec.rb @@ -1,19 +1,17 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#each" do - before :each do - ScratchPad.record [] - @seq = 1.step(10, 4) - end +describe "Enumerator::ArithmeticSequence#each" do + before :each do + ScratchPad.record [] + @seq = 1.step(10, 4) + end - it "calls given block on each item of the sequence" do - @seq.each { |item| ScratchPad << item } - ScratchPad.recorded.should == [1, 5, 9] - end + it "calls given block on each item of the sequence" do + @seq.each { |item| ScratchPad << item } + ScratchPad.recorded.should == [1, 5, 9] + end - it "returns self" do - @seq.each { |item| }.should equal(@seq) - end + it "returns self" do + @seq.each { |item| }.should equal(@seq) end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb index 5a436e8167..29e6e105cf 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/end_spec.rb @@ -1,11 +1,9 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#end" do - it "returns the end of the sequence" do - 1.step(10).end.should == 10 - (1..10).step.end.should == 10 - (1...10).step(17).end.should == 10 - end +describe "Enumerator::ArithmeticSequence#end" do + it "returns the end of the sequence" do + 1.step(10).end.should == 10 + (1..10).step.end.should == 10 + (1...10).step(17).end.should == 10 end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/eq_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/eq_spec.rb index 7895f98047..77eed02d8b 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/eq_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/eq_spec.rb @@ -1,20 +1,18 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#==" do - it "returns true if begin, end, step and exclude_end? are equal" do - 1.step(10).should == 1.step(10) - 1.step(10, 5).should == 1.step(10, 5) +describe "Enumerator::ArithmeticSequence#==" do + it "returns true if begin, end, step and exclude_end? are equal" do + 1.step(10).should == 1.step(10) + 1.step(10, 5).should == 1.step(10, 5) - (1..10).step.should == (1..10).step - (1...10).step(8).should == (1...10).step(8) + (1..10).step.should == (1..10).step + (1...10).step(8).should == (1...10).step(8) - # both have exclude_end? == false - (1..10).step(100).should == 1.step(10, 100) + # both have exclude_end? == false + (1..10).step(100).should == 1.step(10, 100) - ((1..10).step == (1..11).step).should == false - ((1..10).step == (1...10).step).should == false - ((1..10).step == (1..10).step(2)).should == false - end + ((1..10).step == (1..11).step).should == false + ((1..10).step == (1...10).step).should == false + ((1..10).step == (1..10).step(2)).should == false end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/exclude_end_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/exclude_end_spec.rb index 5be189e993..021fe7d90f 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/exclude_end_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/exclude_end_spec.rb @@ -1,19 +1,17 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#exclude_end?" do - context "when created using Numeric#step" do - it "always returns false" do - 1.step(10).should_not.exclude_end? - 10.step(1).should_not.exclude_end? - end +describe "Enumerator::ArithmeticSequence#exclude_end?" do + context "when created using Numeric#step" do + it "always returns false" do + 1.step(10).should_not.exclude_end? + 10.step(1).should_not.exclude_end? end + end - context "when created using Range#step" do - it "mirrors range.exclude_end?" do - (1...10).step.should.exclude_end? - (1..10).step.should_not.exclude_end? - end + context "when created using Range#step" do + it "mirrors range.exclude_end?" do + (1...10).step.should.exclude_end? + (1..10).step.should_not.exclude_end? end end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/first_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/first_spec.rb index 43c520d1f0..ccd02be020 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/first_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/first_spec.rb @@ -1,11 +1,9 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#first" do - it "returns the first element of the sequence" do - 1.step(10).first.should == 1 - (1..10).step.first.should == 1 - (1...10).step.first.should == 1 - end +describe "Enumerator::ArithmeticSequence#first" do + it "returns the first element of the sequence" do + 1.step(10).first.should == 1 + (1..10).step.first.should == 1 + (1...10).step.first.should == 1 end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/hash_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/hash_spec.rb index 236f845f41..bdb308074b 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/hash_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/hash_spec.rb @@ -1,22 +1,20 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#hash" do - it "is based on begin, end, step and exclude_end?" do - 1.step(10).hash.should be_an_instance_of(Integer) +describe "Enumerator::ArithmeticSequence#hash" do + it "is based on begin, end, step and exclude_end?" do + 1.step(10).hash.should be_an_instance_of(Integer) - 1.step(10).hash.should == 1.step(10).hash - 1.step(10, 5).hash.should == 1.step(10, 5).hash + 1.step(10).hash.should == 1.step(10).hash + 1.step(10, 5).hash.should == 1.step(10, 5).hash - (1..10).step.hash.should == (1..10).step.hash - (1...10).step(8).hash.should == (1...10).step(8).hash + (1..10).step.hash.should == (1..10).step.hash + (1...10).step(8).hash.should == (1...10).step(8).hash - # both have exclude_end? == false - (1..10).step(100).hash.should == 1.step(10, 100).hash + # both have exclude_end? == false + (1..10).step(100).hash.should == 1.step(10, 100).hash - ((1..10).step.hash == (1..11).step.hash).should == false - ((1..10).step.hash == (1...10).step.hash).should == false - ((1..10).step.hash == (1..10).step(2).hash).should == false - end + ((1..10).step.hash == (1..11).step.hash).should == false + ((1..10).step.hash == (1...10).step.hash).should == false + ((1..10).step.hash == (1..10).step(2).hash).should == false end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/inspect_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/inspect_spec.rb index 21e64a6b58..b73b49d272 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/inspect_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/inspect_spec.rb @@ -1,22 +1,20 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#inspect" do - context 'when Numeric#step is used' do - it "returns '(begin.step(end{, step}))'" do - 1.step(10).inspect.should == "(1.step(10))" - 1.step(10, 3).inspect.should == "(1.step(10, 3))" - end +describe "Enumerator::ArithmeticSequence#inspect" do + context 'when Numeric#step is used' do + it "returns '(begin.step(end{, step}))'" do + 1.step(10).inspect.should == "(1.step(10))" + 1.step(10, 3).inspect.should == "(1.step(10, 3))" end + end - context 'when Range#step is used' do - it "returns '((range).step{(step)})'" do - (1..10).step.inspect.should == "((1..10).step)" - (1..10).step(3).inspect.should == "((1..10).step(3))" + context 'when Range#step is used' do + it "returns '((range).step{(step)})'" do + (1..10).step.inspect.should == "((1..10).step)" + (1..10).step(3).inspect.should == "((1..10).step(3))" - (1...10).step.inspect.should == "((1...10).step)" - (1...10).step(3).inspect.should == "((1...10).step(3))" - end + (1...10).step.inspect.should == "((1...10).step)" + (1...10).step(3).inspect.should == "((1...10).step(3))" end end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/last_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/last_spec.rb index ebb20090fc..31f982b7c4 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/last_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/last_spec.rb @@ -1,11 +1,9 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#last" do - it "returns the last element of the sequence" do - 1.step(10).last.should == 10 - (1..10).step.last.should == 10 - (1...10).step(4).last.should == 9 - end +describe "Enumerator::ArithmeticSequence#last" do + it "returns the last element of the sequence" do + 1.step(10).last.should == 10 + (1..10).step.last.should == 10 + (1...10).step(4).last.should == 9 end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/new_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/new_spec.rb index 7227581fb9..2015983826 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/new_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/new_spec.rb @@ -1,19 +1,17 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence.new" do - it "is not defined" do - -> { - Enumerator::ArithmeticSequence.new - }.should raise_error(NoMethodError) - end +describe "Enumerator::ArithmeticSequence.new" do + it "is not defined" do + -> { + Enumerator::ArithmeticSequence.new + }.should raise_error(NoMethodError) end +end - describe "Enumerator::ArithmeticSequence.allocate" do - it "is not defined" do - -> { - Enumerator::ArithmeticSequence.allocate - }.should raise_error(TypeError, 'allocator undefined for Enumerator::ArithmeticSequence') - end +describe "Enumerator::ArithmeticSequence.allocate" do + it "is not defined" do + -> { + Enumerator::ArithmeticSequence.allocate + }.should raise_error(TypeError, 'allocator undefined for Enumerator::ArithmeticSequence') end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/size_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/size_spec.rb index 00403b0238..7e03edd961 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/size_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/size_spec.rb @@ -1,19 +1,17 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#size" do - context "for finite sequence" do - it "returns the number of elements in this arithmetic sequence" do - 1.step(10).size.should == 10 - (1...10).step.size.should == 9 - end +describe "Enumerator::ArithmeticSequence#size" do + context "for finite sequence" do + it "returns the number of elements in this arithmetic sequence" do + 1.step(10).size.should == 10 + (1...10).step.size.should == 9 end + end - context "for infinite sequence" do - it "returns Infinity" do - 1.step(Float::INFINITY).size.should == Float::INFINITY - (1..Float::INFINITY).step.size.should == Float::INFINITY - end + context "for infinite sequence" do + it "returns Infinity" do + 1.step(Float::INFINITY).size.should == Float::INFINITY + (1..Float::INFINITY).step.size.should == Float::INFINITY end end end diff --git a/spec/ruby/core/enumerator/arithmetic_sequence/step_spec.rb b/spec/ruby/core/enumerator/arithmetic_sequence/step_spec.rb index 8b00fd4309..c1f2d9173f 100644 --- a/spec/ruby/core/enumerator/arithmetic_sequence/step_spec.rb +++ b/spec/ruby/core/enumerator/arithmetic_sequence/step_spec.rb @@ -1,13 +1,11 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::ArithmeticSequence#step" do - it "returns the original value given to step method" do - (1..10).step.step.should == 1 - (1..10).step(3).step.should == 3 +describe "Enumerator::ArithmeticSequence#step" do + it "returns the original value given to step method" do + (1..10).step.step.should == 1 + (1..10).step(3).step.should == 3 - 1.step(10).step.should == 1 - 1.step(10, 3).step.should == 3 - end + 1.step(10).step.should == 1 + 1.step(10, 3).step.should == 3 end end diff --git a/spec/ruby/core/enumerator/chain/each_spec.rb b/spec/ruby/core/enumerator/chain/each_spec.rb index ab4d355f22..cc93cbac60 100644 --- a/spec/ruby/core/enumerator/chain/each_spec.rb +++ b/spec/ruby/core/enumerator/chain/each_spec.rb @@ -1,17 +1,15 @@ require_relative '../../../spec_helper' require_relative '../../enumerable/fixtures/classes' -ruby_version_is "2.6" do - describe "Enumerator::Chain#each" do - it "calls each on its constituents as needed" do - a = EnumerableSpecs::EachCounter.new(:a, :b) - b = EnumerableSpecs::EachCounter.new(:c, :d) +describe "Enumerator::Chain#each" do + it "calls each on its constituents as needed" do + a = EnumerableSpecs::EachCounter.new(:a, :b) + b = EnumerableSpecs::EachCounter.new(:c, :d) - ScratchPad.record [] - Enumerator::Chain.new(a, b).each do |elem| - ScratchPad << elem << b.times_yielded - end - ScratchPad.recorded.should == [:a, 0, :b, 0, :c, 1, :d, 2] + ScratchPad.record [] + Enumerator::Chain.new(a, b).each do |elem| + ScratchPad << elem << b.times_yielded end + ScratchPad.recorded.should == [:a, 0, :b, 0, :c, 1, :d, 2] end end diff --git a/spec/ruby/core/enumerator/chain/initialize_spec.rb b/spec/ruby/core/enumerator/chain/initialize_spec.rb index e5aa32fd02..69484dfcb4 100644 --- a/spec/ruby/core/enumerator/chain/initialize_spec.rb +++ b/spec/ruby/core/enumerator/chain/initialize_spec.rb @@ -1,33 +1,31 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::Chain#initialize" do - before :each do - @uninitialized = Enumerator::Chain.allocate - end +describe "Enumerator::Chain#initialize" do + before :each do + @uninitialized = Enumerator::Chain.allocate + end - it "is a private method" do - Enumerator::Chain.should have_private_instance_method(:initialize, false) - end + it "is a private method" do + Enumerator::Chain.should have_private_instance_method(:initialize, false) + end - it "returns self" do - @uninitialized.send(:initialize).should equal(@uninitialized) - end + it "returns self" do + @uninitialized.send(:initialize).should equal(@uninitialized) + end - it "accepts many arguments" do - @uninitialized.send(:initialize, 0..1, 2..3, 4..5).should equal(@uninitialized) - end + it "accepts many arguments" do + @uninitialized.send(:initialize, 0..1, 2..3, 4..5).should equal(@uninitialized) + end - it "accepts arguments that are not Enumerable nor responding to :each" do - @uninitialized.send(:initialize, Object.new).should equal(@uninitialized) - end + it "accepts arguments that are not Enumerable nor responding to :each" do + @uninitialized.send(:initialize, Object.new).should equal(@uninitialized) + end - describe "on frozen instance" do - it "raises a RuntimeError" do - -> { - @uninitialized.freeze.send(:initialize) - }.should raise_error(RuntimeError) - end + describe "on frozen instance" do + it "raises a RuntimeError" do + -> { + @uninitialized.freeze.send(:initialize) + }.should raise_error(RuntimeError) end end end diff --git a/spec/ruby/core/enumerator/chain/inspect_spec.rb b/spec/ruby/core/enumerator/chain/inspect_spec.rb index a644d88c6f..a0450c808a 100644 --- a/spec/ruby/core/enumerator/chain/inspect_spec.rb +++ b/spec/ruby/core/enumerator/chain/inspect_spec.rb @@ -1,16 +1,14 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::Chain#inspect" do - it "shows a representation of the Enumerator" do - Enumerator::Chain.new.inspect.should == "#<Enumerator::Chain: []>" - Enumerator::Chain.new(1..2, 3..4).inspect.should == "#<Enumerator::Chain: [1..2, 3..4]>" - end +describe "Enumerator::Chain#inspect" do + it "shows a representation of the Enumerator" do + Enumerator::Chain.new.inspect.should == "#<Enumerator::Chain: []>" + Enumerator::Chain.new(1..2, 3..4).inspect.should == "#<Enumerator::Chain: [1..2, 3..4]>" + end - it "calls inspect on its chain elements" do - obj = mock('inspect') - obj.should_receive(:inspect).and_return('some desc') - Enumerator::Chain.new(obj).inspect.should == "#<Enumerator::Chain: [some desc]>" - end + it "calls inspect on its chain elements" do + obj = mock('inspect') + obj.should_receive(:inspect).and_return('some desc') + Enumerator::Chain.new(obj).inspect.should == "#<Enumerator::Chain: [some desc]>" end end diff --git a/spec/ruby/core/enumerator/chain/rewind_spec.rb b/spec/ruby/core/enumerator/chain/rewind_spec.rb index 951b364f07..5f51ce2cf1 100644 --- a/spec/ruby/core/enumerator/chain/rewind_spec.rb +++ b/spec/ruby/core/enumerator/chain/rewind_spec.rb @@ -1,53 +1,51 @@ require_relative '../../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator::Chain#rewind" do - before(:each) do - @obj = mock('obj') - @obj.should_receive(:each).any_number_of_times.and_yield - @second = mock('obj') - @second.should_receive(:each).any_number_of_times.and_yield - @enum = Enumerator::Chain.new(@obj, @second) - end - - it "returns self" do - @enum.rewind.should equal @enum - end - - it "does nothing if receiver has not been iterated" do - @obj.should_not_receive(:rewind) - @obj.respond_to?(:rewind).should == true # sanity check - @enum.rewind - end - - it "does nothing on objects that don't respond_to rewind" do - @obj.respond_to?(:rewind).should == false # sanity check - @enum.each {} - @enum.rewind - end - - it "calls_rewind its objects" do - @obj.should_receive(:rewind) - @enum.each {} - @enum.rewind - end - - it "calls_rewind in reverse order" do - @obj.should_not_receive(:rewind) - @second.should_receive(:rewind).and_raise(RuntimeError) - @enum.each {} - -> { @enum.rewind }.should raise_error(RuntimeError) - end - - it "calls rewind only for objects that have actually been iterated on" do - @obj = mock('obj') - @obj.should_receive(:each).any_number_of_times.and_raise(RuntimeError) - @enum = Enumerator::Chain.new(@obj, @second) - - @obj.should_receive(:rewind) - @second.should_not_receive(:rewind) - -> { @enum.each {} }.should raise_error(RuntimeError) - @enum.rewind - end +describe "Enumerator::Chain#rewind" do + before(:each) do + @obj = mock('obj') + @obj.should_receive(:each).any_number_of_times.and_yield + @second = mock('obj') + @second.should_receive(:each).any_number_of_times.and_yield + @enum = Enumerator::Chain.new(@obj, @second) + end + + it "returns self" do + @enum.rewind.should equal @enum + end + + it "does nothing if receiver has not been iterated" do + @obj.should_not_receive(:rewind) + @obj.respond_to?(:rewind).should == true # sanity check + @enum.rewind + end + + it "does nothing on objects that don't respond_to rewind" do + @obj.respond_to?(:rewind).should == false # sanity check + @enum.each {} + @enum.rewind + end + + it "calls_rewind its objects" do + @obj.should_receive(:rewind) + @enum.each {} + @enum.rewind + end + + it "calls_rewind in reverse order" do + @obj.should_not_receive(:rewind) + @second.should_receive(:rewind).and_raise(RuntimeError) + @enum.each {} + -> { @enum.rewind }.should raise_error(RuntimeError) + end + + it "calls rewind only for objects that have actually been iterated on" do + @obj = mock('obj') + @obj.should_receive(:each).any_number_of_times.and_raise(RuntimeError) + @enum = Enumerator::Chain.new(@obj, @second) + + @obj.should_receive(:rewind) + @second.should_not_receive(:rewind) + -> { @enum.each {} }.should raise_error(RuntimeError) + @enum.rewind end end diff --git a/spec/ruby/core/enumerator/chain/size_spec.rb b/spec/ruby/core/enumerator/chain/size_spec.rb index 42c31ac10b..d85b88ee8b 100644 --- a/spec/ruby/core/enumerator/chain/size_spec.rb +++ b/spec/ruby/core/enumerator/chain/size_spec.rb @@ -1,24 +1,22 @@ require_relative '../../../spec_helper' require_relative '../../enumerable/fixtures/classes' -ruby_version_is "2.6" do - describe "Enumerator::Chain#size" do - it "returns the sum of the sizes of the elements" do +describe "Enumerator::Chain#size" do + it "returns the sum of the sizes of the elements" do + a = mock('size') + a.should_receive(:size).and_return(40) + Enumerator::Chain.new(a, [:a, :b]).size.should == 42 + end + + it "returns nil or Infinity for the first element of such a size" do + [nil, Float::INFINITY].each do |special| a = mock('size') a.should_receive(:size).and_return(40) - Enumerator::Chain.new(a, [:a, :b]).size.should == 42 - end - - it "returns nil or Infinity for the first element of such a size" do - [nil, Float::INFINITY].each do |special| - a = mock('size') - a.should_receive(:size).and_return(40) - b = mock('special') - b.should_receive(:size).and_return(special) - c = mock('not called') - c.should_not_receive(:size) - Enumerator::Chain.new(a, b, c).size.should == special - end + b = mock('special') + b.should_receive(:size).and_return(special) + c = mock('not called') + c.should_not_receive(:size) + Enumerator::Chain.new(a, b, c).size.should == special end end end diff --git a/spec/ruby/core/enumerator/lazy/filter_spec.rb b/spec/ruby/core/enumerator/lazy/filter_spec.rb index 2ababa69cc..43128241e0 100644 --- a/spec/ruby/core/enumerator/lazy/filter_spec.rb +++ b/spec/ruby/core/enumerator/lazy/filter_spec.rb @@ -1,8 +1,6 @@ require_relative '../../../spec_helper' require_relative 'shared/select' -ruby_version_is "2.6" do - describe "Enumerator::Lazy#filter" do - it_behaves_like :enumerator_lazy_select, :filter - end +describe "Enumerator::Lazy#filter" do + it_behaves_like :enumerator_lazy_select, :filter end diff --git a/spec/ruby/core/enumerator/lazy/with_index_spec.rb b/spec/ruby/core/enumerator/lazy/with_index_spec.rb new file mode 100644 index 0000000000..3a59ba4116 --- /dev/null +++ b/spec/ruby/core/enumerator/lazy/with_index_spec.rb @@ -0,0 +1,30 @@ +# -*- encoding: us-ascii -*- + +require_relative '../../../spec_helper' +require_relative 'fixtures/classes' + +ruby_version_is "2.7" do + describe "Enumerator::Lazy#with_index" do + it "enumerates with an index" do + (0..Float::INFINITY).lazy.with_index.map { |i, idx| [i, idx] }.first(3).should == [[0, 0], [1, 1], [2, 2]] + end + + it "enumerates with an index starting at a given offset" do + (0..Float::INFINITY).lazy.with_index(3).map { |i, idx| [i, idx] }.first(3).should == [[0, 3], [1, 4], [2, 5]] + end + + it "enumerates with an index starting at 0 when offset is nil" do + (0..Float::INFINITY).lazy.with_index(nil).map { |i, idx| [i, idx] }.first(3).should == [[0, 0], [1, 1], [2, 2]] + end + + it "raises TypeError when offset does not convert to Integer" do + -> { (0..Float::INFINITY).lazy.with_index(false).map { |i, idx| i }.first(3) }.should raise_error(TypeError) + end + + it "enumerates with a given block" do + result = [] + (0..Float::INFINITY).lazy.with_index { |i, idx| result << [i * 2, idx] }.first(3) + result.should == [[0,0],[2,1],[4,2]] + end + end +end diff --git a/spec/ruby/core/enumerator/plus_spec.rb b/spec/ruby/core/enumerator/plus_spec.rb index c9bae08b04..755be5b4eb 100644 --- a/spec/ruby/core/enumerator/plus_spec.rb +++ b/spec/ruby/core/enumerator/plus_spec.rb @@ -1,35 +1,33 @@ require_relative '../../spec_helper' -ruby_version_is "2.6" do - describe "Enumerator#+" do - before :each do - ScratchPad.record [] - end +describe "Enumerator#+" do + before :each do + ScratchPad.record [] + end - it "returns a chain of self and provided enumerators" do - one = Enumerator.new { |y| y << 1 } - two = Enumerator.new { |y| y << 2 } - three = Enumerator.new { |y| y << 3 } + it "returns a chain of self and provided enumerators" do + one = Enumerator.new { |y| y << 1 } + two = Enumerator.new { |y| y << 2 } + three = Enumerator.new { |y| y << 3 } - chain = one + two + three + chain = one + two + three - chain.should be_an_instance_of(Enumerator::Chain) - chain.each { |item| ScratchPad << item } - ScratchPad.recorded.should == [1, 2, 3] - end + chain.should be_an_instance_of(Enumerator::Chain) + chain.each { |item| ScratchPad << item } + ScratchPad.recorded.should == [1, 2, 3] + end - it "calls #each on each argument" do - enum = Enumerator.new { |y| y << "one" } + it "calls #each on each argument" do + enum = Enumerator.new { |y| y << "one" } - obj1 = mock("obj1") - obj1.should_receive(:each).once.and_yield("two") + obj1 = mock("obj1") + obj1.should_receive(:each).once.and_yield("two") - obj2 = mock("obj2") - obj2.should_receive(:each).once.and_yield("three") + obj2 = mock("obj2") + obj2.should_receive(:each).once.and_yield("three") - chain = enum + obj1 + obj2 - chain.each { |item| ScratchPad << item } - ScratchPad.recorded.should == ["one", "two", "three"] - end + chain = enum + obj1 + obj2 + chain.each { |item| ScratchPad << item } + ScratchPad.recorded.should == ["one", "two", "three"] end end diff --git a/spec/ruby/core/enumerator/yielder/append_spec.rb b/spec/ruby/core/enumerator/yielder/append_spec.rb index 7f7059774d..a36e5d64b6 100644 --- a/spec/ruby/core/enumerator/yielder/append_spec.rb +++ b/spec/ruby/core/enumerator/yielder/append_spec.rb @@ -23,25 +23,13 @@ describe "Enumerator::Yielder#<<" do end context "when multiple arguments passed" do - ruby_version_is '' ... '2.6' do - it "yields the arguments list to the block" do - ary = [] - y = Enumerator::Yielder.new { |*x| ary << x } - y.<<(1, 2) - - ary.should == [[1, 2]] - end - end + it "raises an ArgumentError" do + ary = [] + y = Enumerator::Yielder.new { |*x| ary << x } - ruby_version_is '2.6' do - it "raises an ArgumentError" do - ary = [] - y = Enumerator::Yielder.new { |*x| ary << x } - - -> { - y.<<(1, 2) - }.should raise_error(ArgumentError, /wrong number of arguments/) - end + -> { + y.<<(1, 2) + }.should raise_error(ArgumentError, /wrong number of arguments/) end end end diff --git a/spec/ruby/core/env/filter_spec.rb b/spec/ruby/core/env/filter_spec.rb index ba18a3b33b..52f8b79a0b 100644 --- a/spec/ruby/core/env/filter_spec.rb +++ b/spec/ruby/core/env/filter_spec.rb @@ -2,14 +2,12 @@ require_relative '../../spec_helper' require_relative '../enumerable/shared/enumeratorized' require_relative 'shared/select' -ruby_version_is "2.6" do - describe "ENV.filter!" do - it_behaves_like :env_select!, :filter! - it_behaves_like :enumeratorized_with_origin_size, :filter!, ENV - end +describe "ENV.filter!" do + it_behaves_like :env_select!, :filter! + it_behaves_like :enumeratorized_with_origin_size, :filter!, ENV +end - describe "ENV.filter" do - it_behaves_like :env_select, :filter - it_behaves_like :enumeratorized_with_origin_size, :filter, ENV - end +describe "ENV.filter" do + it_behaves_like :env_select, :filter + it_behaves_like :enumeratorized_with_origin_size, :filter, ENV end diff --git a/spec/ruby/core/env/slice_spec.rb b/spec/ruby/core/env/slice_spec.rb index 1ac8a303f8..e3b6020391 100644 --- a/spec/ruby/core/env/slice_spec.rb +++ b/spec/ruby/core/env/slice_spec.rb @@ -1,29 +1,27 @@ require_relative '../../spec_helper' -ruby_version_is "2.6" do - describe "ENV.slice" do - before :each do - @saved_foo = ENV["foo"] - @saved_bar = ENV["bar"] - ENV["foo"] = "0" - ENV["bar"] = "1" - end +describe "ENV.slice" do + before :each do + @saved_foo = ENV["foo"] + @saved_bar = ENV["bar"] + ENV["foo"] = "0" + ENV["bar"] = "1" + end - after :each do - ENV["foo"] = @saved_foo - ENV["bar"] = @saved_bar - end + after :each do + ENV["foo"] = @saved_foo + ENV["bar"] = @saved_bar + end - it "returns a hash of the given environment variable names and their values" do - ENV.slice("foo", "bar").should == {"foo" => "0", "bar" => "1"} - end + it "returns a hash of the given environment variable names and their values" do + ENV.slice("foo", "bar").should == {"foo" => "0", "bar" => "1"} + end - it "ignores each String that is not an environment variable name" do - ENV.slice("foo", "boo", "bar").should == {"foo" => "0", "bar" => "1"} - end + it "ignores each String that is not an environment variable name" do + ENV.slice("foo", "boo", "bar").should == {"foo" => "0", "bar" => "1"} + end - it "raises TypeError if any argument is not a String and does not respond to #to_str" do - -> { ENV.slice(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String") - end + it "raises TypeError if any argument is not a String and does not respond to #to_str" do + -> { ENV.slice(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String") end end diff --git a/spec/ruby/core/env/to_h_spec.rb b/spec/ruby/core/env/to_h_spec.rb index 65cdb59951..3c4a92aa57 100644 --- a/spec/ruby/core/env/to_h_spec.rb +++ b/spec/ruby/core/env/to_h_spec.rb @@ -4,57 +4,55 @@ require_relative 'shared/to_hash' describe "ENV.to_h" do it_behaves_like :env_to_hash, :to_h - ruby_version_is "2.6" do - context "with block" do - before do - @orig_hash = ENV.to_hash - end - - after do - ENV.replace @orig_hash - end - - it "converts [key, value] pairs returned by the block to a hash" do - ENV.replace("a" => "b", "c" => "d") - ENV.to_h { |k, v| [k, v.upcase] }.should == { 'a' => "B", 'c' => "D" } - end - - it "does not require the array elements to be strings" do - ENV.replace("a" => "b", "c" => "d") - ENV.to_h { |k, v| [k.to_sym, v.to_sym] }.should == { :a => :b, :c => :d } - end - - it "raises ArgumentError if block returns longer or shorter array" do - -> do - ENV.to_h { |k, v| [k, v.upcase, 1] } - end.should raise_error(ArgumentError, /element has wrong array length/) - - -> do - ENV.to_h { |k, v| [k] } - end.should raise_error(ArgumentError, /element has wrong array length/) - end - - it "raises TypeError if block returns something other than Array" do - -> do - ENV.to_h { |k, v| "not-array" } - end.should raise_error(TypeError, /wrong element type String/) - end - - it "coerces returned pair to Array with #to_ary" do - x = mock('x') - x.stub!(:to_ary).and_return([:b, 'b']) - - ENV.to_h { |k| x }.should == { :b => 'b' } - end - - it "does not coerce returned pair to Array with #to_a" do - x = mock('x') - x.stub!(:to_a).and_return([:b, 'b']) - - -> do - ENV.to_h { |k| x } - end.should raise_error(TypeError, /wrong element type MockObject/) - end + context "with block" do + before do + @orig_hash = ENV.to_hash + end + + after do + ENV.replace @orig_hash + end + + it "converts [key, value] pairs returned by the block to a hash" do + ENV.replace("a" => "b", "c" => "d") + ENV.to_h { |k, v| [k, v.upcase] }.should == { 'a' => "B", 'c' => "D" } + end + + it "does not require the array elements to be strings" do + ENV.replace("a" => "b", "c" => "d") + ENV.to_h { |k, v| [k.to_sym, v.to_sym] }.should == { :a => :b, :c => :d } + end + + it "raises ArgumentError if block returns longer or shorter array" do + -> do + ENV.to_h { |k, v| [k, v.upcase, 1] } + end.should raise_error(ArgumentError, /element has wrong array length/) + + -> do + ENV.to_h { |k, v| [k] } + end.should raise_error(ArgumentError, /element has wrong array length/) + end + + it "raises TypeError if block returns something other than Array" do + -> do + ENV.to_h { |k, v| "not-array" } + end.should raise_error(TypeError, /wrong element type String/) + end + + it "coerces returned pair to Array with #to_ary" do + x = mock('x') + x.stub!(:to_ary).and_return([:b, 'b']) + + ENV.to_h { |k| x }.should == { :b => 'b' } + end + + it "does not coerce returned pair to Array with #to_a" do + x = mock('x') + x.stub!(:to_a).and_return([:b, 'b']) + + -> do + ENV.to_h { |k| x } + end.should raise_error(TypeError, /wrong element type MockObject/) end end end diff --git a/spec/ruby/core/exception/full_message_spec.rb b/spec/ruby/core/exception/full_message_spec.rb index 9cac9fb037..4cece9ebf9 100644 --- a/spec/ruby/core/exception/full_message_spec.rb +++ b/spec/ruby/core/exception/full_message_spec.rb @@ -12,81 +12,77 @@ describe "Exception#full_message" do full_message.should include "b.rb:2" end - ruby_version_is "2.5.1" do - it "supports :highlight option and adds escape sequences to highlight some strings" do - e = RuntimeError.new("Some runtime error") + it "supports :highlight option and adds escape sequences to highlight some strings" do + e = RuntimeError.new("Some runtime error") - full_message = e.full_message(highlight: true, order: :bottom) - full_message.should include "\e[1mTraceback\e[m (most recent call last)" - full_message.should include "\e[1mSome runtime error (\e[1;4mRuntimeError\e[m\e[1m)" + full_message = e.full_message(highlight: true, order: :bottom) + full_message.should include "\e[1mTraceback\e[m (most recent call last)" + full_message.should include "\e[1mSome runtime error (\e[1;4mRuntimeError\e[m\e[1m)" - full_message = e.full_message(highlight: false, order: :bottom) - full_message.should include "Traceback (most recent call last)" - full_message.should include "Some runtime error (RuntimeError)" - end + full_message = e.full_message(highlight: false, order: :bottom) + full_message.should include "Traceback (most recent call last)" + full_message.should include "Some runtime error (RuntimeError)" + end - it "supports :order option and places the error message and the backtrace at the top or the bottom" do - e = RuntimeError.new("Some runtime error") - e.set_backtrace(["a.rb:1", "b.rb:2"]) + it "supports :order option and places the error message and the backtrace at the top or the bottom" do + e = RuntimeError.new("Some runtime error") + e.set_backtrace(["a.rb:1", "b.rb:2"]) - e.full_message(order: :top, highlight: false).should =~ /a.rb:1.*b.rb:2/m - e.full_message(order: :bottom, highlight: false).should =~ /b.rb:2.*a.rb:1/m - end + e.full_message(order: :top, highlight: false).should =~ /a.rb:1.*b.rb:2/m + e.full_message(order: :bottom, highlight: false).should =~ /b.rb:2.*a.rb:1/m + end - it "shows the caller if the exception has no backtrace" do - e = RuntimeError.new("Some runtime error") - e.backtrace.should == nil - full_message = e.full_message(highlight: false, order: :top) - full_message.should include("#{__FILE__}:#{__LINE__-1}:in `") - full_message.should include("': Some runtime error (RuntimeError)\n") - end + it "shows the caller if the exception has no backtrace" do + e = RuntimeError.new("Some runtime error") + e.backtrace.should == nil + full_message = e.full_message(highlight: false, order: :top) + full_message.should include("#{__FILE__}:#{__LINE__-1}:in `") + full_message.should include("': Some runtime error (RuntimeError)\n") + end - it "shows the exception class at the end of the first line of the message when the message contains multiple lines" do - begin - line = __LINE__; raise "first line\nsecond line" - rescue => e - full_message = e.full_message(highlight: false, order: :top).lines - full_message[0].should include("#{__FILE__}:#{line}:in `") - full_message[0].should include(": first line (RuntimeError)\n") - full_message[1].should == "second line\n" - end + it "shows the exception class at the end of the first line of the message when the message contains multiple lines" do + begin + line = __LINE__; raise "first line\nsecond line" + rescue => e + full_message = e.full_message(highlight: false, order: :top).lines + full_message[0].should include("#{__FILE__}:#{line}:in `") + full_message[0].should include(": first line (RuntimeError)\n") + full_message[1].should == "second line\n" end end - ruby_version_is "2.6" do - it "contains cause of exception" do + it "contains cause of exception" do + begin begin - begin - raise 'the cause' - rescue - raise 'main exception' - end - rescue => e - exception = e + raise 'the cause' + rescue + raise 'main exception' end - - exception.full_message.should include "main exception" - exception.full_message.should include "the cause" + rescue => e + exception = e end - it 'contains all the chain of exceptions' do + exception.full_message.should include "main exception" + exception.full_message.should include "the cause" + end + + it 'contains all the chain of exceptions' do + begin begin begin - begin - raise 'origin exception' - rescue - raise 'intermediate exception' - end + raise 'origin exception' rescue - raise 'last exception' + raise 'intermediate exception' end - rescue => e - exception = e + rescue + raise 'last exception' end - - exception.full_message.should include "last exception" - exception.full_message.should include "intermediate exception" - exception.full_message.should include "origin exception" + rescue => e + exception = e end + + exception.full_message.should include "last exception" + exception.full_message.should include "intermediate exception" + exception.full_message.should include "origin exception" end end diff --git a/spec/ruby/core/exception/key_error_spec.rb b/spec/ruby/core/exception/key_error_spec.rb index 71bf2b46ff..c5e2b1efbc 100644 --- a/spec/ruby/core/exception/key_error_spec.rb +++ b/spec/ruby/core/exception/key_error_spec.rb @@ -1,21 +1,19 @@ require_relative '../../spec_helper' describe "KeyError" do - ruby_version_is "2.6" do - it "accepts :receiver and :key options" do - receiver = mock("receiver") - key = mock("key") + it "accepts :receiver and :key options" do + receiver = mock("receiver") + key = mock("key") - error = KeyError.new(receiver: receiver, key: key) + error = KeyError.new(receiver: receiver, key: key) - error.receiver.should == receiver - error.key.should == key + error.receiver.should == receiver + error.key.should == key - error = KeyError.new("message", receiver: receiver, key: key) + error = KeyError.new("message", receiver: receiver, key: key) - error.message.should == "message" - error.receiver.should == receiver - error.key.should == key - end + error.message.should == "message" + error.receiver.should == receiver + error.key.should == key end end diff --git a/spec/ruby/core/exception/name_error_spec.rb b/spec/ruby/core/exception/name_error_spec.rb index e901a80c42..ddd51a92e5 100644 --- a/spec/ruby/core/exception/name_error_spec.rb +++ b/spec/ruby/core/exception/name_error_spec.rb @@ -5,15 +5,13 @@ describe "NameError.new" do NameError.new("msg","name").name.should == "name" end - ruby_version_is "2.6" do - it "accepts a :receiver keyword argument" do - receiver = mock("receiver") + it "accepts a :receiver keyword argument" do + receiver = mock("receiver") - error = NameError.new("msg", :name, receiver: receiver) + error = NameError.new("msg", :name, receiver: receiver) - error.receiver.should == receiver - error.name.should == :name - end + error.receiver.should == receiver + error.name.should == :name end end diff --git a/spec/ruby/core/exception/no_method_error_spec.rb b/spec/ruby/core/exception/no_method_error_spec.rb index a93ef2187e..8428ba0382 100644 --- a/spec/ruby/core/exception/no_method_error_spec.rb +++ b/spec/ruby/core/exception/no_method_error_spec.rb @@ -10,15 +10,13 @@ describe "NoMethodError.new" do NoMethodError.new("msg").message.should == "msg" end - ruby_version_is "2.6" do - it "accepts a :receiver keyword argument" do - receiver = mock("receiver") + it "accepts a :receiver keyword argument" do + receiver = mock("receiver") - error = NoMethodError.new("msg", :name, receiver: receiver) + error = NoMethodError.new("msg", :name, receiver: receiver) - error.receiver.should == receiver - error.name.should == :name - end + error.receiver.should == receiver + error.name.should == :name end end diff --git a/spec/ruby/core/exception/signal_exception_spec.rb b/spec/ruby/core/exception/signal_exception_spec.rb index 2d2179a628..566bcb4672 100644 --- a/spec/ruby/core/exception/signal_exception_spec.rb +++ b/spec/ruby/core/exception/signal_exception_spec.rb @@ -30,10 +30,8 @@ describe "SignalException.new" do -> { SignalException.new("NONEXISTENT") }.should raise_error(ArgumentError) end - ruby_version_is "2.6" do - it "raises an exception with an invalid first argument type" do - -> { SignalException.new(Object.new) }.should raise_error(ArgumentError) - end + it "raises an exception with an invalid first argument type" do + -> { SignalException.new(Object.new) }.should raise_error(ArgumentError) end it "takes a signal symbol without SIG prefix as the first argument" do diff --git a/spec/ruby/core/exception/top_level_spec.rb b/spec/ruby/core/exception/top_level_spec.rb index 5c4514f694..b47648425e 100644 --- a/spec/ruby/core/exception/top_level_spec.rb +++ b/spec/ruby/core/exception/top_level_spec.rb @@ -5,29 +5,27 @@ describe "An Exception reaching the top level" do ruby_exe('raise "foo"', args: "2>&1", exit_status: 1).should.include?("in `<main>': foo (RuntimeError)") end - ruby_version_is "2.6" do - it "the Exception#cause is printed to STDERR with backtraces" do - code = <<-RUBY - def raise_cause - raise "the cause" - end - def raise_wrapped - raise "wrapped" - end - begin - raise_cause - rescue - raise_wrapped - end - RUBY - lines = ruby_exe(code, args: "2>&1", exit_status: 1).lines - lines.reject! { |l| l.include?('rescue in') } - lines.map! { |l| l.chomp[/:(in.+)/, 1] } - lines.should == ["in `raise_wrapped': wrapped (RuntimeError)", - "in `<main>'", - "in `raise_cause': the cause (RuntimeError)", - "in `<main>'"] + it "the Exception#cause is printed to STDERR with backtraces" do + code = <<-RUBY + def raise_cause + raise "the cause" + end + def raise_wrapped + raise "wrapped" + end + begin + raise_cause + rescue + raise_wrapped end + RUBY + lines = ruby_exe(code, args: "2>&1", exit_status: 1).lines + lines.reject! { |l| l.include?('rescue in') } + lines.map! { |l| l.chomp[/:(in.+)/, 1] } + lines.should == ["in `raise_wrapped': wrapped (RuntimeError)", + "in `<main>'", + "in `raise_cause': the cause (RuntimeError)", + "in `<main>'"] end describe "with a custom backtrace" do diff --git a/spec/ruby/core/file/open_spec.rb b/spec/ruby/core/file/open_spec.rb index 8faa31173e..c7dd34d5c6 100644 --- a/spec/ruby/core/file/open_spec.rb +++ b/spec/ruby/core/file/open_spec.rb @@ -629,31 +629,29 @@ describe "File.open" do }.should raise_error(ArgumentError, "newline decorator with binary mode") end - ruby_version_is "2.6" do - context "'x' flag" do - before :each do - @xfile = tmp("x-flag") - rm_r @xfile - end + context "'x' flag" do + before :each do + @xfile = tmp("x-flag") + rm_r @xfile + end - after :each do - rm_r @xfile - end + after :each do + rm_r @xfile + end - it "does nothing if the file doesn't exist" do - File.open(@xfile, "wx") { |f| f.write("content") } - File.read(@xfile).should == "content" - end + it "does nothing if the file doesn't exist" do + File.open(@xfile, "wx") { |f| f.write("content") } + File.read(@xfile).should == "content" + end - it "throws a Errno::EEXIST error if the file exists" do - touch @xfile - -> { File.open(@xfile, "wx") }.should raise_error(Errno::EEXIST) - end + it "throws a Errno::EEXIST error if the file exists" do + touch @xfile + -> { File.open(@xfile, "wx") }.should raise_error(Errno::EEXIST) + end - it "can't be used with 'r' and 'a' flags" do - -> { File.open(@xfile, "rx") }.should raise_error(ArgumentError, 'invalid access mode rx') - -> { File.open(@xfile, "ax") }.should raise_error(ArgumentError, 'invalid access mode ax') - end + it "can't be used with 'r' and 'a' flags" do + -> { File.open(@xfile, "rx") }.should raise_error(ArgumentError, 'invalid access mode rx') + -> { File.open(@xfile, "ax") }.should raise_error(ArgumentError, 'invalid access mode ax') end end end diff --git a/spec/ruby/core/float/comparison_spec.rb b/spec/ruby/core/float/comparison_spec.rb index cbab3a0fa1..e367198903 100644 --- a/spec/ruby/core/float/comparison_spec.rb +++ b/spec/ruby/core/float/comparison_spec.rb @@ -63,4 +63,28 @@ describe "Float#<=>" do it "returns 1 when self is negative and other is -Infinity" do (-Float::MAX.to_i*2 <=> -infinity_value).should == 1 end + + it "returns 0 when self is Infinity and other other is infinite?=1" do + obj = Object.new + def obj.infinite? + 1 + end + (infinity_value <=> obj).should == 0 + end + + it "returns 1 when self is Infinity and other is infinite?=-1" do + obj = Object.new + def obj.infinite? + -1 + end + (infinity_value <=> obj).should == 1 + end + + it "returns 1 when self is Infinity and other is infinite?=nil (which means finite)" do + obj = Object.new + def obj.infinite? + nil + end + (infinity_value <=> obj).should == 1 + end end diff --git a/spec/ruby/core/hash/filter_spec.rb b/spec/ruby/core/hash/filter_spec.rb index 4382c94e62..7dabe44984 100644 --- a/spec/ruby/core/hash/filter_spec.rb +++ b/spec/ruby/core/hash/filter_spec.rb @@ -1,12 +1,10 @@ require_relative '../../spec_helper' require_relative 'shared/select' -ruby_version_is "2.6" do - describe "Hash#filter" do - it_behaves_like :hash_select, :filter - end +describe "Hash#filter" do + it_behaves_like :hash_select, :filter +end - describe "Hash#filter!" do - it_behaves_like :hash_select!, :filter! - end +describe "Hash#filter!" do + it_behaves_like :hash_select!, :filter! end diff --git a/spec/ruby/core/hash/merge_spec.rb b/spec/ruby/core/hash/merge_spec.rb index 91ded30eb7..5521864297 100644 --- a/spec/ruby/core/hash/merge_spec.rb +++ b/spec/ruby/core/hash/merge_spec.rb @@ -81,19 +81,17 @@ describe "Hash#merge" do merge_pairs.should == expected_pairs end - ruby_version_is "2.6" do - it "accepts multiple hashes" do - result = { a: 1 }.merge({ b: 2 }, { c: 3 }, { d: 4 }) - result.should == { a: 1, b: 2, c: 3, d: 4 } - end - - it "accepts zero arguments and returns a copy of self" do - hash = { a: 1 } - merged = hash.merge - - merged.should eql(hash) - merged.should_not equal(hash) - end + it "accepts multiple hashes" do + result = { a: 1 }.merge({ b: 2 }, { c: 3 }, { d: 4 }) + result.should == { a: 1, b: 2, c: 3, d: 4 } + end + + it "accepts zero arguments and returns a copy of self" do + hash = { a: 1 } + merged = hash.merge + + merged.should eql(hash) + merged.should_not equal(hash) end end diff --git a/spec/ruby/core/hash/shared/update.rb b/spec/ruby/core/hash/shared/update.rb index 4bb20e5b85..1b0eb809bf 100644 --- a/spec/ruby/core/hash/shared/update.rb +++ b/spec/ruby/core/hash/shared/update.rb @@ -64,15 +64,13 @@ describe :hash_update, shared: true do hash.should == {1 => :foo, 3 => :bar, 5 => 6} end - ruby_version_is "2.6" do - it "accepts multiple hashes" do - result = { a: 1 }.send(@method, { b: 2 }, { c: 3 }, { d: 4 }) - result.should == { a: 1, b: 2, c: 3, d: 4 } - end + it "accepts multiple hashes" do + result = { a: 1 }.send(@method, { b: 2 }, { c: 3 }, { d: 4 }) + result.should == { a: 1, b: 2, c: 3, d: 4 } + end - it "accepts zero arguments" do - hash = { a: 1 } - hash.send(@method).should eql(hash) - end + it "accepts zero arguments" do + hash = { a: 1 } + hash.send(@method).should eql(hash) end end diff --git a/spec/ruby/core/hash/to_h_spec.rb b/spec/ruby/core/hash/to_h_spec.rb index d6eaac9f33..75ebce68b1 100644 --- a/spec/ruby/core/hash/to_h_spec.rb +++ b/spec/ruby/core/hash/to_h_spec.rb @@ -32,43 +32,41 @@ describe "Hash#to_h" do end end - ruby_version_is "2.6" do - context "with block" do - it "converts [key, value] pairs returned by the block to a hash" do - { a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v]}.should == { "a" => 1, "b" => 4 } - end + context "with block" do + it "converts [key, value] pairs returned by the block to a hash" do + { a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v]}.should == { "a" => 1, "b" => 4 } + end - it "raises ArgumentError if block returns longer or shorter array" do - -> do - { a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v, 1] } - end.should raise_error(ArgumentError, /element has wrong array length/) + it "raises ArgumentError if block returns longer or shorter array" do + -> do + { a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v, 1] } + end.should raise_error(ArgumentError, /element has wrong array length/) - -> do - { a: 1, b: 2 }.to_h { |k, v| [k] } - end.should raise_error(ArgumentError, /element has wrong array length/) - end + -> do + { a: 1, b: 2 }.to_h { |k, v| [k] } + end.should raise_error(ArgumentError, /element has wrong array length/) + end - it "raises TypeError if block returns something other than Array" do - -> do - { a: 1, b: 2 }.to_h { |k, v| "not-array" } - end.should raise_error(TypeError, /wrong element type String/) - end + it "raises TypeError if block returns something other than Array" do + -> do + { a: 1, b: 2 }.to_h { |k, v| "not-array" } + end.should raise_error(TypeError, /wrong element type String/) + end - it "coerces returned pair to Array with #to_ary" do - x = mock('x') - x.stub!(:to_ary).and_return([:b, 'b']) + it "coerces returned pair to Array with #to_ary" do + x = mock('x') + x.stub!(:to_ary).and_return([:b, 'b']) - { a: 1 }.to_h { |k| x }.should == { :b => 'b' } - end + { a: 1 }.to_h { |k| x }.should == { :b => 'b' } + end - it "does not coerce returned pair to Array with #to_a" do - x = mock('x') - x.stub!(:to_a).and_return([:b, 'b']) + it "does not coerce returned pair to Array with #to_a" do + x = mock('x') + x.stub!(:to_a).and_return([:b, 'b']) - -> do - { a: 1 }.to_h { |k| x } - end.should raise_error(TypeError, /wrong element type MockObject/) - end + -> do + { a: 1 }.to_h { |k| x } + end.should raise_error(TypeError, /wrong element type MockObject/) end end end diff --git a/spec/ruby/core/hash/transform_keys_spec.rb b/spec/ruby/core/hash/transform_keys_spec.rb index 4f4544a6c5..70a4cdde36 100644 --- a/spec/ruby/core/hash/transform_keys_spec.rb +++ b/spec/ruby/core/hash/transform_keys_spec.rb @@ -60,31 +60,12 @@ describe "Hash#transform_keys!" do end # https://bugs.ruby-lang.org/issues/14380 - ruby_version_is ""..."2.5.1" do - it "does not prevent conflicts between new keys and old ones" do - @hash.transform_keys!(&:succ) - @hash.should == { e: 1 } - end - end - - ruby_version_is "2.5.1" do - it "prevents conflicts between new keys and old ones" do - @hash.transform_keys!(&:succ) - @hash.should == { b: 1, c: 2, d: 3, e: 4 } - end - end - - ruby_version_is ""..."2.5.1" do - it "partially modifies the contents if we broke from the block" do - @hash.transform_keys! do |v| - break if v == :c - v.succ - end - @hash.should == { c: 1, d: 4 } - end + it "prevents conflicts between new keys and old ones" do + @hash.transform_keys!(&:succ) + @hash.should == { b: 1, c: 2, d: 3, e: 4 } end - ruby_version_is "2.5.1"..."3.0.2" do # https://bugs.ruby-lang.org/issues/17735 + ruby_version_is ""..."3.0.2" do # https://bugs.ruby-lang.org/issues/17735 it "returns the processed keys if we broke from the block" do @hash.transform_keys! do |v| break if v == :c diff --git a/spec/ruby/core/io/set_encoding_by_bom_spec.rb b/spec/ruby/core/io/set_encoding_by_bom_spec.rb index c551042bee..7368ec7677 100644 --- a/spec/ruby/core/io/set_encoding_by_bom_spec.rb +++ b/spec/ruby/core/io/set_encoding_by_bom_spec.rb @@ -67,5 +67,11 @@ describe "IO#set_encoding_by_bom" do -> { @io.set_encoding_by_bom }.should raise_error(ArgumentError, 'encoding is set to UTF-8 already') end + + it 'returns exception if encoding conversion is already set' do + @io.set_encoding(Encoding::UTF_8, Encoding::UTF_16BE) + + -> { @io.set_encoding_by_bom }.should raise_error(ArgumentError, 'encoding conversion is set') + end end end diff --git a/spec/ruby/core/io/ungetbyte_spec.rb b/spec/ruby/core/io/ungetbyte_spec.rb index 1e2ec77e1f..776707205a 100644 --- a/spec/ruby/core/io/ungetbyte_spec.rb +++ b/spec/ruby/core/io/ungetbyte_spec.rb @@ -36,20 +36,7 @@ describe "IO#ungetbyte" do @io.getbyte.should == 97 end - ruby_version_is ''...'2.6' do - it "puts back one byte for an Integer argument..." do - @io.ungetbyte(4095).should be_nil - @io.getbyte.should == 255 - end - - it "... but not for Integer argument (eh?)" do - -> { - @io.ungetbyte(0x4f7574206f6620636861722072616e6765) - }.should raise_error(TypeError) - end - end - - ruby_version_is '2.6'...'2.6.1' do + ruby_version_is ''...'2.6.1' do it "is an RangeError if the integer is not in 8bit" do for i in [4095, 0x4f7574206f6620636861722072616e6765] do -> { @io.ungetbyte(i) }.should raise_error(RangeError) diff --git a/spec/ruby/core/kernel/Complex_spec.rb b/spec/ruby/core/kernel/Complex_spec.rb index 37f9843931..4f043526b8 100644 --- a/spec/ruby/core/kernel/Complex_spec.rb +++ b/spec/ruby/core/kernel/Complex_spec.rb @@ -139,48 +139,46 @@ describe "Kernel.Complex()" do end end - ruby_version_is "2.6" do - describe "when passed exception: false" do - describe "and [Numeric]" do - it "returns a complex number" do - Complex("123", exception: false).should == Complex(123) - end + describe "when passed exception: false" do + describe "and [Numeric]" do + it "returns a complex number" do + Complex("123", exception: false).should == Complex(123) end + end - describe "and [non-Numeric]" do - it "swallows an error" do - Complex(:sym, exception: false).should == nil - end + describe "and [non-Numeric]" do + it "swallows an error" do + Complex(:sym, exception: false).should == nil end + end - describe "and [non-Numeric, Numeric] argument" do - it "throws a TypeError" do - -> { Complex(:sym, 0, exception: false) }.should raise_error(TypeError, "not a real") - end + describe "and [non-Numeric, Numeric] argument" do + it "throws a TypeError" do + -> { Complex(:sym, 0, exception: false) }.should raise_error(TypeError, "not a real") end + end - describe "and [anything, non-Numeric] argument" do - it "swallows an error" do - Complex("a", :sym, exception: false).should == nil - Complex(:sym, :sym, exception: false).should == nil - Complex(0, :sym, exception: false).should == nil - end + describe "and [anything, non-Numeric] argument" do + it "swallows an error" do + Complex("a", :sym, exception: false).should == nil + Complex(:sym, :sym, exception: false).should == nil + Complex(0, :sym, exception: false).should == nil end + end - describe "and non-numeric String arguments" do - it "swallows an error" do - Complex("a", "b", exception: false).should == nil - Complex("a", 0, exception: false).should == nil - Complex(0, "b", exception: false).should == nil - end + describe "and non-numeric String arguments" do + it "swallows an error" do + Complex("a", "b", exception: false).should == nil + Complex("a", 0, exception: false).should == nil + Complex(0, "b", exception: false).should == nil end + end - describe "and nil arguments" do - it "swallows an error" do - Complex(nil, exception: false).should == nil - Complex(0, nil, exception: false).should == nil - Complex(nil, 0, exception: false).should == nil - end + describe "and nil arguments" do + it "swallows an error" do + Complex(nil, exception: false).should == nil + Complex(0, nil, exception: false).should == nil + Complex(nil, 0, exception: false).should == nil end end end diff --git a/spec/ruby/core/kernel/Float_spec.rb b/spec/ruby/core/kernel/Float_spec.rb index af64fcbe86..015bcb33d6 100644 --- a/spec/ruby/core/kernel/Float_spec.rb +++ b/spec/ruby/core/kernel/Float_spec.rb @@ -306,27 +306,25 @@ describe :kernel_float, shared: true do -> { @object.send(:Float, c) }.should raise_error(RangeError) end - ruby_version_is "2.6" do - describe "when passed exception: false" do - describe "and valid input" do - it "returns a Float number" do - @object.send(:Float, 1, exception: false).should == 1.0 - @object.send(:Float, "1", exception: false).should == 1.0 - @object.send(:Float, "1.23", exception: false).should == 1.23 - end + describe "when passed exception: false" do + describe "and valid input" do + it "returns a Float number" do + @object.send(:Float, 1, exception: false).should == 1.0 + @object.send(:Float, "1", exception: false).should == 1.0 + @object.send(:Float, "1.23", exception: false).should == 1.23 end + end - describe "and invalid input" do - it "swallows an error" do - @object.send(:Float, "abc", exception: false).should == nil - @object.send(:Float, :sym, exception: false).should == nil - end + describe "and invalid input" do + it "swallows an error" do + @object.send(:Float, "abc", exception: false).should == nil + @object.send(:Float, :sym, exception: false).should == nil end + end - describe "and nil" do - it "swallows it" do - @object.send(:Float, nil, exception: false).should == nil - end + describe "and nil" do + it "swallows it" do + @object.send(:Float, nil, exception: false).should == nil end end end diff --git a/spec/ruby/core/kernel/Integer_spec.rb b/spec/ruby/core/kernel/Integer_spec.rb index 74bea7ca09..2c78e27428 100644 --- a/spec/ruby/core/kernel/Integer_spec.rb +++ b/spec/ruby/core/kernel/Integer_spec.rb @@ -10,29 +10,18 @@ describe :kernel_integer, shared: true do Integer(100).should == 100 end - ruby_version_is ""..."2.6" do - it "uncritically return the value of to_int even if it is not an Integer" do - obj = mock("object") - obj.should_receive(:to_int).and_return("1") - obj.should_not_receive(:to_i) - Integer(obj).should == "1" - end + it "raises a TypeError when to_int returns not-an-Integer object and to_i returns nil" do + obj = mock("object") + obj.should_receive(:to_int).and_return("1") + obj.should_receive(:to_i).and_return(nil) + -> { Integer(obj) }.should raise_error(TypeError) end - ruby_version_is "2.6" do - it "raises a TypeError when to_int returns not-an-Integer object and to_i returns nil" do - obj = mock("object") - obj.should_receive(:to_int).and_return("1") - obj.should_receive(:to_i).and_return(nil) - -> { Integer(obj) }.should raise_error(TypeError) - end - - it "return a result of to_i when to_int does not return an Integer" do - obj = mock("object") - obj.should_receive(:to_int).and_return("1") - obj.should_receive(:to_i).and_return(42) - Integer(obj).should == 42 - end + it "return a result of to_i when to_int does not return an Integer" do + obj = mock("object") + obj.should_receive(:to_int).and_return("1") + obj.should_receive(:to_i).and_return(42) + Integer(obj).should == 42 end it "raises a TypeError when passed nil" do @@ -100,59 +89,57 @@ describe :kernel_integer, shared: true do -> { Integer(infinity_value) }.should raise_error(FloatDomainError) end - ruby_version_is "2.6" do - describe "when passed exception: false" do - describe "and to_i returns a value that is not an Integer" do - it "swallows an error" do - obj = mock("object") - obj.should_receive(:to_i).and_return("1") - Integer(obj, exception: false).should == nil - end + describe "when passed exception: false" do + describe "and to_i returns a value that is not an Integer" do + it "swallows an error" do + obj = mock("object") + obj.should_receive(:to_i).and_return("1") + Integer(obj, exception: false).should == nil end + end - describe "and no to_int or to_i methods exist" do - it "swallows an error" do - obj = mock("object") - Integer(obj, exception: false).should == nil - end + describe "and no to_int or to_i methods exist" do + it "swallows an error" do + obj = mock("object") + Integer(obj, exception: false).should == nil end + end - describe "and to_int returns nil and no to_i exists" do - it "swallows an error" do - obj = mock("object") - obj.should_receive(:to_i).and_return(nil) - Integer(obj, exception: false).should == nil - end + describe "and to_int returns nil and no to_i exists" do + it "swallows an error" do + obj = mock("object") + obj.should_receive(:to_i).and_return(nil) + Integer(obj, exception: false).should == nil end + end - describe "and passed NaN" do - it "swallows an error" do - Integer(nan_value, exception: false).should == nil - end + describe "and passed NaN" do + it "swallows an error" do + Integer(nan_value, exception: false).should == nil end + end - describe "and passed Infinity" do - it "swallows an error" do - Integer(infinity_value, exception: false).should == nil - end + describe "and passed Infinity" do + it "swallows an error" do + Integer(infinity_value, exception: false).should == nil end + end - describe "and passed nil" do - it "swallows an error" do - Integer(nil, exception: false).should == nil - end + describe "and passed nil" do + it "swallows an error" do + Integer(nil, exception: false).should == nil end + end - describe "and passed a String that contains numbers" do - it "normally parses it and returns an Integer" do - Integer("42", exception: false).should == 42 - end + describe "and passed a String that contains numbers" do + it "normally parses it and returns an Integer" do + Integer("42", exception: false).should == 42 end + end - describe "and passed a String that can't be converted to an Integer" do - it "swallows an error" do - Integer("abc", exception: false).should == nil - end + describe "and passed a String that can't be converted to an Integer" do + it "swallows an error" do + Integer("abc", exception: false).should == nil end end end @@ -246,30 +233,28 @@ describe "Integer() given a String", shared: true do -> { Integer("") }.should raise_error(ArgumentError) end - ruby_version_is "2.6" do - describe "when passed exception: false" do - describe "and multiple leading -s" do - it "swallows an error" do - Integer("---1", exception: false).should == nil - end + describe "when passed exception: false" do + describe "and multiple leading -s" do + it "swallows an error" do + Integer("---1", exception: false).should == nil end + end - describe "and multiple trailing -s" do - it "swallows an error" do - Integer("1---", exception: false).should == nil - end + describe "and multiple trailing -s" do + it "swallows an error" do + Integer("1---", exception: false).should == nil end + end - describe "and an argument that contains a period" do - it "swallows an error" do - Integer("0.0", exception: false).should == nil - end + describe "and an argument that contains a period" do + it "swallows an error" do + Integer("0.0", exception: false).should == nil end + end - describe "and an empty string" do - it "swallows an error" do - Integer("", exception: false).should == nil - end + describe "and an empty string" do + it "swallows an error" do + Integer("", exception: false).should == nil end end end @@ -594,20 +579,18 @@ describe "Integer() given a String and base", shared: true do end end - ruby_version_is "2.6" do - describe "when passed exception: false" do - describe "and valid argument" do - it "returns an Integer number" do - Integer("100", 10, exception: false).should == 100 - Integer("100", 2, exception: false).should == 4 - end + describe "when passed exception: false" do + describe "and valid argument" do + it "returns an Integer number" do + Integer("100", 10, exception: false).should == 100 + Integer("100", 2, exception: false).should == 4 end + end - describe "and invalid argument" do - it "swallows an error" do - Integer("999", 2, exception: false).should == nil - Integer("abc", 10, exception: false).should == nil - end + describe "and invalid argument" do + it "swallows an error" do + Integer("999", 2, exception: false).should == nil + Integer("abc", 10, exception: false).should == nil end end end diff --git a/spec/ruby/core/kernel/autoload_spec.rb b/spec/ruby/core/kernel/autoload_spec.rb index 8d56021fa8..0404caec6d 100644 --- a/spec/ruby/core/kernel/autoload_spec.rb +++ b/spec/ruby/core/kernel/autoload_spec.rb @@ -56,6 +56,21 @@ describe "Kernel#autoload" do end end + describe "inside a Class.new method body" do + # NOTE: this spec is being discussed in https://github.com/ruby/spec/pull/839 + it "should define on the new anonymous class" do + cls = Class.new do + def go + autoload :Object, 'bogus' + autoload? :Object + end + end + + cls.new.go.should == 'bogus' + cls.autoload?(:Object).should == 'bogus' + end + end + describe "when Object is frozen" do it "raises a FrozenError before defining the constant" do ruby_exe(fixture(__FILE__, "autoload_frozen.rb")).should == "FrozenError - nil" diff --git a/spec/ruby/core/kernel/caller_locations_spec.rb b/spec/ruby/core/kernel/caller_locations_spec.rb index bbb7e7b737..3ec8f0f432 100644 --- a/spec/ruby/core/kernel/caller_locations_spec.rb +++ b/spec/ruby/core/kernel/caller_locations_spec.rb @@ -28,12 +28,10 @@ describe 'Kernel#caller_locations' do locations1[2..4].map(&:to_s).should == locations2.map(&:to_s) end - ruby_version_is "2.6" do - it "works with endless ranges" do - locations1 = caller_locations(0) - locations2 = caller_locations(eval("(2..)")) - locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s) - end + it "works with endless ranges" do + locations1 = caller_locations(0) + locations2 = caller_locations(eval("(2..)")) + locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s) end ruby_version_is "2.7" do diff --git a/spec/ruby/core/kernel/caller_spec.rb b/spec/ruby/core/kernel/caller_spec.rb index 6c175868cb..dba65ddcb0 100644 --- a/spec/ruby/core/kernel/caller_spec.rb +++ b/spec/ruby/core/kernel/caller_spec.rb @@ -44,12 +44,10 @@ describe 'Kernel#caller' do ] end - ruby_version_is "2.6" do - it "works with endless ranges" do - locations1 = KernelSpecs::CallerTest.locations(0) - locations2 = KernelSpecs::CallerTest.locations(eval("(2..)")) - locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s) - end + it "works with endless ranges" do + locations1 = KernelSpecs::CallerTest.locations(0) + locations2 = KernelSpecs::CallerTest.locations(eval("(2..)")) + locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s) end ruby_version_is "2.7" do diff --git a/spec/ruby/core/kernel/match_spec.rb b/spec/ruby/core/kernel/match_spec.rb index 6dc1eb7de8..fbfc77f959 100644 --- a/spec/ruby/core/kernel/match_spec.rb +++ b/spec/ruby/core/kernel/match_spec.rb @@ -14,11 +14,9 @@ describe "Kernel#=~" do end end - ruby_version_is "2.6" do - it "is deprecated" do - -> do - Object.new =~ /regexp/ - end.should complain(/deprecated Object#=~ is called on Object/, verbose: true) - end + it "is deprecated" do + -> do + Object.new =~ /regexp/ + end.should complain(/deprecated Object#=~ is called on Object/, verbose: true) end end diff --git a/spec/ruby/core/kernel/open_spec.rb b/spec/ruby/core/kernel/open_spec.rb index 981b5291b3..8d936d8ca0 100644 --- a/spec/ruby/core/kernel/open_spec.rb +++ b/spec/ruby/core/kernel/open_spec.rb @@ -2,7 +2,6 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' describe "Kernel#open" do - before :each do @name = tmp("kernel_open.txt") @content = "This is a test" @@ -137,6 +136,18 @@ describe "Kernel#open" do it "accepts nil for mode and permission" do open(@name, nil, nil) { |f| f.gets }.should == @content end + + ruby_version_is ""..."3.0" do + it "works correctly when redefined by open-uri" do + code = <<~RUBY + require 'open-uri' + obj = Object.new + def obj.to_open; self; end + p open(obj) == obj + RUBY + ruby_exe(code, args: "2>&1").should == "true\n" + end + end end describe "Kernel.open" do diff --git a/spec/ruby/core/kernel/raise_spec.rb b/spec/ruby/core/kernel/raise_spec.rb index 6dac132498..4f190c120b 100644 --- a/spec/ruby/core/kernel/raise_spec.rb +++ b/spec/ruby/core/kernel/raise_spec.rb @@ -28,25 +28,23 @@ describe "Kernel#raise" do ScratchPad.recorded.should be_nil end - ruby_version_is "2.6" do - it "accepts a cause keyword argument that sets the cause" do + it "accepts a cause keyword argument that sets the cause" do + cause = StandardError.new + -> { raise("error", cause: cause) }.should raise_error(RuntimeError) { |e| e.cause.should == cause } + end + + it "accepts a cause keyword argument that overrides the last exception" do + begin + raise "first raise" + rescue => ignored cause = StandardError.new -> { raise("error", cause: cause) }.should raise_error(RuntimeError) { |e| e.cause.should == cause } end + end - it "accepts a cause keyword argument that overrides the last exception" do - begin - raise "first raise" - rescue => ignored - cause = StandardError.new - -> { raise("error", cause: cause) }.should raise_error(RuntimeError) { |e| e.cause.should == cause } - end - end - - it "raises an ArgumentError when only cause is given" do - cause = StandardError.new - -> { raise(cause: cause) }.should raise_error(ArgumentError) - end + it "raises an ArgumentError when only cause is given" do + cause = StandardError.new + -> { raise(cause: cause) }.should raise_error(ArgumentError) end end diff --git a/spec/ruby/core/kernel/system_spec.rb b/spec/ruby/core/kernel/system_spec.rb index 696e6ae3d7..9671a650cc 100644 --- a/spec/ruby/core/kernel/system_spec.rb +++ b/spec/ruby/core/kernel/system_spec.rb @@ -25,14 +25,12 @@ describe :kernel_system, shared: true do $?.exitstatus.should == 1 end - ruby_version_is "2.6" do - it "raises RuntimeError when `exception: true` is given and the command exits with a non-zero exit status" do - -> { @object.system(ruby_cmd('exit 1'), exception: true) }.should raise_error(RuntimeError) - end + it "raises RuntimeError when `exception: true` is given and the command exits with a non-zero exit status" do + -> { @object.system(ruby_cmd('exit 1'), exception: true) }.should raise_error(RuntimeError) + end - it "raises Errno::ENOENT when `exception: true` is given and the specified command does not exist" do - -> { @object.system('feature_14386', exception: true) }.should raise_error(Errno::ENOENT) - end + it "raises Errno::ENOENT when `exception: true` is given and the specified command does not exist" do + -> { @object.system('feature_14386', exception: true) }.should raise_error(Errno::ENOENT) end it "returns nil when command execution fails" do diff --git a/spec/ruby/core/kernel/then_spec.rb b/spec/ruby/core/kernel/then_spec.rb index fa896b52b1..8109a2960a 100644 --- a/spec/ruby/core/kernel/then_spec.rb +++ b/spec/ruby/core/kernel/then_spec.rb @@ -1,8 +1,6 @@ require_relative '../../spec_helper' require_relative 'shared/then' -ruby_version_is "2.6" do - describe "Kernel#then" do - it_behaves_like :kernel_then, :then - end +describe "Kernel#then" do + it_behaves_like :kernel_then, :then end diff --git a/spec/ruby/core/kernel/warn_spec.rb b/spec/ruby/core/kernel/warn_spec.rb index 5953a47e81..511e741f32 100644 --- a/spec/ruby/core/kernel/warn_spec.rb +++ b/spec/ruby/core/kernel/warn_spec.rb @@ -107,11 +107,9 @@ describe "Kernel#warn" do ruby_exe(file, options: "--disable-gems", args: "2>&1").should == "#{file}:2: warning: warn-require-warning\n" end - ruby_version_is "2.6" do - it "shows the caller of #require and not #require itself with RubyGems loaded" do - file = fixture(__FILE__ , "warn_require_caller.rb") - ruby_exe(file, options: "-rrubygems", args: "2>&1").should == "#{file}:2: warning: warn-require-warning\n" - end + it "shows the caller of #require and not #require itself with RubyGems loaded" do + file = fixture(__FILE__ , "warn_require_caller.rb") + ruby_exe(file, options: "-rrubygems", args: "2>&1").should == "#{file}:2: warning: warn-require-warning\n" end guard -> { Kernel.instance_method(:tap).source_location } do diff --git a/spec/ruby/core/marshal/dump_spec.rb b/spec/ruby/core/marshal/dump_spec.rb index 8d6ba245af..a54a4c6735 100644 --- a/spec/ruby/core/marshal/dump_spec.rb +++ b/spec/ruby/core/marshal/dump_spec.rb @@ -78,6 +78,20 @@ describe "Marshal.dump" do s = "\u2192".force_encoding("binary").to_sym Marshal.dump(s).should == "\x04\b:\b\xE2\x86\x92" end + + it "dumps multiple Symbols sharing the same encoding" do + # Note that the encoding is a link for the second Symbol + symbol1 = "I:\t\xE2\x82\xACa\x06:\x06ET" + symbol2 = "I:\t\xE2\x82\xACb\x06;\x06T" + value = [ + "€a".force_encoding(Encoding::UTF_8).to_sym, + "€b".force_encoding(Encoding::UTF_8).to_sym + ] + Marshal.dump(value).should == "\x04\b[\a#{symbol1}#{symbol2}" + + value = [*value, value[0]] + Marshal.dump(value).should == "\x04\b[\b#{symbol1}#{symbol2};\x00" + end end describe "with an object responding to #marshal_dump" do @@ -343,8 +357,13 @@ describe "Marshal.dump" do end it "dumps an extended Struct" do - st = Struct.new("Extended", :a, :b).new - Marshal.dump(st.extend(Meths)).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a0:\006b0" + obj = Struct.new("Extended", :a, :b).new.extend(Meths) + Marshal.dump(obj).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a0:\006b0" + + s = 'hi' + obj.a = [:a, s] + obj.b = [:Meths, s] + Marshal.dump(obj).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a" Struct.send(:remove_const, :Extended) end end diff --git a/spec/ruby/core/marshal/fixtures/marshal_data.rb b/spec/ruby/core/marshal/fixtures/marshal_data.rb index bf58f4888d..9373ef7ba8 100644 --- a/spec/ruby/core/marshal/fixtures/marshal_data.rb +++ b/spec/ruby/core/marshal/fixtures/marshal_data.rb @@ -83,7 +83,7 @@ class UserPreviouslyDefinedWithInitializedIvar end class UserMarshal - attr_reader :data + attr_accessor :data def initialize @data = 'stuff' diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb index 4e940c80a8..a79fb51cd7 100644 --- a/spec/ruby/core/marshal/shared/load.rb +++ b/spec/ruby/core/marshal/shared/load.rb @@ -309,7 +309,8 @@ describe :marshal_load, shared: true do it "loads an extended Array object containing a user-marshaled object" do obj = [UserMarshal.new, UserMarshal.new].extend(Meths) - new_obj = Marshal.send(@method, "\x04\be:\nMeths[\ao:\x10UserMarshal\x06:\n@dataI\"\nstuff\x06:\x06ETo;\x06\x06;\aI\"\nstuff\x06;\bT") + dump = "\x04\be:\nMeths[\ao:\x10UserMarshal\x06:\n@dataI\"\nstuff\x06:\x06ETo;\x06\x06;\aI\"\nstuff\x06;\bT" + new_obj = Marshal.send(@method, dump) new_obj.should == obj obj_ancestors = class << obj; ancestors[1..-1]; end @@ -399,6 +400,24 @@ describe :marshal_load, shared: true do sym.should == s sym.encoding.should == Encoding::BINARY end + + it "loads multiple Symbols sharing the same encoding" do + # Note that the encoding is a link for the second Symbol + symbol1 = "I:\t\xE2\x82\xACa\x06:\x06ET" + symbol2 = "I:\t\xE2\x82\xACb\x06;\x06T" + dump = "\x04\b[\a#{symbol1}#{symbol2}" + value = Marshal.send(@method, dump) + value.map(&:encoding).should == [Encoding::UTF_8, Encoding::UTF_8] + expected = [ + "€a".force_encoding(Encoding::UTF_8).to_sym, + "€b".force_encoding(Encoding::UTF_8).to_sym + ] + value.should == expected + + value = Marshal.send(@method, "\x04\b[\b#{symbol1}#{symbol2};\x00") + value.map(&:encoding).should == [Encoding::UTF_8, Encoding::UTF_8, Encoding::UTF_8] + value.should == [*expected, expected[0]] + end end describe "for a String" do @@ -460,20 +479,23 @@ describe :marshal_load, shared: true do describe "for a Struct" do it "loads a extended_struct having fields with same objects" do s = 'hi' - obj = Struct.new("Ure2", :a, :b).new.extend(Meths) + obj = Struct.new("Extended", :a, :b).new.extend(Meths) + dump = "\004\be:\nMethsS:\025Struct::Extended\a:\006a0:\006b0" + Marshal.send(@method, dump).should == obj + obj.a = [:a, s] obj.b = [:Meths, s] - - Marshal.send(@method, - "\004\be:\nMethsS:\021Struct::Ure2\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a" - ).should == obj - Struct.send(:remove_const, :Ure2) + dump = "\004\be:\nMethsS:\025Struct::Extended\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a" + Marshal.send(@method, dump).should == obj + Struct.send(:remove_const, :Extended) end it "loads a struct having ivar" do obj = Struct.new("Thick").new obj.instance_variable_set(:@foo, 5) - Marshal.send(@method, "\004\bIS:\022Struct::Thick\000\006:\t@fooi\n").should == obj + reloaded = Marshal.send(@method, "\004\bIS:\022Struct::Thick\000\006:\t@fooi\n") + reloaded.should == obj + reloaded.instance_variable_get(:@foo).should == 5 Struct.send(:remove_const, :Thick) end @@ -588,6 +610,18 @@ describe :marshal_load, shared: true do end end + describe "for an object responding to #marshal_dump and #marshal_load" do + it "loads a user-marshaled object" do + obj = UserMarshal.new + obj.data = :data + value = [obj, :data] + dump = Marshal.dump(value) + dump.should == "\x04\b[\aU:\x10UserMarshal:\tdata;\x06" + reloaded = Marshal.load(dump) + reloaded.should == value + end + end + describe "for a user object" do it "loads a user-marshaled extended object" do obj = UserMarshal.new.extend(Meths) diff --git a/spec/ruby/core/method/compose_spec.rb b/spec/ruby/core/method/compose_spec.rb index 0743dd4f8d..87cf61f7ad 100644 --- a/spec/ruby/core/method/compose_spec.rb +++ b/spec/ruby/core/method/compose_spec.rb @@ -2,101 +2,99 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative '../proc/shared/compose' -ruby_version_is "2.6" do - describe "Method#<<" do - it "returns a Proc that is the composition of self and the passed Proc" do - succ = MethodSpecs::Composition.new.method(:succ) - upcase = proc { |s| s.upcase } +describe "Method#<<" do + it "returns a Proc that is the composition of self and the passed Proc" do + succ = MethodSpecs::Composition.new.method(:succ) + upcase = proc { |s| s.upcase } - (succ << upcase).call('Ruby').should == "RUBZ" - end + (succ << upcase).call('Ruby').should == "RUBZ" + end - it "calls passed Proc with arguments and then calls self with result" do - pow_2_proc = proc { |x| x * x } - double_proc = proc { |x| x + x } + it "calls passed Proc with arguments and then calls self with result" do + pow_2_proc = proc { |x| x * x } + double_proc = proc { |x| x + x } - pow_2_method = MethodSpecs::Composition.new.method(:pow_2) - double_method = MethodSpecs::Composition.new.method(:double) + pow_2_method = MethodSpecs::Composition.new.method(:pow_2) + double_method = MethodSpecs::Composition.new.method(:double) - (pow_2_method << double_proc).call(2).should == 16 - (double_method << pow_2_proc).call(2).should == 8 - end + (pow_2_method << double_proc).call(2).should == 16 + (double_method << pow_2_proc).call(2).should == 8 + end - it "accepts any callable object" do - inc = MethodSpecs::Composition.new.method(:inc) + it "accepts any callable object" do + inc = MethodSpecs::Composition.new.method(:inc) - double = Object.new - def double.call(n); n * 2; end + double = Object.new + def double.call(n); n * 2; end - (inc << double).call(3).should == 7 - end + (inc << double).call(3).should == 7 + end - it_behaves_like :proc_compose, :<<, -> { MethodSpecs::Composition.new.method(:upcase) } + it_behaves_like :proc_compose, :<<, -> { MethodSpecs::Composition.new.method(:upcase) } - describe "composition" do - it "is a lambda" do - pow_2 = MethodSpecs::Composition.new.method(:pow_2) - double = proc { |x| x + x } + describe "composition" do + it "is a lambda" do + pow_2 = MethodSpecs::Composition.new.method(:pow_2) + double = proc { |x| x + x } - (pow_2 << double).is_a?(Proc).should == true - ruby_version_is(''...'3.0') { (pow_2 << double).should.lambda? } - ruby_version_is('3.0') { (pow_2 << double).should_not.lambda? } - end + (pow_2 << double).is_a?(Proc).should == true + ruby_version_is(''...'3.0') { (pow_2 << double).should.lambda? } + ruby_version_is('3.0') { (pow_2 << double).should_not.lambda? } + end - it "may accept multiple arguments" do - inc = MethodSpecs::Composition.new.method(:inc) - mul = proc { |n, m| n * m } + it "may accept multiple arguments" do + inc = MethodSpecs::Composition.new.method(:inc) + mul = proc { |n, m| n * m } - (inc << mul).call(2, 3).should == 7 - end + (inc << mul).call(2, 3).should == 7 end end +end - describe "Method#>>" do - it "returns a Proc that is the composition of self and the passed Proc" do - upcase = proc { |s| s.upcase } - succ = MethodSpecs::Composition.new.method(:succ) +describe "Method#>>" do + it "returns a Proc that is the composition of self and the passed Proc" do + upcase = proc { |s| s.upcase } + succ = MethodSpecs::Composition.new.method(:succ) - (succ >> upcase).call('Ruby').should == "RUBZ" - end + (succ >> upcase).call('Ruby').should == "RUBZ" + end - it "calls passed Proc with arguments and then calls self with result" do - pow_2_proc = proc { |x| x * x } - double_proc = proc { |x| x + x } + it "calls passed Proc with arguments and then calls self with result" do + pow_2_proc = proc { |x| x * x } + double_proc = proc { |x| x + x } - pow_2_method = MethodSpecs::Composition.new.method(:pow_2) - double_method = MethodSpecs::Composition.new.method(:double) + pow_2_method = MethodSpecs::Composition.new.method(:pow_2) + double_method = MethodSpecs::Composition.new.method(:double) - (pow_2_method >> double_proc).call(2).should == 8 - (double_method >> pow_2_proc).call(2).should == 16 - end + (pow_2_method >> double_proc).call(2).should == 8 + (double_method >> pow_2_proc).call(2).should == 16 + end - it "accepts any callable object" do - inc = MethodSpecs::Composition.new.method(:inc) + it "accepts any callable object" do + inc = MethodSpecs::Composition.new.method(:inc) - double = Object.new - def double.call(n); n * 2; end + double = Object.new + def double.call(n); n * 2; end - (inc >> double).call(3).should == 8 - end + (inc >> double).call(3).should == 8 + end - it_behaves_like :proc_compose, :>>, -> { MethodSpecs::Composition.new.method(:upcase) } + it_behaves_like :proc_compose, :>>, -> { MethodSpecs::Composition.new.method(:upcase) } - describe "composition" do - it "is a lambda" do - pow_2 = MethodSpecs::Composition.new.method(:pow_2) - double = proc { |x| x + x } + describe "composition" do + it "is a lambda" do + pow_2 = MethodSpecs::Composition.new.method(:pow_2) + double = proc { |x| x + x } - (pow_2 >> double).is_a?(Proc).should == true - (pow_2 >> double).should.lambda? - end + (pow_2 >> double).is_a?(Proc).should == true + (pow_2 >> double).should.lambda? + end - it "may accept multiple arguments" do - mul = MethodSpecs::Composition.new.method(:mul) - inc = proc { |n| n + 1 } + it "may accept multiple arguments" do + mul = MethodSpecs::Composition.new.method(:mul) + inc = proc { |n| n + 1 } - (mul >> inc).call(2, 3).should == 7 - end + (mul >> inc).call(2, 3).should == 7 end end end diff --git a/spec/ruby/core/module/include_spec.rb b/spec/ruby/core/module/include_spec.rb index c7ead1079c..128b9af2bf 100644 --- a/spec/ruby/core/module/include_spec.rb +++ b/spec/ruby/core/module/include_spec.rb @@ -376,6 +376,162 @@ describe "Module#include" do foo.call.should == 'n' end + + it "updates the constant when an included module is updated" do + module ModuleSpecs::ConstUpdated + module A + FOO = 'a' + end + + module M + end + + module B + include A + include M + def self.foo + FOO + end + end + + B.foo.should == 'a' + + M.const_set(:FOO, 'm') + B.foo.should == 'm' + end + end + + it "updates the constant when a module included after a call is later updated" do + module ModuleSpecs::ConstLaterUpdated + module A + FOO = 'a' + end + + module B + include A + def self.foo + FOO + end + end + + B.foo.should == 'a' + + module M + end + B.include M + + B.foo.should == 'a' + + M.const_set(:FOO, 'm') + B.foo.should == 'm' + end + end + + it "updates the constant when a module included in another module after a call is later updated" do + module ModuleSpecs::ConstModuleLaterUpdated + module A + FOO = 'a' + end + + module B + include A + def self.foo + FOO + end + end + + B.foo.should == 'a' + + module M + end + B.include M + + B.foo.should == 'a' + + M.const_set(:FOO, 'm') + B.foo.should == 'm' + end + end + + it "updates the constant when a nested included module is updated" do + module ModuleSpecs::ConstUpdatedNestedIncludeUpdated + module A + FOO = 'a' + end + + module N + end + + module M + include N + end + + module B + include A + include M + def self.foo + FOO + end + end + + B.foo.should == 'a' + + N.const_set(:FOO, 'n') + B.foo.should == 'n' + end + end + + it "updates the constant when a new module is included" do + module ModuleSpecs::ConstUpdatedNewInclude + module A + FOO = 'a' + end + + module M + FOO = 'm' + end + + module B + include A + def self.foo + FOO + end + end + + B.foo.should == 'a' + + B.include(M) + B.foo.should == 'm' + end + end + + it "updates the constant when a new module with nested module is included" do + module ModuleSpecs::ConstUpdatedNestedIncluded + module A + FOO = 'a' + end + + module N + FOO = 'n' + end + + module M + include N + end + + module B + include A + def self.foo + FOO + end + end + + B.foo.should == 'a' + + B.include M + B.foo.should == 'n' + end + end end describe "Module#include?" do diff --git a/spec/ruby/core/module/method_defined_spec.rb b/spec/ruby/core/module/method_defined_spec.rb index dccee870b1..bc5b420e11 100644 --- a/spec/ruby/core/module/method_defined_spec.rb +++ b/spec/ruby/core/module/method_defined_spec.rb @@ -47,54 +47,52 @@ describe "Module#method_defined?" do c.method_defined?(o).should == true end - ruby_version_is "2.6" do - # works as method_defined?(method_name) - describe "when passed true as a second optional argument" do - it "performs a lookup in ancestors" do - ModuleSpecs::Child.method_defined?(:public_child, true).should == true - ModuleSpecs::Child.method_defined?(:protected_child, true).should == true - ModuleSpecs::Child.method_defined?(:accessor_method, true).should == true - ModuleSpecs::Child.method_defined?(:private_child, true).should == false - - # Defined in Parent - ModuleSpecs::Child.method_defined?(:public_parent, true).should == true - ModuleSpecs::Child.method_defined?(:protected_parent, true).should == true - ModuleSpecs::Child.method_defined?(:private_parent, true).should == false - - # Defined in Module - ModuleSpecs::Child.method_defined?(:public_module, true).should == true - ModuleSpecs::Child.method_defined?(:protected_module, true).should == true - ModuleSpecs::Child.method_defined?(:private_module, true).should == false - - # Defined in SuperModule - ModuleSpecs::Child.method_defined?(:public_super_module, true).should == true - ModuleSpecs::Child.method_defined?(:protected_super_module, true).should == true - ModuleSpecs::Child.method_defined?(:private_super_module, true).should == false - end + # works as method_defined?(method_name) + describe "when passed true as a second optional argument" do + it "performs a lookup in ancestors" do + ModuleSpecs::Child.method_defined?(:public_child, true).should == true + ModuleSpecs::Child.method_defined?(:protected_child, true).should == true + ModuleSpecs::Child.method_defined?(:accessor_method, true).should == true + ModuleSpecs::Child.method_defined?(:private_child, true).should == false + + # Defined in Parent + ModuleSpecs::Child.method_defined?(:public_parent, true).should == true + ModuleSpecs::Child.method_defined?(:protected_parent, true).should == true + ModuleSpecs::Child.method_defined?(:private_parent, true).should == false + + # Defined in Module + ModuleSpecs::Child.method_defined?(:public_module, true).should == true + ModuleSpecs::Child.method_defined?(:protected_module, true).should == true + ModuleSpecs::Child.method_defined?(:private_module, true).should == false + + # Defined in SuperModule + ModuleSpecs::Child.method_defined?(:public_super_module, true).should == true + ModuleSpecs::Child.method_defined?(:protected_super_module, true).should == true + ModuleSpecs::Child.method_defined?(:private_super_module, true).should == false end + end - describe "when passed false as a second optional argument" do - it "checks only the class itself" do - ModuleSpecs::Child.method_defined?(:public_child, false).should == true - ModuleSpecs::Child.method_defined?(:protected_child, false).should == true - ModuleSpecs::Child.method_defined?(:accessor_method, false).should == true - ModuleSpecs::Child.method_defined?(:private_child, false).should == false - - # Defined in Parent - ModuleSpecs::Child.method_defined?(:public_parent, false).should == false - ModuleSpecs::Child.method_defined?(:protected_parent, false).should == false - ModuleSpecs::Child.method_defined?(:private_parent, false).should == false - - # Defined in Module - ModuleSpecs::Child.method_defined?(:public_module, false).should == false - ModuleSpecs::Child.method_defined?(:protected_module, false).should == false - ModuleSpecs::Child.method_defined?(:private_module, false).should == false - - # Defined in SuperModule - ModuleSpecs::Child.method_defined?(:public_super_module, false).should == false - ModuleSpecs::Child.method_defined?(:protected_super_module, false).should == false - ModuleSpecs::Child.method_defined?(:private_super_module, false).should == false - end + describe "when passed false as a second optional argument" do + it "checks only the class itself" do + ModuleSpecs::Child.method_defined?(:public_child, false).should == true + ModuleSpecs::Child.method_defined?(:protected_child, false).should == true + ModuleSpecs::Child.method_defined?(:accessor_method, false).should == true + ModuleSpecs::Child.method_defined?(:private_child, false).should == false + + # Defined in Parent + ModuleSpecs::Child.method_defined?(:public_parent, false).should == false + ModuleSpecs::Child.method_defined?(:protected_parent, false).should == false + ModuleSpecs::Child.method_defined?(:private_parent, false).should == false + + # Defined in Module + ModuleSpecs::Child.method_defined?(:public_module, false).should == false + ModuleSpecs::Child.method_defined?(:protected_module, false).should == false + ModuleSpecs::Child.method_defined?(:private_module, false).should == false + + # Defined in SuperModule + ModuleSpecs::Child.method_defined?(:public_super_module, false).should == false + ModuleSpecs::Child.method_defined?(:protected_super_module, false).should == false + ModuleSpecs::Child.method_defined?(:private_super_module, false).should == false end end end diff --git a/spec/ruby/core/module/prepend_spec.rb b/spec/ruby/core/module/prepend_spec.rb index f11ca1b8b6..04cc27d472 100644 --- a/spec/ruby/core/module/prepend_spec.rb +++ b/spec/ruby/core/module/prepend_spec.rb @@ -222,6 +222,191 @@ describe "Module#prepend" do foo.call.should == 'n' end + it "updates the constant when a module is prepended" do + module ModuleSpecs::ConstUpdatePrepended + module M + FOO = 'm' + end + module A + FOO = 'a' + end + module B + include A + def self.foo + FOO + end + end + + B.foo.should == 'a' + B.prepend M + B.foo.should == 'm' + end + end + + it "updates the constant when a prepended module is updated" do + module ModuleSpecs::ConstPrependedUpdated + module M + end + module A + FOO = 'a' + end + module B + include A + prepend M + def self.foo + FOO + end + end + B.foo.should == 'a' + M.const_set(:FOO, 'm') + B.foo.should == 'm' + end + end + + it "updates the constant when there is a base included constant and the prepended module overrides it" do + module ModuleSpecs::ConstIncludedPrependedOverride + module Base + FOO = 'a' + end + module A + include Base + def self.foo + FOO + end + end + A.foo.should == 'a' + + module M + FOO = 'm' + end + A.prepend M + A.foo.should == 'm' + end + end + + it "updates the constant when there is a base included constant and the prepended module is later updated" do + module ModuleSpecs::ConstIncludedPrependedLaterUpdated + module Base + FOO = 'a' + end + module A + include Base + def self.foo + FOO + end + end + A.foo.should == 'a' + + module M + end + A.prepend M + A.foo.should == 'a' + + M.const_set(:FOO, 'm') + A.foo.should == 'm' + end + end + + it "updates the constant when a module prepended after a constant is later updated" do + module ModuleSpecs::ConstUpdatedPrependedAfterLaterUpdated + module M + end + module A + FOO = 'a' + end + module B + include A + def self.foo + FOO + end + end + B.foo.should == 'a' + + B.prepend M + B.foo.should == 'a' + + M.const_set(:FOO, 'm') + B.foo.should == 'm' + end + end + + it "updates the constant when a module is prepended after another and the constant is defined later on that module" do + module ModuleSpecs::ConstUpdatedPrependedAfterConstDefined + module M + FOO = 'm' + end + module A + prepend M + def self.foo + FOO + end + end + + A.foo.should == 'm' + + module N + end + A.prepend N + A.foo.should == 'm' + + N.const_set(:FOO, 'n') + A.foo.should == 'n' + end + end + + it "updates the constant when a module is included in a prepended module and the constant is defined later" do + module ModuleSpecs::ConstUpdatedIncludedInPrependedConstDefinedLater + module A + def self.foo + FOO + end + end + module Base + FOO = 'a' + end + + A.prepend Base + A.foo.should == 'a' + + module N + end + module M + include N + end + + A.prepend M + + N.const_set(:FOO, 'n') + A.foo.should == 'n' + end + end + + it "updates the constant when a new module with an included module is prepended" do + module ModuleSpecs::ConstUpdatedNewModuleIncludedPrepended + module A + FOO = 'a' + end + module B + include A + def self.foo + FOO + end + end + module N + FOO = 'n' + end + + module M + include N + end + + B.foo.should == 'a' + + B.prepend M + B.foo.should == 'n' + end + end + it "raises a TypeError when the argument is not a Module" do -> { ModuleSpecs::Basic.prepend(Class.new) }.should raise_error(TypeError) end diff --git a/spec/ruby/core/module/private_method_defined_spec.rb b/spec/ruby/core/module/private_method_defined_spec.rb index 951f17aaa7..01fc8f8fb9 100644 --- a/spec/ruby/core/module/private_method_defined_spec.rb +++ b/spec/ruby/core/module/private_method_defined_spec.rb @@ -70,53 +70,51 @@ describe "Module#private_method_defined?" do ModuleSpecs::CountsMixin.private_method_defined?(str).should == true end - ruby_version_is "2.6" do - describe "when passed true as a second optional argument" do - it "performs a lookup in ancestors" do - ModuleSpecs::Child.private_method_defined?(:public_child, true).should == false - ModuleSpecs::Child.private_method_defined?(:protected_child, true).should == false - ModuleSpecs::Child.private_method_defined?(:accessor_method, true).should == false - ModuleSpecs::Child.private_method_defined?(:private_child, true).should == true - - # Defined in Parent - ModuleSpecs::Child.private_method_defined?(:public_parent, true).should == false - ModuleSpecs::Child.private_method_defined?(:protected_parent, true).should == false - ModuleSpecs::Child.private_method_defined?(:private_parent, true).should == true - - # Defined in Module - ModuleSpecs::Child.private_method_defined?(:public_module, true).should == false - ModuleSpecs::Child.private_method_defined?(:protected_module, true).should == false - ModuleSpecs::Child.private_method_defined?(:private_module, true).should == true - - # Defined in SuperModule - ModuleSpecs::Child.private_method_defined?(:public_super_module, true).should == false - ModuleSpecs::Child.private_method_defined?(:protected_super_module, true).should == false - ModuleSpecs::Child.private_method_defined?(:private_super_module, true).should == true - end + describe "when passed true as a second optional argument" do + it "performs a lookup in ancestors" do + ModuleSpecs::Child.private_method_defined?(:public_child, true).should == false + ModuleSpecs::Child.private_method_defined?(:protected_child, true).should == false + ModuleSpecs::Child.private_method_defined?(:accessor_method, true).should == false + ModuleSpecs::Child.private_method_defined?(:private_child, true).should == true + + # Defined in Parent + ModuleSpecs::Child.private_method_defined?(:public_parent, true).should == false + ModuleSpecs::Child.private_method_defined?(:protected_parent, true).should == false + ModuleSpecs::Child.private_method_defined?(:private_parent, true).should == true + + # Defined in Module + ModuleSpecs::Child.private_method_defined?(:public_module, true).should == false + ModuleSpecs::Child.private_method_defined?(:protected_module, true).should == false + ModuleSpecs::Child.private_method_defined?(:private_module, true).should == true + + # Defined in SuperModule + ModuleSpecs::Child.private_method_defined?(:public_super_module, true).should == false + ModuleSpecs::Child.private_method_defined?(:protected_super_module, true).should == false + ModuleSpecs::Child.private_method_defined?(:private_super_module, true).should == true end + end - describe "when passed false as a second optional argument" do - it "checks only the class itself" do - ModuleSpecs::Child.private_method_defined?(:public_child, false).should == false - ModuleSpecs::Child.private_method_defined?(:protected_child, false).should == false - ModuleSpecs::Child.private_method_defined?(:accessor_method, false).should == false - ModuleSpecs::Child.private_method_defined?(:private_child, false).should == true - - # Defined in Parent - ModuleSpecs::Child.private_method_defined?(:public_parent, false).should == false - ModuleSpecs::Child.private_method_defined?(:protected_parent, false).should == false - ModuleSpecs::Child.private_method_defined?(:private_parent, false).should == false - - # Defined in Module - ModuleSpecs::Child.private_method_defined?(:public_module, false).should == false - ModuleSpecs::Child.private_method_defined?(:protected_module, false).should == false - ModuleSpecs::Child.private_method_defined?(:private_module, false).should == false - - # Defined in SuperModule - ModuleSpecs::Child.private_method_defined?(:public_super_module, false).should == false - ModuleSpecs::Child.private_method_defined?(:protected_super_module, false).should == false - ModuleSpecs::Child.private_method_defined?(:private_super_module, false).should == false - end + describe "when passed false as a second optional argument" do + it "checks only the class itself" do + ModuleSpecs::Child.private_method_defined?(:public_child, false).should == false + ModuleSpecs::Child.private_method_defined?(:protected_child, false).should == false + ModuleSpecs::Child.private_method_defined?(:accessor_method, false).should == false + ModuleSpecs::Child.private_method_defined?(:private_child, false).should == true + + # Defined in Parent + ModuleSpecs::Child.private_method_defined?(:public_parent, false).should == false + ModuleSpecs::Child.private_method_defined?(:protected_parent, false).should == false + ModuleSpecs::Child.private_method_defined?(:private_parent, false).should == false + + # Defined in Module + ModuleSpecs::Child.private_method_defined?(:public_module, false).should == false + ModuleSpecs::Child.private_method_defined?(:protected_module, false).should == false + ModuleSpecs::Child.private_method_defined?(:private_module, false).should == false + + # Defined in SuperModule + ModuleSpecs::Child.private_method_defined?(:public_super_module, false).should == false + ModuleSpecs::Child.private_method_defined?(:protected_super_module, false).should == false + ModuleSpecs::Child.private_method_defined?(:private_super_module, false).should == false end end end diff --git a/spec/ruby/core/module/protected_method_defined_spec.rb b/spec/ruby/core/module/protected_method_defined_spec.rb index e022d7c5c4..31e24a16c1 100644 --- a/spec/ruby/core/module/protected_method_defined_spec.rb +++ b/spec/ruby/core/module/protected_method_defined_spec.rb @@ -70,53 +70,51 @@ describe "Module#protected_method_defined?" do ModuleSpecs::CountsMixin.protected_method_defined?(str).should == true end - ruby_version_is "2.6" do - describe "when passed true as a second optional argument" do - it "performs a lookup in ancestors" do - ModuleSpecs::Child.protected_method_defined?(:public_child, true).should == false - ModuleSpecs::Child.protected_method_defined?(:protected_child, true).should == true - ModuleSpecs::Child.protected_method_defined?(:accessor_method, true).should == false - ModuleSpecs::Child.protected_method_defined?(:private_child, true).should == false - - # Defined in Parent - ModuleSpecs::Child.protected_method_defined?(:public_parent, true).should == false - ModuleSpecs::Child.protected_method_defined?(:protected_parent, true).should == true - ModuleSpecs::Child.protected_method_defined?(:private_parent, true).should == false - - # Defined in Module - ModuleSpecs::Child.protected_method_defined?(:public_module, true).should == false - ModuleSpecs::Child.protected_method_defined?(:protected_module, true).should == true - ModuleSpecs::Child.protected_method_defined?(:private_module, true).should == false - - # Defined in SuperModule - ModuleSpecs::Child.protected_method_defined?(:public_super_module, true).should == false - ModuleSpecs::Child.protected_method_defined?(:protected_super_module, true).should == true - ModuleSpecs::Child.protected_method_defined?(:private_super_module, true).should == false - end + describe "when passed true as a second optional argument" do + it "performs a lookup in ancestors" do + ModuleSpecs::Child.protected_method_defined?(:public_child, true).should == false + ModuleSpecs::Child.protected_method_defined?(:protected_child, true).should == true + ModuleSpecs::Child.protected_method_defined?(:accessor_method, true).should == false + ModuleSpecs::Child.protected_method_defined?(:private_child, true).should == false + + # Defined in Parent + ModuleSpecs::Child.protected_method_defined?(:public_parent, true).should == false + ModuleSpecs::Child.protected_method_defined?(:protected_parent, true).should == true + ModuleSpecs::Child.protected_method_defined?(:private_parent, true).should == false + + # Defined in Module + ModuleSpecs::Child.protected_method_defined?(:public_module, true).should == false + ModuleSpecs::Child.protected_method_defined?(:protected_module, true).should == true + ModuleSpecs::Child.protected_method_defined?(:private_module, true).should == false + + # Defined in SuperModule + ModuleSpecs::Child.protected_method_defined?(:public_super_module, true).should == false + ModuleSpecs::Child.protected_method_defined?(:protected_super_module, true).should == true + ModuleSpecs::Child.protected_method_defined?(:private_super_module, true).should == false end + end - describe "when passed false as a second optional argument" do - it "checks only the class itself" do - ModuleSpecs::Child.protected_method_defined?(:public_child, false).should == false - ModuleSpecs::Child.protected_method_defined?(:protected_child, false).should == true - ModuleSpecs::Child.protected_method_defined?(:accessor_method, false).should == false - ModuleSpecs::Child.protected_method_defined?(:private_child, false).should == false - - # Defined in Parent - ModuleSpecs::Child.protected_method_defined?(:public_parent, false).should == false - ModuleSpecs::Child.protected_method_defined?(:protected_parent, false).should == false - ModuleSpecs::Child.protected_method_defined?(:private_parent, false).should == false - - # Defined in Module - ModuleSpecs::Child.protected_method_defined?(:public_module, false).should == false - ModuleSpecs::Child.protected_method_defined?(:protected_module, false).should == false - ModuleSpecs::Child.protected_method_defined?(:private_module, false).should == false - - # Defined in SuperModule - ModuleSpecs::Child.protected_method_defined?(:public_super_module, false).should == false - ModuleSpecs::Child.protected_method_defined?(:protected_super_module, false).should == false - ModuleSpecs::Child.protected_method_defined?(:private_super_module, false).should == false - end + describe "when passed false as a second optional argument" do + it "checks only the class itself" do + ModuleSpecs::Child.protected_method_defined?(:public_child, false).should == false + ModuleSpecs::Child.protected_method_defined?(:protected_child, false).should == true + ModuleSpecs::Child.protected_method_defined?(:accessor_method, false).should == false + ModuleSpecs::Child.protected_method_defined?(:private_child, false).should == false + + # Defined in Parent + ModuleSpecs::Child.protected_method_defined?(:public_parent, false).should == false + ModuleSpecs::Child.protected_method_defined?(:protected_parent, false).should == false + ModuleSpecs::Child.protected_method_defined?(:private_parent, false).should == false + + # Defined in Module + ModuleSpecs::Child.protected_method_defined?(:public_module, false).should == false + ModuleSpecs::Child.protected_method_defined?(:protected_module, false).should == false + ModuleSpecs::Child.protected_method_defined?(:private_module, false).should == false + + # Defined in SuperModule + ModuleSpecs::Child.protected_method_defined?(:public_super_module, false).should == false + ModuleSpecs::Child.protected_method_defined?(:protected_super_module, false).should == false + ModuleSpecs::Child.protected_method_defined?(:private_super_module, false).should == false end end end diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb index e5f65f5f96..e3b7fde049 100644 --- a/spec/ruby/core/module/refine_spec.rb +++ b/spec/ruby/core/module/refine_spec.rb @@ -453,44 +453,22 @@ describe "Module#refine" do result.should == ["(1)", "(2)", "(3)"] end - ruby_version_is "" ... "2.6" do - it "is not honored by Kernel#public_send" do - refined_class = ModuleSpecs.build_refined_class - - refinement = Module.new do - refine refined_class do - def foo; "foo from refinement"; end - end - end + it "is honored by Kernel#public_send" do + refined_class = ModuleSpecs.build_refined_class - result = nil - Module.new do - using refinement - result = refined_class.new.public_send :foo + refinement = Module.new do + refine refined_class do + def foo; "foo from refinement"; end end - - result.should == "foo" end - end - - ruby_version_is "2.6" do - it "is honored by Kernel#public_send" do - refined_class = ModuleSpecs.build_refined_class - - refinement = Module.new do - refine refined_class do - def foo; "foo from refinement"; end - end - end - result = nil - Module.new do - using refinement - result = refined_class.new.public_send :foo - end - - result.should == "foo from refinement" + result = nil + Module.new do + using refinement + result = refined_class.new.public_send :foo end + + result.should == "foo from refinement" end it "is honored by string interpolation" do @@ -647,81 +625,39 @@ describe "Module#refine" do end end - ruby_version_is "" ... "2.6" do - it "is not honored by Kernel#respond_to?" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end - end - end - - result = nil - Module.new do - using refinement - result = klass.new.respond_to?(:foo) + it "is honored by Kernel#respond_to?" do + klass = Class.new + refinement = Module.new do + refine klass do + def foo; end end - - result.should == false end - end - - ruby_version_is "2.6" do - it "is honored by Kernel#respond_to?" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end - end - end - - result = nil - Module.new do - using refinement - result = klass.new.respond_to?(:foo) - end - result.should == true + result = nil + Module.new do + using refinement + result = klass.new.respond_to?(:foo) end - end - ruby_version_is ""..."2.6" do - it "is not honored by &" do - refinement = Module.new do - refine String do - def to_proc(*args) - -> * { 'foo' } - end - end - end - - -> do - Module.new do - using refinement - ["hola"].map(&"upcase") - end - end.should raise_error(TypeError, /wrong argument type String \(expected Proc\)/) - end + result.should == true end - ruby_version_is "2.6" do - it "is honored by &" do - refinement = Module.new do - refine String do - def to_proc(*args) - -> * { 'foo' } - end + it "is honored by &" do + refinement = Module.new do + refine String do + def to_proc(*args) + -> * { 'foo' } end end + end - result = nil - Module.new do - using refinement - result = ["hola"].map(&"upcase") - end - - result.should == ['foo'] + result = nil + Module.new do + using refinement + result = ["hola"].map(&"upcase") end + + result.should == ['foo'] end end diff --git a/spec/ruby/core/module/remove_const_spec.rb b/spec/ruby/core/module/remove_const_spec.rb index 20eb2dc3ed..0ac23f05a5 100644 --- a/spec/ruby/core/module/remove_const_spec.rb +++ b/spec/ruby/core/module/remove_const_spec.rb @@ -81,4 +81,25 @@ describe "Module#remove_const" do ConstantSpecs.autoload :AutoloadedConstant, 'a_file' ConstantSpecs.send(:remove_const, :AutoloadedConstant).should be_nil end + + it "updates the constant value" do + module ConstantSpecs::RemovedConstantUpdate + module M + FOO = 'm' + end + + module A + include M + FOO = 'a' + def self.foo + FOO + end + end + + A.foo.should == 'a' + + A.send(:remove_const,:FOO) + A.foo.should == 'm' + end + end end diff --git a/spec/ruby/core/nil/match_spec.rb b/spec/ruby/core/nil/match_spec.rb index 27646e9749..2e2b5d1c1b 100644 --- a/spec/ruby/core/nil/match_spec.rb +++ b/spec/ruby/core/nil/match_spec.rb @@ -1,23 +1,21 @@ require_relative '../../spec_helper' -ruby_version_is "2.6" do - describe "NilClass#=~" do - it "returns nil matching any object" do - o = Object.new +describe "NilClass#=~" do + it "returns nil matching any object" do + o = Object.new - suppress_warning do - (o =~ /Object/).should be_nil - (o =~ 'Object').should be_nil - (o =~ Object).should be_nil - (o =~ Object.new).should be_nil - (o =~ nil).should be_nil - (o =~ false).should be_nil - (o =~ true).should be_nil - end + suppress_warning do + (o =~ /Object/).should be_nil + (o =~ 'Object').should be_nil + (o =~ Object).should be_nil + (o =~ Object.new).should be_nil + (o =~ nil).should be_nil + (o =~ false).should be_nil + (o =~ true).should be_nil end + end - it "should not warn" do - -> { nil =~ /a/ }.should_not complain(verbose: true) - end + it "should not warn" do + -> { nil =~ /a/ }.should_not complain(verbose: true) end end diff --git a/spec/ruby/core/numeric/shared/step.rb b/spec/ruby/core/numeric/shared/step.rb index 72f33016d4..a4fe74f9db 100644 --- a/spec/ruby/core/numeric/shared/step.rb +++ b/spec/ruby/core/numeric/shared/step.rb @@ -257,9 +257,7 @@ describe :numeric_step, :shared => true do describe "when no block is given" do step_enum_class = Enumerator - ruby_version_is "2.6" do - step_enum_class = Enumerator::ArithmeticSequence - end + step_enum_class = Enumerator::ArithmeticSequence ruby_version_is ""..."3.0" do it "returns an #{step_enum_class} when step is 0" do diff --git a/spec/ruby/core/numeric/step_spec.rb b/spec/ruby/core/numeric/step_spec.rb index 2773000229..03af8b0e4d 100644 --- a/spec/ruby/core/numeric/step_spec.rb +++ b/spec/ruby/core/numeric/step_spec.rb @@ -22,9 +22,7 @@ describe "Numeric#step" do describe "when no block is given" do step_enum_class = Enumerator - ruby_version_is "2.6" do - step_enum_class = Enumerator::ArithmeticSequence - end + step_enum_class = Enumerator::ArithmeticSequence ruby_version_is ""..."3.0" do it "returns an #{step_enum_class} when step is 0" do @@ -38,19 +36,7 @@ describe "Numeric#step" do describe "returned #{step_enum_class}" do describe "size" do - ruby_version_is ""..."2.6" do - it "raises an ArgumentError when step is 0" do - enum = 1.step(5, 0) - -> { enum.size }.should raise_error(ArgumentError) - end - - it "raises an ArgumentError when step is 0.0" do - enum = 1.step(2, 0.0) - -> { enum.size }.should raise_error(ArgumentError) - end - end - - ruby_version_is "2.6"..."3.0" do + ruby_version_is ""..."3.0" do it "is infinity when step is 0" do enum = 1.step(5, 0) enum.size.should == Float::INFINITY @@ -69,16 +55,8 @@ describe "Numeric#step" do end describe "type" do - ruby_version_is ""..."2.6" do - it "returns an instance of Enumerator" do - 1.step(10).class.should == Enumerator - end - end - - ruby_version_is "2.6" do - it "returns an instance of Enumerator::ArithmeticSequence" do - 1.step(10).class.should == Enumerator::ArithmeticSequence - end + it "returns an instance of Enumerator::ArithmeticSequence" do + 1.step(10).class.should == Enumerator::ArithmeticSequence end end end diff --git a/spec/ruby/core/proc/compose_spec.rb b/spec/ruby/core/proc/compose_spec.rb index 285e96192b..803a32af7b 100644 --- a/spec/ruby/core/proc/compose_spec.rb +++ b/spec/ruby/core/proc/compose_spec.rb @@ -1,156 +1,154 @@ require_relative '../../spec_helper' require_relative 'shared/compose' -ruby_version_is "2.6" do - describe "Proc#<<" do - it "returns a Proc that is the composition of self and the passed Proc" do - upcase = proc { |s| s.upcase } - succ = proc { |s| s.succ } +describe "Proc#<<" do + it "returns a Proc that is the composition of self and the passed Proc" do + upcase = proc { |s| s.upcase } + succ = proc { |s| s.succ } - (succ << upcase).call('Ruby').should == "RUBZ" - end + (succ << upcase).call('Ruby').should == "RUBZ" + end - it "calls passed Proc with arguments and then calls self with result" do - f = proc { |x| x * x } - g = proc { |x| x + x } + it "calls passed Proc with arguments and then calls self with result" do + f = proc { |x| x * x } + g = proc { |x| x + x } - (f << g).call(2).should == 16 - (g << f).call(2).should == 8 - end + (f << g).call(2).should == 16 + (g << f).call(2).should == 8 + end - it "accepts any callable object" do - inc = proc { |n| n + 1 } + it "accepts any callable object" do + inc = proc { |n| n + 1 } - double = Object.new - def double.call(n); n * 2; end + double = Object.new + def double.call(n); n * 2; end - (inc << double).call(3).should == 7 - end + (inc << double).call(3).should == 7 + end - it_behaves_like :proc_compose, :<<, -> { proc { |s| s.upcase } } + it_behaves_like :proc_compose, :<<, -> { proc { |s| s.upcase } } - describe "composition" do - it "is a Proc" do + describe "composition" do + it "is a Proc" do + f = proc { |x| x * x } + g = proc { |x| x + x } + + (f << g).is_a?(Proc).should == true + (f << g).should_not.lambda? + end + + ruby_version_is(''...'3.0') do + it "is a Proc when other is lambda" do f = proc { |x| x * x } - g = proc { |x| x + x } + g = -> x { x + x } (f << g).is_a?(Proc).should == true (f << g).should_not.lambda? end - ruby_version_is(''...'3.0') do - it "is a Proc when other is lambda" do - f = proc { |x| x * x } - g = -> x { x + x } - - (f << g).is_a?(Proc).should == true - (f << g).should_not.lambda? - end - - it "is a lambda when self is lambda" do - f = -> x { x * x } - g = proc { |x| x + x } + it "is a lambda when self is lambda" do + f = -> x { x * x } + g = proc { |x| x + x } - (f << g).is_a?(Proc).should == true - (f << g).should.lambda? - end + (f << g).is_a?(Proc).should == true + (f << g).should.lambda? end + end - ruby_version_is('3.0') do - it "is a lambda when parameter is lambda" do - f = -> x { x * x } - g = proc { |x| x + x } - lambda_proc = -> x { x } + ruby_version_is('3.0') do + it "is a lambda when parameter is lambda" do + f = -> x { x * x } + g = proc { |x| x + x } + lambda_proc = -> x { x } - (f << g).is_a?(Proc).should == true - (f << g).should_not.lambda? - (f << lambda_proc).should.lambda? - end + (f << g).is_a?(Proc).should == true + (f << g).should_not.lambda? + (f << lambda_proc).should.lambda? end + end - it "may accept multiple arguments" do - inc = proc { |n| n + 1 } - mul = proc { |n, m| n * m } + it "may accept multiple arguments" do + inc = proc { |n| n + 1 } + mul = proc { |n, m| n * m } - (inc << mul).call(2, 3).should == 7 - end + (inc << mul).call(2, 3).should == 7 + end - it "passes blocks to the second proc" do - ScratchPad.record [] - one = proc { |&arg| arg.call :one if arg } - two = proc { |&arg| arg.call :two if arg } - (one << two).call { |x| ScratchPad << x } - ScratchPad.recorded.should == [:two] - end + it "passes blocks to the second proc" do + ScratchPad.record [] + one = proc { |&arg| arg.call :one if arg } + two = proc { |&arg| arg.call :two if arg } + (one << two).call { |x| ScratchPad << x } + ScratchPad.recorded.should == [:two] end end +end - describe "Proc#>>" do - it "returns a Proc that is the composition of self and the passed Proc" do - upcase = proc { |s| s.upcase } - succ = proc { |s| s.succ } +describe "Proc#>>" do + it "returns a Proc that is the composition of self and the passed Proc" do + upcase = proc { |s| s.upcase } + succ = proc { |s| s.succ } - (succ >> upcase).call('Ruby').should == "RUBZ" - end + (succ >> upcase).call('Ruby').should == "RUBZ" + end - it "calls passed Proc with arguments and then calls self with result" do - f = proc { |x| x * x } - g = proc { |x| x + x } + it "calls passed Proc with arguments and then calls self with result" do + f = proc { |x| x * x } + g = proc { |x| x + x } - (f >> g).call(2).should == 8 - (g >> f).call(2).should == 16 - end + (f >> g).call(2).should == 8 + (g >> f).call(2).should == 16 + end - it "accepts any callable object" do - inc = proc { |n| n + 1 } + it "accepts any callable object" do + inc = proc { |n| n + 1 } - double = Object.new - def double.call(n); n * 2; end + double = Object.new + def double.call(n); n * 2; end - (inc >> double).call(3).should == 8 - end + (inc >> double).call(3).should == 8 + end - it_behaves_like :proc_compose, :>>, -> { proc { |s| s.upcase } } + it_behaves_like :proc_compose, :>>, -> { proc { |s| s.upcase } } - describe "composition" do - it "is a Proc" do - f = proc { |x| x * x } - g = proc { |x| x + x } + describe "composition" do + it "is a Proc" do + f = proc { |x| x * x } + g = proc { |x| x + x } - (f >> g).is_a?(Proc).should == true - (f >> g).should_not.lambda? - end + (f >> g).is_a?(Proc).should == true + (f >> g).should_not.lambda? + end - it "is a Proc when other is lambda" do - f = proc { |x| x * x } - g = -> x { x + x } + it "is a Proc when other is lambda" do + f = proc { |x| x * x } + g = -> x { x + x } - (f >> g).is_a?(Proc).should == true - (f >> g).should_not.lambda? - end + (f >> g).is_a?(Proc).should == true + (f >> g).should_not.lambda? + end - it "is a lambda when self is lambda" do - f = -> x { x * x } - g = proc { |x| x + x } + it "is a lambda when self is lambda" do + f = -> x { x * x } + g = proc { |x| x + x } - (f >> g).is_a?(Proc).should == true - (f >> g).should.lambda? - end + (f >> g).is_a?(Proc).should == true + (f >> g).should.lambda? + end - it "may accept multiple arguments" do - inc = proc { |n| n + 1 } - mul = proc { |n, m| n * m } + it "may accept multiple arguments" do + inc = proc { |n| n + 1 } + mul = proc { |n, m| n * m } - (mul >> inc).call(2, 3).should == 7 - end + (mul >> inc).call(2, 3).should == 7 + end - it "passes blocks to the first proc" do - ScratchPad.record [] - one = proc { |&arg| arg.call :one if arg } - two = proc { |&arg| arg.call :two if arg } - (one >> two).call { |x| ScratchPad << x } - ScratchPad.recorded.should == [:one] - end + it "passes blocks to the first proc" do + ScratchPad.record [] + one = proc { |&arg| arg.call :one if arg } + two = proc { |&arg| arg.call :two if arg } + (one >> two).call { |x| ScratchPad << x } + ScratchPad.recorded.should == [:one] end end end diff --git a/spec/ruby/core/proc/shared/compose.rb b/spec/ruby/core/proc/shared/compose.rb index 64338cada8..e3ae7f76b8 100644 --- a/spec/ruby/core/proc/shared/compose.rb +++ b/spec/ruby/core/proc/shared/compose.rb @@ -1,5 +1,5 @@ describe :proc_compose, shared: true do - ruby_version_is "2.6"..."2.7" do + ruby_version_is ""..."2.7" do it "raises NoMethodError when called if passed not callable object" do not_callable = Object.new composed = @object.call.send(@method, not_callable) diff --git a/spec/ruby/core/process/spawn_spec.rb b/spec/ruby/core/process/spawn_spec.rb index e373d8600c..56e02ff38a 100644 --- a/spec/ruby/core/process/spawn_spec.rb +++ b/spec/ruby/core/process/spawn_spec.rb @@ -551,27 +551,14 @@ describe "Process.spawn" do platform_is_not :windows do context "defaults :close_others to" do - ruby_version_is ""..."2.6" do - it "true" do - IO.pipe do |r, w| - w.close_on_exec = false - code = "begin; IO.new(#{w.fileno}).close; rescue Errno::EBADF; puts 'not inherited'; end" - Process.wait Process.spawn(ruby_cmd(code), :out => @name) - File.read(@name).should == "not inherited\n" - end - end - end - - ruby_version_is "2.6" do - it "false" do - IO.pipe do |r, w| - w.close_on_exec = false - code = "io = IO.new(#{w.fileno}); io.puts('inherited'); io.close" - pid = Process.spawn(ruby_cmd(code)) - w.close - Process.wait(pid) - r.read.should == "inherited\n" - end + it "false" do + IO.pipe do |r, w| + w.close_on_exec = false + code = "io = IO.new(#{w.fileno}); io.puts('inherited'); io.close" + pid = Process.spawn(ruby_cmd(code)) + w.close + Process.wait(pid) + r.read.should == "inherited\n" end end end diff --git a/spec/ruby/core/process/status/wait_spec.rb b/spec/ruby/core/process/status/wait_spec.rb new file mode 100644 index 0000000000..b9d80e31f4 --- /dev/null +++ b/spec/ruby/core/process/status/wait_spec.rb @@ -0,0 +1,102 @@ +require_relative '../../../spec_helper' +require_relative '../fixtures/common' + +ruby_version_is "3.0" do + describe "Process::Status.wait" do + ProcessSpecs.use_system_ruby(self) + + before :all do + begin + leaked = Process.waitall + # Ruby-space should not see PIDs used by mjit + raise "subprocesses leaked before wait specs: #{leaked}" unless leaked.empty? + rescue NotImplementedError + end + end + + it "returns a status with pid -1 if there are no child processes" do + Process::Status.wait.pid.should == -1 + end + + platform_is_not :windows do + it "returns a status with its child pid" do + pid = Process.spawn(ruby_cmd('exit')) + status = Process::Status.wait + status.should be_an_instance_of(Process::Status) + status.pid.should == pid + end + + it "should not set $? to the Process::Status" do + pid = Process.spawn(ruby_cmd('exit')) + status = Process::Status.wait + $?.should_not equal(status) + end + + it "should not change the value of $?" do + pid = Process.spawn(ruby_cmd('exit')) + Process.wait + status = $? + Process::Status.wait + status.should equal($?) + end + + it "waits for any child process if no pid is given" do + pid = Process.spawn(ruby_cmd('exit')) + Process::Status.wait.pid.should == pid + -> { Process.kill(0, pid) }.should raise_error(Errno::ESRCH) + end + + it "waits for a specific child if a pid is given" do + pid1 = Process.spawn(ruby_cmd('exit')) + pid2 = Process.spawn(ruby_cmd('exit')) + Process::Status.wait(pid2).pid.should == pid2 + Process::Status.wait(pid1).pid.should == pid1 + -> { Process.kill(0, pid1) }.should raise_error(Errno::ESRCH) + -> { Process.kill(0, pid2) }.should raise_error(Errno::ESRCH) + end + + it "coerces the pid to an Integer" do + pid1 = Process.spawn(ruby_cmd('exit')) + Process::Status.wait(mock_int(pid1)).pid.should == pid1 + -> { Process.kill(0, pid1) }.should raise_error(Errno::ESRCH) + end + + # This spec is probably system-dependent. + it "waits for a child whose process group ID is that of the calling process" do + pid1 = Process.spawn(ruby_cmd('exit'), pgroup: true) + pid2 = Process.spawn(ruby_cmd('exit')) + + Process::Status.wait(0).pid.should == pid2 + Process::Status.wait.pid.should == pid1 + end + + # This spec is probably system-dependent. + it "doesn't block if no child is available when WNOHANG is used" do + read, write = IO.pipe + pid = Process.fork do + read.close + Signal.trap("TERM") { Process.exit! } + write << 1 + write.close + sleep + end + + Process::Status.wait(pid, Process::WNOHANG).should be_nil + + # wait for the child to setup its TERM handler + write.close + read.read(1) + read.close + + Process.kill("TERM", pid) + Process::Status.wait.pid.should == pid + end + + it "always accepts flags=0" do + pid = Process.spawn(ruby_cmd('exit')) + Process::Status.wait(-1, 0).pid.should == pid + -> { Process.kill(0, pid) }.should raise_error(Errno::ESRCH) + end + end + end +end diff --git a/spec/ruby/core/random/bytes_spec.rb b/spec/ruby/core/random/bytes_spec.rb index 2caf18fbd0..06e84d03bd 100644 --- a/spec/ruby/core/random/bytes_spec.rb +++ b/spec/ruby/core/random/bytes_spec.rb @@ -25,8 +25,6 @@ describe "Random#bytes" do end end -ruby_version_is "2.6" do - describe "Random.bytes" do - it_behaves_like :random_bytes, :bytes, Random - end +describe "Random.bytes" do + it_behaves_like :random_bytes, :bytes, Random end diff --git a/spec/ruby/core/random/random_number_spec.rb b/spec/ruby/core/random/random_number_spec.rb index 60a80ae1b9..bad81aeff6 100644 --- a/spec/ruby/core/random/random_number_spec.rb +++ b/spec/ruby/core/random/random_number_spec.rb @@ -4,7 +4,5 @@ require_relative 'shared/rand' describe "Random.random_number" do it_behaves_like :random_number, :random_number, Random.new - ruby_version_is "2.6" do - it_behaves_like :random_number, :random_number, Random - end + it_behaves_like :random_number, :random_number, Random end diff --git a/spec/ruby/core/range/bsearch_spec.rb b/spec/ruby/core/range/bsearch_spec.rb index d31c5d5d51..438c7ce314 100644 --- a/spec/ruby/core/range/bsearch_spec.rb +++ b/spec/ruby/core/range/bsearch_spec.rb @@ -215,118 +215,116 @@ describe "Range#bsearch" do end end - ruby_version_is "2.6" do - context "with endless ranges and Integer values" do - context "with a block returning true or false" do - it "returns minimum element if the block returns true for every element" do - eval("(-2..)").bsearch { |x| true }.should == -2 - end + context "with endless ranges and Integer values" do + context "with a block returning true or false" do + it "returns minimum element if the block returns true for every element" do + eval("(-2..)").bsearch { |x| true }.should == -2 + end - it "returns the smallest element for which block returns true" do - eval("(0..)").bsearch { |x| x >= 2 }.should == 2 - eval("(-1..)").bsearch { |x| x >= 1 }.should == 1 - end + it "returns the smallest element for which block returns true" do + eval("(0..)").bsearch { |x| x >= 2 }.should == 2 + eval("(-1..)").bsearch { |x| x >= 1 }.should == 1 end + end - context "with a block returning negative, zero, positive numbers" do - it "returns nil if the block returns less than zero for every element" do - eval("(0..)").bsearch { |x| -1 }.should be_nil - end + context "with a block returning negative, zero, positive numbers" do + it "returns nil if the block returns less than zero for every element" do + eval("(0..)").bsearch { |x| -1 }.should be_nil + end - it "returns nil if the block never returns zero" do - eval("(0..)").bsearch { |x| x > 5 ? -1 : 1 }.should be_nil - end + it "returns nil if the block never returns zero" do + eval("(0..)").bsearch { |x| x > 5 ? -1 : 1 }.should be_nil + end - it "accepts -Float::INFINITY from the block" do - eval("(0..)").bsearch { |x| -Float::INFINITY }.should be_nil - end + it "accepts -Float::INFINITY from the block" do + eval("(0..)").bsearch { |x| -Float::INFINITY }.should be_nil + end - it "returns an element at an index for which block returns 0.0" do - result = eval("(0..)").bsearch { |x| x < 2 ? 1.0 : x > 2 ? -1.0 : 0.0 } - result.should == 2 - end + it "returns an element at an index for which block returns 0.0" do + result = eval("(0..)").bsearch { |x| x < 2 ? 1.0 : x > 2 ? -1.0 : 0.0 } + result.should == 2 + end - it "returns an element at an index for which block returns 0" do - result = eval("(0..)").bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 } - [1, 2, 3].should include(result) - end + it "returns an element at an index for which block returns 0" do + result = eval("(0..)").bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 } + [1, 2, 3].should include(result) end end + end - context "with endless ranges and Float values" do - context "with a block returning true or false" do - it "returns nil if the block returns false for every element" do - eval("(0.1..)").bsearch { |x| x < 0.0 }.should be_nil - eval("(0.1...)").bsearch { |x| x < 0.0 }.should be_nil - end + context "with endless ranges and Float values" do + context "with a block returning true or false" do + it "returns nil if the block returns false for every element" do + eval("(0.1..)").bsearch { |x| x < 0.0 }.should be_nil + eval("(0.1...)").bsearch { |x| x < 0.0 }.should be_nil + end - it "returns nil if the block returns nil for every element" do - eval("(-0.0..)").bsearch { |x| nil }.should be_nil - eval("(-0.0...)").bsearch { |x| nil }.should be_nil - end + it "returns nil if the block returns nil for every element" do + eval("(-0.0..)").bsearch { |x| nil }.should be_nil + eval("(-0.0...)").bsearch { |x| nil }.should be_nil + end - it "returns minimum element if the block returns true for every element" do - eval("(-0.2..)").bsearch { |x| true }.should == -0.2 - eval("(-0.2...)").bsearch { |x| true }.should == -0.2 - end + it "returns minimum element if the block returns true for every element" do + eval("(-0.2..)").bsearch { |x| true }.should == -0.2 + eval("(-0.2...)").bsearch { |x| true }.should == -0.2 + end - it "returns the smallest element for which block returns true" do - eval("(0..)").bsearch { |x| x >= 2 }.should == 2 - eval("(-1.2..)").bsearch { |x| x >= 1 }.should == 1 - end + it "returns the smallest element for which block returns true" do + eval("(0..)").bsearch { |x| x >= 2 }.should == 2 + eval("(-1.2..)").bsearch { |x| x >= 1 }.should == 1 + end - it "works with infinity bounds" do - inf = Float::INFINITY - eval("(inf..)").bsearch { |x| true }.should == inf - eval("(inf...)").bsearch { |x| true }.should == nil - eval("(-inf..)").bsearch { |x| true }.should == -inf - eval("(-inf...)").bsearch { |x| true }.should == -inf - end + it "works with infinity bounds" do + inf = Float::INFINITY + eval("(inf..)").bsearch { |x| true }.should == inf + eval("(inf...)").bsearch { |x| true }.should == nil + eval("(-inf..)").bsearch { |x| true }.should == -inf + eval("(-inf...)").bsearch { |x| true }.should == -inf end + end - context "with a block returning negative, zero, positive numbers" do - it "returns nil if the block returns less than zero for every element" do - eval("(-2.0..)").bsearch { |x| -1 }.should be_nil - eval("(-2.0...)").bsearch { |x| -1 }.should be_nil - end + context "with a block returning negative, zero, positive numbers" do + it "returns nil if the block returns less than zero for every element" do + eval("(-2.0..)").bsearch { |x| -1 }.should be_nil + eval("(-2.0...)").bsearch { |x| -1 }.should be_nil + end - it "returns nil if the block returns greater than zero for every element" do - eval("(0.3..)").bsearch { |x| 1 }.should be_nil - eval("(0.3...)").bsearch { |x| 1 }.should be_nil - end + it "returns nil if the block returns greater than zero for every element" do + eval("(0.3..)").bsearch { |x| 1 }.should be_nil + eval("(0.3...)").bsearch { |x| 1 }.should be_nil + end - it "returns nil if the block never returns zero" do - eval("(0.2..)").bsearch { |x| x < 2 ? 1 : -1 }.should be_nil - end + it "returns nil if the block never returns zero" do + eval("(0.2..)").bsearch { |x| x < 2 ? 1 : -1 }.should be_nil + end - it "accepts (+/-)Float::INFINITY from the block" do - eval("(0.1..)").bsearch { |x| Float::INFINITY }.should be_nil - eval("(-5.0..)").bsearch { |x| -Float::INFINITY }.should be_nil - end + it "accepts (+/-)Float::INFINITY from the block" do + eval("(0.1..)").bsearch { |x| Float::INFINITY }.should be_nil + eval("(-5.0..)").bsearch { |x| -Float::INFINITY }.should be_nil + end - it "returns an element at an index for which block returns 0.0" do - result = eval("(0.0..)").bsearch { |x| x < 2 ? 1.0 : x > 2 ? -1.0 : 0.0 } - result.should == 2 - end + it "returns an element at an index for which block returns 0.0" do + result = eval("(0.0..)").bsearch { |x| x < 2 ? 1.0 : x > 2 ? -1.0 : 0.0 } + result.should == 2 + end - it "returns an element at an index for which block returns 0" do - result = eval("(0.1..)").bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 } - result.should >= 1 - result.should <= 3 - end + it "returns an element at an index for which block returns 0" do + result = eval("(0.1..)").bsearch { |x| x < 1 ? 1 : x > 3 ? -1 : 0 } + result.should >= 1 + result.should <= 3 + end - it "works with infinity bounds" do - inf = Float::INFINITY - eval("(inf..)").bsearch { |x| 1 }.should == nil - eval("(inf...)").bsearch { |x| 1 }.should == nil - eval("(inf..)").bsearch { |x| x == inf ? 0 : 1 }.should == inf - eval("(inf...)").bsearch { |x| x == inf ? 0 : 1 }.should == nil - eval("(-inf..)").bsearch { |x| x == -inf ? 0 : -1 }.should == -inf - eval("(-inf...)").bsearch { |x| x == -inf ? 0 : -1 }.should == -inf - eval("(-inf..)").bsearch { |x| 3 - x }.should == 3 - eval("(-inf...)").bsearch { |x| 3 - x }.should == 3 - eval("(0.0...)").bsearch { 0 }.should != inf - end + it "works with infinity bounds" do + inf = Float::INFINITY + eval("(inf..)").bsearch { |x| 1 }.should == nil + eval("(inf...)").bsearch { |x| 1 }.should == nil + eval("(inf..)").bsearch { |x| x == inf ? 0 : 1 }.should == inf + eval("(inf...)").bsearch { |x| x == inf ? 0 : 1 }.should == nil + eval("(-inf..)").bsearch { |x| x == -inf ? 0 : -1 }.should == -inf + eval("(-inf...)").bsearch { |x| x == -inf ? 0 : -1 }.should == -inf + eval("(-inf..)").bsearch { |x| 3 - x }.should == 3 + eval("(-inf...)").bsearch { |x| 3 - x }.should == 3 + eval("(0.0...)").bsearch { 0 }.should != inf end end end diff --git a/spec/ruby/core/range/case_compare_spec.rb b/spec/ruby/core/range/case_compare_spec.rb index b1afa90a41..e795026230 100644 --- a/spec/ruby/core/range/case_compare_spec.rb +++ b/spec/ruby/core/range/case_compare_spec.rb @@ -3,27 +3,9 @@ require_relative 'shared/cover_and_include' require_relative 'shared/cover' describe "Range#===" do - ruby_version_is ""..."2.6" do - it "returns the result of calling #include? on self" do - range = 0...10 - range.should_receive(:include?).with(2).and_return(:true) - (range === 2).should == :true - end - - it "requires #succ method to be implemented" do - range = RangeSpecs::WithoutSucc.new(0)..RangeSpecs::WithoutSucc.new(10) - - -> do - range === RangeSpecs::WithoutSucc.new(2) - end.should raise_error(TypeError, /can't iterate from/) - end - end - - ruby_version_is "2.6" do - it "returns the result of calling #cover? on self" do - range = RangeSpecs::WithoutSucc.new(0)..RangeSpecs::WithoutSucc.new(10) - (range === RangeSpecs::WithoutSucc.new(2)).should == true - end + it "returns the result of calling #cover? on self" do + range = RangeSpecs::WithoutSucc.new(0)..RangeSpecs::WithoutSucc.new(10) + (range === RangeSpecs::WithoutSucc.new(2)).should == true end ruby_version_is "2.7" do diff --git a/spec/ruby/core/range/each_spec.rb b/spec/ruby/core/range/each_spec.rb index 1dce9c1f1e..bd4bbb82e5 100644 --- a/spec/ruby/core/range/each_spec.rb +++ b/spec/ruby/core/range/each_spec.rb @@ -38,26 +38,24 @@ describe "Range#each" do a.should == ["Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω"] end - ruby_version_is "2.6" do - it "works with endless ranges" do - a = [] - eval("(-2..)").each { |x| break if x > 2; a << x } - a.should == [-2, -1, 0, 1, 2] - - a = [] - eval("(-2...)").each { |x| break if x > 2; a << x } - a.should == [-2, -1, 0, 1, 2] - end + it "works with endless ranges" do + a = [] + eval("(-2..)").each { |x| break if x > 2; a << x } + a.should == [-2, -1, 0, 1, 2] + + a = [] + eval("(-2...)").each { |x| break if x > 2; a << x } + a.should == [-2, -1, 0, 1, 2] + end - it "works with String endless ranges" do - a = [] - eval("('A'..)").each { |x| break if x > "D"; a << x } - a.should == ["A", "B", "C", "D"] + it "works with String endless ranges" do + a = [] + eval("('A'..)").each { |x| break if x > "D"; a << x } + a.should == ["A", "B", "C", "D"] - a = [] - eval("('A'...)").each { |x| break if x > "D"; a << x } - a.should == ["A", "B", "C", "D"] - end + a = [] + eval("('A'...)").each { |x| break if x > "D"; a << x } + a.should == ["A", "B", "C", "D"] end ruby_version_is "2.7" do diff --git a/spec/ruby/core/range/equal_value_spec.rb b/spec/ruby/core/range/equal_value_spec.rb index f88d3029bb..0aaebfb59a 100644 --- a/spec/ruby/core/range/equal_value_spec.rb +++ b/spec/ruby/core/range/equal_value_spec.rb @@ -8,10 +8,8 @@ describe "Range#==" do (0..1).should == (0..1.0) end - ruby_version_is "2.6" do - it "returns true if the endpoints are == for endless ranges" do - eval("(1.0..)").should == eval("(1.0..)") - end + it "returns true if the endpoints are == for endless ranges" do + eval("(1.0..)").should == eval("(1.0..)") end ruby_version_is "2.7" do diff --git a/spec/ruby/core/range/inspect_spec.rb b/spec/ruby/core/range/inspect_spec.rb index 6a206a0355..f49882e6ce 100644 --- a/spec/ruby/core/range/inspect_spec.rb +++ b/spec/ruby/core/range/inspect_spec.rb @@ -12,11 +12,9 @@ describe "Range#inspect" do (0.5..2.4).inspect.should == "0.5..2.4" end - ruby_version_is "2.6" do - it "works for endless ranges" do - eval("(1..)").inspect.should == "1.." - eval("(0.1...)").inspect.should == "0.1..." - end + it "works for endless ranges" do + eval("(1..)").inspect.should == "1.." + eval("(0.1...)").inspect.should == "0.1..." end ruby_version_is '2.7' do diff --git a/spec/ruby/core/range/last_spec.rb b/spec/ruby/core/range/last_spec.rb index 54884ba4d6..d7ef776b42 100644 --- a/spec/ruby/core/range/last_spec.rb +++ b/spec/ruby/core/range/last_spec.rb @@ -47,9 +47,7 @@ describe "Range#last" do -> { (2..3).last("1") }.should raise_error(TypeError) end - ruby_version_is "2.6" do - it "raises a RangeError when called on an endless range" do - -> { eval("(1..)").last }.should raise_error(RangeError) - end + it "raises a RangeError when called on an endless range" do + -> { eval("(1..)").last }.should raise_error(RangeError) end end diff --git a/spec/ruby/core/range/max_spec.rb b/spec/ruby/core/range/max_spec.rb index f2672170d9..a970144d66 100644 --- a/spec/ruby/core/range/max_spec.rb +++ b/spec/ruby/core/range/max_spec.rb @@ -46,10 +46,8 @@ describe "Range#max" do -> { (time_start...time_end).max }.should raise_error(TypeError) end - ruby_version_is "2.6" do - it "raises RangeError when called on an endless range" do - -> { eval("(1..)").max }.should raise_error(RangeError) - end + it "raises RangeError when called on an endless range" do + -> { eval("(1..)").max }.should raise_error(RangeError) end ruby_version_is "3.0" do diff --git a/spec/ruby/core/range/min_spec.rb b/spec/ruby/core/range/min_spec.rb index ffd40f3a07..6e56cc733b 100644 --- a/spec/ruby/core/range/min_spec.rb +++ b/spec/ruby/core/range/min_spec.rb @@ -39,11 +39,9 @@ describe "Range#min" do (time_start...time_end).min.should equal(time_start) end - ruby_version_is "2.6" do - it "returns the start point for endless ranges" do - eval("(1..)").min.should == 1 - eval("(1.0...)").min.should == 1.0 - end + it "returns the start point for endless ranges" do + eval("(1..)").min.should == 1 + eval("(1.0...)").min.should == 1.0 end ruby_version_is "2.7" do @@ -86,9 +84,7 @@ describe "Range#min given a block" do (7...7).min {|x,y| x <=> y}.should be_nil end - ruby_version_is "2.6" do - it "raises RangeError when called with custom comparison method on an endless range" do - -> { eval("(1..)").min {|a, b| a} }.should raise_error(RangeError) - end + it "raises RangeError when called with custom comparison method on an endless range" do + -> { eval("(1..)").min {|a, b| a} }.should raise_error(RangeError) end end diff --git a/spec/ruby/core/range/minmax_spec.rb b/spec/ruby/core/range/minmax_spec.rb index fa0637ac56..1db9bfce38 100644 --- a/spec/ruby/core/range/minmax_spec.rb +++ b/spec/ruby/core/range/minmax_spec.rb @@ -1,6 +1,6 @@ require_relative '../../spec_helper' -# These specs use Range.new instead of the literal notation so they parse fine on Ruby < 2.6 +# These specs use Range.new instead of the literal notation for beginless Ranges so they parse fine on Ruby < 2.7 describe 'Range#minmax' do before(:each) do @x = mock('x') @@ -13,10 +13,10 @@ describe 'Range#minmax' do end describe 'on an inclusive range' do - ruby_version_is '2.6'...'2.7' do + ruby_version_is ''...'2.7' do it 'should try to iterate endlessly on an endless range' do @x.should_receive(:succ).once.and_return(@y) - range = Range.new(@x, nil) + range = (@x..) -> { range.minmax }.should raise_error(NoMethodError, /^undefined method `succ' for/) end @@ -26,7 +26,7 @@ describe 'Range#minmax' do it 'should raise RangeError on an endless range without iterating the range' do @x.should_not_receive(:succ) - range = Range.new(@x, nil) + range = (@x..) -> { range.minmax }.should raise_error(RangeError, 'cannot get the maximum of endless range') end @@ -96,11 +96,11 @@ describe 'Range#minmax' do end describe 'on an exclusive range' do - ruby_version_is '2.6'...'2.7' do + ruby_version_is ''...'2.7' do # Endless ranges introduced in 2.6 it 'should try to iterate endlessly on an endless range' do @x.should_receive(:succ).once.and_return(@y) - range = Range.new(@x, nil, true) + range = (@x...) -> { range.minmax }.should raise_error(NoMethodError, /^undefined method `succ' for/) end @@ -109,7 +109,7 @@ describe 'Range#minmax' do ruby_version_is '2.7' do it 'should raise RangeError on an endless range' do @x.should_not_receive(:succ) - range = Range.new(@x, nil, true) + range = (@x...) -> { range.minmax }.should raise_error(RangeError, 'cannot get the maximum of endless range') end diff --git a/spec/ruby/core/range/new_spec.rb b/spec/ruby/core/range/new_spec.rb index be10ff244e..a4de4963e7 100644 --- a/spec/ruby/core/range/new_spec.rb +++ b/spec/ruby/core/range/new_spec.rb @@ -62,24 +62,16 @@ describe "Range.new" do end end - ruby_version_is ""..."2.6" do - it "does not allow range without right boundary" do - -> { Range.new(1, nil) }.should raise_error(ArgumentError, /bad value for range/) - end + it "allows endless right boundary" do + range = Range.new(1, nil) + range.end.should == nil end - ruby_version_is "2.6" do - it "allows endless right boundary" do - range = Range.new(1, nil) - range.end.should == nil - end - - it "distinguishes ranges with included and excluded right boundary" do - range_exclude = Range.new(1, nil, true) - range_include = Range.new(1, nil, false) + it "distinguishes ranges with included and excluded right boundary" do + range_exclude = Range.new(1, nil, true) + range_include = Range.new(1, nil, false) - range_exclude.should_not == range_include - end + range_exclude.should_not == range_include end end end diff --git a/spec/ruby/core/range/percent_spec.rb b/spec/ruby/core/range/percent_spec.rb index 41badd4f72..5ec6770ddb 100644 --- a/spec/ruby/core/range/percent_spec.rb +++ b/spec/ruby/core/range/percent_spec.rb @@ -1,18 +1,16 @@ require_relative '../../spec_helper' -ruby_version_is "2.6" do - describe "Range#%" do - it "works as a Range#step" do - aseq = (1..10) % 2 - aseq.class.should == Enumerator::ArithmeticSequence - aseq.begin.should == 1 - aseq.end.should == 10 - aseq.step.should == 2 - aseq.to_a.should == [1, 3, 5, 7, 9] - end +describe "Range#%" do + it "works as a Range#step" do + aseq = (1..10) % 2 + aseq.class.should == Enumerator::ArithmeticSequence + aseq.begin.should == 1 + aseq.end.should == 10 + aseq.step.should == 2 + aseq.to_a.should == [1, 3, 5, 7, 9] + end - it "produces an arithmetic sequence with a percent sign in #inspect" do - ((1..10) % 2).inspect.should == "((1..10).%(2))" - end + it "produces an arithmetic sequence with a percent sign in #inspect" do + ((1..10) % 2).inspect.should == "((1..10).%(2))" end end diff --git a/spec/ruby/core/range/shared/cover.rb b/spec/ruby/core/range/shared/cover.rb index e04682ba71..f3c7d22668 100644 --- a/spec/ruby/core/range/shared/cover.rb +++ b/spec/ruby/core/range/shared/cover.rb @@ -93,63 +93,61 @@ describe :range_cover, shared: true do end describe :range_cover_subrange, shared: true do - ruby_version_is "2.6" do - context "range argument" do - it "accepts range argument" do - (0..10).send(@method, (3..7)).should be_true - (0..10).send(@method, (3..15)).should be_false - (0..10).send(@method, (-2..7)).should be_false - - (1.1..7.9).send(@method, (2.5..6.5)).should be_true - (1.1..7.9).send(@method, (2.5..8.5)).should be_false - (1.1..7.9).send(@method, (0.5..6.5)).should be_false - - ('c'..'i').send(@method, ('d'..'f')).should be_true - ('c'..'i').send(@method, ('d'..'z')).should be_false - ('c'..'i').send(@method, ('a'..'f')).should be_false - - range_10_100 = RangeSpecs::TenfoldSucc.new(10)..RangeSpecs::TenfoldSucc.new(100) - range_20_90 = RangeSpecs::TenfoldSucc.new(20)..RangeSpecs::TenfoldSucc.new(90) - range_20_110 = RangeSpecs::TenfoldSucc.new(20)..RangeSpecs::TenfoldSucc.new(110) - range_0_90 = RangeSpecs::TenfoldSucc.new(0)..RangeSpecs::TenfoldSucc.new(90) - - range_10_100.send(@method, range_20_90).should be_true - range_10_100.send(@method, range_20_110).should be_false - range_10_100.send(@method, range_0_90).should be_false - end + context "range argument" do + it "accepts range argument" do + (0..10).send(@method, (3..7)).should be_true + (0..10).send(@method, (3..15)).should be_false + (0..10).send(@method, (-2..7)).should be_false + + (1.1..7.9).send(@method, (2.5..6.5)).should be_true + (1.1..7.9).send(@method, (2.5..8.5)).should be_false + (1.1..7.9).send(@method, (0.5..6.5)).should be_false + + ('c'..'i').send(@method, ('d'..'f')).should be_true + ('c'..'i').send(@method, ('d'..'z')).should be_false + ('c'..'i').send(@method, ('a'..'f')).should be_false + + range_10_100 = RangeSpecs::TenfoldSucc.new(10)..RangeSpecs::TenfoldSucc.new(100) + range_20_90 = RangeSpecs::TenfoldSucc.new(20)..RangeSpecs::TenfoldSucc.new(90) + range_20_110 = RangeSpecs::TenfoldSucc.new(20)..RangeSpecs::TenfoldSucc.new(110) + range_0_90 = RangeSpecs::TenfoldSucc.new(0)..RangeSpecs::TenfoldSucc.new(90) + + range_10_100.send(@method, range_20_90).should be_true + range_10_100.send(@method, range_20_110).should be_false + range_10_100.send(@method, range_0_90).should be_false + end - it "supports boundaries of different comparable types" do - (0..10).send(@method, (3.1..7.9)).should be_true - (0..10).send(@method, (3.1..15.9)).should be_false - (0..10).send(@method, (-2.1..7.9)).should be_false - end + it "supports boundaries of different comparable types" do + (0..10).send(@method, (3.1..7.9)).should be_true + (0..10).send(@method, (3.1..15.9)).should be_false + (0..10).send(@method, (-2.1..7.9)).should be_false + end - it "returns false if types are not comparable" do - (0..10).send(@method, ('a'..'z')).should be_false - (0..10).send(@method, (RangeSpecs::TenfoldSucc.new(0)..RangeSpecs::TenfoldSucc.new(100))).should be_false - end + it "returns false if types are not comparable" do + (0..10).send(@method, ('a'..'z')).should be_false + (0..10).send(@method, (RangeSpecs::TenfoldSucc.new(0)..RangeSpecs::TenfoldSucc.new(100))).should be_false + end - it "honors exclusion of right boundary (:exclude_end option)" do - # Integer - (0..10).send(@method, (0..10)).should be_true - (0...10).send(@method, (0...10)).should be_true + it "honors exclusion of right boundary (:exclude_end option)" do + # Integer + (0..10).send(@method, (0..10)).should be_true + (0...10).send(@method, (0...10)).should be_true - (0..10).send(@method, (0...10)).should be_true - (0...10).send(@method, (0..10)).should be_false + (0..10).send(@method, (0...10)).should be_true + (0...10).send(@method, (0..10)).should be_false - (0...11).send(@method, (0..10)).should be_true - (0..10).send(@method, (0...11)).should be_true + (0...11).send(@method, (0..10)).should be_true + (0..10).send(@method, (0...11)).should be_true - # Float - (0..10.1).send(@method, (0..10.1)).should be_true - (0...10.1).send(@method, (0...10.1)).should be_true + # Float + (0..10.1).send(@method, (0..10.1)).should be_true + (0...10.1).send(@method, (0...10.1)).should be_true - (0..10.1).send(@method, (0...10.1)).should be_true - (0...10.1).send(@method, (0..10.1)).should be_false + (0..10.1).send(@method, (0...10.1)).should be_true + (0...10.1).send(@method, (0..10.1)).should be_false - (0...11.1).send(@method, (0..10.1)).should be_true - (0..10.1).send(@method, (0...11.1)).should be_false - end + (0...11.1).send(@method, (0..10.1)).should be_true + (0..10.1).send(@method, (0...11.1)).should be_false end end diff --git a/spec/ruby/core/range/shared/cover_and_include.rb b/spec/ruby/core/range/shared/cover_and_include.rb index 0267e3ccb0..e978e39af5 100644 --- a/spec/ruby/core/range/shared/cover_and_include.rb +++ b/spec/ruby/core/range/shared/cover_and_include.rb @@ -19,11 +19,9 @@ describe :range_cover_and_include, shared: true do (0.5...2.4).send(@method, 2.4).should == false end - ruby_version_is "2.6" do - it "returns true if other is an element of self for endless ranges" do - eval("(1..)").send(@method, 2.4).should == true - eval("(0.5...)").send(@method, 2.4).should == true - end + it "returns true if other is an element of self for endless ranges" do + eval("(1..)").send(@method, 2.4).should == true + eval("(0.5...)").send(@method, 2.4).should == true end ruby_version_is "2.7" do diff --git a/spec/ruby/core/range/shared/equal_value.rb b/spec/ruby/core/range/shared/equal_value.rb index 8872b4efc0..363c6be558 100644 --- a/spec/ruby/core/range/shared/equal_value.rb +++ b/spec/ruby/core/range/shared/equal_value.rb @@ -43,11 +43,9 @@ describe :range_eql, shared: true do a.send(@method, b).should == true end - ruby_version_is "2.6" do - it "works for endless Ranges" do - eval("(1..)").send(@method, eval("(1..)")).should == true - eval("(0.5...)").send(@method, eval("(0.5...)")).should == true - eval("(1..)").send(@method, eval("(1...)")).should == false - end + it "works for endless Ranges" do + eval("(1..)").send(@method, eval("(1..)")).should == true + eval("(0.5...)").send(@method, eval("(0.5...)")).should == true + eval("(1..)").send(@method, eval("(1...)")).should == false end end diff --git a/spec/ruby/core/range/size_spec.rb b/spec/ruby/core/range/size_spec.rb index 4bf525e541..0019c5ff00 100644 --- a/spec/ruby/core/range/size_spec.rb +++ b/spec/ruby/core/range/size_spec.rb @@ -24,16 +24,14 @@ describe "Range#size" do (-Float::INFINITY..Float::INFINITY).size.should == Float::INFINITY end - ruby_version_is "2.6" do - it 'returns Float::INFINITY for endless ranges if the start is numeric' do - eval("(1..)").size.should == Float::INFINITY - eval("(0.5...)").size.should == Float::INFINITY - end + it 'returns Float::INFINITY for endless ranges if the start is numeric' do + eval("(1..)").size.should == Float::INFINITY + eval("(0.5...)").size.should == Float::INFINITY + end - it 'returns nil for endless ranges if the start is not numeric' do - eval("('z'..)").size.should == nil - eval("([]...)").size.should == nil - end + it 'returns nil for endless ranges if the start is not numeric' do + eval("('z'..)").size.should == nil + eval("([]...)").size.should == nil end ruby_version_is "2.7" do diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb index be4b482654..624fa71f5f 100644 --- a/spec/ruby/core/range/step_spec.rb +++ b/spec/ruby/core/range/step_spec.rb @@ -282,98 +282,96 @@ describe "Range#step" do end end - ruby_version_is "2.6" do - describe "with an endless range" do - describe "and Integer values" do - it "yield Integer values incremented by 1 when not passed a step" do - eval("(-2..)").step { |x| break if x > 2; ScratchPad << x } - ScratchPad.recorded.should eql([-2, -1, 0, 1, 2]) - - ScratchPad.record [] - eval("(-2...)").step { |x| break if x > 2; ScratchPad << x } - ScratchPad.recorded.should eql([-2, -1, 0, 1, 2]) - end + describe "with an endless range" do + describe "and Integer values" do + it "yield Integer values incremented by 1 when not passed a step" do + eval("(-2..)").step { |x| break if x > 2; ScratchPad << x } + ScratchPad.recorded.should eql([-2, -1, 0, 1, 2]) - it "yields Integer values incremented by an Integer step" do - eval("(-5..)").step(2) { |x| break if x > 3; ScratchPad << x } - ScratchPad.recorded.should eql([-5, -3, -1, 1, 3]) + ScratchPad.record [] + eval("(-2...)").step { |x| break if x > 2; ScratchPad << x } + ScratchPad.recorded.should eql([-2, -1, 0, 1, 2]) + end - ScratchPad.record [] - eval("(-5...)").step(2) { |x| break if x > 3; ScratchPad << x } - ScratchPad.recorded.should eql([-5, -3, -1, 1, 3]) - end + it "yields Integer values incremented by an Integer step" do + eval("(-5..)").step(2) { |x| break if x > 3; ScratchPad << x } + ScratchPad.recorded.should eql([-5, -3, -1, 1, 3]) - it "yields Float values incremented by a Float step" do - eval("(-2..)").step(1.5) { |x| break if x > 1.0; ScratchPad << x } - ScratchPad.recorded.should eql([-2.0, -0.5, 1.0]) + ScratchPad.record [] + eval("(-5...)").step(2) { |x| break if x > 3; ScratchPad << x } + ScratchPad.recorded.should eql([-5, -3, -1, 1, 3]) + end - ScratchPad.record [] - eval("(-2..)").step(1.5) { |x| break if x > 1.0; ScratchPad << x } - ScratchPad.recorded.should eql([-2.0, -0.5, 1.0]) - end + it "yields Float values incremented by a Float step" do + eval("(-2..)").step(1.5) { |x| break if x > 1.0; ScratchPad << x } + ScratchPad.recorded.should eql([-2.0, -0.5, 1.0]) + + ScratchPad.record [] + eval("(-2..)").step(1.5) { |x| break if x > 1.0; ScratchPad << x } + ScratchPad.recorded.should eql([-2.0, -0.5, 1.0]) end + end - describe "and Float values" do - it "yields Float values incremented by 1 and less than end when not passed a step" do - eval("(-2.0..)").step { |x| break if x > 1.5; ScratchPad << x } - ScratchPad.recorded.should eql([-2.0, -1.0, 0.0, 1.0]) + describe "and Float values" do + it "yields Float values incremented by 1 and less than end when not passed a step" do + eval("(-2.0..)").step { |x| break if x > 1.5; ScratchPad << x } + ScratchPad.recorded.should eql([-2.0, -1.0, 0.0, 1.0]) - ScratchPad.record [] - eval("(-2.0...)").step { |x| break if x > 1.5; ScratchPad << x } - ScratchPad.recorded.should eql([-2.0, -1.0, 0.0, 1.0]) - end + ScratchPad.record [] + eval("(-2.0...)").step { |x| break if x > 1.5; ScratchPad << x } + ScratchPad.recorded.should eql([-2.0, -1.0, 0.0, 1.0]) + end - it "yields Float values incremented by an Integer step" do - eval("(-5.0..)").step(2) { |x| break if x > 3.5; ScratchPad << x } - ScratchPad.recorded.should eql([-5.0, -3.0, -1.0, 1.0, 3.0]) + it "yields Float values incremented by an Integer step" do + eval("(-5.0..)").step(2) { |x| break if x > 3.5; ScratchPad << x } + ScratchPad.recorded.should eql([-5.0, -3.0, -1.0, 1.0, 3.0]) - ScratchPad.record [] - eval("(-5.0...)").step(2) { |x| break if x > 3.5; ScratchPad << x } - ScratchPad.recorded.should eql([-5.0, -3.0, -1.0, 1.0, 3.0]) - end + ScratchPad.record [] + eval("(-5.0...)").step(2) { |x| break if x > 3.5; ScratchPad << x } + ScratchPad.recorded.should eql([-5.0, -3.0, -1.0, 1.0, 3.0]) + end - it "yields Float values incremented by a Float step" do - eval("(-1.0..)").step(0.5) { |x| break if x > 0.6; ScratchPad << x } - ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5]) + it "yields Float values incremented by a Float step" do + eval("(-1.0..)").step(0.5) { |x| break if x > 0.6; ScratchPad << x } + ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5]) - ScratchPad.record [] - eval("(-1.0...)").step(0.5) { |x| break if x > 0.6; ScratchPad << x } - ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5]) - end + ScratchPad.record [] + eval("(-1.0...)").step(0.5) { |x| break if x > 0.6; ScratchPad << x } + ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5]) + end - it "handles infinite values at the start" do - eval("(-Float::INFINITY..)").step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 } - ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY]) + it "handles infinite values at the start" do + eval("(-Float::INFINITY..)").step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 } + ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY]) - ScratchPad.record [] - eval("(-Float::INFINITY...)").step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 } - ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY]) - end + ScratchPad.record [] + eval("(-Float::INFINITY...)").step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 } + ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY]) end + end - describe "and String values" do - it "yields String values incremented by #succ and less than or equal to end when not passed a step" do - eval("('A'..)").step { |x| break if x > "D"; ScratchPad << x } - ScratchPad.recorded.should == ["A", "B", "C", "D"] + describe "and String values" do + it "yields String values incremented by #succ and less than or equal to end when not passed a step" do + eval("('A'..)").step { |x| break if x > "D"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "B", "C", "D"] - ScratchPad.record [] - eval("('A'...)").step { |x| break if x > "D"; ScratchPad << x } - ScratchPad.recorded.should == ["A", "B", "C", "D"] - end + ScratchPad.record [] + eval("('A'...)").step { |x| break if x > "D"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "B", "C", "D"] + end - it "yields String values incremented by #succ called Integer step times" do - eval("('A'..)").step(2) { |x| break if x > "F"; ScratchPad << x } - ScratchPad.recorded.should == ["A", "C", "E"] + it "yields String values incremented by #succ called Integer step times" do + eval("('A'..)").step(2) { |x| break if x > "F"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "C", "E"] - ScratchPad.record [] - eval("('A'...)").step(2) { |x| break if x > "F"; ScratchPad << x } - ScratchPad.recorded.should == ["A", "C", "E"] - end + ScratchPad.record [] + eval("('A'...)").step(2) { |x| break if x > "F"; ScratchPad << x } + ScratchPad.recorded.should == ["A", "C", "E"] + end - it "raises a TypeError when passed a Float step" do - -> { eval("('A'..)").step(2.0) { } }.should raise_error(TypeError) - -> { eval("('A'...)").step(2.0) { } }.should raise_error(TypeError) - end + it "raises a TypeError when passed a Float step" do + -> { eval("('A'..)").step(2.0) { } }.should raise_error(TypeError) + -> { eval("('A'...)").step(2.0) { } }.should raise_error(TypeError) end end end @@ -416,24 +414,7 @@ describe "Range#step" do end end - ruby_version_is ""..."2.6" do - it "raises an ArgumentError if step is 0" do - enum = (-1..1).step(0) - -> { enum.size }.should raise_error(ArgumentError) - end - - it "raises an ArgumentError if step is 0.0" do - enum = (-1..1).step(0.0) - -> { enum.size }.should raise_error(ArgumentError) - end - - it "raises an ArgumentError if step is negative" do - enum = (-1..1).step(-2) - -> { enum.size }.should raise_error(ArgumentError) - end - end - - ruby_version_is "2.6"..."3.0" do + ruby_version_is ""..."3.0" do it "returns Float::INFINITY for zero step" do (-1..1).step(0).size.should == Float::INFINITY (-1..1).step(0.0).size.should == Float::INFINITY @@ -453,11 +434,9 @@ describe "Range#step" do (-5...5).step(2).size.should == 5 end - ruby_version_is "2.6" do - it "returns the ceil of range size divided by the number of steps even if step is negative" do - (-1..1).step(-1).size.should == 0 - (1..-1).step(-1).size.should == 3 - end + it "returns the ceil of range size divided by the number of steps even if step is negative" do + (-1..1).step(-1).size.should == 0 + (1..-1).step(-1).size.should == 3 end it "returns the correct number of steps when one of the arguments is a float" do @@ -496,23 +475,15 @@ describe "Range#step" do end describe "type" do - ruby_version_is ""..."2.6" do - it "returns an instance of Enumerator" do - (1..10).step.class.should == Enumerator + context "when both begin and end are numerics" do + it "returns an instance of Enumerator::ArithmeticSequence" do + (1..10).step.class.should == Enumerator::ArithmeticSequence end end - ruby_version_is "2.6" do - context "when both begin and end are numerics" do - it "returns an instance of Enumerator::ArithmeticSequence" do - (1..10).step.class.should == Enumerator::ArithmeticSequence - end - end - - context "when begin and end are not numerics" do - it "returns an instance of Enumerator" do - ("a".."z").step.class.should == Enumerator - end + context "when begin and end are not numerics" do + it "returns an instance of Enumerator" do + ("a".."z").step.class.should == Enumerator end end end diff --git a/spec/ruby/core/range/to_a_spec.rb b/spec/ruby/core/range/to_a_spec.rb index 9a1352b7b0..52ebc02941 100644 --- a/spec/ruby/core/range/to_a_spec.rb +++ b/spec/ruby/core/range/to_a_spec.rb @@ -29,10 +29,8 @@ describe "Range#to_a" do ('Σ'..'Ω').to_a.should == ["Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω"] end - ruby_version_is "2.6" do - it "throws an exception for endless ranges" do - -> { eval("(1..)").to_a }.should raise_error(RangeError) - end + it "throws an exception for endless ranges" do + -> { eval("(1..)").to_a }.should raise_error(RangeError) end ruby_version_is "2.7" do diff --git a/spec/ruby/core/range/to_s_spec.rb b/spec/ruby/core/range/to_s_spec.rb index 59672da822..581c2e7d90 100644 --- a/spec/ruby/core/range/to_s_spec.rb +++ b/spec/ruby/core/range/to_s_spec.rb @@ -11,11 +11,9 @@ describe "Range#to_s" do (0.5..2.4).to_s.should == "0.5..2.4" end - ruby_version_is "2.6" do - it "can show endless ranges" do - eval("(1..)").to_s.should == "1.." - eval("(1.0...)").to_s.should == "1.0..." - end + it "can show endless ranges" do + eval("(1..)").to_s.should == "1.." + eval("(1.0...)").to_s.should == "1.0..." end ruby_version_is "2.7" do diff --git a/spec/ruby/core/string/gsub_spec.rb b/spec/ruby/core/string/gsub_spec.rb index 6789199ff3..ad41b7e0a2 100644 --- a/spec/ruby/core/string/gsub_spec.rb +++ b/spec/ruby/core/string/gsub_spec.rb @@ -594,6 +594,14 @@ describe "String#gsub with pattern and without replacement and block" do end end +describe "String#gsub with a string pattern" do + it "handles multibyte characters" do + "é".gsub("é", "â").should == "â" + "aé".gsub("é", "â").should == "aâ" + "éa".gsub("é", "â").should == "âa" + end +end + describe "String#gsub! with pattern and replacement" do it "modifies self in place and returns self" do a = "hello" diff --git a/spec/ruby/core/string/index_spec.rb b/spec/ruby/core/string/index_spec.rb index 8d2c8af193..5d77a88e4e 100644 --- a/spec/ruby/core/string/index_spec.rb +++ b/spec/ruby/core/string/index_spec.rb @@ -146,6 +146,7 @@ describe "String#index with String" do it "returns the character index after offset" do "われわれ".index("わ", 1).should == 2 + "ありがとうありがとう".index("が", 3).should == 7 end it "returns the character index after a partial first match" do diff --git a/spec/ruby/core/string/scrub_spec.rb b/spec/ruby/core/string/scrub_spec.rb index b513acfb70..5c67ad01bc 100644 --- a/spec/ruby/core/string/scrub_spec.rb +++ b/spec/ruby/core/string/scrub_spec.rb @@ -119,4 +119,10 @@ describe "String#scrub!" do input.scrub! input.instance_variable_get(:@a).should == 'b' end + + it "accepts a frozen string as a replacement" do + input = "a\xE2" + input.scrub!('.'.freeze) + input.should == 'a.' + end end diff --git a/spec/ruby/core/string/shared/slice.rb b/spec/ruby/core/string/shared/slice.rb index a674e0b6ef..1db8fd6730 100644 --- a/spec/ruby/core/string/shared/slice.rb +++ b/spec/ruby/core/string/shared/slice.rb @@ -327,13 +327,11 @@ describe :string_slice_range, shared: true do -> { "hello".send(@method, 0..bignum_value) }.should raise_error(RangeError) end - ruby_version_is "2.6" do - it "works with endless ranges" do - "hello there".send(@method, eval("(2..)")).should == "llo there" - "hello there".send(@method, eval("(2...)")).should == "llo there" - "hello there".send(@method, eval("(-4..)")).should == "here" - "hello there".send(@method, eval("(-4...)")).should == "here" - end + it "works with endless ranges" do + "hello there".send(@method, eval("(2..)")).should == "llo there" + "hello there".send(@method, eval("(2...)")).should == "llo there" + "hello there".send(@method, eval("(-4..)")).should == "here" + "hello there".send(@method, eval("(-4...)")).should == "here" end ruby_version_is "2.7" do diff --git a/spec/ruby/core/string/split_spec.rb b/spec/ruby/core/string/split_spec.rb index e3641b33e0..a373be360d 100644 --- a/spec/ruby/core/string/split_spec.rb +++ b/spec/ruby/core/string/split_spec.rb @@ -471,108 +471,106 @@ describe "String#split with Regexp" do results.should == [%w[a b c d e]] * 10 end - ruby_version_is "2.6" do - context "when a block is given" do - it "yields each split substring with default pattern" do - a = [] - returned_object = "chunky bacon".split { |str| a << str.capitalize } + context "when a block is given" do + it "yields each split substring with default pattern" do + a = [] + returned_object = "chunky bacon".split { |str| a << str.capitalize } - returned_object.should == "chunky bacon" - a.should == ["Chunky", "Bacon"] - end + returned_object.should == "chunky bacon" + a.should == ["Chunky", "Bacon"] + end - it "yields each split substring with default pattern for a non-ASCII string" do - a = [] - returned_object = "l'été arrive bientôt".split { |str| a << str } + it "yields each split substring with default pattern for a non-ASCII string" do + a = [] + returned_object = "l'été arrive bientôt".split { |str| a << str } - returned_object.should == "l'été arrive bientôt" - a.should == ["l'été", "arrive", "bientôt"] - end + returned_object.should == "l'été arrive bientôt" + a.should == ["l'été", "arrive", "bientôt"] + end - it "yields the string when limit is 1" do - a = [] - returned_object = "chunky bacon".split("", 1) { |str| a << str.capitalize } + it "yields the string when limit is 1" do + a = [] + returned_object = "chunky bacon".split("", 1) { |str| a << str.capitalize } - returned_object.should == "chunky bacon" - a.should == ["Chunky bacon"] - end + returned_object.should == "chunky bacon" + a.should == ["Chunky bacon"] + end - it "yields each split letter" do - a = [] - returned_object = "chunky".split("", 0) { |str| a << str.capitalize } + it "yields each split letter" do + a = [] + returned_object = "chunky".split("", 0) { |str| a << str.capitalize } - returned_object.should == "chunky" - a.should == %w(C H U N K Y) - end + returned_object.should == "chunky" + a.should == %w(C H U N K Y) + end - it "yields each split substring with a pattern" do - a = [] - returned_object = "chunky-bacon".split("-", 0) { |str| a << str.capitalize } + it "yields each split substring with a pattern" do + a = [] + returned_object = "chunky-bacon".split("-", 0) { |str| a << str.capitalize } - returned_object.should == "chunky-bacon" - a.should == ["Chunky", "Bacon"] - end + returned_object.should == "chunky-bacon" + a.should == ["Chunky", "Bacon"] + end - it "yields each split substring with empty regexp pattern" do - a = [] - returned_object = "chunky".split(//) { |str| a << str.capitalize } + it "yields each split substring with empty regexp pattern" do + a = [] + returned_object = "chunky".split(//) { |str| a << str.capitalize } - returned_object.should == "chunky" - a.should == %w(C H U N K Y) - end + returned_object.should == "chunky" + a.should == %w(C H U N K Y) + end - it "yields each split substring with empty regexp pattern and limit" do - a = [] - returned_object = "chunky".split(//, 3) { |str| a << str.capitalize } + it "yields each split substring with empty regexp pattern and limit" do + a = [] + returned_object = "chunky".split(//, 3) { |str| a << str.capitalize } - returned_object.should == "chunky" - a.should == %w(C H Unky) - end + returned_object.should == "chunky" + a.should == %w(C H Unky) + end - it "yields each split substring with a regexp pattern" do - a = [] - returned_object = "chunky:bacon".split(/:/) { |str| a << str.capitalize } + it "yields each split substring with a regexp pattern" do + a = [] + returned_object = "chunky:bacon".split(/:/) { |str| a << str.capitalize } - returned_object.should == "chunky:bacon" - a.should == ["Chunky", "Bacon"] - end + returned_object.should == "chunky:bacon" + a.should == ["Chunky", "Bacon"] + end - it "returns a string as is (and doesn't call block) if it is empty" do - a = [] - returned_object = "".split { |str| a << str.capitalize } + it "returns a string as is (and doesn't call block) if it is empty" do + a = [] + returned_object = "".split { |str| a << str.capitalize } - returned_object.should == "" - a.should == [] - end + returned_object.should == "" + a.should == [] end + end - describe "for a String subclass" do - ruby_version_is ''...'3.0' do - it "yields instances of the same subclass" do - a = [] - StringSpecs::MyString.new("a|b").split("|") { |str| a << str } - first, last = a + describe "for a String subclass" do + ruby_version_is ''...'3.0' do + it "yields instances of the same subclass" do + a = [] + StringSpecs::MyString.new("a|b").split("|") { |str| a << str } + first, last = a - first.should be_an_instance_of(StringSpecs::MyString) - first.should == "a" + first.should be_an_instance_of(StringSpecs::MyString) + first.should == "a" - last.should be_an_instance_of(StringSpecs::MyString) - last.should == "b" - end + last.should be_an_instance_of(StringSpecs::MyString) + last.should == "b" end + end - ruby_version_is '3.0' do - it "yields instances of String" do - a = [] - StringSpecs::MyString.new("a|b").split("|") { |str| a << str } - first, last = a + ruby_version_is '3.0' do + it "yields instances of String" do + a = [] + StringSpecs::MyString.new("a|b").split("|") { |str| a << str } + first, last = a - first.should be_an_instance_of(String) - first.should == "a" + first.should be_an_instance_of(String) + first.should == "a" - last.should be_an_instance_of(String) - last.should == "b" - end + last.should be_an_instance_of(String) + last.should == "b" end end end diff --git a/spec/ruby/core/string/uminus_spec.rb b/spec/ruby/core/string/uminus_spec.rb index 3a81b64126..800dca5044 100644 --- a/spec/ruby/core/string/uminus_spec.rb +++ b/spec/ruby/core/string/uminus_spec.rb @@ -31,43 +31,13 @@ describe 'String#-@' do (-"unfrozen string").should_not equal(-"another unfrozen string") end - ruby_version_is ""..."2.6" do - it "does not deduplicate already frozen strings" do - dynamic = %w(this string is frozen).join(' ').freeze + it "deduplicates frozen strings" do + dynamic = %w(this string is frozen).join(' ').freeze - dynamic.should_not equal("this string is frozen".freeze) + dynamic.should_not equal("this string is frozen".freeze) - (-dynamic).should_not equal("this string is frozen".freeze) - (-dynamic).should_not equal(-"this string is frozen".freeze) - (-dynamic).should == "this string is frozen" - end - - it "does not deduplicate tainted strings" do - dynamic = %w(this string is frozen).join(' ') - dynamic.taint - (-dynamic).should_not equal("this string is frozen".freeze) - (-dynamic).should_not equal(-"this string is frozen".freeze) - (-dynamic).should == "this string is frozen" - end - - it "does not deduplicate strings with additional instance variables" do - dynamic = %w(this string is frozen).join(' ') - dynamic.instance_variable_set(:@foo, :bar) - (-dynamic).should_not equal("this string is frozen".freeze) - (-dynamic).should_not equal(-"this string is frozen".freeze) - (-dynamic).should == "this string is frozen" - end - end - - ruby_version_is "2.6" do - it "deduplicates frozen strings" do - dynamic = %w(this string is frozen).join(' ').freeze - - dynamic.should_not equal("this string is frozen".freeze) - - (-dynamic).should equal("this string is frozen".freeze) - (-dynamic).should equal(-"this string is frozen".freeze) - end + (-dynamic).should equal("this string is frozen".freeze) + (-dynamic).should equal(-"this string is frozen".freeze) end ruby_version_is "3.0" do diff --git a/spec/ruby/core/struct/filter_spec.rb b/spec/ruby/core/struct/filter_spec.rb index 1105ed064a..0ccd8ad6b2 100644 --- a/spec/ruby/core/struct/filter_spec.rb +++ b/spec/ruby/core/struct/filter_spec.rb @@ -3,10 +3,8 @@ require_relative 'shared/select' require_relative 'shared/accessor' require_relative '../enumerable/shared/enumeratorized' -ruby_version_is "2.6" do - describe "Struct#filter" do - it_behaves_like :struct_select, :filter - it_behaves_like :struct_accessor, :filter - it_behaves_like :enumeratorized_with_origin_size, :filter, Struct.new(:foo).new - end +describe "Struct#filter" do + it_behaves_like :struct_select, :filter + it_behaves_like :struct_accessor, :filter + it_behaves_like :enumeratorized_with_origin_size, :filter, Struct.new(:foo).new end diff --git a/spec/ruby/core/struct/to_h_spec.rb b/spec/ruby/core/struct/to_h_spec.rb index b5f4e40701..bfb0af07ba 100644 --- a/spec/ruby/core/struct/to_h_spec.rb +++ b/spec/ruby/core/struct/to_h_spec.rb @@ -13,46 +13,44 @@ describe "Struct#to_h" do car.make.should == 'Ford' end - ruby_version_is "2.6" do - context "with block" do - it "converts [key, value] pairs returned by the block to a hash" do - car = StructClasses::Car.new('Ford', 'Ranger') - - h = car.to_h { |k, v| [k.to_s, "#{v}".downcase] } - h.should == { "make" => "ford", "model" => "ranger", "year" => "" } - end - - it "raises ArgumentError if block returns longer or shorter array" do - -> do - StructClasses::Car.new.to_h { |k, v| [k.to_s, "#{v}".downcase, 1] } - end.should raise_error(ArgumentError, /element has wrong array length/) - - -> do - StructClasses::Car.new.to_h { |k, v| [k] } - end.should raise_error(ArgumentError, /element has wrong array length/) - end - - it "raises TypeError if block returns something other than Array" do - -> do - StructClasses::Car.new.to_h { |k, v| "not-array" } - end.should raise_error(TypeError, /wrong element type String/) - end - - it "coerces returned pair to Array with #to_ary" do - x = mock('x') - x.stub!(:to_ary).and_return([:b, 'b']) - - StructClasses::Car.new.to_h { |k| x }.should == { :b => 'b' } - end - - it "does not coerce returned pair to Array with #to_a" do - x = mock('x') - x.stub!(:to_a).and_return([:b, 'b']) - - -> do - StructClasses::Car.new.to_h { |k| x } - end.should raise_error(TypeError, /wrong element type MockObject/) - end + context "with block" do + it "converts [key, value] pairs returned by the block to a hash" do + car = StructClasses::Car.new('Ford', 'Ranger') + + h = car.to_h { |k, v| [k.to_s, "#{v}".downcase] } + h.should == { "make" => "ford", "model" => "ranger", "year" => "" } + end + + it "raises ArgumentError if block returns longer or shorter array" do + -> do + StructClasses::Car.new.to_h { |k, v| [k.to_s, "#{v}".downcase, 1] } + end.should raise_error(ArgumentError, /element has wrong array length/) + + -> do + StructClasses::Car.new.to_h { |k, v| [k] } + end.should raise_error(ArgumentError, /element has wrong array length/) + end + + it "raises TypeError if block returns something other than Array" do + -> do + StructClasses::Car.new.to_h { |k, v| "not-array" } + end.should raise_error(TypeError, /wrong element type String/) + end + + it "coerces returned pair to Array with #to_ary" do + x = mock('x') + x.stub!(:to_ary).and_return([:b, 'b']) + + StructClasses::Car.new.to_h { |k| x }.should == { :b => 'b' } + end + + it "does not coerce returned pair to Array with #to_a" do + x = mock('x') + x.stub!(:to_a).and_return([:b, 'b']) + + -> do + StructClasses::Car.new.to_h { |k| x } + end.should raise_error(TypeError, /wrong element type MockObject/) end end end diff --git a/spec/ruby/core/thread/backtrace_locations_spec.rb b/spec/ruby/core/thread/backtrace_locations_spec.rb index 1f77e13378..237941c214 100644 --- a/spec/ruby/core/thread/backtrace_locations_spec.rb +++ b/spec/ruby/core/thread/backtrace_locations_spec.rb @@ -43,12 +43,10 @@ describe "Thread#backtrace_locations" do Thread.current.backtrace_locations(2..-2).map(&:to_s).should == Thread.current.backtrace_locations[2..-2].map(&:to_s) end - ruby_version_is "2.6" do - it "can be called with an endless range" do - locations1 = Thread.current.backtrace_locations(0) - locations2 = Thread.current.backtrace_locations(eval("(2..)")) - locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s) - end + it "can be called with an endless range" do + locations1 = Thread.current.backtrace_locations(0) + locations2 = Thread.current.backtrace_locations(eval("(2..)")) + locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s) end ruby_version_is "2.7" do diff --git a/spec/ruby/core/thread/shared/wakeup.rb b/spec/ruby/core/thread/shared/wakeup.rb index f111edf0fd..6f010fea25 100644 --- a/spec/ruby/core/thread/shared/wakeup.rb +++ b/spec/ruby/core/thread/shared/wakeup.rb @@ -36,7 +36,7 @@ describe :thread_wakeup, shared: true do it "does not result in a deadlock" do t = Thread.new do - 100.times { Thread.stop } + 10.times { Thread.stop } end while t.status @@ -47,6 +47,7 @@ describe :thread_wakeup, shared: true do t.status.should == false end Thread.pass + sleep 0.001 end t.status.should == false diff --git a/spec/ruby/core/time/at_spec.rb b/spec/ruby/core/time/at_spec.rb index ff43537dcc..2cc46ab8c9 100644 --- a/spec/ruby/core/time/at_spec.rb +++ b/spec/ruby/core/time/at_spec.rb @@ -218,55 +218,53 @@ describe "Time.at" do end end - ruby_version_is "2.6" do - describe ":in keyword argument" do - before do - @epoch_time = Time.now.to_i - end + describe ":in keyword argument" do + before do + @epoch_time = Time.now.to_i + end - it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do - time = Time.at(@epoch_time, in: "+05:00") + it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do + time = Time.at(@epoch_time, in: "+05:00") - time.utc_offset.should == 5*60*60 - time.zone.should == nil - time.to_i.should == @epoch_time + time.utc_offset.should == 5*60*60 + time.zone.should == nil + time.to_i.should == @epoch_time - time = Time.at(@epoch_time, in: "-09:00") + time = Time.at(@epoch_time, in: "-09:00") - time.utc_offset.should == -9*60*60 - time.zone.should == nil - time.to_i.should == @epoch_time - end + time.utc_offset.should == -9*60*60 + time.zone.should == nil + time.to_i.should == @epoch_time + end - it "could be UTC offset as a number of seconds" do - time = Time.at(@epoch_time, in: 5*60*60) + it "could be UTC offset as a number of seconds" do + time = Time.at(@epoch_time, in: 5*60*60) - time.utc_offset.should == 5*60*60 - time.zone.should == nil - time.to_i.should == @epoch_time + time.utc_offset.should == 5*60*60 + time.zone.should == nil + time.to_i.should == @epoch_time - time = Time.at(@epoch_time, in: -9*60*60) + time = Time.at(@epoch_time, in: -9*60*60) - time.utc_offset.should == -9*60*60 - time.zone.should == nil - time.to_i.should == @epoch_time - end + time.utc_offset.should == -9*60*60 + time.zone.should == nil + time.to_i.should == @epoch_time + end - it "could be a timezone object" do - zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo") - time = Time.at(@epoch_time, in: zone) + it "could be a timezone object" do + zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo") + time = Time.at(@epoch_time, in: zone) - time.utc_offset.should == 5*3600+30*60 - time.zone.should == zone - time.to_i.should == @epoch_time + time.utc_offset.should == 5*3600+30*60 + time.zone.should == zone + time.to_i.should == @epoch_time - zone = TimeSpecs::TimezoneWithName.new(name: "PST") - time = Time.at(@epoch_time, in: zone) + zone = TimeSpecs::TimezoneWithName.new(name: "PST") + time = Time.at(@epoch_time, in: zone) - time.utc_offset.should == -9*60*60 - time.zone.should == zone - time.to_i.should == @epoch_time - end + time.utc_offset.should == -9*60*60 + time.zone.should == zone + time.to_i.should == @epoch_time end end end diff --git a/spec/ruby/core/time/getlocal_spec.rb b/spec/ruby/core/time/getlocal_spec.rb index 7196577dab..926a6dbf45 100644 --- a/spec/ruby/core/time/getlocal_spec.rb +++ b/spec/ruby/core/time/getlocal_spec.rb @@ -97,71 +97,69 @@ describe "Time#getlocal" do -> { t.getlocal(86400) }.should raise_error(ArgumentError) end - ruby_version_is "2.6" do - describe "with a timezone argument" do - it "returns a Time in the timezone" do - zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) - time = Time.utc(2000, 1, 1, 12, 0, 0).getlocal(zone) - - time.zone.should == zone - time.utc_offset.should == 5*3600+30*60 - end + describe "with a timezone argument" do + it "returns a Time in the timezone" do + zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) + time = Time.utc(2000, 1, 1, 12, 0, 0).getlocal(zone) - it "accepts timezone argument that must have #local_to_utc and #utc_to_local methods" do - zone = Object.new - def zone.utc_to_local(time) - time - end - def zone.local_to_utc(time) - time - end + time.zone.should == zone + time.utc_offset.should == 5*3600+30*60 + end - -> { - Time.utc(2000, 1, 1, 12, 0, 0).getlocal(zone).should be_kind_of(Time) - }.should_not raise_error + it "accepts timezone argument that must have #local_to_utc and #utc_to_local methods" do + zone = Object.new + def zone.utc_to_local(time) + time + end + def zone.local_to_utc(time) + time end - it "raises TypeError if timezone does not implement #utc_to_local method" do - zone = Object.new - def zone.local_to_utc(time) - time - end + -> { + Time.utc(2000, 1, 1, 12, 0, 0).getlocal(zone).should be_kind_of(Time) + }.should_not raise_error + end - -> { - Time.utc(2000, 1, 1, 12, 0, 0).getlocal(zone) - }.should raise_error(TypeError, /can't convert \w+ into an exact number/) + it "raises TypeError if timezone does not implement #utc_to_local method" do + zone = Object.new + def zone.local_to_utc(time) + time end - it "does not raise exception if timezone does not implement #local_to_utc method" do - zone = Object.new - def zone.utc_to_local(time) - time - end + -> { + Time.utc(2000, 1, 1, 12, 0, 0).getlocal(zone) + }.should raise_error(TypeError, /can't convert \w+ into an exact number/) + end - -> { - Time.utc(2000, 1, 1, 12, 0, 0).getlocal(zone).should be_kind_of(Time) - }.should_not raise_error + it "does not raise exception if timezone does not implement #local_to_utc method" do + zone = Object.new + def zone.utc_to_local(time) + time end - context "subject's class implements .find_timezone method" do - it "calls .find_timezone to build a time object if passed zone name as a timezone argument" do - time = TimeSpecs::TimeWithFindTimezone.utc(2000, 1, 1, 12, 0, 0).getlocal("Asia/Colombo") - time.zone.should be_kind_of TimeSpecs::TimezoneWithName - time.zone.name.should == "Asia/Colombo" + -> { + Time.utc(2000, 1, 1, 12, 0, 0).getlocal(zone).should be_kind_of(Time) + }.should_not raise_error + end + + context "subject's class implements .find_timezone method" do + it "calls .find_timezone to build a time object if passed zone name as a timezone argument" do + time = TimeSpecs::TimeWithFindTimezone.utc(2000, 1, 1, 12, 0, 0).getlocal("Asia/Colombo") + time.zone.should be_kind_of TimeSpecs::TimezoneWithName + time.zone.name.should == "Asia/Colombo" - time = TimeSpecs::TimeWithFindTimezone.utc(2000, 1, 1, 12, 0, 0).getlocal("some invalid zone name") - time.zone.should be_kind_of TimeSpecs::TimezoneWithName - time.zone.name.should == "some invalid zone name" - end + time = TimeSpecs::TimeWithFindTimezone.utc(2000, 1, 1, 12, 0, 0).getlocal("some invalid zone name") + time.zone.should be_kind_of TimeSpecs::TimezoneWithName + time.zone.name.should == "some invalid zone name" + end - it "does not call .find_timezone if passed any not string/numeric/timezone timezone argument" do - [Object.new, [], {}, :"some zone"].each do |zone| - time = TimeSpecs::TimeWithFindTimezone.utc(2000, 1, 1, 12, 0, 0) + it "does not call .find_timezone if passed any not string/numeric/timezone timezone argument" do + [Object.new, [], {}, :"some zone"].each do |zone| + time = TimeSpecs::TimeWithFindTimezone.utc(2000, 1, 1, 12, 0, 0) - -> { - time.getlocal(zone) - }.should raise_error(TypeError, /can't convert \w+ into an exact number/) - end + -> { + time.getlocal(zone) + }.should raise_error(TypeError, /can't convert \w+ into an exact number/) end end end diff --git a/spec/ruby/core/time/minus_spec.rb b/spec/ruby/core/time/minus_spec.rb index 995dac8462..8449778465 100644 --- a/spec/ruby/core/time/minus_spec.rb +++ b/spec/ruby/core/time/minus_spec.rb @@ -98,14 +98,12 @@ describe "Time#-" do time_with_zone.zone.should == (time_with_zone - 1).zone end - ruby_version_is "2.6" do - context "zone is a timezone object" do - it "preserves time zone" do - zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) - time = Time.new(2012, 1, 1, 12, 0, 0, zone) - 1 - - time.zone.should == zone - end + context "zone is a timezone object" do + it "preserves time zone" do + zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) + time = Time.new(2012, 1, 1, 12, 0, 0, zone) - 1 + + time.zone.should == zone end end diff --git a/spec/ruby/core/time/new_spec.rb b/spec/ruby/core/time/new_spec.rb index a4bb5b362c..09b4d03a44 100644 --- a/spec/ruby/core/time/new_spec.rb +++ b/spec/ruby/core/time/new_spec.rb @@ -121,216 +121,214 @@ describe "Time.new with a utc_offset argument" do end end -ruby_version_is "2.6" do - describe "Time.new with a timezone argument" do - it "returns a Time in the timezone" do - zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) - time = Time.new(2000, 1, 1, 12, 0, 0, zone) +describe "Time.new with a timezone argument" do + it "returns a Time in the timezone" do + zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) + time = Time.new(2000, 1, 1, 12, 0, 0, zone) + + time.zone.should == zone + time.utc_offset.should == 5*3600+30*60 + ruby_version_is "3.0" do + time.wday.should == 6 + time.yday.should == 1 + end + end - time.zone.should == zone - time.utc_offset.should == 5*3600+30*60 - ruby_version_is "3.0" do - time.wday.should == 6 - time.yday.should == 1 - end + it "accepts timezone argument that must have #local_to_utc and #utc_to_local methods" do + zone = Object.new + def zone.utc_to_local(time) + time end + def zone.local_to_utc(time) + time + end + + -> { + Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time) + }.should_not raise_error + end - it "accepts timezone argument that must have #local_to_utc and #utc_to_local methods" do + it "raises TypeError if timezone does not implement #local_to_utc method" do + zone = Object.new + def zone.utc_to_local(time) + time + end + + -> { + Time.new(2000, 1, 1, 12, 0, 0, zone) + }.should raise_error(TypeError, /can't convert \w+ into an exact number/) + end + + it "does not raise exception if timezone does not implement #utc_to_local method" do + zone = Object.new + def zone.local_to_utc(time) + time + end + + -> { + Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time) + }.should_not raise_error + end + + # The result also should be a Time or Time-like object (not necessary to be the same class) + # The zone of the result is just ignored + describe "returned value by #utc_to_local and #local_to_utc methods" do + it "could be Time instance" do zone = Object.new - def zone.utc_to_local(time) - time - end - def zone.local_to_utc(time) - time + def zone.local_to_utc(t) + Time.utc(t.year, t.mon, t.day, t.hour - 1, t.min, t.sec) end -> { Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time) + Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60 }.should_not raise_error end - it "raises TypeError if timezone does not implement #local_to_utc method" do + it "could be Time subclass instance" do zone = Object.new - def zone.utc_to_local(time) - time + def zone.local_to_utc(t) + Class.new(Time).utc(t.year, t.mon, t.day, t.hour - 1, t.min, t.sec) end -> { - Time.new(2000, 1, 1, 12, 0, 0, zone) - }.should raise_error(TypeError, /can't convert \w+ into an exact number/) + Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time) + Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60 + }.should_not raise_error end - it "does not raise exception if timezone does not implement #utc_to_local method" do + it "could be any object with #to_i method" do zone = Object.new def zone.local_to_utc(time) - time + Struct.new(:to_i).new(time.to_i - 60*60) end -> { Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time) + Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60 }.should_not raise_error end - # The result also should be a Time or Time-like object (not necessary to be the same class) - # The zone of the result is just ignored - describe "returned value by #utc_to_local and #local_to_utc methods" do - it "could be Time instance" do - zone = Object.new - def zone.local_to_utc(t) - Time.utc(t.year, t.mon, t.day, t.hour - 1, t.min, t.sec) - end - - -> { - Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time) - Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60 - }.should_not raise_error - end - - it "could be Time subclass instance" do - zone = Object.new - def zone.local_to_utc(t) - Class.new(Time).utc(t.year, t.mon, t.day, t.hour - 1, t.min, t.sec) - end - - -> { - Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time) - Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60 - }.should_not raise_error - end - - it "could be any object with #to_i method" do - zone = Object.new - def zone.local_to_utc(time) - Struct.new(:to_i).new(time.to_i - 60*60) - end - - -> { - Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time) - Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60 - }.should_not raise_error - end - - it "could have any #zone and #utc_offset because they are ignored" do - zone = Object.new - def zone.local_to_utc(time) - Struct.new(:to_i, :zone, :utc_offset).new(time.to_i, 'America/New_York', -5*60*60) - end - Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 0 - - zone = Object.new - def zone.local_to_utc(time) - Struct.new(:to_i, :zone, :utc_offset).new(time.to_i, 'Asia/Tokyo', 9*60*60) - end - Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 0 + it "could have any #zone and #utc_offset because they are ignored" do + zone = Object.new + def zone.local_to_utc(time) + Struct.new(:to_i, :zone, :utc_offset).new(time.to_i, 'America/New_York', -5*60*60) end + Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 0 - it "leads to raising Argument error if difference between argument and result is too large" do - zone = Object.new - def zone.local_to_utc(t) - Time.utc(t.year, t.mon, t.day + 1, t.hour, t.min, t.sec) - end - - -> { - Time.new(2000, 1, 1, 12, 0, 0, zone) - }.should raise_error(ArgumentError, "utc_offset out of range") + zone = Object.new + def zone.local_to_utc(time) + Struct.new(:to_i, :zone, :utc_offset).new(time.to_i, 'Asia/Tokyo', 9*60*60) end + Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 0 end - # https://github.com/ruby/ruby/blob/v2_6_0/time.c#L5330 - # - # Time-like argument to these methods is similar to a Time object in UTC without sub-second; - # it has attribute readers for the parts, e.g. year, month, and so on, and epoch time readers, to_i - # - # The sub-second attributes are fixed as 0, and utc_offset, zone, isdst, and their aliases are same as a Time object in UTC - describe "Time-like argument of #utc_to_local and #local_to_utc methods" do - before do - @obj = TimeSpecs::TimeLikeArgumentRecorder.result - @obj.should_not == nil + it "leads to raising Argument error if difference between argument and result is too large" do + zone = Object.new + def zone.local_to_utc(t) + Time.utc(t.year, t.mon, t.day + 1, t.hour, t.min, t.sec) end - it "implements subset of Time methods" do - [ - :year, :mon, :month, :mday, :hour, :min, :sec, - :tv_sec, :tv_usec, :usec, :tv_nsec, :nsec, :subsec, - :to_i, :to_f, :to_r, :+, :-, - :isdst, :dst?, :zone, :gmtoff, :gmt_offset, :utc_offset, :utc?, :gmt?, - :to_s, :inspect, :to_a, :to_time, - ].each do |name| - @obj.respond_to?(name).should == true - end - end + -> { + Time.new(2000, 1, 1, 12, 0, 0, zone) + }.should raise_error(ArgumentError, "utc_offset out of range") + end + end - it "has attribute values the same as a Time object in UTC" do - @obj.usec.should == 0 - @obj.nsec.should == 0 - @obj.subsec.should == 0 - @obj.tv_usec.should == 0 - @obj.tv_nsec.should == 0 + # https://github.com/ruby/ruby/blob/v2_6_0/time.c#L5330 + # + # Time-like argument to these methods is similar to a Time object in UTC without sub-second; + # it has attribute readers for the parts, e.g. year, month, and so on, and epoch time readers, to_i + # + # The sub-second attributes are fixed as 0, and utc_offset, zone, isdst, and their aliases are same as a Time object in UTC + describe "Time-like argument of #utc_to_local and #local_to_utc methods" do + before do + @obj = TimeSpecs::TimeLikeArgumentRecorder.result + @obj.should_not == nil + end - @obj.utc_offset.should == 0 - @obj.zone.should == "UTC" - @obj.isdst.should == Time.new.utc.isdst + it "implements subset of Time methods" do + [ + :year, :mon, :month, :mday, :hour, :min, :sec, + :tv_sec, :tv_usec, :usec, :tv_nsec, :nsec, :subsec, + :to_i, :to_f, :to_r, :+, :-, + :isdst, :dst?, :zone, :gmtoff, :gmt_offset, :utc_offset, :utc?, :gmt?, + :to_s, :inspect, :to_a, :to_time, + ].each do |name| + @obj.respond_to?(name).should == true end end - context "#name method" do - it "uses the optional #name method for marshaling" do - zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo") - time = Time.new(2000, 1, 1, 12, 0, 0, zone) - time_loaded = Marshal.load(Marshal.dump(time)) + it "has attribute values the same as a Time object in UTC" do + @obj.usec.should == 0 + @obj.nsec.should == 0 + @obj.subsec.should == 0 + @obj.tv_usec.should == 0 + @obj.tv_nsec.should == 0 - time_loaded.zone.should == "Asia/Colombo" - time_loaded.utc_offset.should == 5*3600+30*60 - end + @obj.utc_offset.should == 0 + @obj.zone.should == "UTC" + @obj.isdst.should == Time.new.utc.isdst + end + end - it "cannot marshal Time if #name method isn't implemented" do - zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) - time = Time.new(2000, 1, 1, 12, 0, 0, zone) + context "#name method" do + it "uses the optional #name method for marshaling" do + zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo") + time = Time.new(2000, 1, 1, 12, 0, 0, zone) + time_loaded = Marshal.load(Marshal.dump(time)) - -> { - Marshal.dump(time) - }.should raise_error(NoMethodError, /undefined method `name' for/) - end + time_loaded.zone.should == "Asia/Colombo" + time_loaded.utc_offset.should == 5*3600+30*60 end - it "the #abbr method is used by '%Z' in #strftime" do - zone = TimeSpecs::TimezoneWithAbbr.new(name: "Asia/Colombo") + it "cannot marshal Time if #name method isn't implemented" do + zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) time = Time.new(2000, 1, 1, 12, 0, 0, zone) - time.strftime("%Z").should == "MMT" + -> { + Marshal.dump(time) + }.should raise_error(NoMethodError, /undefined method `name' for/) end + end - # At loading marshaled data, a timezone name will be converted to a timezone object - # by find_timezone class method, if the method is defined. - # Similarly, that class method will be called when a timezone argument does not have - # the necessary methods mentioned above. - context "subject's class implements .find_timezone method" do - it "calls .find_timezone to build a time object at loading marshaled data" do - zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo") - time = TimeSpecs::TimeWithFindTimezone.new(2000, 1, 1, 12, 0, 0, zone) - time_loaded = Marshal.load(Marshal.dump(time)) - - time_loaded.zone.should be_kind_of TimeSpecs::TimezoneWithName - time_loaded.zone.name.should == "Asia/Colombo" - time_loaded.utc_offset.should == 5*3600+30*60 - end + it "the #abbr method is used by '%Z' in #strftime" do + zone = TimeSpecs::TimezoneWithAbbr.new(name: "Asia/Colombo") + time = Time.new(2000, 1, 1, 12, 0, 0, zone) - it "calls .find_timezone to build a time object if passed zone name as a timezone argument" do - time = TimeSpecs::TimeWithFindTimezone.new(2000, 1, 1, 12, 0, 0, "Asia/Colombo") - time.zone.should be_kind_of TimeSpecs::TimezoneWithName - time.zone.name.should == "Asia/Colombo" + time.strftime("%Z").should == "MMT" + end - time = TimeSpecs::TimeWithFindTimezone.new(2000, 1, 1, 12, 0, 0, "some invalid zone name") - time.zone.should be_kind_of TimeSpecs::TimezoneWithName - time.zone.name.should == "some invalid zone name" - end + # At loading marshaled data, a timezone name will be converted to a timezone object + # by find_timezone class method, if the method is defined. + # Similarly, that class method will be called when a timezone argument does not have + # the necessary methods mentioned above. + context "subject's class implements .find_timezone method" do + it "calls .find_timezone to build a time object at loading marshaled data" do + zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo") + time = TimeSpecs::TimeWithFindTimezone.new(2000, 1, 1, 12, 0, 0, zone) + time_loaded = Marshal.load(Marshal.dump(time)) + + time_loaded.zone.should be_kind_of TimeSpecs::TimezoneWithName + time_loaded.zone.name.should == "Asia/Colombo" + time_loaded.utc_offset.should == 5*3600+30*60 + end - it "does not call .find_timezone if passed any not string/numeric/timezone timezone argument" do - [Object.new, [], {}, :"some zone"].each do |zone| - -> { - TimeSpecs::TimeWithFindTimezone.new(2000, 1, 1, 12, 0, 0, zone) - }.should raise_error(TypeError, /can't convert \w+ into an exact number/) - end + it "calls .find_timezone to build a time object if passed zone name as a timezone argument" do + time = TimeSpecs::TimeWithFindTimezone.new(2000, 1, 1, 12, 0, 0, "Asia/Colombo") + time.zone.should be_kind_of TimeSpecs::TimezoneWithName + time.zone.name.should == "Asia/Colombo" + + time = TimeSpecs::TimeWithFindTimezone.new(2000, 1, 1, 12, 0, 0, "some invalid zone name") + time.zone.should be_kind_of TimeSpecs::TimezoneWithName + time.zone.name.should == "some invalid zone name" + end + + it "does not call .find_timezone if passed any not string/numeric/timezone timezone argument" do + [Object.new, [], {}, :"some zone"].each do |zone| + -> { + TimeSpecs::TimeWithFindTimezone.new(2000, 1, 1, 12, 0, 0, zone) + }.should raise_error(TypeError, /can't convert \w+ into an exact number/) end end end diff --git a/spec/ruby/core/time/plus_spec.rb b/spec/ruby/core/time/plus_spec.rb index c59d9a32bb..642393b615 100644 --- a/spec/ruby/core/time/plus_spec.rb +++ b/spec/ruby/core/time/plus_spec.rb @@ -56,14 +56,12 @@ describe "Time#+" do time_with_zone.zone.should == (time_with_zone + 1).zone end - ruby_version_is "2.6" do - context "zone is a timezone object" do - it "preserves time zone" do - zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) - time = Time.new(2012, 1, 1, 12, 0, 0, zone) + 1 - - time.zone.should == zone - end + context "zone is a timezone object" do + it "preserves time zone" do + zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) + time = Time.new(2012, 1, 1, 12, 0, 0, zone) + 1 + + time.zone.should == zone end end diff --git a/spec/ruby/core/time/succ_spec.rb b/spec/ruby/core/time/succ_spec.rb index fa6343f8e2..e8249059d1 100644 --- a/spec/ruby/core/time/succ_spec.rb +++ b/spec/ruby/core/time/succ_spec.rb @@ -27,14 +27,12 @@ ruby_version_is ""..."3.0" do }.should complain(/Time#succ is obsolete/) end - ruby_version_is "2.6" do - context "zone is a timezone object" do - it "preserves time zone" do - zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) - time = Time.new(2012, 1, 1, 12, 0, 0, zone) - 1 - - time.zone.should == zone - end + context "zone is a timezone object" do + it "preserves time zone" do + zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60)) + time = Time.new(2012, 1, 1, 12, 0, 0, zone) - 1 + + time.zone.should == zone end end end diff --git a/spec/ruby/core/tracepoint/enable_spec.rb b/spec/ruby/core/tracepoint/enable_spec.rb index 50fded90e4..ab392c7583 100644 --- a/spec/ruby/core/tracepoint/enable_spec.rb +++ b/spec/ruby/core/tracepoint/enable_spec.rb @@ -161,65 +161,112 @@ describe 'TracePoint#enable' do end end - ruby_version_is "2.6" do - describe 'target: option' do - before :each do - ScratchPad.record [] + describe 'target: option' do + before :each do + ScratchPad.record [] + end + + it 'enables trace point for specific location' do + trace = TracePoint.new(:call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << tp.method_id end - it 'enables trace point for specific location' do - trace = TracePoint.new(:call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << tp.method_id - end + obj = Object.new + def obj.foo; end + def obj.bar; end - obj = Object.new - def obj.foo; end - def obj.bar; end + trace.enable(target: obj.method(:foo)) do + obj.foo + obj.bar + end - trace.enable(target: obj.method(:foo)) do - obj.foo - obj.bar - end + ScratchPad.recorded.should == [:foo] + end - ScratchPad.recorded.should == [:foo] + it 'traces all the events triggered in specified location' do + trace = TracePoint.new(:line, :call, :return, :b_call, :b_return) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << tp.event end - it 'traces all the events triggered in specified location' do - trace = TracePoint.new(:line, :call, :return, :b_call, :b_return) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << tp.event - end + obj = Object.new + def obj.foo + bar + -> {}.call + end + def obj.bar; end - obj = Object.new - def obj.foo - bar - -> {}.call + trace.enable(target: obj.method(:foo)) do + obj.foo + end + + ScratchPad.recorded.uniq.sort.should == [:call, :return, :b_call, :b_return, :line].sort + end + + it 'does not trace events in nested locations' do + trace = TracePoint.new(:call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << tp.method_id + end + + obj = Object.new + def obj.foo + bar + end + def obj.bar + baz + end + def obj.baz + end + + trace.enable(target: obj.method(:foo)) do + obj.foo + end + + ScratchPad.recorded.should == [:foo] + end + + it "traces some events in nested blocks" do + klass = Class.new do + def foo + 1.times do + 1.times do + bar do + end + end + end end - def obj.bar; end - trace.enable(target: obj.method(:foo)) do - obj.foo + def bar(&blk) + blk.call end + end + + trace = TracePoint.new(:b_call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << tp.lineno + end + + obj = klass.new + _, lineno = obj.method(:foo).source_location - ScratchPad.recorded.uniq.sort.should == [:call, :return, :b_call, :b_return, :line].sort + trace.enable(target: obj.method(:foo)) do + obj.foo end - it 'does not trace events in nested locations' do + ScratchPad.recorded.should == (lineno+1..lineno+3).to_a + end + + describe 'option value' do + it 'accepts Method' do trace = TracePoint.new(:call) do |tp| next unless TracePointSpec.target_thread? ScratchPad << tp.method_id end obj = Object.new - def obj.foo - bar - end - def obj.bar - baz - end - def obj.baz - end + def obj.foo; end trace.enable(target: obj.method(:foo)) do obj.foo @@ -228,324 +275,275 @@ describe 'TracePoint#enable' do ScratchPad.recorded.should == [:foo] end - it "traces some events in nested blocks" do + it 'accepts UnboundMethod' do + trace = TracePoint.new(:call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << tp.method_id + end + klass = Class.new do - def foo - 1.times do - 1.times do - bar do - end - end - end - end + def foo; end + end - def bar(&blk) - blk.call - end + unbound_method = klass.instance_method(:foo) + trace.enable(target: unbound_method) do + klass.new.foo end + ScratchPad.recorded.should == [:foo] + end + + it 'accepts Proc' do trace = TracePoint.new(:b_call) do |tp| next unless TracePointSpec.target_thread? ScratchPad << tp.lineno end - obj = klass.new - _, lineno = obj.method(:foo).source_location + block = proc {} + _, lineno = block.source_location - trace.enable(target: obj.method(:foo)) do - obj.foo + trace.enable(target: block) do + block.call end - ScratchPad.recorded.should == (lineno+1..lineno+3).to_a + ScratchPad.recorded.should == [lineno] + lineno.should be_kind_of(Integer) end + end - describe 'option value' do - it 'accepts Method' do - trace = TracePoint.new(:call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << tp.method_id - end - - obj = Object.new - def obj.foo; end + it "raises ArgumentError if target object cannot trigger specified event" do + trace = TracePoint.new(:call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << tp.method_id + end - trace.enable(target: obj.method(:foo)) do - obj.foo - end + block = proc {} - ScratchPad.recorded.should == [:foo] + -> { + trace.enable(target: block) do + block.call # triggers :b_call and :b_return events end + }.should raise_error(ArgumentError, /can not enable any hooks/) + end - it 'accepts UnboundMethod' do - trace = TracePoint.new(:call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << tp.method_id - end - - klass = Class.new do - def foo; end - end - - unbound_method = klass.instance_method(:foo) - trace.enable(target: unbound_method) do - klass.new.foo - end + it "raises ArgumentError if passed not Method/UnboundMethod/Proc" do + trace = TracePoint.new(:call) {} - ScratchPad.recorded.should == [:foo] + -> { + trace.enable(target: Object.new) do end + }.should raise_error(ArgumentError, /specified target is not supported/) + end - it 'accepts Proc' do - trace = TracePoint.new(:b_call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << tp.lineno + context "nested enabling and disabling" do + it "raises ArgumentError if trace point already enabled with target is re-enabled with target" do + trace = TracePoint.new(:b_call) {} + + -> { + trace.enable(target: -> {}) do + trace.enable(target: -> {}) do + end end + }.should raise_error(ArgumentError, /can't nest-enable a targett?ing TracePoint/) + end - block = proc {} - _, lineno = block.source_location + it "raises ArgumentError if trace point already enabled without target is re-enabled with target" do + trace = TracePoint.new(:b_call) {} - trace.enable(target: block) do - block.call + -> { + trace.enable do + trace.enable(target: -> {}) do + end end - - ScratchPad.recorded.should == [lineno] - lineno.should be_kind_of(Integer) - end + }.should raise_error(ArgumentError, /can't nest-enable a targett?ing TracePoint/) end - it "raises ArgumentError if target object cannot trigger specified event" do - trace = TracePoint.new(:call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << tp.method_id - end - - block = proc {} + it "raises ArgumentError if trace point already enabled with target is re-enabled without target" do + trace = TracePoint.new(:b_call) {} -> { - trace.enable(target: block) do - block.call # triggers :b_call and :b_return events + trace.enable(target: -> {}) do + trace.enable do + end end - }.should raise_error(ArgumentError, /can not enable any hooks/) + }.should raise_error(ArgumentError, /can't nest-enable a targett?ing TracePoint/) end - it "raises ArgumentError if passed not Method/UnboundMethod/Proc" do - trace = TracePoint.new(:call) {} + it "raises ArgumentError if trace point already enabled with target is disabled with block" do + trace = TracePoint.new(:b_call) {} -> { - trace.enable(target: Object.new) do + trace.enable(target: -> {}) do + trace.disable do + end end - }.should raise_error(ArgumentError, /specified target is not supported/) + }.should raise_error(ArgumentError, /can't disable a targett?ing TracePoint in a block/) end - context "nested enabling and disabling" do - it "raises ArgumentError if trace point already enabled with target is re-enabled with target" do - trace = TracePoint.new(:b_call) {} + it "traces events when trace point with target is enabled in another trace point enabled without target" do + trace_outer = TracePoint.new(:b_call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << :outer + end - -> { - trace.enable(target: -> {}) do - trace.enable(target: -> {}) do - end - end - }.should raise_error(ArgumentError, /can't nest-enable a targett?ing TracePoint/) + trace_inner = TracePoint.new(:b_call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << :inner end - it "raises ArgumentError if trace point already enabled without target is re-enabled with target" do - trace = TracePoint.new(:b_call) {} + target = -> {} - -> { - trace.enable do - trace.enable(target: -> {}) do - end - end - }.should raise_error(ArgumentError, /can't nest-enable a targett?ing TracePoint/) + trace_outer.enable do + trace_inner.enable(target: target) do + target.call + end end - it "raises ArgumentError if trace point already enabled with target is re-enabled without target" do - trace = TracePoint.new(:b_call) {} + ScratchPad.recorded.should == [:outer, :outer, :outer, :inner] + end - -> { - trace.enable(target: -> {}) do - trace.enable do - end - end - }.should raise_error(ArgumentError, /can't nest-enable a targett?ing TracePoint/) + it "traces events when trace point with target is enabled in another trace point enabled with target" do + trace_outer = TracePoint.new(:b_call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << :outer end - it "raises ArgumentError if trace point already enabled with target is disabled with block" do - trace = TracePoint.new(:b_call) {} - - -> { - trace.enable(target: -> {}) do - trace.disable do - end - end - }.should raise_error(ArgumentError, /can't disable a targett?ing TracePoint in a block/) + trace_inner = TracePoint.new(:b_call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << :inner end - it "traces events when trace point with target is enabled in another trace point enabled without target" do - trace_outer = TracePoint.new(:b_call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << :outer - end + target = -> {} - trace_inner = TracePoint.new(:b_call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << :inner + trace_outer.enable(target: target) do + trace_inner.enable(target: target) do + target.call end + end - target = -> {} - - trace_outer.enable do - trace_inner.enable(target: target) do - target.call - end - end + ScratchPad.recorded.should == [:inner, :outer] + end - ScratchPad.recorded.should == [:outer, :outer, :outer, :inner] + it "traces events when trace point without target is enabled in another trace point enabled with target" do + trace_outer = TracePoint.new(:b_call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << :outer end - it "traces events when trace point with target is enabled in another trace point enabled with target" do - trace_outer = TracePoint.new(:b_call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << :outer - end - - trace_inner = TracePoint.new(:b_call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << :inner - end + trace_inner = TracePoint.new(:b_call) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << :inner + end - target = -> {} + target = -> {} - trace_outer.enable(target: target) do - trace_inner.enable(target: target) do - target.call - end + trace_outer.enable(target: target) do + trace_inner.enable do + target.call end - - ScratchPad.recorded.should == [:inner, :outer] end - it "traces events when trace point without target is enabled in another trace point enabled with target" do - trace_outer = TracePoint.new(:b_call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << :outer - end + ScratchPad.recorded.should == [:inner, :inner, :outer] + end + end + end - trace_inner = TracePoint.new(:b_call) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << :inner - end + describe 'target_line: option' do + before :each do + ScratchPad.record [] + end - target = -> {} + it "traces :line events only on specified line of code" do + trace = TracePoint.new(:line) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << tp.lineno + end - trace_outer.enable(target: target) do - trace_inner.enable do - target.call - end - end + target = -> { + x = 1 + y = 2 # <= this line is target + z = x + y + } + _, lineno = target.source_location + target_line = lineno + 2 - ScratchPad.recorded.should == [:inner, :inner, :outer] - end + trace.enable(target_line: target_line, target: target) do + target.call end + + ScratchPad.recorded.should == [target_line] end - describe 'target_line: option' do - before :each do - ScratchPad.record [] - end + it "raises ArgumentError if :target option isn't specified" do + trace = TracePoint.new(:line) {} - it "traces :line events only on specified line of code" do - trace = TracePoint.new(:line) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << tp.lineno + -> { + trace.enable(target_line: 67) do end + }.should raise_error(ArgumentError, /only target_line is specified/) + end + + it "raises ArgumentError if :line event isn't registered" do + trace = TracePoint.new(:call) {} - target = -> { - x = 1 - y = 2 # <= this line is target - z = x + y - } - _, lineno = target.source_location - target_line = lineno + 2 + target = -> { + x = 1 + y = 2 # <= this line is target + z = x + y + } + _, lineno = target.source_location + target_line = lineno + 2 + -> { trace.enable(target_line: target_line, target: target) do - target.call end + }.should raise_error(ArgumentError, /target_line is specified, but line event is not specified/) + end - ScratchPad.recorded.should == [target_line] - end - - it "raises ArgumentError if :target option isn't specified" do - trace = TracePoint.new(:line) {} - - -> { - trace.enable(target_line: 67) do - end - }.should raise_error(ArgumentError, /only target_line is specified/) - end - - it "raises ArgumentError if :line event isn't registered" do - trace = TracePoint.new(:call) {} + it "raises ArgumentError if :target_line value is out of target code lines range" do + trace = TracePoint.new(:line) {} - target = -> { - x = 1 - y = 2 # <= this line is target - z = x + y - } - _, lineno = target.source_location - target_line = lineno + 2 + -> { + trace.enable(target_line: 1, target: -> { }) do + end + }.should raise_error(ArgumentError, /can not enable any hooks/) + end - -> { - trace.enable(target_line: target_line, target: target) do - end - }.should raise_error(ArgumentError, /target_line is specified, but line event is not specified/) - end + it "raises TypeError if :target_line value couldn't be coerced to Integer" do + trace = TracePoint.new(:line) {} - it "raises ArgumentError if :target_line value is out of target code lines range" do - trace = TracePoint.new(:line) {} + -> { + trace.enable(target_line: Object.new, target: -> { }) do + end + }.should raise_error(TypeError, /no implicit conversion of \w+? into Integer/) + end - -> { - trace.enable(target_line: 1, target: -> { }) do - end - }.should raise_error(ArgumentError, /can not enable any hooks/) - end + it "raises ArgumentError if :target_line value is negative" do + trace = TracePoint.new(:line) {} - it "raises TypeError if :target_line value couldn't be coerced to Integer" do - trace = TracePoint.new(:line) {} + -> { + trace.enable(target_line: -2, target: -> { }) do + end + }.should raise_error(ArgumentError, /can not enable any hooks/) + end - -> { - trace.enable(target_line: Object.new, target: -> { }) do - end - }.should raise_error(TypeError, /no implicit conversion of \w+? into Integer/) + it "accepts value that could be coerced to Integer" do + trace = TracePoint.new(:line) do |tp| + next unless TracePointSpec.target_thread? + ScratchPad << tp.lineno end - it "raises ArgumentError if :target_line value is negative" do - trace = TracePoint.new(:line) {} + target = -> { + x = 1 # <= this line is target + } + _, lineno = target.source_location + target_line = lineno + 1 - -> { - trace.enable(target_line: -2, target: -> { }) do - end - }.should raise_error(ArgumentError, /can not enable any hooks/) + trace.enable(target_line: target_line.to_r, target: target) do + target.call end - it "accepts value that could be coerced to Integer" do - trace = TracePoint.new(:line) do |tp| - next unless TracePointSpec.target_thread? - ScratchPad << tp.lineno - end - - target = -> { - x = 1 # <= this line is target - } - _, lineno = target.source_location - target_line = lineno + 1 - - trace.enable(target_line: target_line.to_r, target: target) do - target.call - end - - ScratchPad.recorded.should == [target_line] - end + ScratchPad.recorded.should == [target_line] end end end diff --git a/spec/ruby/core/tracepoint/eval_script_spec.rb b/spec/ruby/core/tracepoint/eval_script_spec.rb index ccf7fb5975..7ec53e7094 100644 --- a/spec/ruby/core/tracepoint/eval_script_spec.rb +++ b/spec/ruby/core/tracepoint/eval_script_spec.rb @@ -1,25 +1,23 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' -ruby_version_is "2.6" do - describe "TracePoint#eval_script" do - it "is the evald source code" do - ScratchPad.record [] +describe "TracePoint#eval_script" do + it "is the evald source code" do + ScratchPad.record [] - script = <<-CODE - def foo - p :hello - end - CODE - - TracePoint.new(:script_compiled) do |e| - next unless TracePointSpec.target_thread? - ScratchPad << e.eval_script - end.enable do - eval script + script = <<-CODE + def foo + p :hello end + CODE - ScratchPad.recorded.should == [script] + TracePoint.new(:script_compiled) do |e| + next unless TracePointSpec.target_thread? + ScratchPad << e.eval_script + end.enable do + eval script end + + ScratchPad.recorded.should == [script] end end diff --git a/spec/ruby/core/tracepoint/parameters_spec.rb b/spec/ruby/core/tracepoint/parameters_spec.rb index 3a2cdd7750..82aee3caa4 100644 --- a/spec/ruby/core/tracepoint/parameters_spec.rb +++ b/spec/ruby/core/tracepoint/parameters_spec.rb @@ -1,30 +1,28 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' -ruby_version_is "2.6" do - describe 'TracePoint#parameters' do - it 'returns the parameters of block' do - f = proc {|x, y, z| } - parameters = nil - TracePoint.new(:b_call) { |tp| - next unless TracePointSpec.target_thread? - parameters = tp.parameters - }.enable do - f.call - parameters.should == [[:opt, :x], [:opt, :y], [:opt, :z]] - end +describe 'TracePoint#parameters' do + it 'returns the parameters of block' do + f = proc {|x, y, z| } + parameters = nil + TracePoint.new(:b_call) { |tp| + next unless TracePointSpec.target_thread? + parameters = tp.parameters + }.enable do + f.call + parameters.should == [[:opt, :x], [:opt, :y], [:opt, :z]] end + end - it 'returns the parameters of lambda block' do - f = -> x, y, z { } - parameters = nil - TracePoint.new(:b_call) { |tp| - next unless TracePointSpec.target_thread? - parameters = tp.parameters - }.enable do - f.call(1, 2, 3) - parameters.should == [[:req, :x], [:req, :y], [:req, :z]] - end + it 'returns the parameters of lambda block' do + f = -> x, y, z { } + parameters = nil + TracePoint.new(:b_call) { |tp| + next unless TracePointSpec.target_thread? + parameters = tp.parameters + }.enable do + f.call(1, 2, 3) + parameters.should == [[:req, :x], [:req, :y], [:req, :z]] end end end diff --git a/spec/ruby/language/constants_spec.rb b/spec/ruby/language/constants_spec.rb index 760b9d4a24..03f1272401 100644 --- a/spec/ruby/language/constants_spec.rb +++ b/spec/ruby/language/constants_spec.rb @@ -432,17 +432,15 @@ describe "Module#private_constant marked constants" do -> {mod::Foo}.should raise_error(NameError) end - ruby_version_is "2.6" do - it "sends #const_missing to the original class or module" do - mod = Module.new - mod.const_set :Foo, true - mod.send :private_constant, :Foo - def mod.const_missing(name) - name == :Foo ? name : super - end - - mod::Foo.should == :Foo + it "sends #const_missing to the original class or module" do + mod = Module.new + mod.const_set :Foo, true + mod.send :private_constant, :Foo + def mod.const_missing(name) + name == :Foo ? name : super end + + mod::Foo.should == :Foo end describe "in a module" do @@ -713,20 +711,10 @@ describe 'Allowed characters' do end.should raise_error(NameError, /wrong constant name/) end - ruby_version_is ""..."2.6" do - it 'does not allow not ASCII upcased characters at the beginning' do - -> do - Module.new.const_set("ἍBB", 1) - end.should raise_error(NameError, /wrong constant name/) - end - end - - ruby_version_is "2.6" do - it 'allows not ASCII upcased characters at the beginning' do - mod = Module.new - mod.const_set("ἍBB", 1) + it 'allows not ASCII upcased characters at the beginning' do + mod = Module.new + mod.const_set("ἍBB", 1) - eval("mod::ἍBB").should == 1 - end + eval("mod::ἍBB").should == 1 end end diff --git a/spec/ruby/language/delegation_spec.rb b/spec/ruby/language/delegation_spec.rb index ac7b511f65..8e4183cbcc 100644 --- a/spec/ruby/language/delegation_spec.rb +++ b/spec/ruby/language/delegation_spec.rb @@ -39,3 +39,30 @@ ruby_version_is "2.7" do end end end + +ruby_version_is "2.7.3" do + describe "delegation with def(x, ...)" do + it "delegates rest and kwargs" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(x, ...) + target(...) + end + RUBY + + a.new.delegate(0, 1, b: 2).should == [[1], {b: 2}] + end + + it "delegates block" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate_block(x, ...) + target_block(...) + end + RUBY + + a.new.delegate_block(0, 1, b: 2) { |x| x }.should == [{b: 2}, [1]] + end + + end +end diff --git a/spec/ruby/language/hash_spec.rb b/spec/ruby/language/hash_spec.rb index 9b2e5a2dc7..f99ff8ab3f 100644 --- a/spec/ruby/language/hash_spec.rb +++ b/spec/ruby/language/hash_spec.rb @@ -58,11 +58,16 @@ describe "Hash literal" do }.should complain(/key 1000 is duplicated|duplicated key/) @h.keys.size.should == 1 @h.should == {1000 => :foo} - -> { - @h = eval "{1.0 => :bar, 1.0 => :foo}" - }.should complain(/key 1.0 is duplicated|duplicated key/) - @h.keys.size.should == 1 - @h.should == {1.0 => :foo} + end + + ruby_version_is "3.1" do + it "checks duplicated float keys on initialization" do + -> { + @h = eval "{1.0 => :bar, 1.0 => :foo}" + }.should complain(/key 1.0 is duplicated|duplicated key/) + @h.keys.size.should == 1 + @h.should == {1.0 => :foo} + end end it "accepts a hanging comma" do diff --git a/spec/ruby/language/lambda_spec.rb b/spec/ruby/language/lambda_spec.rb index 630817c909..6393fb5c47 100644 --- a/spec/ruby/language/lambda_spec.rb +++ b/spec/ruby/language/lambda_spec.rb @@ -22,14 +22,12 @@ describe "A lambda literal -> () { }" do -> { }.lambda?.should be_true end - ruby_version_is "2.6" do - it "may include a rescue clause" do - eval('-> do raise ArgumentError; rescue ArgumentError; 7; end').should be_an_instance_of(Proc) - end + it "may include a rescue clause" do + eval('-> do raise ArgumentError; rescue ArgumentError; 7; end').should be_an_instance_of(Proc) + end - it "may include a ensure clause" do - eval('-> do 1; ensure; 2; end').should be_an_instance_of(Proc) - end + it "may include a ensure clause" do + eval('-> do 1; ensure; 2; end').should be_an_instance_of(Proc) end it "has its own scope for local variables" do diff --git a/spec/ruby/language/range_spec.rb b/spec/ruby/language/range_spec.rb index c0f90f84d6..79500c6b33 100644 --- a/spec/ruby/language/range_spec.rb +++ b/spec/ruby/language/range_spec.rb @@ -10,11 +10,9 @@ describe "Literal Ranges" do (1...10).should == Range.new(1, 10, true) end - ruby_version_is "2.6" do - it "creates endless ranges" do - eval("(1..)").should == Range.new(1, nil) - eval("(1...)").should == Range.new(1, nil, true) - end + it "creates endless ranges" do + (1..).should == Range.new(1, nil) + (1...).should == Range.new(1, nil, true) end ruby_version_is "2.7" do diff --git a/spec/ruby/language/regexp_spec.rb b/spec/ruby/language/regexp_spec.rb index def9bba5f7..f607fa6010 100644 --- a/spec/ruby/language/regexp_spec.rb +++ b/spec/ruby/language/regexp_spec.rb @@ -115,10 +115,11 @@ describe "Literal Regexps" do /foo.(?<=\d)/.match("fooA foo1").to_a.should == ["foo1"] end - # https://bugs.ruby-lang.org/issues/13671 - it "raises a RegexpError for lookbehind with specific characters" do - r = Regexp.new("(?<!dss)", Regexp::IGNORECASE) - -> { r =~ "✨" }.should raise_error(RegexpError) + ruby_bug "#13671", ""..."3.2" do # https://bugs.ruby-lang.org/issues/13671 + it "handles a lookbehind with ss characters" do + r = Regexp.new("(?<!dss)", Regexp::IGNORECASE) + r.should =~ "✨" + end end it "supports (?<! ) (negative lookbehind)" do diff --git a/spec/ruby/language/rescue_spec.rb b/spec/ruby/language/rescue_spec.rb index 1c78f3935a..4d164b38c6 100644 --- a/spec/ruby/language/rescue_spec.rb +++ b/spec/ruby/language/rescue_spec.rb @@ -238,34 +238,16 @@ describe "The rescue keyword" do ScratchPad.recorded.should == [:one, :else_ran, :ensure_ran, :outside_begin] end - ruby_version_is ''...'2.6' do - it "will execute an else block even without rescue and ensure" do - -> { - eval <<-ruby - begin - ScratchPad << :begin - else - ScratchPad << :else - end - ruby - }.should complain(/else without rescue is useless/) - - ScratchPad.recorded.should == [:begin, :else] - end - end - - ruby_version_is '2.6' do - it "raises SyntaxError when else is used without rescue and ensure" do - -> { - eval <<-ruby - begin - ScratchPad << :begin - else - ScratchPad << :else - end - ruby - }.should raise_error(SyntaxError, /else without rescue is useless/) - end + it "raises SyntaxError when else is used without rescue and ensure" do + -> { + eval <<-ruby + begin + ScratchPad << :begin + else + ScratchPad << :else + end + ruby + }.should raise_error(SyntaxError, /else without rescue is useless/) end it "will not execute an else block if an exception was raised" do diff --git a/spec/ruby/language/safe_spec.rb b/spec/ruby/language/safe_spec.rb index f3a7efc953..062381d729 100644 --- a/spec/ruby/language/safe_spec.rb +++ b/spec/ruby/language/safe_spec.rb @@ -2,10 +2,8 @@ require_relative '../spec_helper' describe "The $SAFE variable" do ruby_version_is ""..."2.7" do - ruby_version_is "2.6" do - after :each do - $SAFE = 0 - end + after :each do + $SAFE = 0 end it "is 0 by default" do @@ -39,24 +37,12 @@ describe "The $SAFE variable" do end end - ruby_version_is ""..."2.6" do - it "cannot be set to values below 0" do - -> { - proc { - $SAFE = -100 - }.call - }.should raise_error(SecurityError, /tried to downgrade safe level from 0 to -100/) - end - end - - ruby_version_is "2.6" do - it "raises ArgumentError when set to values below 0" do - -> { - proc { - $SAFE = -100 - }.call - }.should raise_error(ArgumentError, "$SAFE should be >= 0") - end + it "raises ArgumentError when set to values below 0" do + -> { + proc { + $SAFE = -100 + }.call + }.should raise_error(ArgumentError, "$SAFE should be >= 0") end it "cannot be set to values above 4" do @@ -67,61 +53,32 @@ describe "The $SAFE variable" do }.should raise_error(ArgumentError, /\$SAFE=2 to 4 are obsolete/) end - ruby_version_is ""..."2.6" do - it "cannot be manually lowered" do - proc { - $SAFE = 1 - -> { - $SAFE = 0 - }.should raise_error(SecurityError, /tried to downgrade safe level from 1 to 0/) - }.call - end - - it "is automatically lowered when leaving a proc" do - $SAFE.should == 0 - proc { - $SAFE = 1 - }.call - $SAFE.should == 0 - end - - it "is automatically lowered when leaving a lambda" do - $SAFE.should == 0 - -> { - $SAFE = 1 - }.call - $SAFE.should == 0 - end + it "can be manually lowered" do + $SAFE = 1 + $SAFE = 0 + $SAFE.should == 0 end - ruby_version_is "2.6" do - it "can be manually lowered" do + it "is not Proc local" do + $SAFE.should == 0 + proc { $SAFE = 1 - $SAFE = 0 - $SAFE.should == 0 - end - - it "is not Proc local" do - $SAFE.should == 0 - proc { - $SAFE = 1 - }.call - $SAFE.should == 1 - end - - it "is not lambda local" do - $SAFE.should == 0 - -> { - $SAFE = 1 - }.call - $SAFE.should == 1 - end + }.call + $SAFE.should == 1 + end - it "is global like regular global variables" do - Thread.new { $SAFE }.value.should == 0 + it "is not lambda local" do + $SAFE.should == 0 + -> { $SAFE = 1 - Thread.new { $SAFE }.value.should == 1 - end + }.call + $SAFE.should == 1 + end + + it "is global like regular global variables" do + Thread.new { $SAFE }.value.should == 0 + $SAFE = 1 + Thread.new { $SAFE }.value.should == 1 end it "can be read when default from Thread#safe_level" do diff --git a/spec/ruby/language/variables_spec.rb b/spec/ruby/language/variables_spec.rb index ce072baa2c..7d6969e659 100644 --- a/spec/ruby/language/variables_spec.rb +++ b/spec/ruby/language/variables_spec.rb @@ -715,6 +715,18 @@ describe "Multiple assignment" do x.should == [1, 2, 3, 4, 5] end + it "can be used to swap array elements" do + a = [1, 2] + a[0], a[1] = a[1], a[0] + a.should == [2, 1] + end + + it "can be used to swap range of array elements" do + a = [1, 2, 3, 4] + a[0, 2], a[2, 2] = a[2, 2], a[0, 2] + a.should == [3, 4, 1, 2] + end + it "assigns RHS values to LHS constants" do module VariableSpecs MRHS_VALUES_1, MRHS_VALUES_2 = 1, 2 @@ -770,45 +782,30 @@ describe "A local variable assigned only within a conditional block" do end describe 'Local variable shadowing' do - ruby_version_is ""..."2.6" do - it "leads to warning in verbose mode" do - -> do - eval <<-CODE - a = [1, 2, 3] - a.each { |a| a = 3 } - CODE - end.should complain(/shadowing outer local variable/, verbose: true) - end - end - - ruby_version_is "2.6" do - it "does not warn in verbose mode" do - result = nil + it "does not warn in verbose mode" do + result = nil - -> do - eval <<-CODE - a = [1, 2, 3] - result = a.map { |a| a = 3 } - CODE - end.should_not complain(verbose: true) + -> do + eval <<-CODE + a = [1, 2, 3] + result = a.map { |a| a = 3 } + CODE + end.should_not complain(verbose: true) - result.should == [3, 3, 3] - end + result.should == [3, 3, 3] end end describe 'Allowed characters' do - ruby_version_is "2.6" do - # new feature in 2.6 -- https://bugs.ruby-lang.org/issues/13770 - it 'does not allow non-ASCII upcased characters at the beginning' do - -> do - eval <<-CODE - def test - ἍBB = 1 - end - CODE - end.should raise_error(SyntaxError, /dynamic constant assignment/) - end + # new feature in 2.6 -- https://bugs.ruby-lang.org/issues/13770 + it 'does not allow non-ASCII upcased characters at the beginning' do + -> do + eval <<-CODE + def test + ἍBB = 1 + end + CODE + end.should raise_error(SyntaxError, /dynamic constant assignment/) end it 'allows non-ASCII lowercased characters at the beginning' do diff --git a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb index d56c0a664b..43a779b420 100644 --- a/spec/ruby/library/bigdecimal/BigDecimal_spec.rb +++ b/spec/ruby/library/bigdecimal/BigDecimal_spec.rb @@ -56,22 +56,11 @@ describe "Kernel#BigDecimal" do BigDecimal(initial).should == BigDecimal("123") end - ruby_version_is ""..."2.6" do - it "ignores trailing garbage" do - BigDecimal("123E45ruby").should == BigDecimal("123E45") - BigDecimal("123x45").should == BigDecimal("123") - BigDecimal("123.4%E5").should == BigDecimal("123.4") - BigDecimal("1E2E3E4E5E").should == BigDecimal("100") - end - end - - ruby_version_is "2.6" do - it "does not ignores trailing garbage" do - -> { BigDecimal("123E45ruby") }.should raise_error(ArgumentError) - -> { BigDecimal("123x45") }.should raise_error(ArgumentError) - -> { BigDecimal("123.4%E5") }.should raise_error(ArgumentError) - -> { BigDecimal("1E2E3E4E5E") }.should raise_error(ArgumentError) - end + it "does not ignores trailing garbage" do + -> { BigDecimal("123E45ruby") }.should raise_error(ArgumentError) + -> { BigDecimal("123x45") }.should raise_error(ArgumentError) + -> { BigDecimal("123.4%E5") }.should raise_error(ArgumentError) + -> { BigDecimal("1E2E3E4E5E") }.should raise_error(ArgumentError) end it "raises ArgumentError for invalid strings" do @@ -83,24 +72,12 @@ describe "Kernel#BigDecimal" do BigDecimal(".123").should == BigDecimal("0.123") end - ruby_version_is ""..."2.6" do - it "allows for underscores in all parts" do - reference = BigDecimal("12345.67E89") - - BigDecimal("12_345.67E89").should == reference - BigDecimal("1_2_3_4_5_._6____7_E89").should == reference - BigDecimal("12345_.67E_8__9_").should == reference - end - end - - ruby_version_is "2.6" do - it "process underscores as Float()" do - reference = BigDecimal("12345.67E89") + it "process underscores as Float()" do + reference = BigDecimal("12345.67E89") - BigDecimal("12_345.67E89").should == reference - -> { BigDecimal("1_2_3_4_5_._6____7_E89") }.should raise_error(ArgumentError) - -> { BigDecimal("12345_.67E_8__9_") }.should raise_error(ArgumentError) - end + BigDecimal("12_345.67E89").should == reference + -> { BigDecimal("1_2_3_4_5_._6____7_E89") }.should raise_error(ArgumentError) + -> { BigDecimal("12345_.67E_8__9_") }.should raise_error(ArgumentError) end it "accepts NaN and [+-]Infinity" do @@ -116,14 +93,12 @@ describe "Kernel#BigDecimal" do neg_inf.should < 0 end - ruby_version_is "2.6" do - describe "with exception: false" do - it "returns nil for invalid strings" do - BigDecimal("invalid", exception: false).should be_nil - BigDecimal("0invalid", exception: false).should be_nil - BigDecimal("invalid0", exception: false).should be_nil - BigDecimal("0.", exception: false).should be_nil - end + describe "with exception: false" do + it "returns nil for invalid strings" do + BigDecimal("invalid", exception: false).should be_nil + BigDecimal("0invalid", exception: false).should be_nil + BigDecimal("invalid0", exception: false).should be_nil + BigDecimal("0.", exception: false).should be_nil end end diff --git a/spec/ruby/library/bigdecimal/util_spec.rb b/spec/ruby/library/bigdecimal/util_spec.rb index f41e131144..fc67fcf200 100644 --- a/spec/ruby/library/bigdecimal/util_spec.rb +++ b/spec/ruby/library/bigdecimal/util_spec.rb @@ -27,10 +27,8 @@ describe "BigDecimal's util method definitions" do Rational(22, 7).to_d(3).should == BigDecimal(3.14, 3) end - ruby_version_is "2.6" do - it "should define #to_d on nil" do - nil.to_d.should == BigDecimal(0) - end + it "should define #to_d on nil" do + nil.to_d.should == BigDecimal(0) end end diff --git a/spec/ruby/library/erb/fixtures/classes.rb b/spec/ruby/library/erb/fixtures/classes.rb index 03da889941..e07a6ed68d 100644 --- a/spec/ruby/library/erb/fixtures/classes.rb +++ b/spec/ruby/library/erb/fixtures/classes.rb @@ -1,9 +1,5 @@ module ERBSpecs def self.new_erb(input, trim_mode: nil) - if ruby_version_is "2.6" - ERB.new(input, trim_mode: trim_mode) - else - ERB.new(input, nil, trim_mode) - end + ERB.new(input, trim_mode: trim_mode) end end diff --git a/spec/ruby/library/erb/new_spec.rb b/spec/ruby/library/erb/new_spec.rb index 3bb870dd3f..f18e25939e 100644 --- a/spec/ruby/library/erb/new_spec.rb +++ b/spec/ruby/library/erb/new_spec.rb @@ -36,12 +36,10 @@ END end end - ruby_version_is "2.6" do - it "warns invalid trim_mode" do - -> do - ERBSpecs.new_erb(@eruby_str, trim_mode: '') - end.should complain(/Invalid ERB trim mode/) - end + it "warns invalid trim_mode" do + -> do + ERBSpecs.new_erb(@eruby_str, trim_mode: '') + end.should complain(/Invalid ERB trim mode/) end it "removes '\n' when trim_mode is 1 or '>'" do @@ -120,13 +118,8 @@ END it "changes '_erbout' variable name in the produced source" do input = @eruby_str - if RUBY_VERSION >= '2.6' - match_erbout = ERB.new(input, trim_mode: nil).src - match_buf = ERB.new(input, trim_mode: nil, eoutvar: 'buf').src - else - match_erbout = ERB.new(input, nil, nil).src - match_buf = ERB.new(input, nil, nil, 'buf').src - end + match_erbout = ERB.new(input, trim_mode: nil).src + match_buf = ERB.new(input, trim_mode: nil, eoutvar: 'buf').src match_erbout.gsub("_erbout", "buf").should == match_buf end diff --git a/spec/ruby/library/matrix/antisymmetric_spec.rb b/spec/ruby/library/matrix/antisymmetric_spec.rb index a0d1a5f69b..dcc3c30f3e 100644 --- a/spec/ruby/library/matrix/antisymmetric_spec.rb +++ b/spec/ruby/library/matrix/antisymmetric_spec.rb @@ -3,37 +3,35 @@ require_relative '../../spec_helper' ruby_version_is ""..."3.1" do require 'matrix' - ruby_version_is "2.6" do - describe "Matrix#antisymmetric?" do - it "returns true for an antisymmetric Matrix" do - Matrix[[0, -2, Complex(1, 3)], [2, 0, 5], [-Complex(1, 3), -5, 0]].antisymmetric?.should be_true - end + describe "Matrix#antisymmetric?" do + it "returns true for an antisymmetric Matrix" do + Matrix[[0, -2, Complex(1, 3)], [2, 0, 5], [-Complex(1, 3), -5, 0]].antisymmetric?.should be_true + end - it "returns true for a 0x0 empty matrix" do - Matrix.empty.antisymmetric?.should be_true - end + it "returns true for a 0x0 empty matrix" do + Matrix.empty.antisymmetric?.should be_true + end - it "returns false for non-antisymmetric matrices" do - [ - Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]], - Matrix[[1, -2, 3], [2, 0, 6], [-3, -6, 0]], # wrong diagonal element - Matrix[[0, 2, -3], [2, 0, 6], [-3, 6, 0]] # only signs wrong - ].each do |matrix| - matrix.antisymmetric?.should be_false - end + it "returns false for non-antisymmetric matrices" do + [ + Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]], + Matrix[[1, -2, 3], [2, 0, 6], [-3, -6, 0]], # wrong diagonal element + Matrix[[0, 2, -3], [2, 0, 6], [-3, 6, 0]] # only signs wrong + ].each do |matrix| + matrix.antisymmetric?.should be_false end + end - it "raises an error for rectangular matrices" do - [ - Matrix[[0], [0]], - Matrix[[0, 0]], - Matrix.empty(0, 2), - Matrix.empty(2, 0), - ].each do |rectangular_matrix| - -> { - rectangular_matrix.antisymmetric? - }.should raise_error(Matrix::ErrDimensionMismatch) - end + it "raises an error for rectangular matrices" do + [ + Matrix[[0], [0]], + Matrix[[0, 0]], + Matrix.empty(0, 2), + Matrix.empty(2, 0), + ].each do |rectangular_matrix| + -> { + rectangular_matrix.antisymmetric? + }.should raise_error(Matrix::ErrDimensionMismatch) end end end diff --git a/spec/ruby/library/monitor/enter_spec.rb b/spec/ruby/library/monitor/enter_spec.rb new file mode 100644 index 0000000000..f523c42087 --- /dev/null +++ b/spec/ruby/library/monitor/enter_spec.rb @@ -0,0 +1,28 @@ +require_relative '../../spec_helper' +require 'monitor' + +describe "Monitor#enter" do + it "acquires the monitor" do + monitor = Monitor.new + 10.times do + wait_q = Queue.new + continue_q = Queue.new + + thread = Thread.new do + begin + monitor.enter + wait_q << true + continue_q.pop + ensure + monitor.exit + end + end + + wait_q.pop + monitor.mon_locked?.should == true + continue_q << true + thread.join + monitor.mon_locked?.should == false + end + end +end diff --git a/spec/ruby/library/monitor/new_cond_spec.rb b/spec/ruby/library/monitor/new_cond_spec.rb new file mode 100644 index 0000000000..ec25d3f8a2 --- /dev/null +++ b/spec/ruby/library/monitor/new_cond_spec.rb @@ -0,0 +1,88 @@ +require_relative '../../spec_helper' +require 'monitor' + +describe "Monitor#new_cond" do + it "creates a MonitorMixin::ConditionVariable" do + m = Monitor.new + c = m.new_cond + c.class.should == MonitorMixin::ConditionVariable + end + + it 'returns a condition variable which can be waited on by a thread holding the monitor' do + m = Monitor.new + c = m.new_cond + + 10.times do + + wait_q = Queue.new + thread = Thread.new do + m.synchronize do + wait_q << true + c.wait + end + :done + end + + wait_q.pop + + # Synchronize can't happen until the other thread is waiting. + m.synchronize { c.signal } + + thread.join + thread.value.should == :done + end + end + + it 'returns a condition variable which can be waited on by a thread holding the monitor inside multiple synchronize blocks' do + m = Monitor.new + c = m.new_cond + + 10.times do + + wait_q = Queue.new + thread = Thread.new do + m.synchronize do + m.synchronize do + wait_q << true + c.wait + end + end + :done + end + + wait_q.pop + + #No need to wait here as we cannot synchronize until the other thread is waiting. + m.synchronize { c.signal } + + thread.join + thread.value.should == :done + end + end + + it 'returns a condition variable which can be signalled by a thread holding the monitor inside multiple synchronize blocks' do + m = Monitor.new + c = m.new_cond + + 10.times do + + wait_q = Queue.new + thread = Thread.new do + m.synchronize do + wait_q << true + c.wait + end + :done + end + + wait_q.pop + + # Synchronize can't happen until the other thread is waiting. + m.synchronize { m.synchronize { c.signal } } + + thread.join + thread.value.should == :done + end + end + +end diff --git a/spec/ruby/library/monitor/synchronize_spec.rb b/spec/ruby/library/monitor/synchronize_spec.rb index d851b98d6c..d78393eb3a 100644 --- a/spec/ruby/library/monitor/synchronize_spec.rb +++ b/spec/ruby/library/monitor/synchronize_spec.rb @@ -7,24 +7,35 @@ describe "Monitor#synchronize" do monitor = Monitor.new 10.times do - locked = false + wait_q = Queue.new + continue_q = Queue.new thread = Thread.new do begin monitor.synchronize do - locked = true + wait_q << true # Do not wait here, we are trying to interrupt the ensure part of #synchronize end - sleep # wait for exception if it did not happen yet + continue_q.pop rescue exc_class monitor.should_not.mon_locked? :ok end end - Thread.pass until locked + wait_q.pop thread.raise exc_class, "interrupt" + continue_q << true thread.value.should == :ok end end + + it "raises a LocalJumpError if not passed a block" do + -> { Monitor.new.synchronize }.should raise_error(LocalJumpError) + end + + it "raises a thread error if the monitor is not owned on exiting the block" do + monitor = Monitor.new + -> { monitor.synchronize { monitor.exit } }.should raise_error(ThreadError) + end end diff --git a/spec/ruby/library/monitor/try_enter_spec.rb b/spec/ruby/library/monitor/try_enter_spec.rb new file mode 100644 index 0000000000..04b878f720 --- /dev/null +++ b/spec/ruby/library/monitor/try_enter_spec.rb @@ -0,0 +1,39 @@ +require_relative '../../spec_helper' +require 'monitor' + +describe "Monitor#try_enter" do + it "will acquire a monitor not held by another thread" do + monitor = Monitor.new + 10.times do + + thread = Thread.new do + val = monitor.try_enter + monitor.exit if val + val + end + + thread.join + thread.value.should == true + end + end + + it "will not acquire a monitor already held by another thread" do + monitor = Monitor.new + 10.times do + monitor.enter + begin + thread = Thread.new do + val = monitor.try_enter + monitor.exit if val + val + end + + thread.join + thread.value.should == false + ensure + monitor.exit + end + monitor.mon_locked?.should == false + end + end +end diff --git a/spec/ruby/library/net/http/HTTPClientExcepton_spec.rb b/spec/ruby/library/net/http/HTTPClientExcepton_spec.rb index 08347464ec..d576349a57 100644 --- a/spec/ruby/library/net/http/HTTPClientExcepton_spec.rb +++ b/spec/ruby/library/net/http/HTTPClientExcepton_spec.rb @@ -1,14 +1,12 @@ require_relative '../../../spec_helper' require 'net/http' -ruby_version_is "2.6" do - describe "Net::HTTPClientException" do - it "is a subclass of Net::ProtoServerError" do - Net::HTTPClientException.should < Net::ProtoServerError - end +describe "Net::HTTPClientException" do + it "is a subclass of Net::ProtoServerError" do + Net::HTTPClientException.should < Net::ProtoServerError + end - it "includes the Net::HTTPExceptions module" do - Net::HTTPClientException.should < Net::HTTPExceptions - end + it "includes the Net::HTTPExceptions module" do + Net::HTTPClientException.should < Net::HTTPExceptions end end diff --git a/spec/ruby/library/net/http/HTTPServerException_spec.rb b/spec/ruby/library/net/http/HTTPServerException_spec.rb index 87841ab499..23b0657364 100644 --- a/spec/ruby/library/net/http/HTTPServerException_spec.rb +++ b/spec/ruby/library/net/http/HTTPServerException_spec.rb @@ -1,26 +1,12 @@ require_relative '../../../spec_helper' require 'net/http' -ruby_version_is ""..."2.6" do - describe "Net::HTTPServerException" do - it "is a subclass of Net::ProtoServerError" do - Net::HTTPServerException.should < Net::ProtoServerError - end - - it "includes the Net::HTTPExceptions module" do - Net::HTTPServerException.should < Net::HTTPExceptions - end +describe "Net::HTTPServerException" do + it "is a subclass of Net::ProtoServerError and is warned as deprecated" do + -> { Net::HTTPServerException.should < Net::ProtoServerError }.should complain(/warning: constant Net::HTTPServerException is deprecated/) end -end - -ruby_version_is "2.6" do - describe "Net::HTTPServerException" do - it "is a subclass of Net::ProtoServerError and is warned as deprecated" do - -> { Net::HTTPServerException.should < Net::ProtoServerError }.should complain(/warning: constant Net::HTTPServerException is deprecated/) - end - it "includes the Net::HTTPExceptions module and is warned as deprecated" do - -> { Net::HTTPServerException.should < Net::HTTPExceptions }.should complain(/warning: constant Net::HTTPServerException is deprecated/) - end + it "includes the Net::HTTPExceptions module and is warned as deprecated" do + -> { Net::HTTPServerException.should < Net::HTTPExceptions }.should complain(/warning: constant Net::HTTPServerException is deprecated/) end end diff --git a/spec/ruby/library/net/http/http/fixtures/http_server.rb b/spec/ruby/library/net/http/http/fixtures/http_server.rb index a84e0d47d0..c06012cc86 100644 --- a/spec/ruby/library/net/http/http/fixtures/http_server.rb +++ b/spec/ruby/library/net/http/http/fixtures/http_server.rb @@ -63,8 +63,9 @@ module NetHTTPSpecs end def start_server + bind_address = platform_is(:windows) ? "localhost" : "127.0.0.1" server_config = { - BindAddress: "localhost", + BindAddress: bind_address, Port: 0, Logger: WEBrick::Log.new(NullWriter.new), AccessLog: [], diff --git a/spec/ruby/library/net/http/httpresponse/error_spec.rb b/spec/ruby/library/net/http/httpresponse/error_spec.rb index d2b2f53d89..89f4a47f60 100644 --- a/spec/ruby/library/net/http/httpresponse/error_spec.rb +++ b/spec/ruby/library/net/http/httpresponse/error_spec.rb @@ -16,12 +16,7 @@ describe "Net::HTTPResponse#error!" do -> { res.error! }.should raise_error(Net::HTTPRetriableError) res = Net::HTTPClientError.new("1.0", "4xx", "test response") - ruby_version_is ""..."2.6" do - -> { res.error! }.should raise_error(Net::HTTPServerException) - end - ruby_version_is "2.6" do - -> { res.error! }.should raise_error(Net::HTTPClientException) - end + -> { res.error! }.should raise_error(Net::HTTPClientException) res = Net::HTTPServerError.new("1.0", "5xx", "test response") -> { res.error! }.should raise_error(Net::HTTPFatalError) diff --git a/spec/ruby/library/net/http/httpresponse/error_type_spec.rb b/spec/ruby/library/net/http/httpresponse/error_type_spec.rb index 6705f8b1aa..8885b7706b 100644 --- a/spec/ruby/library/net/http/httpresponse/error_type_spec.rb +++ b/spec/ruby/library/net/http/httpresponse/error_type_spec.rb @@ -16,12 +16,7 @@ describe "Net::HTTPResponse#error_type" do res.error_type.should == Net::HTTPRetriableError res = Net::HTTPClientError.new("1.0", "4xx", "test response") - ruby_version_is ""..."2.6" do - res.error_type.should == Net::HTTPServerException - end - ruby_version_is "2.6" do - res.error_type.should == Net::HTTPClientException - end + res.error_type.should == Net::HTTPClientException res = Net::HTTPServerError.new("1.0", "5xx", "test response") res.error_type.should == Net::HTTPFatalError diff --git a/spec/ruby/library/net/http/httpresponse/exception_type_spec.rb b/spec/ruby/library/net/http/httpresponse/exception_type_spec.rb index c0812cd322..0c9c11291f 100644 --- a/spec/ruby/library/net/http/httpresponse/exception_type_spec.rb +++ b/spec/ruby/library/net/http/httpresponse/exception_type_spec.rb @@ -7,12 +7,7 @@ describe "Net::HTTPResponse.exception_type" do Net::HTTPInformation.exception_type.should == Net::HTTPError Net::HTTPSuccess.exception_type.should == Net::HTTPError Net::HTTPRedirection.exception_type.should == Net::HTTPRetriableError - ruby_version_is ""..."2.6" do - Net::HTTPClientError.exception_type.should == Net::HTTPServerException - end - ruby_version_is "2.6" do - Net::HTTPClientError.exception_type.should == Net::HTTPClientException - end + Net::HTTPClientError.exception_type.should == Net::HTTPClientException Net::HTTPServerError.exception_type.should == Net::HTTPFatalError end end diff --git a/spec/ruby/library/net/http/httpresponse/value_spec.rb b/spec/ruby/library/net/http/httpresponse/value_spec.rb index 4a5930d4e5..5cd58316ef 100644 --- a/spec/ruby/library/net/http/httpresponse/value_spec.rb +++ b/spec/ruby/library/net/http/httpresponse/value_spec.rb @@ -16,12 +16,7 @@ describe "Net::HTTPResponse#value" do -> { res.value }.should raise_error(Net::HTTPRetriableError) res = Net::HTTPClientError.new("1.0", "4xx", "test response") - ruby_version_is ""..."2.6" do - -> { res.value }.should raise_error(Net::HTTPServerException) - end - ruby_version_is "2.6" do - -> { res.value }.should raise_error(Net::HTTPClientException) - end + -> { res.value }.should raise_error(Net::HTTPClientException) res = Net::HTTPServerError.new("1.0", "5xx", "test response") -> { res.value }.should raise_error(Net::HTTPFatalError) diff --git a/spec/ruby/library/objectspace/memsize_of_all_spec.rb b/spec/ruby/library/objectspace/memsize_of_all_spec.rb new file mode 100644 index 0000000000..6898862e8f --- /dev/null +++ b/spec/ruby/library/objectspace/memsize_of_all_spec.rb @@ -0,0 +1,21 @@ +require_relative '../../spec_helper' +require 'objspace' + +describe "ObjectSpace.memsize_of_all" do + it "returns a non-zero Integer for all objects" do + ObjectSpace.memsize_of_all.should be_kind_of(Integer) + ObjectSpace.memsize_of_all.should > 0 + end + + it "returns a non-zero Integer for Class" do + ObjectSpace.memsize_of_all(Class).should be_kind_of(Integer) + ObjectSpace.memsize_of_all(Class).should > 0 + end + + it "increases when a new object is allocated" do + before = ObjectSpace.memsize_of_all(Class) + o = Class.new + after = ObjectSpace.memsize_of_all(Class) + after.should > before + end +end diff --git a/spec/ruby/library/objectspace/memsize_of_spec.rb b/spec/ruby/library/objectspace/memsize_of_spec.rb index 36d845824d..eefafbb334 100644 --- a/spec/ruby/library/objectspace/memsize_of_spec.rb +++ b/spec/ruby/library/objectspace/memsize_of_spec.rb @@ -16,7 +16,7 @@ describe "ObjectSpace.memsize_of" do ObjectSpace.memsize_of(:abc).should == 0 end - it "returns an Integer for an Object" do + it "returns a positive Integer for an Object" do obj = Object.new ObjectSpace.memsize_of(obj).should be_kind_of(Integer) ObjectSpace.memsize_of(obj).should > 0 diff --git a/spec/ruby/library/objectspace/trace_object_allocations_spec.rb b/spec/ruby/library/objectspace/trace_object_allocations_spec.rb new file mode 100644 index 0000000000..3100511dc9 --- /dev/null +++ b/spec/ruby/library/objectspace/trace_object_allocations_spec.rb @@ -0,0 +1,131 @@ +require_relative '../../spec_helper' +require 'objspace' + +describe "ObjectSpace.trace_object_allocations" do + it "runs a block" do + ScratchPad.clear + ObjectSpace.trace_object_allocations do + ScratchPad.record :a + end + ScratchPad.recorded.should == :a + end + + it "records info for allocation_class_path" do + ObjectSpace.trace_object_allocations do + o = Object.new + ObjectSpace.allocation_class_path(o).should == "Class" + a = [1, 2, 3] + ObjectSpace.allocation_class_path(a).should == nil + end + end + + it "records info for allocation_generation" do + ObjectSpace.trace_object_allocations do + o = Object.new + ObjectSpace.allocation_generation(o).should.kind_of?(Integer) + a = [1, 2, 3] + ObjectSpace.allocation_generation(a).should.kind_of?(Integer) + end + end + + it "records info for allocation_method_id" do + ObjectSpace.trace_object_allocations do + o = Object.new + ObjectSpace.allocation_method_id(o).should == :new + a = [1, 2, 3] + ObjectSpace.allocation_method_id(a).should == nil + end + end + + it "records info for allocation_sourcefile" do + ObjectSpace.trace_object_allocations do + o = Object.new + ObjectSpace.allocation_sourcefile(o).should == __FILE__ + a = [1, 2, 3] + ObjectSpace.allocation_sourcefile(a).should == __FILE__ + end + end + + it "records info for allocation_sourceline" do + ObjectSpace.trace_object_allocations do + o = Object.new + ObjectSpace.allocation_sourceline(o).should == __LINE__ - 1 + a = [1, 2, 3] + ObjectSpace.allocation_sourceline(a).should == __LINE__ - 1 + end + end + + it "can be cleared using trace_object_allocations_clear" do + ObjectSpace.trace_object_allocations do + o = Object.new + ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.trace_object_allocations_clear + ObjectSpace.allocation_class_path(o).should be_nil + end + end + + it "does not clears allocation data after returning" do + o = nil + ObjectSpace.trace_object_allocations do + o = Object.new + end + ObjectSpace.allocation_class_path(o).should == "Class" + end + + it "can be used without a block using trace_object_allocations_start and _stop" do + ObjectSpace.trace_object_allocations_start + begin + o = Object.new + ObjectSpace.allocation_class_path(o).should == "Class" + a = [1, 2, 3] + ObjectSpace.allocation_class_path(a).should == nil + ensure + ObjectSpace.trace_object_allocations_stop + end + end + + it "does not clears allocation data after trace_object_allocations_stop" do + ObjectSpace.trace_object_allocations_start + begin + o = Object.new + ensure + ObjectSpace.trace_object_allocations_stop + end + ObjectSpace.allocation_class_path(o).should == "Class" + end + + it "can be nested" do + ObjectSpace.trace_object_allocations do + ObjectSpace.trace_object_allocations do + o = Object.new + ObjectSpace.allocation_class_path(o).should == "Class" + end + end + end + + it "can be nested without a block using trace_object_allocations_start and _stop" do + ObjectSpace.trace_object_allocations_start + begin + ObjectSpace.trace_object_allocations_start + begin + o = Object.new + ObjectSpace.allocation_class_path(o).should == "Class" + ensure + ObjectSpace.trace_object_allocations_stop + end + ensure + ObjectSpace.trace_object_allocations_stop + end + end + + it "can be nested with more _stop than _start" do + ObjectSpace.trace_object_allocations_start + begin + o = Object.new + ObjectSpace.allocation_class_path(o).should == "Class" + ObjectSpace.trace_object_allocations_stop + ensure + ObjectSpace.trace_object_allocations_stop + end + end +end diff --git a/spec/ruby/library/openstruct/to_h_spec.rb b/spec/ruby/library/openstruct/to_h_spec.rb index ebdec16174..6c272bcc71 100644 --- a/spec/ruby/library/openstruct/to_h_spec.rb +++ b/spec/ruby/library/openstruct/to_h_spec.rb @@ -27,44 +27,42 @@ describe "OpenStruct#to_h" do @os.age.should == 70 end - ruby_version_is "2.6" do - context "with block" do - it "converts [key, value] pairs returned by the block to a hash" do - h = @os.to_h { |k, v| [k.to_s, v*2] } - h.should == { "name" => "John SmithJohn Smith", "age" => 140, "pension" => 600 } - end + context "with block" do + it "converts [key, value] pairs returned by the block to a hash" do + h = @os.to_h { |k, v| [k.to_s, v*2] } + h.should == { "name" => "John SmithJohn Smith", "age" => 140, "pension" => 600 } + end - it "raises ArgumentError if block returns longer or shorter array" do - -> do - @os.to_h { |k, v| [k.to_s, v*2, 1] } - end.should raise_error(ArgumentError, /element has wrong array length/) + it "raises ArgumentError if block returns longer or shorter array" do + -> do + @os.to_h { |k, v| [k.to_s, v*2, 1] } + end.should raise_error(ArgumentError, /element has wrong array length/) - -> do - @os.to_h { |k, v| [k] } - end.should raise_error(ArgumentError, /element has wrong array length/) - end + -> do + @os.to_h { |k, v| [k] } + end.should raise_error(ArgumentError, /element has wrong array length/) + end - it "raises TypeError if block returns something other than Array" do - -> do - @os.to_h { |k, v| "not-array" } - end.should raise_error(TypeError, /wrong element type String/) - end + it "raises TypeError if block returns something other than Array" do + -> do + @os.to_h { |k, v| "not-array" } + end.should raise_error(TypeError, /wrong element type String/) + end - it "coerces returned pair to Array with #to_ary" do - x = mock('x') - x.stub!(:to_ary).and_return([:b, 'b']) + it "coerces returned pair to Array with #to_ary" do + x = mock('x') + x.stub!(:to_ary).and_return([:b, 'b']) - @os.to_h { |k| x }.should == { :b => 'b' } - end + @os.to_h { |k| x }.should == { :b => 'b' } + end - it "does not coerce returned pair to Array with #to_a" do - x = mock('x') - x.stub!(:to_a).and_return([:b, 'b']) + it "does not coerce returned pair to Array with #to_a" do + x = mock('x') + x.stub!(:to_a).and_return([:b, 'b']) - -> do - @os.to_h { |k| x } - end.should raise_error(TypeError, /wrong element type MockObject/) - end + -> do + @os.to_h { |k| x } + end.should raise_error(TypeError, /wrong element type MockObject/) end end end diff --git a/spec/ruby/library/rbconfig/unicode_version_spec.rb b/spec/ruby/library/rbconfig/unicode_version_spec.rb index a6dc6478ff..fe19b10293 100644 --- a/spec/ruby/library/rbconfig/unicode_version_spec.rb +++ b/spec/ruby/library/rbconfig/unicode_version_spec.rb @@ -2,12 +2,6 @@ require_relative '../../spec_helper' require 'rbconfig' describe "RbConfig::CONFIG['UNICODE_VERSION']" do - ruby_version_is "2.5"..."2.6" do - it "is 10.0.0 for Ruby 2.5" do - RbConfig::CONFIG['UNICODE_VERSION'].should == "10.0.0" - end - end - ruby_version_is "2.6"..."2.6.2" do it "is 11.0.0 for Ruby 2.6.0 and 2.6.1" do RbConfig::CONFIG['UNICODE_VERSION'].should == "11.0.0" diff --git a/spec/ruby/library/set/filter_spec.rb b/spec/ruby/library/set/filter_spec.rb index a4dfe70d52..779254ad68 100644 --- a/spec/ruby/library/set/filter_spec.rb +++ b/spec/ruby/library/set/filter_spec.rb @@ -1,8 +1,6 @@ require_relative '../../spec_helper' require_relative 'shared/select' -ruby_version_is "2.6" do - describe "Set#filter!" do - it_behaves_like :set_select_bang, :filter! - end +describe "Set#filter!" do + it_behaves_like :set_select_bang, :filter! end diff --git a/spec/ruby/library/set/sortedset/filter_spec.rb b/spec/ruby/library/set/sortedset/filter_spec.rb index c6d881de67..3b9dcb63c9 100644 --- a/spec/ruby/library/set/sortedset/filter_spec.rb +++ b/spec/ruby/library/set/sortedset/filter_spec.rb @@ -4,9 +4,7 @@ ruby_version_is ""..."3.0" do require_relative 'shared/select' require 'set' - ruby_version_is "2.6" do - describe "SortedSet#filter!" do - it_behaves_like :sorted_set_select_bang, :filter! - end + describe "SortedSet#filter!" do + it_behaves_like :sorted_set_select_bang, :filter! end end diff --git a/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb index 0363f2f8de..b6ab8a9cea 100644 --- a/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb +++ b/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb @@ -67,4 +67,25 @@ describe "Socket::BasicSocket#recv_nonblock" do }.should raise_error(IO::WaitReadable) end end + + SocketSpecs.each_ip_protocol do |family, ip_address| + describe 'using a connected but not bound socket' do + before do + @server = Socket.new(family, :STREAM) + end + + after do + @server.close + end + + it "raises Errno::ENOTCONN" do + -> { @server.recv_nonblock(1) }.should raise_error { |e| + [Errno::ENOTCONN, Errno::EINVAL].should.include?(e.class) + } + -> { @server.recv_nonblock(1, exception: false) }.should raise_error { |e| + [Errno::ENOTCONN, Errno::EINVAL].should.include?(e.class) + } + end + end + end end diff --git a/spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb index 8e6c232c59..cc4275c417 100644 --- a/spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb +++ b/spec/ruby/library/socket/basicsocket/recvmsg_nonblock_spec.rb @@ -114,6 +114,21 @@ describe 'BasicSocket#recvmsg_nonblock' do end platform_is_not :windows do + describe 'using a connected but not bound socket' do + before do + @server = Socket.new(family, :STREAM) + end + + after do + @server.close + end + + it "raises Errno::ENOTCONN" do + -> { @server.recvmsg_nonblock }.should raise_error(Errno::ENOTCONN) + -> { @server.recvmsg_nonblock(exception: false) }.should raise_error(Errno::ENOTCONN) + end + end + describe 'using a connected socket' do before do @client = Socket.new(family, :STREAM) diff --git a/spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb index c112f2ab4a..7acfc659bd 100644 --- a/spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb +++ b/spec/ruby/library/socket/basicsocket/sendmsg_nonblock_spec.rb @@ -18,7 +18,12 @@ describe 'BasicSocket#sendmsg_nonblock' do describe 'without a destination address' do it "raises #{SocketSpecs.dest_addr_req_error}" do - -> { @client.sendmsg_nonblock('hello') }.should raise_error(SocketSpecs.dest_addr_req_error) + -> { + @client.sendmsg_nonblock('hello') + }.should raise_error(SocketSpecs.dest_addr_req_error) + -> { + @client.sendmsg_nonblock('hello', exception: false) + }.should raise_error(SocketSpecs.dest_addr_req_error) end end diff --git a/spec/ruby/library/socket/socket/accept_nonblock_spec.rb b/spec/ruby/library/socket/socket/accept_nonblock_spec.rb index 3221f0b128..011622988c 100644 --- a/spec/ruby/library/socket/socket/accept_nonblock_spec.rb +++ b/spec/ruby/library/socket/socket/accept_nonblock_spec.rb @@ -46,6 +46,7 @@ describe 'Socket#accept_nonblock' do describe 'using an unbound socket' do it 'raises Errno::EINVAL' do -> { @server.accept_nonblock }.should raise_error(Errno::EINVAL) + -> { @server.accept_nonblock(exception: false) }.should raise_error(Errno::EINVAL) end end @@ -56,6 +57,7 @@ describe 'Socket#accept_nonblock' do it 'raises Errno::EINVAL' do -> { @server.accept_nonblock }.should raise_error(Errno::EINVAL) + -> { @server.accept_nonblock(exception: false) }.should raise_error(Errno::EINVAL) end end @@ -64,6 +66,7 @@ describe 'Socket#accept_nonblock' do @server.close -> { @server.accept_nonblock }.should raise_error(IOError) + -> { @server.accept_nonblock(exception: false) }.should raise_error(IOError) end end diff --git a/spec/ruby/optional/capi/debug_spec.rb b/spec/ruby/optional/capi/debug_spec.rb index 89e72f0049..c8c91417d1 100644 --- a/spec/ruby/optional/capi/debug_spec.rb +++ b/spec/ruby/optional/capi/debug_spec.rb @@ -34,13 +34,11 @@ describe "C-API Debug function" do b.local_variable_get(:a).should == "test" end - ruby_version_is "2.6" do - it "matches the locations in rb_debug_inspector_backtrace_locations" do - frames = @o.rb_debug_inspector_open(42); - frames.each do |_s, _klass, binding, _iseq, backtrace_location| - if binding - "#{backtrace_location.path}:#{backtrace_location.lineno}".should == "#{binding.source_location[0]}:#{binding.source_location[1]}" - end + it "matches the locations in rb_debug_inspector_backtrace_locations" do + frames = @o.rb_debug_inspector_open(42); + frames.each do |_s, _klass, binding, _iseq, backtrace_location| + if binding + "#{backtrace_location.path}:#{backtrace_location.lineno}".should == "#{binding.source_location[0]}:#{binding.source_location[1]}" end end end diff --git a/spec/ruby/optional/capi/encoding_spec.rb b/spec/ruby/optional/capi/encoding_spec.rb index 93bde54069..66c2dd40de 100644 --- a/spec/ruby/optional/capi/encoding_spec.rb +++ b/spec/ruby/optional/capi/encoding_spec.rb @@ -31,13 +31,11 @@ describe :rb_enc_set_index, shared: true do result.first.should == result.last end - ruby_version_is "2.6" do - it "raises an ArgumentError for a non-encoding capable object" do - obj = Object.new - -> { - result = @s.send(@method, obj, 1) - }.should raise_error(ArgumentError, "cannot set encoding on non-encoding capable object") - end + it "raises an ArgumentError for a non-encoding capable object" do + obj = Object.new + -> { + result = @s.send(@method, obj, 1) + }.should raise_error(ArgumentError, "cannot set encoding on non-encoding capable object") end end @@ -48,13 +46,11 @@ describe "C-API Encoding function" do @s = CApiEncodingSpecs.new end - ruby_version_is "2.6" do - describe "rb_enc_alias" do - it "creates an alias for an existing Encoding" do - name = "ZOMGWTFBBQ#{@n += 1}" - @s.rb_enc_alias(name, "UTF-8").should >= 0 - Encoding.find(name).name.should == "UTF-8" - end + describe "rb_enc_alias" do + it "creates an alias for an existing Encoding" do + name = "ZOMGWTFBBQ#{@n += 1}" + @s.rb_enc_alias(name, "UTF-8").should >= 0 + Encoding.find(name).name.should == "UTF-8" end end @@ -239,11 +235,9 @@ describe "C-API Encoding function" do @s.rb_enc_get_index(1).should == -1 end - ruby_version_is "2.6" do - it "returns -1 for an object without an encoding" do - obj = Object.new - @s.rb_enc_get_index(obj).should == -1 - end + it "returns -1 for an object without an encoding" do + obj = Object.new + @s.rb_enc_get_index(obj).should == -1 end end diff --git a/spec/ruby/optional/capi/ext/fiber_spec.c b/spec/ruby/optional/capi/ext/fiber_spec.c new file mode 100644 index 0000000000..7912e878f3 --- /dev/null +++ b/spec/ruby/optional/capi/ext/fiber_spec.c @@ -0,0 +1,58 @@ +#include "ruby.h" +#include "rubyspec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +VALUE fiber_spec_rb_fiber_current(VALUE self) { + return rb_fiber_current(); +} + +VALUE fiber_spec_rb_fiber_alive_p(VALUE self, VALUE fiber) { + return rb_fiber_alive_p(fiber); +} + +VALUE fiber_spec_rb_fiber_resume(VALUE self, VALUE fiber, VALUE ary) { + long argc = RARRAY_LEN(ary); + VALUE *argv = (VALUE*) alloca(sizeof(VALUE) * argc); + int i; + + for (i = 0; i < argc; i++) { + argv[i] = rb_ary_entry(ary, i); + } + + return rb_fiber_resume(fiber, (int)argc, argv); +} + +VALUE fiber_spec_rb_fiber_yield(VALUE self, VALUE ary) { + long argc = RARRAY_LEN(ary); + VALUE *argv = (VALUE*) alloca(sizeof(VALUE) * argc); + int i; + + for (i = 0; i < argc; i++) { + argv[i] = rb_ary_entry(ary, i); + } + return rb_fiber_yield((int)argc, argv); +} + +VALUE fiber_spec_rb_fiber_new_function(RB_BLOCK_CALL_FUNC_ARGLIST(args, dummy)) { + return rb_funcall(args, rb_intern("inspect"), 0); +} + +VALUE fiber_spec_rb_fiber_new(VALUE self) { + return rb_fiber_new(fiber_spec_rb_fiber_new_function, Qnil); +} + +void Init_fiber_spec(void) { + VALUE cls = rb_define_class("CApiFiberSpecs", rb_cObject); + rb_define_method(cls, "rb_fiber_current", fiber_spec_rb_fiber_current, 0); + rb_define_method(cls, "rb_fiber_alive_p", fiber_spec_rb_fiber_alive_p, 1); + rb_define_method(cls, "rb_fiber_resume", fiber_spec_rb_fiber_resume, 2); + rb_define_method(cls, "rb_fiber_yield", fiber_spec_rb_fiber_yield, 1); + rb_define_method(cls, "rb_fiber_new", fiber_spec_rb_fiber_new, 0); +} + +#ifdef __cplusplus +} +#endif diff --git a/spec/ruby/optional/capi/ext/regexp_spec.c b/spec/ruby/optional/capi/ext/regexp_spec.c index 70780bae2a..0a62616f33 100644 --- a/spec/ruby/optional/capi/ext/regexp_spec.c +++ b/spec/ruby/optional/capi/ext/regexp_spec.c @@ -35,6 +35,11 @@ VALUE regexp_spec_backref_get(VALUE self) { return rb_backref_get(); } +static VALUE regexp_spec_backref_set(VALUE self, VALUE backref) { + rb_backref_set(backref); + return Qnil; +} + VALUE regexp_spec_reg_match_backref_get(VALUE self, VALUE re, VALUE str) { rb_reg_match(re, str); return rb_backref_get(); @@ -51,6 +56,7 @@ void Init_regexp_spec(void) { rb_define_method(cls, "a_re_1st_match", regexp_spec_reg_1st_match, 1); rb_define_method(cls, "rb_reg_match", regexp_spec_reg_match, 2); rb_define_method(cls, "rb_backref_get", regexp_spec_backref_get, 0); + rb_define_method(cls, "rb_backref_set", regexp_spec_backref_set, 1); rb_define_method(cls, "rb_reg_match_backref_get", regexp_spec_reg_match_backref_get, 2); rb_define_method(cls, "rb_reg_options", regexp_spec_rb_reg_options, 1); rb_define_method(cls, "rb_reg_regcomp", regexp_spec_rb_reg_regcomp, 1); diff --git a/spec/ruby/optional/capi/ext/rubyspec.h b/spec/ruby/optional/capi/ext/rubyspec.h index a10ab49f7c..7e4a252b38 100644 --- a/spec/ruby/optional/capi/ext/rubyspec.h +++ b/spec/ruby/optional/capi/ext/rubyspec.h @@ -55,6 +55,7 @@ #define rb_catch(tag, func, data) rb_catch(tag, RUBY_METHOD_FUNC(func), data) #define rb_catch_obj(tag, func, data) rb_catch_obj(tag, RUBY_METHOD_FUNC(func), data) #define rb_proc_new(fn, arg) rb_proc_new(RUBY_METHOD_FUNC(fn), arg) +#define rb_fiber_new(fn, arg) rb_fiber_new(RUBY_METHOD_FUNC(fn), arg) #define rb_thread_create(fn, arg) rb_thread_create(RUBY_METHOD_FUNC(fn), arg) #define rb_define_hooked_variable(name, var, getter, setter) rb_define_hooked_variable(name, var, RUBY_METHOD_FUNC(getter), (void (*)(...))setter) #endif diff --git a/spec/ruby/optional/capi/ext/string_spec.c b/spec/ruby/optional/capi/ext/string_spec.c index dd7bc397cd..f2245be0ef 100644 --- a/spec/ruby/optional/capi/ext/string_spec.c +++ b/spec/ruby/optional/capi/ext/string_spec.c @@ -1,6 +1,7 @@ #include "ruby.h" #include "rubyspec.h" +#include <fcntl.h> #include <string.h> #include <stdarg.h> @@ -279,6 +280,16 @@ VALUE string_spec_rb_str_resize_RSTRING_LEN(VALUE self, VALUE str, VALUE size) { return INT2FIX(RSTRING_LEN(modified)); } +VALUE string_spec_rb_str_resize_copy(VALUE self, VALUE str) { + rb_str_modify_expand(str, 5); + char *buffer = RSTRING_PTR(str); + buffer[1] = 'e'; + buffer[2] = 's'; + buffer[3] = 't'; + rb_str_resize(str, 4); + return str; +} + VALUE string_spec_rb_str_split(VALUE self, VALUE str) { return rb_str_split(str, ","); } @@ -374,6 +385,20 @@ VALUE string_spec_RSTRING_PTR_after_yield(VALUE self, VALUE str) { return from_rstring_ptr; } +VALUE string_spec_RSTRING_PTR_read(VALUE self, VALUE str, VALUE path) { + char *cpath = StringValueCStr(path); + int fd = open(cpath, O_RDONLY); + rb_str_modify_expand(str, 10); + char *buffer = RSTRING_PTR(str); + read(fd, buffer, 10); + rb_str_modify_expand(str, 21); + char *buffer2 = RSTRING_PTR(str); + read(fd, buffer2 + 10, 11); + rb_str_set_len(str, 21); + close(fd); + return str; +} + VALUE string_spec_StringValue(VALUE self, VALUE str) { return StringValue(str); } @@ -476,6 +501,18 @@ static VALUE string_spec_rb_utf8_str_new_cstr(VALUE self) { return rb_utf8_str_new_cstr("nokogiri"); } +static VALUE call_rb_str_vcatf(VALUE mesg, const char *fmt, ...){ + va_list ap; + va_start(ap, fmt); + VALUE result = rb_str_vcatf(mesg, fmt, ap); + va_end(ap); + return result; +} + +static VALUE string_spec_rb_str_vcatf(VALUE self, VALUE mesg) { + return call_rb_str_vcatf(mesg, "fmt %d %d number", 42, 7); +} + void Init_string_spec(void) { VALUE cls = rb_define_class("CApiStringSpecs", rb_cObject); rb_define_method(cls, "rb_cstr2inum", string_spec_rb_cstr2inum, 2); @@ -527,6 +564,7 @@ void Init_string_spec(void) { rb_define_method(cls, "rb_str_modify_expand", string_spec_rb_str_modify_expand, 2); rb_define_method(cls, "rb_str_resize", string_spec_rb_str_resize, 2); rb_define_method(cls, "rb_str_resize_RSTRING_LEN", string_spec_rb_str_resize_RSTRING_LEN, 2); + rb_define_method(cls, "rb_str_resize_copy", string_spec_rb_str_resize_copy, 1); rb_define_method(cls, "rb_str_set_len", string_spec_rb_str_set_len, 2); rb_define_method(cls, "rb_str_set_len_RSTRING_LEN", string_spec_rb_str_set_len_RSTRING_LEN, 2); rb_define_method(cls, "rb_str_split", string_spec_rb_str_split, 1); @@ -542,6 +580,7 @@ void Init_string_spec(void) { rb_define_method(cls, "RSTRING_PTR_set", string_spec_RSTRING_PTR_set, 3); rb_define_method(cls, "RSTRING_PTR_after_funcall", string_spec_RSTRING_PTR_after_funcall, 2); rb_define_method(cls, "RSTRING_PTR_after_yield", string_spec_RSTRING_PTR_after_yield, 1); + rb_define_method(cls, "RSTRING_PTR_read", string_spec_RSTRING_PTR_read, 2); rb_define_method(cls, "StringValue", string_spec_StringValue, 1); rb_define_method(cls, "SafeStringValue", string_spec_SafeStringValue, 1); rb_define_method(cls, "rb_str_hash", string_spec_rb_str_hash, 1); @@ -563,6 +602,7 @@ void Init_string_spec(void) { rb_define_method(cls, "rb_utf8_str_new_static", string_spec_rb_utf8_str_new_static, 0); rb_define_method(cls, "rb_utf8_str_new", string_spec_rb_utf8_str_new, 0); rb_define_method(cls, "rb_utf8_str_new_cstr", string_spec_rb_utf8_str_new_cstr, 0); + rb_define_method(cls, "rb_str_vcatf", string_spec_rb_str_vcatf, 1); } #ifdef __cplusplus diff --git a/spec/ruby/optional/capi/fiber_spec.rb b/spec/ruby/optional/capi/fiber_spec.rb new file mode 100644 index 0000000000..196ddc45fb --- /dev/null +++ b/spec/ruby/optional/capi/fiber_spec.rb @@ -0,0 +1,51 @@ +require_relative 'spec_helper' +require 'fiber' + +load_extension('fiber') + +describe "C-API Fiber function" do + before :each do + @s = CApiFiberSpecs.new + end + + describe "rb_fiber_current" do + it "returns the current fiber" do + result = @s.rb_fiber_current() + result.should be_an_instance_of(Fiber) + result.should == Fiber.current + end + end + + describe "rb_fiber_alive_p" do + it "returns the fibers alive status" do + fiber = Fiber.new { Fiber.yield } + fiber.resume + @s.rb_fiber_alive_p(fiber).should be_true + fiber.resume + @s.rb_fiber_alive_p(fiber).should be_false + end + end + + describe "rb_fiber_resume" do + it "resumes the fiber" do + fiber = Fiber.new { |arg| Fiber.yield arg } + @s.rb_fiber_resume(fiber, [1]).should == 1 + @s.rb_fiber_resume(fiber, [2]).should == 2 + end + end + + describe "rb_fiber_yield" do + it "yields the fiber" do + fiber = Fiber.new { @s.rb_fiber_yield([1]) } + fiber.resume.should == 1 + end + end + + describe "rb_fiber_new" do + it "returns a new fiber" do + fiber = @s.rb_fiber_new + fiber.should be_an_instance_of(Fiber) + fiber.resume(42).should == "42" + end + end +end diff --git a/spec/ruby/optional/capi/fixtures/read.txt b/spec/ruby/optional/capi/fixtures/read.txt new file mode 100644 index 0000000000..f976cfd9b9 --- /dev/null +++ b/spec/ruby/optional/capi/fixtures/read.txt @@ -0,0 +1 @@ +fixture file contents diff --git a/spec/ruby/optional/capi/proc_spec.rb b/spec/ruby/optional/capi/proc_spec.rb index ff119416f6..6e797fdeb4 100644 --- a/spec/ruby/optional/capi/proc_spec.rb +++ b/spec/ruby/optional/capi/proc_spec.rb @@ -104,8 +104,9 @@ describe "C-API when calling Proc.new from a C function" do # Ruby -> C -> Ruby -> Proc.new it "raises an ArgumentError when the C function calls a Ruby method that calls Proc.new" do - def @p.Proc_new() Proc.new end - -> { @p.rb_Proc_new(2) { :called } }.should raise_error(ArgumentError) + -> { + @p.rb_Proc_new(2) { :called } + }.should raise_error(ArgumentError) end # Ruby -> C -> Ruby -> C -> rb_funcall(Proc.new) diff --git a/spec/ruby/optional/capi/regexp_spec.rb b/spec/ruby/optional/capi/regexp_spec.rb index 806157368d..81844e2a6e 100644 --- a/spec/ruby/optional/capi/regexp_spec.rb +++ b/spec/ruby/optional/capi/regexp_spec.rb @@ -80,4 +80,33 @@ describe "C-API Regexp function" do @p.rb_reg_match_backref_get(/a/, 'ab')[0].should == 'a' end end + + describe "rb_backref_set" do + before :each do + @md = "foo".match(/foo/) + $~ = nil + end + + it "sets the value of $~" do + @p.rb_backref_set(@md) + @p.rb_backref_get.should == @md + $~.should == @md + end + + it "sets a Thread-local value" do + running = false + + thr = Thread.new do + @p.rb_backref_set(@md) + @p.rb_backref_get.should == @md + $~.should == @md + running = true + end + + Thread.pass while thr.status and !running + $~.should be_nil + + thr.join + end + end end diff --git a/spec/ruby/optional/capi/string_spec.rb b/spec/ruby/optional/capi/string_spec.rb index 7c33b79348..151dfefef7 100644 --- a/spec/ruby/optional/capi/string_spec.rb +++ b/spec/ruby/optional/capi/string_spec.rb @@ -598,6 +598,12 @@ describe "C-API String function" do str = " " @s.RSTRING_PTR_short_memcpy(str).should == "Infinity" end + + it "allows read to update string contents" do + filename = fixture(__FILE__, "read.txt") + str = "" + @s.RSTRING_PTR_read(str, filename).should == "fixture file contents" + end end describe "RSTRING_LEN" do @@ -665,6 +671,12 @@ describe "C-API String function" do end end + describe "rb_str_modify" do + it "raises an error if the string is frozen" do + -> { @s.rb_str_modify("frozen".freeze) }.should raise_error(FrozenError) + end + end + describe "rb_str_modify_expand" do it "grows the capacity to bytesize + expand, not changing the bytesize" do str = @s.rb_str_buf_new(256, "abcd") @@ -684,6 +696,15 @@ describe "C-API String function" do str.bytesize.should == 3 @s.RSTRING_LEN(str).should == 3 @s.rb_str_capacity(str).should == 1027 + + @s.rb_str_modify_expand(str, 1) + str.bytesize.should == 3 + @s.RSTRING_LEN(str).should == 3 + @s.rb_str_capacity(str).should == 4 + end + + it "raises an error if the string is frozen" do + -> { @s.rb_str_modify_expand("frozen".freeze, 10) }.should raise_error(FrozenError) end end @@ -700,6 +721,11 @@ describe "C-API String function" do @s.rb_str_resize_RSTRING_LEN("test", 2).should == 2 end + it "copies the existing bytes" do + str = "t" + @s.rb_str_resize_copy(str).should == "test" + end + it "increases the size of the string" do expected = "test".force_encoding("US-ASCII") str = @s.rb_str_resize(expected.dup, 12) @@ -1116,4 +1142,14 @@ end str.encoding.should == Encoding::UTF_8 end end + + describe "rb_str_vcatf" do + it "appends the message to the string" do + @s.rb_str_vcatf("").should == "fmt 42 7 number" + + str = "test " + @s.rb_str_vcatf(str) + str.should == "test fmt 42 7 number" + end + end end diff --git a/spec/ruby/security/cve_2019_8321_spec.rb b/spec/ruby/security/cve_2019_8321_spec.rb index affcd00e02..a8a86e7d97 100644 --- a/spec/ruby/security/cve_2019_8321_spec.rb +++ b/spec/ruby/security/cve_2019_8321_spec.rb @@ -3,20 +3,18 @@ require_relative '../spec_helper' require 'rubygems' require 'rubygems/user_interaction' -ruby_version_is "2.5.5" do - describe "CVE-2019-8321 is resisted by" do - it "sanitising verbose messages" do - ui = Class.new { - include Gem::UserInteraction - }.new - ui.should_receive(:say).with(".]2;nyan.") - verbose_before = Gem.configuration.verbose - begin - Gem.configuration.verbose = :really_verbose - ui.verbose("\e]2;nyan\a") - ensure - Gem.configuration.verbose = verbose_before - end +describe "CVE-2019-8321 is resisted by" do + it "sanitising verbose messages" do + ui = Class.new { + include Gem::UserInteraction + }.new + ui.should_receive(:say).with(".]2;nyan.") + verbose_before = Gem.configuration.verbose + begin + Gem.configuration.verbose = :really_verbose + ui.verbose("\e]2;nyan\a") + ensure + Gem.configuration.verbose = verbose_before end end end diff --git a/spec/ruby/security/cve_2019_8322_spec.rb b/spec/ruby/security/cve_2019_8322_spec.rb index 04fb1a7a26..b70d78c033 100644 --- a/spec/ruby/security/cve_2019_8322_spec.rb +++ b/spec/ruby/security/cve_2019_8322_spec.rb @@ -5,19 +5,17 @@ require 'rubygems' require 'rubygems/safe_yaml' require 'rubygems/commands/owner_command' -ruby_version_is "2.5.5" do - describe "CVE-2019-8322 is resisted by" do - it "sanitising owner names" do - command = Gem::Commands::OwnerCommand.new - def command.rubygems_api_request(*args) - Struct.new(:body).new("---\n- email: \"\e]2;nyan\a\"\n handle: handle\n id: id\n") - end - def command.with_response(response) - yield response - end - command.should_receive(:say).with("Owners for gem: name") - command.should_receive(:say).with("- .]2;nyan.") - command.show_owners "name" +describe "CVE-2019-8322 is resisted by" do + it "sanitising owner names" do + command = Gem::Commands::OwnerCommand.new + def command.rubygems_api_request(*args) + Struct.new(:body).new("---\n- email: \"\e]2;nyan\a\"\n handle: handle\n id: id\n") end + def command.with_response(response) + yield response + end + command.should_receive(:say).with("Owners for gem: name") + command.should_receive(:say).with("- .]2;nyan.") + command.show_owners "name" end end diff --git a/spec/ruby/security/cve_2019_8323_spec.rb b/spec/ruby/security/cve_2019_8323_spec.rb index af0b270880..d4606de054 100644 --- a/spec/ruby/security/cve_2019_8323_spec.rb +++ b/spec/ruby/security/cve_2019_8323_spec.rb @@ -5,34 +5,32 @@ require 'optparse' require 'rubygems' require 'rubygems/gemcutter_utilities' -ruby_version_is "2.5.5" do - describe "CVE-2019-8323 is resisted by" do - describe "sanitising the body" do - it "for success codes" do - cutter = Class.new { - include Gem::GemcutterUtilities - }.new - response = Net::HTTPSuccess.new(nil, nil, nil) - def response.body - "\e]2;nyan\a" - end - cutter.should_receive(:say).with(".]2;nyan.") - cutter.with_response response +describe "CVE-2019-8323 is resisted by" do + describe "sanitising the body" do + it "for success codes" do + cutter = Class.new { + include Gem::GemcutterUtilities + }.new + response = Net::HTTPSuccess.new(nil, nil, nil) + def response.body + "\e]2;nyan\a" end + cutter.should_receive(:say).with(".]2;nyan.") + cutter.with_response response + end - it "for error codes" do - cutter = Class.new { - include Gem::GemcutterUtilities - }.new - def cutter.terminate_interaction(n) - end - response = Net::HTTPNotFound.new(nil, nil, nil) - def response.body - "\e]2;nyan\a" - end - cutter.should_receive(:say).with(".]2;nyan.") - cutter.with_response response + it "for error codes" do + cutter = Class.new { + include Gem::GemcutterUtilities + }.new + def cutter.terminate_interaction(n) + end + response = Net::HTTPNotFound.new(nil, nil, nil) + def response.body + "\e]2;nyan\a" end + cutter.should_receive(:say).with(".]2;nyan.") + cutter.with_response response end end end diff --git a/spec/ruby/security/cve_2019_8325_spec.rb b/spec/ruby/security/cve_2019_8325_spec.rb index dcdbe34210..935f127d7f 100644 --- a/spec/ruby/security/cve_2019_8325_spec.rb +++ b/spec/ruby/security/cve_2019_8325_spec.rb @@ -3,7 +3,7 @@ require_relative '../spec_helper' require 'rubygems' require 'rubygems/command_manager' -ruby_version_is "2.5.5" do +platform_is_not :darwin do # frequent timeout/hang on macOS describe "CVE-2019-8325 is resisted by" do describe "sanitising error message components" do it "for the 'while executing' message" do diff --git a/spec/ruby/security/cve_2020_10663_spec.rb b/spec/ruby/security/cve_2020_10663_spec.rb index b97323af08..766590d501 100644 --- a/spec/ruby/security/cve_2020_10663_spec.rb +++ b/spec/ruby/security/cve_2020_10663_spec.rb @@ -18,12 +18,11 @@ module JSONSpecs end guard -> { - ruby_version_is "2.5.8"..."2.6.0" or ruby_version_is "2.6.6" or JSON.const_defined?(:Pure) or version_is(JSON::VERSION, '2.3.0') } do - platform_is_not :darwin do + platform_is_not :darwin do # frequent timeout/hang on macOS describe "CVE-2020-10663 is resisted by" do it "only creating custom objects if passed create_additions: true or using JSON.load" do obj = JSONSpecs::MyClass.new("bar") diff --git a/spec/ruby/shared/rational/Rational.rb b/spec/ruby/shared/rational/Rational.rb index 2c36243dc3..936a90c086 100644 --- a/spec/ruby/shared/rational/Rational.rb +++ b/spec/ruby/shared/rational/Rational.rb @@ -101,42 +101,40 @@ describe :kernel_Rational, shared: true do end end - ruby_version_is "2.6" do - describe "when passed exception: false" do - describe "and [non-Numeric]" do - it "swallows an error" do - Rational(:sym, exception: false).should == nil - Rational("abc", exception: false).should == nil - end + describe "when passed exception: false" do + describe "and [non-Numeric]" do + it "swallows an error" do + Rational(:sym, exception: false).should == nil + Rational("abc", exception: false).should == nil end + end - describe "and [non-Numeric, Numeric]" do - it "swallows an error" do - Rational(:sym, 1, exception: false).should == nil - Rational("abc", 1, exception: false).should == nil - end + describe "and [non-Numeric, Numeric]" do + it "swallows an error" do + Rational(:sym, 1, exception: false).should == nil + Rational("abc", 1, exception: false).should == nil end + end - describe "and [anything, non-Numeric]" do - it "swallows an error" do - Rational(:sym, :sym, exception: false).should == nil - Rational("abc", :sym, exception: false).should == nil - end + describe "and [anything, non-Numeric]" do + it "swallows an error" do + Rational(:sym, :sym, exception: false).should == nil + Rational("abc", :sym, exception: false).should == nil end + end - describe "and non-Numeric String arguments" do - it "swallows an error" do - Rational("a", "b", exception: false).should == nil - Rational("a", 0, exception: false).should == nil - Rational(0, "b", exception: false).should == nil - end + describe "and non-Numeric String arguments" do + it "swallows an error" do + Rational("a", "b", exception: false).should == nil + Rational("a", 0, exception: false).should == nil + Rational(0, "b", exception: false).should == nil end + end - describe "and nil arguments" do - it "swallows an error" do - Rational(nil, exception: false).should == nil - Rational(nil, nil, exception: false).should == nil - end + describe "and nil arguments" do + it "swallows an error" do + Rational(nil, exception: false).should == nil + Rational(nil, nil, exception: false).should == nil end end end |