diff options
Diffstat (limited to 'spec/ruby/language')
82 files changed, 2468 insertions, 1413 deletions
diff --git a/spec/ruby/language/BEGIN_spec.rb b/spec/ruby/language/BEGIN_spec.rb index 5aef5a1d7c..25db32b96a 100644 --- a/spec/ruby/language/BEGIN_spec.rb +++ b/spec/ruby/language/BEGIN_spec.rb @@ -15,7 +15,7 @@ describe "The BEGIN keyword" do end it "must appear in a top-level context" do - -> { eval "1.times { BEGIN { 1 } }" }.should raise_error(SyntaxError) + -> { eval "1.times { BEGIN { 1 } }" }.should.raise(SyntaxError) end it "uses top-level for self" do diff --git a/spec/ruby/language/alias_spec.rb b/spec/ruby/language/alias_spec.rb index 61fddb0184..4b3d36d308 100644 --- a/spec/ruby/language/alias_spec.rb +++ b/spec/ruby/language/alias_spec.rb @@ -140,7 +140,7 @@ describe "The alias keyword" do end @obj.__value.should == 5 - -> { AliasObject.new.__value }.should raise_error(NoMethodError) + -> { AliasObject.new.__value }.should.raise(NoMethodError) end it "operates on the class/module metaclass when used in instance_eval" do @@ -149,7 +149,7 @@ describe "The alias keyword" do end AliasObject.__klass_method.should == 7 - -> { Object.__klass_method }.should raise_error(NoMethodError) + -> { Object.__klass_method }.should.raise(NoMethodError) end it "operates on the class/module metaclass when used in instance_exec" do @@ -158,7 +158,7 @@ describe "The alias keyword" do end AliasObject.__klass_method2.should == 7 - -> { Object.__klass_method2 }.should raise_error(NoMethodError) + -> { Object.__klass_method2 }.should.raise(NoMethodError) end it "operates on methods defined via attr, attr_reader, and attr_accessor" do @@ -241,13 +241,13 @@ describe "The alias keyword" do 1.instance_eval do alias :foo :to_s end - end.should raise_error(TypeError) + end.should.raise(TypeError) -> do :blah.instance_eval do alias :foo :to_s end - end.should raise_error(TypeError) + end.should.raise(TypeError) end it "on top level defines the alias on Object" do @@ -256,7 +256,7 @@ describe "The alias keyword" do end it "raises a NameError when passed a missing name" do - -> { @meta.class_eval { alias undef_method not_exist } }.should raise_error(NameError) { |e| + -> { @meta.class_eval { alias undef_method not_exist } }.should.raise(NameError) { |e| # a NameError and not a NoMethodError e.class.should == NameError } @@ -272,7 +272,7 @@ describe "The alias keyword" do end child.instance_method(:parent_method_alias).owner.should == child - child.instance_methods(false).should include(:parent_method_alias) + child.instance_methods(false).should.include?(:parent_method_alias) end end diff --git a/spec/ruby/language/and_spec.rb b/spec/ruby/language/and_spec.rb index 55a2a3103a..c5c255989b 100644 --- a/spec/ruby/language/and_spec.rb +++ b/spec/ruby/language/and_spec.rb @@ -5,7 +5,7 @@ describe "The '&&' statement" do it "short-circuits evaluation at the first condition to be false" do x = nil true && false && x = 1 - x.should be_nil + x.should == nil end it "evaluates to the first condition not to be true" do @@ -33,9 +33,9 @@ describe "The '&&' statement" do end it "treats empty expressions as nil" do - (() && true).should be_nil - (true && ()).should be_nil - (() && ()).should be_nil + (() && true).should == nil + (true && ()).should == nil + (() && ()).should == nil end end @@ -44,7 +44,7 @@ describe "The 'and' statement" do it "short-circuits evaluation at the first condition to be false" do x = nil true and false and x = 1 - x.should be_nil + x.should == nil end it "evaluates to the first condition not to be true" do @@ -72,9 +72,9 @@ describe "The 'and' statement" do end it "treats empty expressions as nil" do - (() and true).should be_nil - (true and ()).should be_nil - (() and ()).should be_nil + (() and true).should == nil + (true and ()).should == nil + (() and ()).should == nil end end diff --git a/spec/ruby/language/array_spec.rb b/spec/ruby/language/array_spec.rb index 2583cffbf7..3601eb0e00 100644 --- a/spec/ruby/language/array_spec.rb +++ b/spec/ruby/language/array_spec.rb @@ -4,7 +4,7 @@ require_relative 'fixtures/array' describe "Array literals" do it "[] should return a new array populated with the given elements" do array = [1, 'a', nil] - array.should be_kind_of(Array) + array.should.is_a?(Array) array[0].should == 1 array[1].should == 'a' array[2].should == nil @@ -12,7 +12,7 @@ describe "Array literals" do it "[] treats empty expressions as nil elements" do array = [0, (), 2, (), 4] - array.should be_kind_of(Array) + array.should.is_a?(Array) array[0].should == 0 array[1].should == nil array[2].should == 2 @@ -89,7 +89,7 @@ describe "The unpacking splat operator (*)" do it "returns a new array containing the same values when applied to an array inside an empty array" do splatted_array = [3, 4, 5] [*splatted_array].should == splatted_array - [*splatted_array].should_not equal(splatted_array) + [*splatted_array].should_not.equal?(splatted_array) end it "unpacks the start and count arguments in an array slice assignment" do @@ -135,7 +135,7 @@ describe "The unpacking splat operator (*)" do it "when applied to a non-Array value uses it unchanged if it does not respond_to?(:to_a)" do obj = Object.new - obj.should_not respond_to(:to_a) + obj.should_not.respond_to?(:to_a) [1, *obj].should == [1, obj] end diff --git a/spec/ruby/language/assignments_spec.rb b/spec/ruby/language/assignments_spec.rb index 222d8699c5..d621c9f0c6 100644 --- a/spec/ruby/language/assignments_spec.rb +++ b/spec/ruby/language/assignments_spec.rb @@ -23,25 +23,12 @@ describe 'Assignments' do ScratchPad.recorded.should == [:receiver, :argument, :rhs] end - # similar tests for evaluation order are located in language/constants_spec.rb - ruby_version_is ''...'3.2' do - it 'evaluates expressions right to left when assignment with compounded constant' do - m = Module.new - ScratchPad.record [] - - (ScratchPad << :module; m)::A = (ScratchPad << :rhs; :value) - ScratchPad.recorded.should == [:rhs, :module] - end - end - - ruby_version_is '3.2' do - it 'evaluates expressions left to right when assignment with compounded constant' do - m = Module.new - ScratchPad.record [] + it 'evaluates expressions left to right when assignment with compounded constant' do + m = Module.new + ScratchPad.record [] - (ScratchPad << :module; m)::A = (ScratchPad << :rhs; :value) - ScratchPad.recorded.should == [:module, :rhs] - end + (ScratchPad << :module; m)::A = (ScratchPad << :rhs; :value) + ScratchPad.recorded.should == [:module, :rhs] end it 'raises TypeError after evaluation of right-hand-side when compounded constant module is not a module' do @@ -49,11 +36,70 @@ describe 'Assignments' do -> { (:not_a_module)::A = (ScratchPad << :rhs; :value) - }.should raise_error(TypeError) + }.should.raise(TypeError) ScratchPad.recorded.should == [:rhs] end end + + context "given block argument" do + before do + @klass = Class.new do + def initialize(h) @h = h end + def [](k, &block) @h[k]; end + def []=(k, v, &block) @h[k] = v; end + end + end + + ruby_version_is ""..."3.4" do + it "accepts block argument" do + obj = @klass.new(a: 1) + block = proc {} + + eval "obj[:a, &block] = 2" + eval("obj[:a, &block]").should == 2 + end + end + + ruby_version_is "3.4" do + it "raises SyntaxError" do + obj = @klass.new(a: 1) + block = proc {} + + -> { + eval "obj[:a, &block] = 2" + }.should.raise(SyntaxError, /unexpected block arg given in index assignment|block arg given in index assignment/) + end + end + end + + context "given keyword arguments" do + before do + @klass = Class.new do + attr_reader :x + + def []=(*args, **kw) + @x = [args, kw] + end + end + end + + ruby_version_is ""..."3.4" do + it "supports keyword arguments in index assignments" do + a = @klass.new + eval "a[1, 2, 3, b: 4] = 5" + a.x.should == [[1, 2, 3, {b: 4}, 5], {}] + end + end + + ruby_version_is "3.4" do + it "raises SyntaxError when given keyword arguments in index assignments" do + a = @klass.new + -> { eval "a[1, 2, 3, b: 4] = 5" }.should.raise(SyntaxError, + /keywords are not allowed in index assignment expressions|keyword arg given in index assignment/) # prism|parse.y + end + end + end end describe 'using +=' do @@ -127,6 +173,69 @@ describe 'Assignments' do a.public_method(:k, 2).should == 2 end + context "given block argument" do + before do + @klass = Class.new do + def initialize(h) @h = h end + def [](k, &block) @h[k]; end + def []=(k, v, &block) @h[k] = v; end + end + end + + ruby_version_is ""..."3.4" do + it "accepts block argument" do + obj = @klass.new(a: 1) + block = proc {} + + eval "obj[:a, &block] += 2" + eval("obj[:a, &block]").should == 3 + end + end + + ruby_version_is "3.4" do + it "raises SyntaxError" do + obj = @klass.new(a: 1) + block = proc {} + + -> { + eval "obj[:a, &block] += 2" + }.should.raise(SyntaxError, /unexpected block arg given in index assignment|block arg given in index assignment/) + end + end + end + + context "given keyword arguments" do + before do + @klass = Class.new do + attr_reader :x + + def [](*args) + 100 + end + + def []=(*args, **kw) + @x = [args, kw] + end + end + end + + ruby_version_is ""..."3.4" do + it "supports keyword arguments in index assignments" do + a = @klass.new + eval "a[1, 2, 3, b: 4] += 5" + a.x.should == [[1, 2, 3, 105], {b: 4}] + end + end + + ruby_version_is "3.4" do + it "raises SyntaxError when given keyword arguments in index assignments" do + a = @klass.new + -> { eval "a[1, 2, 3, b: 4] += 5" }.should.raise(SyntaxError, + /keywords are not allowed in index assignment expressions|keyword arg given in index assignment/) # prism|parse.y + end + end + end + context 'splatted argument' do it 'correctly handles it' do @b[:m] = 10 @@ -345,45 +454,33 @@ describe 'Multiple assignments' do ScratchPad.recorded.should == [:ra, :aa, :rb, :ab, :rc, :ac, :rd, :ad, :re, :ae, :rf, :af, :value] end - ruby_version_is ''...'3.2' do - it 'evaluates expressions right to left when assignment with compounded constant' do - m = Module.new - ScratchPad.record [] + it 'evaluates expressions left to right when assignment with compounded constant' do + m = Module.new + ScratchPad.record [] - (ScratchPad << :a; m)::A, (ScratchPad << :b; m)::B = (ScratchPad << :c; :c), (ScratchPad << :d; :d) - ScratchPad.recorded.should == [:c, :d, :a, :b] - end + (ScratchPad << :a; m)::A, (ScratchPad << :b; m)::B = (ScratchPad << :c; :c), (ScratchPad << :d; :d) + ScratchPad.recorded.should == [:a, :b, :c, :d] end - ruby_version_is '3.2' do - it 'evaluates expressions left to right when assignment with compounded constant' do - m = Module.new - ScratchPad.record [] - - (ScratchPad << :a; m)::A, (ScratchPad << :b; m)::B = (ScratchPad << :c; :c), (ScratchPad << :d; :d) - ScratchPad.recorded.should == [:a, :b, :c, :d] - end - - it 'evaluates expressions left to right when assignment with a nested compounded constant' do - m = Module.new - ScratchPad.record [] + it 'evaluates expressions left to right when assignment with a nested compounded constant' do + m = Module.new + ScratchPad.record [] - ((ScratchPad << :a; m)::A, foo), bar = [(ScratchPad << :b; :b)] - ScratchPad.recorded.should == [:a, :b] - end + ((ScratchPad << :a; m)::A, foo), bar = [(ScratchPad << :b; :b)] + ScratchPad.recorded.should == [:a, :b] + end - it 'evaluates expressions left to right when assignment with deeply nested compounded constants' do - m = Module.new - ScratchPad.record [] + it 'evaluates expressions left to right when assignment with deeply nested compounded constants' do + m = Module.new + ScratchPad.record [] - (ScratchPad << :a; m)::A, - ((ScratchPad << :b; m)::B, - ((ScratchPad << :c; m)::C, (ScratchPad << :d; m)::D), - (ScratchPad << :e; m)::E), - (ScratchPad << :f; m)::F = (ScratchPad << :value; :value) + (ScratchPad << :a; m)::A, + ((ScratchPad << :b; m)::B, + ((ScratchPad << :c; m)::C, (ScratchPad << :d; m)::D), + (ScratchPad << :e; m)::E), + (ScratchPad << :f; m)::F = (ScratchPad << :value; :value) - ScratchPad.recorded.should == [:a, :b, :c, :d, :e, :f, :value] - end + ScratchPad.recorded.should == [:a, :b, :c, :d, :e, :f, :value] end end diff --git a/spec/ruby/language/block_spec.rb b/spec/ruby/language/block_spec.rb index 1a73b415f2..5bdb993aea 100644 --- a/spec/ruby/language/block_spec.rb +++ b/spec/ruby/language/block_spec.rb @@ -13,7 +13,7 @@ describe "A block yielded a single" do it "receives the identical Array object" do ary = [1, 2] - m(ary) { |a| a }.should equal(ary) + m(ary) { |a| a }.should.equal?(ary) end it "assigns the Array to a single rest argument" do @@ -62,37 +62,18 @@ describe "A block yielded a single" do m([1, 2, 3, 4, 5, 6]) { |a, b=5, c=6, *d, e, f| [a, b, c, d, e, f] }.should == [1, 2, 3, [4], 5, 6] end - ruby_version_is "3.2" do - it "does not autosplat single argument to required arguments when a keyword rest argument is present" do - m([1, 2]) { |a, **k| [a, k] }.should == [[1, 2], {}] - end - - it "does not autosplat single argument to required arguments when keyword arguments are present" do - m([1, 2]) { |a, b: :b, c: :c| [a, b, c] }.should == [[1, 2], :b, :c] - end - - it "raises error when required keyword arguments are present" do - -> { - m([1, 2]) { |a, b:, c:| [a, b, c] } - }.should raise_error(ArgumentError, "missing keywords: :b, :c") - end + it "does not autosplat single argument to required arguments when a keyword rest argument is present" do + m([1, 2]) { |a, **k| [a, k] }.should == [[1, 2], {}] end - ruby_version_is ''..."3.2" do - # https://bugs.ruby-lang.org/issues/18633 - it "autosplats single argument to required arguments when a keyword rest argument is present" do - m([1, 2]) { |a, **k| [a, k] }.should == [1, {}] - end - - it "autosplats single argument to required arguments when optional keyword arguments are present" do - m([1, 2]) { |a, b: :b, c: :c| [a, b, c] }.should == [1, :b, :c] - end + it "does not autosplat single argument to required arguments when keyword arguments are present" do + m([1, 2]) { |a, b: :b, c: :c| [a, b, c] }.should == [[1, 2], :b, :c] + end - it "raises error when required keyword arguments are present" do - -> { - m([1, 2]) { |a, b:, c:| [a, b, c] } - }.should raise_error(ArgumentError, "missing keywords: :b, :c") - end + it "raises error when required keyword arguments are present" do + -> { + m([1, 2]) { |a, b:, c:| [a, b, c] } + }.should.raise(ArgumentError, "missing keywords: :b, :c") end it "assigns elements to mixed argument types" do @@ -211,6 +192,22 @@ describe "A block yielded a single" do m(obj) { |a, b, c| [a, b, c] }.should == [1, 2, nil] end + it "calls #respond_to? on a BasicObject to check if object has method #to_ary" do + ScratchPad.record [] + obj = BasicObject.new + def obj.respond_to?(name, *) + ScratchPad << [:respond_to?, name] + name == :to_ary ? true : super + end + def obj.to_ary + ScratchPad << :to_ary + [1, 2] + end + + m(obj) { |a, b, c| [a, b, c] }.should == [1, 2, nil] + ScratchPad.recorded.should == [[:respond_to?, :to_ary], :to_ary] + end + it "receives the object if it does not respond to #respond_to?" do obj = BasicObject.new @@ -237,14 +234,14 @@ describe "A block yielded a single" do obj = mock("destructure block arguments") obj.should_receive(:to_ary).and_return(1) - -> { m(obj) { |a, b| } }.should raise_error(TypeError) + -> { m(obj) { |a, b| } }.should.raise(TypeError) end it "raises error transparently if #to_ary raises error on its own" do obj = Object.new def obj.to_ary; raise "Exception raised in #to_ary" end - -> { m(obj) { |a, b| } }.should raise_error(RuntimeError, "Exception raised in #to_ary") + -> { m(obj) { |a, b| } }.should.raise(RuntimeError, "Exception raised in #to_ary") end end end @@ -314,7 +311,7 @@ describe "A block" do describe "taking |a| arguments" do it "assigns nil to the argument when no values are yielded" do - @y.z { |a| a }.should be_nil + @y.z { |a| a }.should == nil end it "assigns the value yielded to the argument" do @@ -325,7 +322,7 @@ describe "A block" do obj = mock("block yield to_ary") obj.should_not_receive(:to_ary) - @y.s(obj) { |a| a }.should equal(obj) + @y.s(obj) { |a| a }.should.equal?(obj) end it "assigns the first value yielded to the argument" do @@ -401,14 +398,14 @@ describe "A block" do obj = mock("block yield to_ary invalid") obj.should_receive(:to_ary).and_return(1) - -> { @y.s(obj) { |a, b| } }.should raise_error(TypeError) + -> { @y.s(obj) { |a, b| } }.should.raise(TypeError) end it "raises the original exception if #to_ary raises an exception" do obj = mock("block yield to_ary raising an exception") obj.should_receive(:to_ary).and_raise(ZeroDivisionError) - -> { @y.s(obj) { |a, b| } }.should raise_error(ZeroDivisionError) + -> { @y.s(obj) { |a, b| } }.should.raise(ZeroDivisionError) end end @@ -464,7 +461,7 @@ describe "A block" do obj = mock("block yield to_ary invalid") obj.should_receive(:to_ary).and_return(1) - -> { @y.s(obj) { |a, *b| } }.should raise_error(TypeError) + -> { @y.s(obj) { |a, *b| } }.should.raise(TypeError) end end @@ -542,7 +539,7 @@ describe "A block" do describe "taking |a, | arguments" do it "assigns nil to the argument when no values are yielded" do - @y.z { |a, | a }.should be_nil + @y.z { |a, | a }.should == nil end it "assigns the argument a single value yielded" do @@ -558,7 +555,7 @@ describe "A block" do end it "assigns nil to the argument when passed an empty Array" do - @y.s([]) { |a, | a }.should be_nil + @y.s([]) { |a, | a }.should == nil end it "assigns the argument the first element of the Array when passed a single Array" do @@ -589,7 +586,7 @@ describe "A block" do obj = mock("block yield to_ary invalid") obj.should_receive(:to_ary).and_return(1) - -> { @y.s(obj) { |a, | } }.should raise_error(TypeError) + -> { @y.s(obj) { |a, | } }.should.raise(TypeError) end end @@ -631,7 +628,7 @@ describe "A block" do obj = mock("block yield to_ary invalid") obj.should_receive(:to_ary).and_return(1) - -> { @y.s(obj) { |(a, b)| } }.should raise_error(TypeError) + -> { @y.s(obj) { |(a, b)| } }.should.raise(TypeError) end end @@ -672,7 +669,7 @@ describe "A block" do obj = mock("block yield to_ary invalid") obj.should_receive(:to_ary).and_return(1) - -> { @y.s(obj) { |(a, b), c| } }.should raise_error(TypeError) + -> { @y.s(obj) { |(a, b), c| } }.should.raise(TypeError) end end @@ -731,15 +728,15 @@ describe "A block" do describe "taking identically-named arguments" do it "raises a SyntaxError for standard arguments" do - -> { eval "lambda { |x,x| }" }.should raise_error(SyntaxError) - -> { eval "->(x,x) {}" }.should raise_error(SyntaxError) - -> { eval "Proc.new { |x,x| }" }.should raise_error(SyntaxError) + -> { eval "lambda { |x,x| }" }.should.raise(SyntaxError) + -> { eval "->(x,x) {}" }.should.raise(SyntaxError) + -> { eval "Proc.new { |x,x| }" }.should.raise(SyntaxError) end it "accepts unnamed arguments" do - lambda { |_,_| }.should be_an_instance_of(Proc) # rubocop:disable Style/Lambda - -> _,_ {}.should be_an_instance_of(Proc) - Proc.new { |_,_| }.should be_an_instance_of(Proc) + lambda { |_,_| }.should.instance_of?(Proc) # rubocop:disable Style/Lambda + -> _,_ {}.should.instance_of?(Proc) + Proc.new { |_,_| }.should.instance_of?(Proc) end end @@ -790,29 +787,29 @@ describe "Block-local variables" do end it "can not have the same name as one of the standard parameters" do - -> { eval "[1].each {|foo; foo| }" }.should raise_error(SyntaxError) - -> { eval "[1].each {|foo, bar; glark, bar| }" }.should raise_error(SyntaxError) + -> { eval "[1].each {|foo; foo| }" }.should.raise(SyntaxError) + -> { eval "[1].each {|foo, bar; glark, bar| }" }.should.raise(SyntaxError) end it "can not be prefixed with an asterisk" do - -> { eval "[1].each {|foo; *bar| }" }.should raise_error(SyntaxError) + -> { eval "[1].each {|foo; *bar| }" }.should.raise(SyntaxError) -> do eval "[1].each {|foo, bar; glark, *fnord| }" - end.should raise_error(SyntaxError) + end.should.raise(SyntaxError) end it "can not be prefixed with an ampersand" do - -> { eval "[1].each {|foo; &bar| }" }.should raise_error(SyntaxError) + -> { eval "[1].each {|foo; &bar| }" }.should.raise(SyntaxError) -> do eval "[1].each {|foo, bar; glark, &fnord| }" - end.should raise_error(SyntaxError) + end.should.raise(SyntaxError) end it "can not be assigned default values" do - -> { eval "[1].each {|foo; bar=1| }" }.should raise_error(SyntaxError) + -> { eval "[1].each {|foo; bar=1| }" }.should.raise(SyntaxError) -> do eval "[1].each {|foo, bar; glark, fnord=:fnord| }" - end.should raise_error(SyntaxError) + end.should.raise(SyntaxError) end it "need not be preceded by standard parameters" do @@ -821,8 +818,8 @@ describe "Block-local variables" do end it "only allow a single semi-colon in the parameter list" do - -> { eval "[1].each {|foo; bar; glark| }" }.should raise_error(SyntaxError) - -> { eval "[1].each {|; bar; glark| }" }.should raise_error(SyntaxError) + -> { eval "[1].each {|foo; bar; glark| }" }.should.raise(SyntaxError) + -> { eval "[1].each {|; bar; glark| }" }.should.raise(SyntaxError) end it "override shadowed variables from the outer scope" do @@ -847,21 +844,21 @@ describe "Block-local variables" do end it "are not automatically instantiated in the outer scope" do - defined?(glark).should be_nil + defined?(glark).should == nil [1].each {|;glark| 1} - defined?(glark).should be_nil + defined?(glark).should == nil end it "are automatically instantiated in the block" do [1].each do |;glark| - glark.should be_nil + glark.should == nil end end it "are visible in deeper scopes before initialization" do [1].each {|;glark| [1].each { - defined?(glark).should_not be_nil + defined?(glark).should_not == nil glark = 1 } glark.should == 1 @@ -889,7 +886,7 @@ describe "Post-args" do -> *a, b do [a, b] end.call - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end it "are assigned to nil when not enough arguments are given to a proc" do @@ -965,7 +962,7 @@ describe "Post-args" do a = 1 -> { eval "proc { |a=a| a }" - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end end @@ -1009,7 +1006,7 @@ describe "Anonymous block forwarding" do end it "requires the anonymous block parameter to be declared if directly passing a block" do - -> { eval "def a; b(&); end; def b; end" }.should raise_error(SyntaxError) + -> { eval "def a; b(&); end; def b; end" }.should.raise(SyntaxError) end it "works when it's the only declared parameter" do @@ -1040,36 +1037,40 @@ describe "Anonymous block forwarding" do no_kw(:a) { 1 }.should == 1 end - ruby_version_is "3.2" do - it "works alongside explicit keyword arguments" do - eval <<-EOF - def inner; yield end - def rest_kw(*a, kwarg: 1, &); inner(&) end - def kw(kwarg: 1, &); inner(&) end - def pos_kw_kwrest(arg1, kwarg: 1, **kw, &); inner(&) end - def pos_rkw(arg1, kwarg1:, &); inner(&) end - def all(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, &); inner(&) end - def all_kwrest(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, **kw, &); inner(&) end - EOF - - rest_kw { 1 }.should == 1 - kw { 1 }.should == 1 - pos_kw_kwrest(:a) { 1 }.should == 1 - pos_rkw(:a, kwarg1: 3) { 1 }.should == 1 - all(:a, :b, :c, :d, :e, okw1: 'x', okw2: 'y') { 1 }.should == 1 - all_kwrest(:a, :b, :c, :d, :e, okw1: 'x', okw2: 'y') { 1 }.should == 1 - end + it "works alongside explicit keyword arguments" do + eval <<-EOF + def inner; yield end + def rest_kw(*a, kwarg: 1, &); inner(&) end + def kw(kwarg: 1, &); inner(&) end + def pos_kw_kwrest(arg1, kwarg: 1, **kw, &); inner(&) end + def pos_rkw(arg1, kwarg1:, &); inner(&) end + def all(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, &); inner(&) end + def all_kwrest(arg1, arg2, *rest, post1, post2, kw1: 1, kw2: 2, okw1:, okw2:, **kw, &); inner(&) end + EOF + + rest_kw { 1 }.should == 1 + kw { 1 }.should == 1 + pos_kw_kwrest(:a) { 1 }.should == 1 + pos_rkw(:a, kwarg1: 3) { 1 }.should == 1 + all(:a, :b, :c, :d, :e, okw1: 'x', okw2: 'y') { 1 }.should == 1 + all_kwrest(:a, :b, :c, :d, :e, okw1: 'x', okw2: 'y') { 1 }.should == 1 end end -describe "`it` calls without arguments in a block with no ordinary parameters" do - ruby_version_is "3.3"..."3.4" do +describe "`it` calls without arguments in a block" do + ruby_version_is ""..."3.4" do it "emits a deprecation warning" do -> { eval "proc { it }" }.should complain(/warning: `it` calls without arguments will refer to the first block param in Ruby 3.4; use it\(\) or self.it/) end + it "emits a deprecation warning if numbered parameters are used" do + -> { + eval "proc { it; _1 }" + }.should complain(/warning: `it` calls without arguments will refer to the first block param in Ruby 3.4; use it\(\) or self.it/) + end + it "does not emit a deprecation warning when a block has parameters" do -> { eval "proc { |a, b| it }" }.should_not complain -> { eval "proc { |*rest| it }" }.should_not complain @@ -1079,14 +1080,69 @@ describe "`it` calls without arguments in a block with no ordinary parameters" d -> { eval "proc { |**| it }" }.should_not complain -> { eval "proc { |&block| it }" }.should_not complain -> { eval "proc { |&| it }" }.should_not complain + -> { eval "proc { || it }" }.should_not complain end it "does not emit a deprecation warning when `it` calls with arguments" do -> { eval "proc { it(42) }" }.should_not complain + -> { eval "proc { it 42 }" }.should_not complain + end + + it "does not emit a deprecation warning when `it` calls with a block" do + -> { eval "proc { it {} }" }.should_not complain + end + + it "does not emit a deprecation warning when a local variable inside the block named `it` exists" do + -> { eval "proc { it = 42; it }" }.should_not complain end it "does not emit a deprecation warning when `it` calls with explicit empty arguments list" do -> { eval "proc { it() }" }.should_not complain end + + it "calls the method `it` if defined" do + o = Object.new + def o.it + 21 + end + suppress_warning do + o.instance_eval("proc { it * 2 }").call(1).should == 42 + end + end + end + + ruby_version_is "4.1" do + it "works alongside disallowed block argument" do + no_block = eval <<-EOF + proc {|arg1, &nil| arg1} + EOF + + no_block.call(:a).should == :a + -> { no_block.call(:a) {} }.should.raise(ArgumentError, 'no block accepted') + end + end +end + +# Duplicates specs in language/it_parameter_spec.rb +# Need them here to run on Ruby versions prior 3.4 +# TODO: remove when the minimal supported Ruby version is 3.4 +describe "if `it` is defined as a variable" do + it "treats `it` as a captured variable if defined outside of a block" do + it = 5 + proc { it }.call(0).should == 5 + end + + it "treats `it` as a local variable if defined inside of a block" do + proc { it = 5; it }.call(0).should == 5 + end +end + +describe "Block-parameter destructuring" do + it "does not warn about unused inner names in verbose mode" do + -> { + eval <<~RUBY, binding, __FILE__, __LINE__ + 1 + proc { |key, (val1, val2)| [key, val2] } + RUBY + }.should_not complain(verbose: true) end end diff --git a/spec/ruby/language/break_spec.rb b/spec/ruby/language/break_spec.rb index 7e5b6fb328..5c9b8060c3 100644 --- a/spec/ruby/language/break_spec.rb +++ b/spec/ruby/language/break_spec.rb @@ -52,29 +52,29 @@ describe "The break statement in a captured block" do describe "when the invocation of the scope creating the block is still active" do it "raises a LocalJumpError when invoking the block from the scope creating the block" do - -> { @program.break_in_method }.should raise_error(LocalJumpError) + -> { @program.break_in_method }.should.raise(LocalJumpError) ScratchPad.recorded.should == [:a, :xa, :d, :b] end it "raises a LocalJumpError when invoking the block from a method" do - -> { @program.break_in_nested_method }.should raise_error(LocalJumpError) + -> { @program.break_in_nested_method }.should.raise(LocalJumpError) ScratchPad.recorded.should == [:a, :xa, :cc, :aa, :b] end it "raises a LocalJumpError when yielding to the block" do - -> { @program.break_in_yielding_method }.should raise_error(LocalJumpError) + -> { @program.break_in_yielding_method }.should.raise(LocalJumpError) ScratchPad.recorded.should == [:a, :xa, :cc, :aa, :b] end end describe "from a scope that has returned" do it "raises a LocalJumpError when calling the block from a method" do - -> { @program.break_in_method_captured }.should raise_error(LocalJumpError) + -> { @program.break_in_method_captured }.should.raise(LocalJumpError) ScratchPad.recorded.should == [:a, :za, :xa, :zd, :zb] end it "raises a LocalJumpError when yielding to the block" do - -> { @program.break_in_yield_captured }.should raise_error(LocalJumpError) + -> { @program.break_in_yield_captured }.should.raise(LocalJumpError) ScratchPad.recorded.should == [:a, :za, :xa, :zd, :aa, :zb] end end @@ -88,7 +88,7 @@ describe "The break statement in a captured block" do e end end - thread_with_break.value.should be_an_instance_of(LocalJumpError) + thread_with_break.value.should.instance_of?(LocalJumpError) end end end @@ -256,7 +256,7 @@ describe "The break statement in a method" do it "is invalid and raises a SyntaxError" do -> { eval("def m; break; end") - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end end @@ -268,7 +268,7 @@ describe "The break statement in a module literal" do end RUBY - -> { eval(code) }.should raise_error(SyntaxError) + -> { eval(code) }.should.raise(SyntaxError) end end @@ -388,7 +388,7 @@ describe "Executing break from within a block" do -> do cls2.new.foo.should == 1 - end.should_not raise_error + end.should_not.raise end it "raises LocalJumpError when converted into a proc during a super call" do @@ -397,6 +397,6 @@ describe "Executing break from within a block" do -> do cls2.new.foo - end.should raise_error(LocalJumpError) + end.should.raise(LocalJumpError) end end diff --git a/spec/ruby/language/case_spec.rb b/spec/ruby/language/case_spec.rb index 464d06e46a..8355062e44 100644 --- a/spec/ruby/language/case_spec.rb +++ b/spec/ruby/language/case_spec.rb @@ -94,12 +94,12 @@ describe "The 'case'-construct" do it "tests with matching regexps and sets $~ and captures" do case "foo42" when /oo(\d+)/ - $~.should be_kind_of(MatchData) + $~.should.is_a?(MatchData) $1.should == "42" else flunk end - $~.should be_kind_of(MatchData) + $~.should.is_a?(MatchData) $1.should == "42" end @@ -107,12 +107,12 @@ describe "The 'case'-construct" do digits = '\d+' case "foo44" when /oo(#{digits})/ - $~.should be_kind_of(MatchData) + $~.should.is_a?(MatchData) $1.should == "44" else flunk end - $~.should be_kind_of(MatchData) + $~.should.is_a?(MatchData) $1.should == "44" end @@ -120,12 +120,12 @@ describe "The 'case'-construct" do digits_regexp = /\d+/ case "foo43" when /oo(#{digits_regexp})/ - $~.should be_kind_of(MatchData) + $~.should.is_a?(MatchData) $1.should == "43" else flunk end - $~.should be_kind_of(MatchData) + $~.should.is_a?(MatchData) $1.should == "43" end @@ -268,7 +268,7 @@ describe "The 'case'-construct" do true end CODE - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end it "raises a SyntaxError when 'else' is used before a 'when' was given" do @@ -280,7 +280,7 @@ describe "The 'case'-construct" do when 4; false end CODE - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end it "supports nested case statements" do diff --git a/spec/ruby/language/class_spec.rb b/spec/ruby/language/class_spec.rb index 0b770d69b5..7ea4857514 100644 --- a/spec/ruby/language/class_spec.rb +++ b/spec/ruby/language/class_spec.rb @@ -10,23 +10,23 @@ end describe "The class keyword" do it "creates a new class with semicolon" do class ClassSpecsKeywordWithSemicolon; end - ClassSpecsKeywordWithSemicolon.should be_an_instance_of(Class) + ClassSpecsKeywordWithSemicolon.should.instance_of?(Class) end it "does not raise a SyntaxError when opening a class without a semicolon" do eval "class ClassSpecsKeywordWithoutSemicolon end" - ClassSpecsKeywordWithoutSemicolon.should be_an_instance_of(Class) + ClassSpecsKeywordWithoutSemicolon.should.instance_of?(Class) end it "can redefine a class when called from a block" do ClassSpecs::DEFINE_CLASS.call - A.should be_an_instance_of(Class) + A.should.instance_of?(Class) Object.send(:remove_const, :A) - defined?(A).should be_nil + defined?(A).should == nil ClassSpecs::DEFINE_CLASS.call - A.should be_an_instance_of(Class) + A.should.instance_of?(Class) ensure Object.send(:remove_const, :A) if defined?(::A) end @@ -34,8 +34,8 @@ end describe "A class definition" do it "creates a new class" do - ClassSpecs::A.should be_kind_of(Class) - ClassSpecs::A.new.should be_kind_of(ClassSpecs::A) + ClassSpecs::A.should.is_a?(Class) + ClassSpecs::A.new.should.is_a?(ClassSpecs::A) end it "has no class variables" do @@ -46,7 +46,14 @@ describe "A class definition" do -> { class ClassSpecsNumber end - }.should raise_error(TypeError) + }.should.raise(TypeError, /\AClassSpecsNumber is not a class/) + end + + it "raises TypeError if constant given as class name exists and is a Module but not a Class" do + -> { + class ClassSpecs + end + }.should.raise(TypeError, /\AClassSpecs is not a class/) end # test case known to be detecting bugs (JRuby, MRI) @@ -54,19 +61,19 @@ describe "A class definition" do -> { class nil::Foo end - }.should raise_error(TypeError) + }.should.raise(TypeError) end it "raises TypeError if any constant qualifying the class is not a Module" do -> { class ClassSpecs::Number::MyClass end - }.should raise_error(TypeError) + }.should.raise(TypeError) -> { class ClassSpecsNumber::MyClass end - }.should raise_error(TypeError) + }.should.raise(TypeError) end it "inherits from Object by default" do @@ -80,7 +87,7 @@ describe "A class definition" do -> { class SuperclassResetToSubclass < M end - }.should raise_error(TypeError, /superclass mismatch/) + }.should.raise(TypeError, /superclass mismatch/) end end @@ -93,7 +100,7 @@ describe "A class definition" do -> { class SuperclassReopenedBasicObject < BasicObject end - }.should raise_error(TypeError, /superclass mismatch/) + }.should.raise(TypeError, /superclass mismatch/) SuperclassReopenedBasicObject.superclass.should == A end end @@ -108,7 +115,7 @@ describe "A class definition" do -> { class SuperclassReopenedObject < Object end - }.should raise_error(TypeError, /superclass mismatch/) + }.should.raise(TypeError, /superclass mismatch/) SuperclassReopenedObject.superclass.should == A end end @@ -133,7 +140,7 @@ describe "A class definition" do -> { class NoSuperclassSet < String end - }.should raise_error(TypeError, /superclass mismatch/) + }.should.raise(TypeError, /superclass mismatch/) end end @@ -142,7 +149,7 @@ describe "A class definition" do -> { class ShouldNotWork < self; end - }.should raise_error(TypeError) + }.should.raise(TypeError) end it "first evaluates the superclass before checking if the class already exists" do @@ -161,7 +168,7 @@ describe "A class definition" do it "raises a TypeError if inheriting from a metaclass" do obj = mock("metaclass super") meta = obj.singleton_class - -> { class ClassSpecs::MetaclassSuper < meta; end }.should raise_error(TypeError) + -> { class ClassSpecs::MetaclassSuper < meta; end }.should.raise(TypeError) end it "allows the declaration of class variables in the body" do @@ -170,7 +177,7 @@ describe "A class definition" do end it "stores instance variables defined in the class body in the class object" do - ClassSpecs.string_instance_variables(ClassSpecs::B).should include("@ivar") + ClassSpecs.string_instance_variables(ClassSpecs::B).should.include?("@ivar") ClassSpecs::B.instance_variable_get(:@ivar).should == :ivar end @@ -182,9 +189,9 @@ describe "A class definition" do end it "allows the definition of class-level instance variables in a class method" do - ClassSpecs.string_instance_variables(ClassSpecs::C).should_not include("@civ") + ClassSpecs.string_instance_variables(ClassSpecs::C).should_not.include?("@civ") ClassSpecs::C.make_class_instance_variable - ClassSpecs.string_instance_variables(ClassSpecs::C).should include("@civ") + ClassSpecs.string_instance_variables(ClassSpecs::C).should.include?("@civ") ClassSpecs::C.remove_instance_variable :@civ end @@ -279,7 +286,8 @@ end describe "An outer class definition" do it "contains the inner classes" do - ClassSpecs::Container.constants.should include(:A, :B) + ClassSpecs::Container.constants.should.include?(:A) + ClassSpecs::Container.constants.should.include?(:B) end end @@ -297,23 +305,23 @@ describe "A class definition extending an object (sclass)" do end end CODE - }.should raise_error(TypeError) + }.should.raise(TypeError) end it "raises a TypeError when trying to extend non-Class" do error_msg = /superclass must be a.* Class/ - -> { class TestClass < ""; end }.should raise_error(TypeError, error_msg) - -> { class TestClass < 1; end }.should raise_error(TypeError, error_msg) - -> { class TestClass < :symbol; end }.should raise_error(TypeError, error_msg) - -> { class TestClass < mock('o'); end }.should raise_error(TypeError, error_msg) - -> { class TestClass < Module.new; end }.should raise_error(TypeError, error_msg) - -> { class TestClass < BasicObject.new; end }.should raise_error(TypeError, error_msg) + -> { class TestClass < ""; end }.should.raise(TypeError, error_msg) + -> { class TestClass < 1; end }.should.raise(TypeError, error_msg) + -> { class TestClass < :symbol; end }.should.raise(TypeError, error_msg) + -> { class TestClass < mock('o'); end }.should.raise(TypeError, error_msg) + -> { class TestClass < Module.new; end }.should.raise(TypeError, error_msg) + -> { class TestClass < BasicObject.new; end }.should.raise(TypeError, error_msg) end it "does not allow accessing the block of the original scope" do -> { ClassSpecs.sclass_with_block { 123 } - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end it "can use return to cause the enclosing method to return" do @@ -333,11 +341,11 @@ describe "Reopening a class" do end it "raises a TypeError when superclasses mismatch" do - -> { class ClassSpecs::A < Array; end }.should raise_error(TypeError) + -> { class ClassSpecs::A < Array; end }.should.raise(TypeError) end it "adds new methods to subclasses" do - -> { ClassSpecs::M.m }.should raise_error(NoMethodError) + -> { ClassSpecs::M.m }.should.raise(NoMethodError) class ClassSpecs::L def self.m 1 @@ -346,6 +354,39 @@ describe "Reopening a class" do ClassSpecs::M.m.should == 1 ClassSpecs::L.singleton_class.send(:remove_method, :m) end + + it "does not reopen a class included in Object" do + ruby_exe(<<~RUBY).should == "false" + module IncludedInObject + class IncludedClass + end + end + class Object + include IncludedInObject + end + class IncludedClass + end + print IncludedInObject::IncludedClass == Object::IncludedClass + RUBY + end + + it "does not reopen a class included in non-Object modules" do + ruby_exe(<<~RUBY).should == "false/false" + module Included + module IncludedClass; end + end + module M + include Included + module IncludedClass; end + end + class C + include Included + module IncludedClass; end + end + print Included::IncludedClass == M::IncludedClass, "/", + Included::IncludedClass == C::IncludedClass + RUBY + end end describe "class provides hooks" do diff --git a/spec/ruby/language/class_variable_spec.rb b/spec/ruby/language/class_variable_spec.rb index a26a3fb8de..84a7684c6d 100644 --- a/spec/ruby/language/class_variable_spec.rb +++ b/spec/ruby/language/class_variable_spec.rb @@ -30,19 +30,19 @@ describe "A class variable defined in a module" do end it "is not defined in these classes" do - ClassVariablesSpec::ClassC.cvar_defined?.should be_false + ClassVariablesSpec::ClassC.cvar_defined?.should == false end it "is only updated in the module a method defined in the module is used" do ClassVariablesSpec::ClassC.cvar_m = "new value" ClassVariablesSpec::ClassC.cvar_m.should == "new value" - ClassVariablesSpec::ClassC.cvar_defined?.should be_false + ClassVariablesSpec::ClassC.cvar_defined?.should == false end it "is updated in the class when a Method defined in the class is used" do ClassVariablesSpec::ClassC.cvar_c = "new value" - ClassVariablesSpec::ClassC.cvar_defined?.should be_true + ClassVariablesSpec::ClassC.cvar_defined?.should == true end it "can be accessed inside the class using the module methods" do @@ -55,11 +55,11 @@ describe "A class variable defined in a module" do end it "is defined in the extended module" do - ClassVariablesSpec::ModuleN.class_variable_defined?(:@@cvar_n).should be_true + ClassVariablesSpec::ModuleN.class_variable_defined?(:@@cvar_n).should == true end it "is not defined in the extending module" do - ClassVariablesSpec::ModuleO.class_variable_defined?(:@@cvar_n).should be_false + ClassVariablesSpec::ModuleO.class_variable_defined?(:@@cvar_n).should == false end end @@ -70,14 +70,14 @@ describe 'A class variable definition' do c = Class.new(b) b.class_variable_set(:@@cv, :value) - -> { a.class_variable_get(:@@cv) }.should raise_error(NameError) + -> { a.class_variable_get(:@@cv) }.should.raise(NameError) b.class_variable_get(:@@cv).should == :value c.class_variable_get(:@@cv).should == :value # updates the same variable c.class_variable_set(:@@cv, :next) - -> { a.class_variable_get(:@@cv) }.should raise_error(NameError) + -> { a.class_variable_get(:@@cv) }.should.raise(NameError) b.class_variable_get(:@@cv).should == :next c.class_variable_get(:@@cv).should == :next end @@ -87,16 +87,16 @@ describe 'Accessing a class variable' do it "raises a RuntimeError when accessed from the toplevel scope (not in some module or class)" do -> { eval "@@cvar_toplevel1" - }.should raise_error(RuntimeError, 'class variable access from toplevel') + }.should.raise(RuntimeError, 'class variable access from toplevel') -> { eval "@@cvar_toplevel2 = 2" - }.should raise_error(RuntimeError, 'class variable access from toplevel') + }.should.raise(RuntimeError, 'class variable access from toplevel') end it "does not raise an error when checking if defined from the toplevel scope" do -> { eval "defined?(@@cvar_toplevel1)" - }.should_not raise_error + }.should_not.raise end it "raises a RuntimeError when a class variable is overtaken in an ancestor class" do @@ -107,7 +107,7 @@ describe 'Accessing a class variable' do -> { subclass.class_variable_get(:@@cvar_overtaken) - }.should raise_error(RuntimeError, /class variable @@cvar_overtaken of .+ is overtaken by .+/) + }.should.raise(RuntimeError, /class variable @@cvar_overtaken of .+ is overtaken by .+/) parent.class_variable_get(:@@cvar_overtaken).should == :parent end diff --git a/spec/ruby/language/constants_spec.rb b/spec/ruby/language/constants_spec.rb index 35913b9e30..0880230a36 100644 --- a/spec/ruby/language/constants_spec.rb +++ b/spec/ruby/language/constants_spec.rb @@ -51,8 +51,8 @@ describe "Literal (A::X) constant resolution" do it "does not search the singleton class of the class or module" do -> do ConstantSpecs::ContainerA::ChildA::CS_CONST14 - end.should raise_error(NameError) - -> { ConstantSpecs::CS_CONST14 }.should raise_error(NameError) + end.should.raise(NameError) + -> { ConstantSpecs::CS_CONST14 }.should.raise(NameError) end end @@ -135,7 +135,7 @@ describe "Literal (A::X) constant resolution" do -> do ConstantSpecs::ContainerB::ChildB::CS_CONST108 - end.should raise_error(NameError) + end.should.raise(NameError) module ConstantSpecs class << self @@ -143,7 +143,7 @@ describe "Literal (A::X) constant resolution" do end end - -> { ConstantSpecs::CS_CONST108 }.should raise_error(NameError) + -> { ConstantSpecs::CS_CONST108 }.should.raise(NameError) ensure ConstantSpecs::ContainerB::ChildB.singleton_class.send(:remove_const, :CS_CONST108) ConstantSpecs.singleton_class.send(:remove_const, :CS_CONST108) @@ -161,39 +161,21 @@ describe "Literal (A::X) constant resolution" do ConstantSpecs::ClassB.send(:remove_const, :CS_CONST109) end - ruby_version_is "3.2" do - it "evaluates left-to-right" do - mod = Module.new + it "evaluates left-to-right" do + mod = Module.new - mod.module_eval <<-EOC - order = [] - ConstantSpecsRHS = Module.new - (order << :lhs; ConstantSpecsRHS)::B = (order << :rhs) - EOC + mod.module_eval <<-EOC + order = [] + ConstantSpecsRHS = Module.new + (order << :lhs; ConstantSpecsRHS)::B = (order << :rhs) + EOC - mod::ConstantSpecsRHS::B.should == [:lhs, :rhs] - end - end - - ruby_version_is ""..."3.2" do - it "evaluates the right hand side before evaluating a constant path" do - mod = Module.new - - mod.module_eval <<-EOC - ConstantSpecsRHS::B = begin - module ConstantSpecsRHS; end - - "hello" - end - EOC - - mod::ConstantSpecsRHS::B.should == 'hello' - end + mod::ConstantSpecsRHS::B.should == [:lhs, :rhs] end end it "raises a NameError if no constant is defined in the search path" do - -> { ConstantSpecs::ParentA::CS_CONSTX }.should raise_error(NameError) + -> { ConstantSpecs::ParentA::CS_CONSTX }.should.raise(NameError) end it "uses the module or class #name to craft the error message" do @@ -207,7 +189,7 @@ describe "Literal (A::X) constant resolution" do end end - -> { mod::DOES_NOT_EXIST }.should raise_error(NameError, /uninitialized constant ModuleName::DOES_NOT_EXIST/) + -> { mod::DOES_NOT_EXIST }.should.raise(NameError, /uninitialized constant ModuleName::DOES_NOT_EXIST/) end it "uses the module or class #inspect to craft the error message if they are anonymous" do @@ -221,7 +203,7 @@ describe "Literal (A::X) constant resolution" do end end - -> { mod::DOES_NOT_EXIST }.should raise_error(NameError, /uninitialized constant <unusable info>::DOES_NOT_EXIST/) + -> { mod::DOES_NOT_EXIST }.should.raise(NameError, /uninitialized constant <unusable info>::DOES_NOT_EXIST/) end it "sends #const_missing to the original class or module scope" do @@ -233,10 +215,10 @@ describe "Literal (A::X) constant resolution" do end it "raises a TypeError if a non-class or non-module qualifier is given" do - -> { CS_CONST1::CS_CONST }.should raise_error(TypeError) - -> { 1::CS_CONST }.should raise_error(TypeError) - -> { "mod"::CS_CONST }.should raise_error(TypeError) - -> { false::CS_CONST }.should raise_error(TypeError) + -> { CS_CONST1::CS_CONST }.should.raise(TypeError) + -> { 1::CS_CONST }.should.raise(TypeError) + -> { "mod"::CS_CONST }.should.raise(TypeError) + -> { false::CS_CONST }.should.raise(TypeError) end end @@ -282,7 +264,7 @@ describe "Constant resolution within methods" do end it "does not search the lexical scope of the caller" do - -> { ConstantSpecs::ClassA.const16 }.should raise_error(NameError) + -> { ConstantSpecs::ClassA.const16 }.should.raise(NameError) end it "searches the lexical scope of a block" do @@ -297,7 +279,7 @@ describe "Constant resolution within methods" do it "does not search the lexical scope of qualifying modules" do -> do ConstantSpecs::ContainerA::ChildA.const23 - end.should raise_error(NameError) + end.should.raise(NameError) end end @@ -395,7 +377,7 @@ describe "Constant resolution within methods" do it "does not search the lexical scope of the caller" do ConstantSpecs::ClassB::CS_CONST209 = :const209 - -> { ConstantSpecs::ClassB.const209 }.should raise_error(NameError) + -> { ConstantSpecs::ClassB.const209 }.should.raise(NameError) ensure ConstantSpecs::ClassB.send(:remove_const, :CS_CONST209) end @@ -444,14 +426,14 @@ describe "Constant resolution within methods" do -> do ConstantSpecs::ContainerB::ChildB.const214 - end.should raise_error(NameError) + end.should.raise(NameError) ensure ConstantSpecs::ContainerB.send(:remove_const, :CS_CONST214) end end it "raises a NameError if no constant is defined in the search path" do - -> { ConstantSpecs::ParentA.constx }.should raise_error(NameError) + -> { ConstantSpecs::ParentA.constx }.should.raise(NameError) end it "sends #const_missing to the original class or module scope" do @@ -474,7 +456,7 @@ describe "Constant resolution within a singleton class (class << obj)" do it "uses its own namespace for nested modules" do a = ConstantSpecs::CS_SINGLETON3[0].x b = ConstantSpecs::CS_SINGLETON3[1].x - a.should_not equal(b) + a.should_not.equal?(b) end it "allows nested modules to have proper resolution" do @@ -487,12 +469,12 @@ end describe "top-level constant lookup" do context "on a class" do it "does not search Object after searching other scopes" do - -> { String::Hash }.should raise_error(NameError) + -> { String::Hash }.should.raise(NameError) end end it "searches Object unsuccessfully when searches on a module" do - -> { Enumerable::Hash }.should raise_error(NameError) + -> { Enumerable::Hash }.should.raise(NameError) end end @@ -506,7 +488,7 @@ describe "Module#private_constant marked constants" do mod.const_set :Foo, false }.should complain(/already initialized constant/) - -> {mod::Foo}.should raise_error(NameError) + -> {mod::Foo}.should.raise(NameError) end it "sends #const_missing to the original class or module" do @@ -524,19 +506,19 @@ describe "Module#private_constant marked constants" do it "cannot be accessed from outside the module" do -> do ConstantVisibility::PrivConstModule::PRIVATE_CONSTANT_MODULE - end.should raise_error(NameError) + end.should.raise(NameError) end it "cannot be reopened as a module from scope where constant would be private" do -> do module ConstantVisibility::ModuleContainer::PrivateModule; end - end.should raise_error(NameError) + end.should.raise(NameError) end it "cannot be reopened as a class from scope where constant would be private" do -> do class ConstantVisibility::ModuleContainer::PrivateClass; end - end.should raise_error(NameError) + end.should.raise(NameError) end it "can be reopened as a module where constant is not private" do @@ -572,7 +554,7 @@ describe "Module#private_constant marked constants" do end it "can be accessed from the module itself" do - ConstantVisibility::PrivConstModule.private_constant_from_self.should be_true + ConstantVisibility::PrivConstModule.private_constant_from_self.should == true end it "is defined? from the module itself" do @@ -580,7 +562,7 @@ describe "Module#private_constant marked constants" do end it "can be accessed from lexical scope" do - ConstantVisibility::PrivConstModule::Nested.private_constant_from_scope.should be_true + ConstantVisibility::PrivConstModule::Nested.private_constant_from_scope.should == true end it "is defined? from lexical scope" do @@ -588,20 +570,20 @@ describe "Module#private_constant marked constants" do end it "can be accessed from classes that include the module" do - ConstantVisibility::ClassIncludingPrivConstModule.new.private_constant_from_include.should be_true + ConstantVisibility::ClassIncludingPrivConstModule.new.private_constant_from_include.should == true end it "can be accessed from modules that include the module" do - ConstantVisibility::ModuleIncludingPrivConstModule.private_constant_from_include.should be_true + ConstantVisibility::ModuleIncludingPrivConstModule.private_constant_from_include.should == true end it "raises a NameError when accessed directly from modules that include the module" do -> do ConstantVisibility::ModuleIncludingPrivConstModule.private_constant_self_from_include - end.should raise_error(NameError) + end.should.raise(NameError) -> do ConstantVisibility::ModuleIncludingPrivConstModule.private_constant_named_from_include - end.should raise_error(NameError) + end.should.raise(NameError) end it "is defined? from classes that include the module" do @@ -613,19 +595,19 @@ describe "Module#private_constant marked constants" do it "cannot be accessed from outside the class" do -> do ConstantVisibility::PrivConstClass::PRIVATE_CONSTANT_CLASS - end.should raise_error(NameError) + end.should.raise(NameError) end it "cannot be reopened as a module" do -> do module ConstantVisibility::ClassContainer::PrivateModule; end - end.should raise_error(NameError) + end.should.raise(NameError) end it "cannot be reopened as a class" do -> do class ConstantVisibility::ClassContainer::PrivateClass; end - end.should raise_error(NameError) + end.should.raise(NameError) end it "can be reopened as a module where constant is not private" do @@ -661,7 +643,7 @@ describe "Module#private_constant marked constants" do end it "can be accessed from the class itself" do - ConstantVisibility::PrivConstClass.private_constant_from_self.should be_true + ConstantVisibility::PrivConstClass.private_constant_from_self.should == true end it "is defined? from the class itself" do @@ -669,7 +651,7 @@ describe "Module#private_constant marked constants" do end it "can be accessed from lexical scope" do - ConstantVisibility::PrivConstClass::Nested.private_constant_from_scope.should be_true + ConstantVisibility::PrivConstClass::Nested.private_constant_from_scope.should == true end it "is defined? from lexical scope" do @@ -677,7 +659,7 @@ describe "Module#private_constant marked constants" do end it "can be accessed from subclasses" do - ConstantVisibility::PrivConstClassChild.new.private_constant_from_subclass.should be_true + ConstantVisibility::PrivConstClassChild.new.private_constant_from_subclass.should == true end it "is defined? from subclasses" do @@ -689,7 +671,7 @@ describe "Module#private_constant marked constants" do it "cannot be accessed using ::Const form" do -> do ::PRIVATE_CONSTANT_IN_OBJECT - end.should raise_error(NameError) + end.should.raise(NameError) end it "is not defined? using ::Const form" do @@ -709,14 +691,14 @@ describe "Module#private_constant marked constants" do it "has :receiver and :name attributes" do -> do ConstantVisibility::PrivConstClass::PRIVATE_CONSTANT_CLASS - end.should raise_error(NameError) {|e| + end.should.raise(NameError) {|e| e.receiver.should == ConstantVisibility::PrivConstClass e.name.should == :PRIVATE_CONSTANT_CLASS } -> do ConstantVisibility::PrivConstModule::PRIVATE_CONSTANT_MODULE - end.should raise_error(NameError) {|e| + end.should.raise(NameError) {|e| e.receiver.should == ConstantVisibility::PrivConstModule e.name.should == :PRIVATE_CONSTANT_MODULE } @@ -725,14 +707,14 @@ describe "Module#private_constant marked constants" do it "has the defined class as the :name attribute" do -> do ConstantVisibility::PrivConstClassChild::PRIVATE_CONSTANT_CLASS - end.should raise_error(NameError) {|e| + end.should.raise(NameError) {|e| e.receiver.should == ConstantVisibility::PrivConstClass e.name.should == :PRIVATE_CONSTANT_CLASS } -> do ConstantVisibility::ClassIncludingPrivConstModule::PRIVATE_CONSTANT_MODULE - end.should raise_error(NameError) {|e| + end.should.raise(NameError) {|e| e.receiver.should == ConstantVisibility::PrivConstModule e.name.should == :PRIVATE_CONSTANT_MODULE } @@ -801,7 +783,7 @@ describe 'Allowed characters' do it 'does not allow not ASCII characters that cannot be upcased or lowercased at the beginning' do -> do Module.new.const_set("થBB", 1) - end.should raise_error(NameError, /wrong constant name/) + end.should.raise(NameError, /wrong constant name/) end it 'allows not ASCII upcased characters at the beginning' do @@ -821,7 +803,7 @@ describe 'Assignment' do B = 1 end CODE - end.should raise_error(SyntaxError, /dynamic constant assignment/) + end.should.raise(SyntaxError, /dynamic constant assignment/) end end end diff --git a/spec/ruby/language/def_spec.rb b/spec/ruby/language/def_spec.rb index eb44331bb5..82c89a0d08 100644 --- a/spec/ruby/language/def_spec.rb +++ b/spec/ruby/language/def_spec.rb @@ -14,11 +14,11 @@ end describe "Defining a method at the top-level" do it "defines it on Object with private visibility by default" do - Object.should have_private_instance_method(:some_toplevel_method, false) + Object.private_instance_methods(false).should.include?(:some_toplevel_method) end it "defines it on Object with public visibility after calling public" do - Object.should have_public_instance_method(:public_toplevel_method, false) + Object.public_instance_methods(false).should.include?(:public_toplevel_method) end end @@ -28,7 +28,7 @@ describe "Defining an 'initialize' method" do def initialize end end - DefInitializeSpec.should have_private_instance_method(:initialize, false) + DefInitializeSpec.private_instance_methods(false).should.include?(:initialize) end end @@ -38,7 +38,7 @@ describe "Defining an 'initialize_copy' method" do def initialize_copy end end - DefInitializeCopySpec.should have_private_instance_method(:initialize_copy, false) + DefInitializeCopySpec.private_instance_methods(false).should.include?(:initialize_copy) end end @@ -48,7 +48,7 @@ describe "Defining an 'initialize_dup' method" do def initialize_dup end end - DefInitializeDupSpec.should have_private_instance_method(:initialize_dup, false) + DefInitializeDupSpec.private_instance_methods(false).should.include?(:initialize_dup) end end @@ -58,7 +58,7 @@ describe "Defining an 'initialize_clone' method" do def initialize_clone end end - DefInitializeCloneSpec.should have_private_instance_method(:initialize_clone, false) + DefInitializeCloneSpec.private_instance_methods(false).should.include?(:initialize_clone) end end @@ -68,7 +68,7 @@ describe "Defining a 'respond_to_missing?' method" do def respond_to_missing? end end - DefRespondToMissingPSpec.should have_private_instance_method(:respond_to_missing?, false) + DefRespondToMissingPSpec.private_instance_methods(false).should.include?(:respond_to_missing?) end end @@ -82,12 +82,12 @@ end describe "An instance method" do it "raises an error with too few arguments" do def foo(a, b); end - -> { foo 1 }.should raise_error(ArgumentError, 'wrong number of arguments (given 1, expected 2)') + -> { foo 1 }.should.raise(ArgumentError, 'wrong number of arguments (given 1, expected 2)') end it "raises an error with too many arguments" do def foo(a); end - -> { foo 1, 2 }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 1)') + -> { foo 1, 2 }.should.raise(ArgumentError, 'wrong number of arguments (given 2, expected 1)') end it "raises FrozenError with the correct class name" do @@ -96,8 +96,9 @@ describe "An instance method" do self.freeze def foo; end end - }.should raise_error(FrozenError) { |e| - e.message.should.start_with? "can't modify frozen module" + }.should.raise(FrozenError) { |e| + msg_class = ruby_version_is("4.0") ? "Module" : "module" + e.message.should == "can't modify frozen #{msg_class}: #{e.receiver}" } -> { @@ -105,8 +106,9 @@ describe "An instance method" do self.freeze def foo; end end - }.should raise_error(FrozenError){ |e| - e.message.should.start_with? "can't modify frozen class" + }.should.raise(FrozenError){ |e| + msg_class = ruby_version_is("4.0") ? "Class" : "class" + e.message.should == "can't modify frozen #{msg_class}: #{e.receiver}" } end end @@ -133,12 +135,12 @@ describe "An instance method definition with a splat" do end it "allows only a single * argument" do - -> { eval 'def foo(a, *b, *c); end' }.should raise_error(SyntaxError) + -> { eval 'def foo(a, *b, *c); end' }.should.raise(SyntaxError) end it "requires the presence of any arguments that precede the *" do def foo(a, b, *c); end - -> { foo 1 }.should raise_error(ArgumentError, 'wrong number of arguments (given 1, expected 2+)') + -> { foo 1 }.should.raise(ArgumentError, 'wrong number of arguments (given 1, expected 2+)') end end @@ -171,7 +173,7 @@ describe "An instance method with a default argument" do def foo(a, b = 2) [a,b] end - -> { foo }.should raise_error(ArgumentError, 'wrong number of arguments (given 0, expected 1..2)') + -> { foo }.should.raise(ArgumentError, 'wrong number of arguments (given 0, expected 1..2)') foo(1).should == [1, 2] end @@ -179,7 +181,7 @@ describe "An instance method with a default argument" do def foo(a, b = 2, *c) [a,b,c] end - -> { foo }.should raise_error(ArgumentError, 'wrong number of arguments (given 0, expected 1+)') + -> { foo }.should.raise(ArgumentError, 'wrong number of arguments (given 0, expected 1+)') foo(1).should == [1,2,[]] end @@ -203,7 +205,7 @@ describe "An instance method with a default argument" do eval "def foo(bar = bar) bar end" - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end end @@ -277,26 +279,27 @@ describe "A singleton method definition" do it "raises FrozenError if frozen" do obj = Object.new obj.freeze - -> { def obj.foo; end }.should raise_error(FrozenError) + -> { def obj.foo; end }.should.raise(FrozenError) end it "raises FrozenError with the correct class name" do obj = Object.new obj.freeze - -> { def obj.foo; end }.should raise_error(FrozenError){ |e| - e.message.should.start_with? "can't modify frozen object" - } + msg_class = ruby_version_is("4.0") ? "Object" : "object" + -> { def obj.foo; end }.should.raise(FrozenError, "can't modify frozen #{msg_class}: #{obj}") + obj = Object.new c = obj.singleton_class - -> { def c.foo; end }.should raise_error(FrozenError){ |e| - e.message.should.start_with? "can't modify frozen Class" - } + c.singleton_class.freeze + -> { def c.foo; end }.should.raise(FrozenError, "can't modify frozen Class: #{c}") + + c = Class.new + c.freeze + -> { def c.foo; end }.should.raise(FrozenError, "can't modify frozen Class: #{c}") m = Module.new m.freeze - -> { def m.foo; end }.should raise_error(FrozenError){ |e| - e.message.should.start_with? "can't modify frozen Module" - } + -> { def m.foo; end }.should.raise(FrozenError, "can't modify frozen Module: #{m}") end end @@ -431,7 +434,7 @@ describe "A method definition inside a metaclass scope" do end DefSpecSingleton.a_class_method.should == DefSpecSingleton - -> { Object.a_class_method }.should raise_error(NoMethodError) + -> { Object.a_class_method }.should.raise(NoMethodError) end it "can create a singleton method" do @@ -441,7 +444,7 @@ describe "A method definition inside a metaclass scope" do end obj.a_singleton_method.should == obj - -> { Object.new.a_singleton_method }.should raise_error(NoMethodError) + -> { Object.new.a_singleton_method }.should.raise(NoMethodError) end it "raises FrozenError if frozen" do @@ -449,7 +452,7 @@ describe "A method definition inside a metaclass scope" do obj.freeze class << obj - -> { def foo; end }.should raise_error(FrozenError) + -> { def foo; end }.should.raise(FrozenError) end end end @@ -470,7 +473,7 @@ describe "A nested method definition" do other = DefSpecNested.new other.an_instance_method.should == other - DefSpecNested.should have_instance_method(:an_instance_method) + DefSpecNested.should.method_defined?(:an_instance_method, false) end it "creates a class method when evaluated in a class method" do @@ -485,11 +488,11 @@ describe "A nested method definition" do end end - -> { DefSpecNested.a_class_method }.should raise_error(NoMethodError) + -> { DefSpecNested.a_class_method }.should.raise(NoMethodError) DefSpecNested.create_class_method.should == DefSpecNested DefSpecNested.a_class_method.should == DefSpecNested - -> { Object.a_class_method }.should raise_error(NoMethodError) - -> { DefSpecNested.new.a_class_method }.should raise_error(NoMethodError) + -> { Object.a_class_method }.should.raise(NoMethodError) + -> { DefSpecNested.new.a_class_method }.should.raise(NoMethodError) end it "creates a singleton method when evaluated in the metaclass of an instance" do @@ -507,7 +510,7 @@ describe "A nested method definition" do obj.a_singleton_method.should == obj other = DefSpecNested.new - -> { other.a_singleton_method }.should raise_error(NoMethodError) + -> { other.a_singleton_method }.should.raise(NoMethodError) end it "creates a method in the surrounding context when evaluated in a def expr.method" do @@ -519,8 +522,8 @@ describe "A nested method definition" do end DefSpecNested::TARGET.defs_method - DefSpecNested.should have_instance_method :inherited_method - DefSpecNested::TARGET.should_not have_method :inherited_method + DefSpecNested.should.method_defined?(:inherited_method, false) + DefSpecNested::TARGET.should_not.respond_to? :inherited_method obj = DefSpecNested.new obj.inherited_method.should == obj @@ -542,11 +545,11 @@ describe "A nested method definition" do obj = DefSpecNested::OBJ obj.create_method_in_instance_eval - obj.should have_method :arg_method - obj.should have_method :body_method + obj.should.respond_to? :arg_method + obj.should.respond_to? :body_method - DefSpecNested.should_not have_instance_method :arg_method - DefSpecNested.should_not have_instance_method :body_method + DefSpecNested.should_not.method_defined? :arg_method + DefSpecNested.should_not.method_defined? :body_method ensure DefSpecNested.send(:remove_const, :OBJ) end @@ -566,7 +569,7 @@ describe "A nested method definition" do cls.new.new_def.should == 1 - -> { Object.new.new_def }.should raise_error(NoMethodError) + -> { Object.new.new_def }.should.raise(NoMethodError) end end @@ -582,18 +585,18 @@ describe "A method definition always resets the visibility to public for nested end obj = cls.new - -> { obj.do_def }.should raise_error(NoMethodError, /private/) + -> { obj.do_def }.should.raise(NoMethodError, /private/) obj.send :do_def obj.new_def.should == 1 cls.new.new_def.should == 1 - -> { Object.new.new_def }.should raise_error(NoMethodError) + -> { Object.new.new_def }.should.raise(NoMethodError) end it "at the toplevel" do obj = Object.new - -> { obj.toplevel_define_other_method }.should raise_error(NoMethodError, /private/) + -> { obj.toplevel_define_other_method }.should.raise(NoMethodError, /private/) toplevel_define_other_method nested_method_in_toplevel_method.should == 42 @@ -610,7 +613,7 @@ describe "A method definition inside an instance_eval" do obj.an_instance_eval_method.should == obj other = Object.new - -> { other.an_instance_eval_method }.should raise_error(NoMethodError) + -> { other.an_instance_eval_method }.should.raise(NoMethodError) end it "creates a singleton method when evaluated inside a metaclass" do @@ -623,7 +626,7 @@ describe "A method definition inside an instance_eval" do obj.a_metaclass_eval_method.should == obj other = Object.new - -> { other.a_metaclass_eval_method }.should raise_error(NoMethodError) + -> { other.a_metaclass_eval_method }.should.raise(NoMethodError) end it "creates a class method when the receiver is a class" do @@ -632,7 +635,7 @@ describe "A method definition inside an instance_eval" do end DefSpecNested.an_instance_eval_class_method.should == DefSpecNested - -> { Object.an_instance_eval_class_method }.should raise_error(NoMethodError) + -> { Object.an_instance_eval_class_method }.should.raise(NoMethodError) end it "creates a class method when the receiver is an anonymous class" do @@ -644,7 +647,7 @@ describe "A method definition inside an instance_eval" do end m.klass_method.should == :test - -> { Object.klass_method }.should raise_error(NoMethodError) + -> { Object.klass_method }.should.raise(NoMethodError) end it "creates a class method when instance_eval is within class" do @@ -657,7 +660,7 @@ describe "A method definition inside an instance_eval" do end m.klass_method.should == :test - -> { Object.klass_method }.should raise_error(NoMethodError) + -> { Object.klass_method }.should.raise(NoMethodError) end end @@ -670,7 +673,7 @@ describe "A method definition inside an instance_exec" do end DefSpecNested.an_instance_exec_class_method.should == 1 - -> { Object.an_instance_exec_class_method }.should raise_error(NoMethodError) + -> { Object.an_instance_exec_class_method }.should.raise(NoMethodError) end it "creates a class method when the receiver is an anonymous class" do @@ -684,7 +687,7 @@ describe "A method definition inside an instance_exec" do end m.klass_method.should == 1 - -> { Object.klass_method }.should raise_error(NoMethodError) + -> { Object.klass_method }.should.raise(NoMethodError) end it "creates a class method when instance_exec is within class" do @@ -699,7 +702,7 @@ describe "A method definition inside an instance_exec" do end m.klass_method.should == 2 - -> { Object.klass_method }.should raise_error(NoMethodError) + -> { Object.klass_method }.should.raise(NoMethodError) end end @@ -719,7 +722,7 @@ describe "A method definition in an eval" do other = DefSpecNested.new other.an_eval_instance_method.should == other - -> { Object.new.an_eval_instance_method }.should raise_error(NoMethodError) + -> { Object.new.an_eval_instance_method }.should.raise(NoMethodError) end it "creates a class method" do @@ -735,8 +738,8 @@ describe "A method definition in an eval" do DefSpecNestedB.eval_class_method.should == DefSpecNestedB DefSpecNestedB.an_eval_class_method.should == DefSpecNestedB - -> { Object.an_eval_class_method }.should raise_error(NoMethodError) - -> { DefSpecNestedB.new.an_eval_class_method}.should raise_error(NoMethodError) + -> { Object.an_eval_class_method }.should.raise(NoMethodError) + -> { DefSpecNestedB.new.an_eval_class_method}.should.raise(NoMethodError) end it "creates a singleton method" do @@ -754,7 +757,7 @@ describe "A method definition in an eval" do obj.an_eval_singleton_method.should == obj other = DefSpecNested.new - -> { other.an_eval_singleton_method }.should raise_error(NoMethodError) + -> { other.an_eval_singleton_method }.should.raise(NoMethodError) end end @@ -765,8 +768,8 @@ describe "a method definition that sets more than one default parameter all to t it "assigns them all the same object by default" do foo.should == [{},{},{}] a, b, c = foo - a.should eql(b) - a.should eql(c) + a.should.eql?(b) + a.should.eql?(c) end it "allows the first argument to be given, and sets the rest to null" do @@ -776,11 +779,11 @@ describe "a method definition that sets more than one default parameter all to t it "assigns the parameters different objects across different default calls" do a, _b, _c = foo d, _e, _f = foo - a.should_not equal(d) + a.should_not.equal?(d) end it "only allows overriding the default value of the first such parameter in each set" do - -> { foo(1,2) }.should raise_error(ArgumentError, 'wrong number of arguments (given 2, expected 0..1)') + -> { foo(1,2) }.should.raise(ArgumentError, 'wrong number of arguments (given 2, expected 0..1)') end def bar(a=b=c=1,d=2) @@ -791,7 +794,7 @@ describe "a method definition that sets more than one default parameter all to t bar.should == [1,1,1,2] bar(3).should == [3,nil,nil,2] bar(3,4).should == [3,nil,nil,4] - -> { bar(3,4,5) }.should raise_error(ArgumentError, 'wrong number of arguments (given 3, expected 0..2)') + -> { bar(3,4,5) }.should.raise(ArgumentError, 'wrong number of arguments (given 3, expected 0..2)') end end @@ -806,7 +809,7 @@ describe "The def keyword" do }.call end - DefSpecsLambdaVisibility.should have_private_instance_method("some_method") + DefSpecsLambdaVisibility.private_instance_methods(false).should.include?(:some_method) end end end diff --git a/spec/ruby/language/defined_spec.rb b/spec/ruby/language/defined_spec.rb index 80ad1818b1..3fd611d09e 100644 --- a/spec/ruby/language/defined_spec.rb +++ b/spec/ruby/language/defined_spec.rb @@ -70,7 +70,7 @@ describe "The defined? keyword when called with a method name" do end it "returns nil if the method is not defined" do - defined?(defined_specs_undefined_method).should be_nil + defined?(defined_specs_undefined_method).should == nil end it "returns 'method' if the method is defined and private" do @@ -90,23 +90,23 @@ describe "The defined? keyword when called with a method name" do end it "returns nil if the method is private" do - defined?(Object.print).should be_nil + defined?(Object.print).should == nil end it "returns nil if the method is protected" do - defined?(DefinedSpecs::Basic.new.protected_method).should be_nil + defined?(DefinedSpecs::Basic.new.protected_method).should == nil end it "returns nil if the method is not defined" do - defined?(Kernel.defined_specs_undefined_method).should be_nil + defined?(Kernel.defined_specs_undefined_method).should == nil end it "returns nil if the class is not defined" do - defined?(DefinedSpecsUndefined.puts).should be_nil + defined?(DefinedSpecsUndefined.puts).should == nil end it "returns nil if the subclass is not defined" do - defined?(DefinedSpecs::Undefined.puts).should be_nil + defined?(DefinedSpecs::Undefined.puts).should == nil end end @@ -123,11 +123,11 @@ describe "The defined? keyword when called with a method name" do it "returns nil if the method is not defined" do obj = DefinedSpecs::Basic.new - defined?(obj.an_undefined_method).should be_nil + defined?(obj.an_undefined_method).should == nil end it "returns nil if the variable does not exist" do - defined?(nonexistent_local_variable.some_method).should be_nil + defined?(nonexistent_local_variable.some_method).should == nil end it "calls #respond_to_missing?" do @@ -145,11 +145,11 @@ describe "The defined? keyword when called with a method name" do it "returns nil if the method is not defined" do @defined_specs_obj = DefinedSpecs::Basic.new - defined?(@defined_specs_obj.an_undefined_method).should be_nil + defined?(@defined_specs_obj.an_undefined_method).should == nil end it "returns nil if the variable does not exist" do - defined?(@nonexistent_instance_variable.some_method).should be_nil + defined?(@nonexistent_instance_variable.some_method).should == nil end end @@ -161,22 +161,22 @@ describe "The defined? keyword when called with a method name" do it "returns nil if the method is not defined" do $defined_specs_obj = DefinedSpecs::Basic.new - defined?($defined_specs_obj.an_undefined_method).should be_nil + defined?($defined_specs_obj.an_undefined_method).should == nil end it "returns nil if the variable does not exist" do - defined?($nonexistent_global_variable.some_method).should be_nil + defined?($nonexistent_global_variable.some_method).should == nil end end describe "having a method call as a receiver" do it "returns nil if evaluating the receiver raises an exception" do - defined?(DefinedSpecs.exception_method / 2).should be_nil + defined?(DefinedSpecs.exception_method / 2).should == nil ScratchPad.recorded.should == :defined_specs_exception end it "returns nil if the method is not defined on the object the receiver returns" do - defined?(DefinedSpecs.side_effects / 2).should be_nil + defined?(DefinedSpecs.side_effects / 2).should == nil ScratchPad.recorded.should == :defined_specs_side_effects end @@ -403,15 +403,15 @@ describe "The defined? keyword for an expression" do end it "returns nil for an expression with == and an undefined method" do - defined?(defined_specs_undefined_method == 2).should be_nil + defined?(defined_specs_undefined_method == 2).should == nil end it "returns nil for an expression with != and an undefined method" do - defined?(defined_specs_undefined_method != 2).should be_nil + defined?(defined_specs_undefined_method != 2).should == nil end it "returns nil for an expression with !~ and an undefined method" do - defined?(defined_specs_undefined_method !~ 2).should be_nil + defined?(defined_specs_undefined_method !~ 2).should == nil end it "returns 'method' for an expression with '=='" do @@ -431,25 +431,25 @@ describe "The defined? keyword for an expression" do describe "with logical connectives" do it "returns nil for an expression with '!' and an undefined method" do - defined?(!defined_specs_undefined_method).should be_nil + defined?(!defined_specs_undefined_method).should == nil end it "returns nil for an expression with '!' and an unset class variable" do @result = eval("class singleton_class::A; defined?(!@@doesnt_exist) end", binding, __FILE__, __LINE__) - @result.should be_nil + @result.should == nil end it "returns nil for an expression with 'not' and an undefined method" do - defined?(not defined_specs_undefined_method).should be_nil + defined?(not defined_specs_undefined_method).should == nil end it "returns nil for an expression with 'not' and an unset class variable" do @result = eval("class singleton_class::A; defined?(not @@doesnt_exist) end", binding, __FILE__, __LINE__) - @result.should be_nil + @result.should == nil end it "does not propagate an exception raised by a method in a 'not' expression" do - defined?(not DefinedSpecs.exception_method).should be_nil + defined?(not DefinedSpecs.exception_method).should == nil ScratchPad.recorded.should == :defined_specs_exception end @@ -488,11 +488,11 @@ describe "The defined? keyword for an expression" do end it "returns nil for an expression with '!' and an unset global variable" do - defined?(!$defined_specs_undefined_global_variable).should be_nil + defined?(!$defined_specs_undefined_global_variable).should == nil end it "returns nil for an expression with '!' and an unset instance variable" do - defined?(!@defined_specs_undefined_instance_variable).should be_nil + defined?(!@defined_specs_undefined_instance_variable).should == nil end it "returns 'method' for a 'not' expression with a method" do @@ -505,11 +505,11 @@ describe "The defined? keyword for an expression" do end it "returns nil for an expression with 'not' and an unset global variable" do - defined?(not $defined_specs_undefined_global_variable).should be_nil + defined?(not $defined_specs_undefined_global_variable).should == nil end it "returns nil for an expression with 'not' and an unset instance variable" do - defined?(not @defined_specs_undefined_instance_variable).should be_nil + defined?(not @defined_specs_undefined_instance_variable).should == nil end it "returns 'expression' for an expression with '&&/and' and an undefined method" do @@ -524,12 +524,12 @@ describe "The defined? keyword for an expression" do it "does not call a method in an '&&' expression and returns 'expression'" do defined?(DefinedSpecs.side_effects && true).should == "expression" - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end it "does not call a method in an 'and' expression and returns 'expression'" do defined?(DefinedSpecs.side_effects and true).should == "expression" - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end it "returns 'expression' for an expression with '||/or' and an undefined method" do @@ -544,12 +544,12 @@ describe "The defined? keyword for an expression" do it "does not call a method in an '||' expression and returns 'expression'" do defined?(DefinedSpecs.side_effects || true).should == "expression" - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end it "does not call a method in an 'or' expression and returns 'expression'" do defined?(DefinedSpecs.side_effects or true).should == "expression" - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end end @@ -572,7 +572,7 @@ describe "The defined? keyword for an expression" do it "does not call the method in the String" do defined?("garble #{DefinedSpecs.dynamic_string}").should == "expression" - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end end @@ -591,7 +591,7 @@ describe "The defined? keyword for an expression" do it "does not call the method in the Regexp" do defined?(/garble #{DefinedSpecs.dynamic_string}/).should == "expression" - ScratchPad.recorded.should be_nil + ScratchPad.recorded.should == nil end end @@ -640,11 +640,11 @@ describe "The defined? keyword for variables" do end it "returns nil for an instance variable that has not been read" do - DefinedSpecs::Basic.new.instance_variable_undefined.should be_nil + DefinedSpecs::Basic.new.instance_variable_undefined.should == nil end it "returns nil for an instance variable that has been read but not assigned to" do - DefinedSpecs::Basic.new.instance_variable_read.should be_nil + DefinedSpecs::Basic.new.instance_variable_read.should == nil end it "returns 'instance-variable' for an instance variable that has been assigned" do @@ -658,11 +658,11 @@ describe "The defined? keyword for variables" do end it "returns nil for a global variable that has not been read" do - DefinedSpecs::Basic.new.global_variable_undefined.should be_nil + DefinedSpecs::Basic.new.global_variable_undefined.should == nil end it "returns nil for a global variable that has been read but not assigned to" do - DefinedSpecs::Basic.new.global_variable_read.should be_nil + DefinedSpecs::Basic.new.global_variable_read.should == nil end it "returns 'global-variable' for a global variable that has been assigned nil" do @@ -694,27 +694,27 @@ describe "The defined? keyword for variables" do end it "returns nil for $&" do - defined?($&).should be_nil + defined?($&).should == nil end it "returns nil for $`" do - defined?($`).should be_nil + defined?($`).should == nil end it "returns nil for $'" do - defined?($').should be_nil + defined?($').should == nil end it "returns nil for $+" do - defined?($+).should be_nil + defined?($+).should == nil end it "returns nil for any last match global" do - defined?($1).should be_nil - defined?($4).should be_nil - defined?($7).should be_nil - defined?($10).should be_nil - defined?($200).should be_nil + defined?($1).should == nil + defined?($4).should == nil + defined?($7).should == nil + defined?($10).should == nil + defined?($200).should == nil end end @@ -749,10 +749,10 @@ describe "The defined? keyword for variables" do end it "returns nil for non-captures" do - defined?($4).should be_nil - defined?($7).should be_nil - defined?($10).should be_nil - defined?($200).should be_nil + defined?($4).should == nil + defined?($7).should == nil + defined?($10).should == nil + defined?($200).should == nil end end @@ -766,27 +766,27 @@ describe "The defined? keyword for variables" do end it "returns nil for $&" do - defined?($&).should be_nil + defined?($&).should == nil end it "returns nil for $`" do - defined?($`).should be_nil + defined?($`).should == nil end it "returns nil for $'" do - defined?($').should be_nil + defined?($').should == nil end it "returns nil for $+" do - defined?($+).should be_nil + defined?($+).should == nil end it "returns nil for any last match global" do - defined?($1).should be_nil - defined?($4).should be_nil - defined?($7).should be_nil - defined?($10).should be_nil - defined?($200).should be_nil + defined?($1).should == nil + defined?($4).should == nil + defined?($7).should == nil + defined?($10).should == nil + defined?($200).should == nil end end @@ -821,10 +821,10 @@ describe "The defined? keyword for variables" do end it "returns nil for non-captures" do - defined?($4).should be_nil - defined?($7).should be_nil - defined?($10).should be_nil - defined?($200).should be_nil + defined?($4).should == nil + defined?($7).should == nil + defined?($10).should == nil + defined?($200).should == nil end end it "returns 'global-variable' for a global variable that has been assigned" do @@ -832,7 +832,7 @@ describe "The defined? keyword for variables" do end it "returns nil for a class variable that has not been read" do - DefinedSpecs::Basic.new.class_variable_undefined.should be_nil + DefinedSpecs::Basic.new.class_variable_undefined.should == nil end # There is no spec for a class variable that is read before being assigned @@ -859,12 +859,12 @@ describe "The defined? keyword for a simple constant" do end it "returns nil when the constant is not defined" do - defined?(DefinedSpecsUndefined).should be_nil + defined?(DefinedSpecsUndefined).should == nil end it "does not call Object.const_missing if the constant is not defined" do Object.should_not_receive(:const_missing) - defined?(DefinedSpecsUndefined).should be_nil + defined?(DefinedSpecsUndefined).should == nil end it "returns 'constant' for an included module" do @@ -882,12 +882,12 @@ describe "The defined? keyword for a top-level constant" do end it "returns nil if the constant is not defined" do - defined?(::DefinedSpecsUndefined).should be_nil + defined?(::DefinedSpecsUndefined).should == nil end it "does not call Object.const_missing if the constant is not defined" do Object.should_not_receive(:const_missing) - defined?(::DefinedSpecsUndefined).should be_nil + defined?(::DefinedSpecsUndefined).should == nil end end @@ -897,37 +897,37 @@ describe "The defined? keyword for a scoped constant" do end it "returns nil when the scoped constant is not defined" do - defined?(DefinedSpecs::Undefined).should be_nil + defined?(DefinedSpecs::Undefined).should == nil end it "returns nil when the constant is not defined and the outer module implements .const_missing" do - defined?(DefinedSpecs::ModuleWithConstMissing::Undefined).should be_nil + defined?(DefinedSpecs::ModuleWithConstMissing::Undefined).should == nil end it "does not call .const_missing if the constant is not defined" do DefinedSpecs.should_not_receive(:const_missing) - defined?(DefinedSpecs::UnknownChild).should be_nil + defined?(DefinedSpecs::UnknownChild).should == nil end it "returns nil when an undefined constant is scoped to a defined constant" do - defined?(DefinedSpecs::Child::Undefined).should be_nil + defined?(DefinedSpecs::Child::Undefined).should == nil end it "returns nil when a constant is scoped to an undefined constant" do Object.should_not_receive(:const_missing) - defined?(Undefined::Object).should be_nil + defined?(Undefined::Object).should == nil end it "returns nil when the undefined constant is scoped to an undefined constant" do - defined?(DefinedSpecs::Undefined::Undefined).should be_nil + defined?(DefinedSpecs::Undefined::Undefined).should == nil end it "returns nil when a constant is defined on top-level but not on the module" do - defined?(DefinedSpecs::String).should be_nil + defined?(DefinedSpecs::String).should == nil end it "returns nil when a constant is defined on top-level but not on the class" do - defined?(DefinedSpecs::Basic::String).should be_nil + defined?(DefinedSpecs::Basic::String).should == nil end it "returns 'constant' if the scoped-scoped constant is defined" do @@ -941,15 +941,15 @@ describe "The defined? keyword for a top-level scoped constant" do end it "returns nil when the scoped constant is not defined" do - defined?(::DefinedSpecs::Undefined).should be_nil + defined?(::DefinedSpecs::Undefined).should == nil end it "returns nil when an undefined constant is scoped to a defined constant" do - defined?(::DefinedSpecs::Child::Undefined).should be_nil + defined?(::DefinedSpecs::Child::Undefined).should == nil end it "returns nil when the undefined constant is scoped to an undefined constant" do - defined?(::DefinedSpecs::Undefined::Undefined).should be_nil + defined?(::DefinedSpecs::Undefined::Undefined).should == nil end it "returns 'constant' if the scoped-scoped constant is defined" do @@ -959,7 +959,7 @@ end describe "The defined? keyword for a self-send method call scoped constant" do it "returns nil if the constant is not defined in the scope of the method's value" do - defined?(defined_specs_method::Undefined).should be_nil + defined?(defined_specs_method::Undefined).should == nil end it "returns 'constant' if the constant is defined in the scope of the method's value" do @@ -967,11 +967,11 @@ describe "The defined? keyword for a self-send method call scoped constant" do end it "returns nil if the last constant is not defined in the scope chain" do - defined?(defined_specs_method::Basic::Undefined).should be_nil + defined?(defined_specs_method::Basic::Undefined).should == nil end it "returns nil if the middle constant is not defined in the scope chain" do - defined?(defined_specs_method::Undefined::Undefined).should be_nil + defined?(defined_specs_method::Undefined::Undefined).should == nil end it "returns 'constant' if all the constants in the scope chain are defined" do @@ -981,7 +981,7 @@ end describe "The defined? keyword for a receiver method call scoped constant" do it "returns nil if the constant is not defined in the scope of the method's value" do - defined?(defined_specs_receiver.defined_method::Undefined).should be_nil + defined?(defined_specs_receiver.defined_method::Undefined).should == nil end it "returns 'constant' if the constant is defined in the scope of the method's value" do @@ -989,11 +989,11 @@ describe "The defined? keyword for a receiver method call scoped constant" do end it "returns nil if the last constant is not defined in the scope chain" do - defined?(defined_specs_receiver.defined_method::Basic::Undefined).should be_nil + defined?(defined_specs_receiver.defined_method::Basic::Undefined).should == nil end it "returns nil if the middle constant is not defined in the scope chain" do - defined?(defined_specs_receiver.defined_method::Undefined::Undefined).should be_nil + defined?(defined_specs_receiver.defined_method::Undefined::Undefined).should == nil end it "returns 'constant' if all the constants in the scope chain are defined" do @@ -1003,7 +1003,7 @@ end describe "The defined? keyword for a module method call scoped constant" do it "returns nil if the constant is not defined in the scope of the method's value" do - defined?(DefinedSpecs.defined_method::Undefined).should be_nil + defined?(DefinedSpecs.defined_method::Undefined).should == nil end it "returns 'constant' if the constant scoped by the method's value is defined" do @@ -1011,11 +1011,11 @@ describe "The defined? keyword for a module method call scoped constant" do end it "returns nil if the last constant in the scope chain is not defined" do - defined?(DefinedSpecs.defined_method::Basic::Undefined).should be_nil + defined?(DefinedSpecs.defined_method::Basic::Undefined).should == nil end it "returns nil if the middle constant in the scope chain is not defined" do - defined?(DefinedSpecs.defined_method::Undefined::Undefined).should be_nil + defined?(DefinedSpecs.defined_method::Undefined::Undefined).should == nil end it "returns 'constant' if all the constants in the scope chain are defined" do @@ -1023,11 +1023,11 @@ describe "The defined? keyword for a module method call scoped constant" do end it "returns nil if the outer scope constant in the receiver is not defined" do - defined?(Undefined::DefinedSpecs.defined_method::Basic).should be_nil + defined?(Undefined::DefinedSpecs.defined_method::Basic).should == nil end it "returns nil if the scoped constant in the receiver is not defined" do - defined?(DefinedSpecs::Undefined.defined_method::Basic).should be_nil + defined?(DefinedSpecs::Undefined.defined_method::Basic).should == nil end it "returns 'constant' if all the constants in the receiver are defined" do @@ -1048,7 +1048,7 @@ describe "The defined? keyword for a variable scoped constant" do it "returns nil if the instance scoped constant is not defined" do @defined_specs_obj = DefinedSpecs::Basic - defined?(@defined_specs_obj::Undefined).should be_nil + defined?(@defined_specs_obj::Undefined).should == nil end it "returns 'constant' if the constant is defined in the scope of the instance variable" do @@ -1058,7 +1058,7 @@ describe "The defined? keyword for a variable scoped constant" do it "returns nil if the global scoped constant is not defined" do $defined_specs_obj = DefinedSpecs::Basic - defined?($defined_specs_obj::Undefined).should be_nil + defined?($defined_specs_obj::Undefined).should == nil end it "returns 'constant' if the constant is defined in the scope of the global variable" do @@ -1070,7 +1070,7 @@ describe "The defined? keyword for a variable scoped constant" do eval(<<-END, binding, __FILE__, __LINE__) class singleton_class::A @@defined_specs_obj = DefinedSpecs::Basic - defined?(@@defined_specs_obj::Undefined).should be_nil + defined?(@@defined_specs_obj::Undefined).should == nil end END end @@ -1086,7 +1086,7 @@ describe "The defined? keyword for a variable scoped constant" do it "returns nil if the local scoped constant is not defined" do defined_specs_obj = DefinedSpecs::Basic - defined?(defined_specs_obj::Undefined).should be_nil + defined?(defined_specs_obj::Undefined).should == nil end it "returns 'constant' if the constant is defined in the scope of the local variable" do @@ -1107,11 +1107,11 @@ end describe "The defined? keyword for yield" do it "returns nil if no block is passed to a method not taking a block parameter" do - DefinedSpecs::Basic.new.no_yield_block.should be_nil + DefinedSpecs::Basic.new.no_yield_block.should == nil end it "returns nil if no block is passed to a method taking a block parameter" do - DefinedSpecs::Basic.new.no_yield_block_parameter.should be_nil + DefinedSpecs::Basic.new.no_yield_block_parameter.should == nil end it "returns 'yield' if a block is passed to a method not taking a block parameter" do @@ -1139,24 +1139,24 @@ end describe "The defined? keyword for super" do it "returns nil when a superclass undef's the method" do - DefinedSpecs::ClassWithoutMethod.new.test.should be_nil + DefinedSpecs::ClassWithoutMethod.new.test.should == nil end describe "for a method taking no arguments" do it "returns nil when no superclass method exists" do - DefinedSpecs::Super.new.no_super_method_no_args.should be_nil + DefinedSpecs::Super.new.no_super_method_no_args.should == nil end it "returns nil from a block when no superclass method exists" do - DefinedSpecs::Super.new.no_super_method_block_no_args.should be_nil + DefinedSpecs::Super.new.no_super_method_block_no_args.should == nil end it "returns nil from a #define_method when no superclass method exists" do - DefinedSpecs::Super.new.no_super_define_method_no_args.should be_nil + DefinedSpecs::Super.new.no_super_define_method_no_args.should == nil end it "returns nil from a block in a #define_method when no superclass method exists" do - DefinedSpecs::Super.new.no_super_define_method_block_no_args.should be_nil + DefinedSpecs::Super.new.no_super_define_method_block_no_args.should == nil end it "returns 'super' when a superclass method exists" do @@ -1184,19 +1184,19 @@ describe "The defined? keyword for super" do describe "for a method taking arguments" do it "returns nil when no superclass method exists" do - DefinedSpecs::Super.new.no_super_method_args.should be_nil + DefinedSpecs::Super.new.no_super_method_args.should == nil end it "returns nil from a block when no superclass method exists" do - DefinedSpecs::Super.new.no_super_method_block_args.should be_nil + DefinedSpecs::Super.new.no_super_method_block_args.should == nil end it "returns nil from a #define_method when no superclass method exists" do - DefinedSpecs::Super.new.no_super_define_method_args.should be_nil + DefinedSpecs::Super.new.no_super_define_method_args.should == nil end it "returns nil from a block in a #define_method when no superclass method exists" do - DefinedSpecs::Super.new.no_super_define_method_block_args.should be_nil + DefinedSpecs::Super.new.no_super_define_method_block_args.should == nil end it "returns 'super' when a superclass method exists" do @@ -1231,7 +1231,7 @@ describe "The defined? keyword for instance variables" do end it "returns nil if not assigned" do - defined?(@unassigned_ivar).should be_nil + defined?(@unassigned_ivar).should == nil end end diff --git a/spec/ruby/language/delegation_spec.rb b/spec/ruby/language/delegation_spec.rb index 0fcd3e57bf..3d917993f5 100644 --- a/spec/ruby/language/delegation_spec.rb +++ b/spec/ruby/language/delegation_spec.rb @@ -37,6 +37,16 @@ describe "delegation with def(...)" do a.new.delegate(1, b: 2, &block).should == [[1], {b: 2}, block] end + it "delegates with additional arguments" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(...) + target(:first, :second, ...) + end + RUBY + a.new.delegate(1, b: 2).should == [[:first, :second, 1], {b: 2}, nil] + end + it "parses as open endless Range when brackets are omitted" do a = Class.new(DelegationSpecs::Target) suppress_warning do @@ -87,52 +97,44 @@ describe "delegation with def(x, ...)" do end end -ruby_version_is "3.2" do - describe "delegation with def(*)" do - it "delegates rest" do - a = Class.new(DelegationSpecs::Target) - a.class_eval(<<-RUBY) - def delegate(*) - target(*) - end - RUBY - - a.new.delegate(0, 1).should == [[0, 1], {}, nil] +describe "delegation with def(*)" do + it "delegates rest" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(*) + target(*) end + RUBY - ruby_version_is "3.3" do - context "within a block that accepts anonymous rest within a method that accepts anonymous rest" do - it "does not allow delegating rest" do - -> { - eval "def m(*); proc { |*| n(*) } end" - }.should raise_error(SyntaxError, /anonymous rest parameter is also used within block/) - end - end + a.new.delegate(0, 1).should == [[0, 1], {}, nil] + end + + context "within a block that accepts anonymous rest within a method that accepts anonymous rest" do + it "does not allow delegating rest" do + -> { + eval "def m(*); proc { |*| n(*) } end" + }.should.raise(SyntaxError, /anonymous rest parameter is also used within block/) end end end -ruby_version_is "3.2" do - describe "delegation with def(**)" do - it "delegates kwargs" do - a = Class.new(DelegationSpecs::Target) - a.class_eval(<<-RUBY) - def delegate(**) - target(**) - end - RUBY - - a.new.delegate(a: 1) { |x| x }.should == [[], {a: 1}, nil] +describe "delegation with def(**)" do + it "delegates kwargs" do + a = Class.new(DelegationSpecs::Target) + a.class_eval(<<-RUBY) + def delegate(**) + target(**) end + RUBY - ruby_version_is "3.3" do - context "within a block that accepts anonymous kwargs within a method that accepts anonymous kwargs" do - it "does not allow delegating kwargs" do - -> { - eval "def m(**); proc { |**| n(**) } end" - }.should raise_error(SyntaxError, /anonymous keyword rest parameter is also used within block/) - end - end + a.new.delegate(a: 1) { |x| x }.should == [[], {a: 1}, nil] + end + + context "within a block that accepts anonymous kwargs within a method that accepts anonymous kwargs" do + it "does not allow delegating kwargs" do + -> { + eval "def m(**); proc { |**| n(**) } end" + }.should.raise(SyntaxError, /anonymous keyword rest parameter is also used within block/) end end end @@ -150,13 +152,11 @@ describe "delegation with def(&)" do a.new.delegate(&block).should == [[], {}, block] end - ruby_version_is "3.3" do - context "within a block that accepts anonymous block within a method that accepts anonymous block" do - it "does not allow delegating a block" do - -> { - eval "def m(&); proc { |&| n(&) } end" - }.should raise_error(SyntaxError, /anonymous block parameter is also used within block/) - end + context "within a block that accepts anonymous block within a method that accepts anonymous block" do + it "does not allow delegating a block" do + -> { + eval "def m(&); proc { |&| n(&) } end" + }.should.raise(SyntaxError, /anonymous block parameter is also used within block/) end end end diff --git a/spec/ruby/language/encoding_spec.rb b/spec/ruby/language/encoding_spec.rb index e761a53cb6..116f53a77d 100644 --- a/spec/ruby/language/encoding_spec.rb +++ b/spec/ruby/language/encoding_spec.rb @@ -5,7 +5,7 @@ require_relative 'fixtures/coding_utf_8' describe "The __ENCODING__ pseudo-variable" do it "is an instance of Encoding" do - __ENCODING__.should be_kind_of(Encoding) + __ENCODING__.should.is_a?(Encoding) end it "is US-ASCII by default" do @@ -31,6 +31,6 @@ describe "The __ENCODING__ pseudo-variable" do end it "raises a SyntaxError if assigned to" do - -> { eval("__ENCODING__ = 1") }.should raise_error(SyntaxError) + -> { eval("__ENCODING__ = 1") }.should.raise(SyntaxError) end end diff --git a/spec/ruby/language/ensure_spec.rb b/spec/ruby/language/ensure_spec.rb index b76292c007..04ff0305ab 100644 --- a/spec/ruby/language/ensure_spec.rb +++ b/spec/ruby/language/ensure_spec.rb @@ -6,7 +6,7 @@ describe "An ensure block inside a begin block" do ScratchPad.record [] end - it "is executed when an exception is raised in it's corresponding begin block" do + it "is executed when an exception is raised in its corresponding begin block" do -> { begin ScratchPad << :begin @@ -14,12 +14,12 @@ describe "An ensure block inside a begin block" do ensure ScratchPad << :ensure end - }.should raise_error(EnsureSpec::Error) + }.should.raise(EnsureSpec::Error) ScratchPad.recorded.should == [:begin, :ensure] end - it "is executed when an exception is raised and rescued in it's corresponding begin block" do + it "is executed when an exception is raised and rescued in its corresponding begin block" do begin ScratchPad << :begin raise "An exception occurred!" @@ -32,7 +32,7 @@ describe "An ensure block inside a begin block" do ScratchPad.recorded.should == [:begin, :rescue, :ensure] end - it "is executed even when a symbol is thrown in it's corresponding begin block" do + it "is executed even when a symbol is thrown in its corresponding begin block" do catch(:symbol) do begin ScratchPad << :begin @@ -47,7 +47,7 @@ describe "An ensure block inside a begin block" do ScratchPad.recorded.should == [:begin, :ensure] end - it "is executed when nothing is raised or thrown in it's corresponding begin block" do + it "is executed when nothing is raised or thrown in its corresponding begin block" do begin ScratchPad << :begin rescue @@ -74,7 +74,7 @@ describe "An ensure block inside a begin block" do ensure raise "from ensure" end - }.should raise_error(RuntimeError, "from ensure") { |e| + }.should.raise(RuntimeError, "from ensure") { |e| e.cause.message.should == "from block" } end @@ -108,7 +108,7 @@ describe "An ensure block inside a method" do end it "is executed when an exception is raised in the method" do - -> { @obj.raise_in_method_with_ensure }.should raise_error(EnsureSpec::Error) + -> { @obj.raise_in_method_with_ensure }.should.raise(EnsureSpec::Error) @obj.executed.should == [:method, :ensure] end @@ -149,13 +149,13 @@ describe "An ensure block inside a method" do it "overrides exception raised in rescue if raises exception itself" do -> { @obj.raise_in_rescue_and_raise_in_ensure - }.should raise_error(RuntimeError, "raised in ensure") + }.should.raise(RuntimeError, "raised in ensure") end it "suppresses exception raised in method if raises exception itself" do -> { @obj.raise_in_method_and_raise_in_ensure - }.should raise_error(RuntimeError, "raised in ensure") + }.should.raise(RuntimeError, "raised in ensure") end end @@ -174,7 +174,7 @@ describe "An ensure block inside a class" do ScratchPad << :ensure end ruby - }.should raise_error(EnsureSpec::Error) + }.should.raise(EnsureSpec::Error) ScratchPad.recorded.should == [:class, :ensure] end @@ -247,7 +247,7 @@ describe "An ensure block inside {} block" do ensure } ruby - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end end @@ -256,7 +256,7 @@ describe "An ensure block inside 'do end' block" do ScratchPad.record [] end - it "is executed when an exception is raised in it's corresponding begin block" do + it "is executed when an exception is raised in its corresponding begin block" do -> { eval(<<-ruby).call lambda do @@ -266,12 +266,12 @@ describe "An ensure block inside 'do end' block" do ScratchPad << :ensure end ruby - }.should raise_error(EnsureSpec::Error) + }.should.raise(EnsureSpec::Error) ScratchPad.recorded.should == [:begin, :ensure] end - it "is executed when an exception is raised and rescued in it's corresponding begin block" do + it "is executed when an exception is raised and rescued in its corresponding begin block" do eval(<<-ruby).call lambda do ScratchPad << :begin @@ -286,7 +286,7 @@ describe "An ensure block inside 'do end' block" do ScratchPad.recorded.should == [:begin, :rescue, :ensure] end - it "is executed even when a symbol is thrown in it's corresponding begin block" do + it "is executed even when a symbol is thrown in its corresponding begin block" do catch(:symbol) do eval(<<-ruby).call lambda do @@ -303,7 +303,7 @@ describe "An ensure block inside 'do end' block" do ScratchPad.recorded.should == [:begin, :ensure] end - it "is executed when nothing is raised or thrown in it's corresponding begin block" do + it "is executed when nothing is raised or thrown in its corresponding begin block" do eval(<<-ruby).call lambda do ScratchPad << :begin diff --git a/spec/ruby/language/file_spec.rb b/spec/ruby/language/file_spec.rb index 59563d9642..dd89ce2385 100644 --- a/spec/ruby/language/file_spec.rb +++ b/spec/ruby/language/file_spec.rb @@ -4,19 +4,11 @@ require_relative 'shared/__FILE__' describe "The __FILE__ pseudo-variable" do it "raises a SyntaxError if assigned to" do - -> { eval("__FILE__ = 1") }.should raise_error(SyntaxError) + -> { eval("__FILE__ = 1") }.should.raise(SyntaxError) end - ruby_version_is ""..."3.3" do - it "equals (eval) inside an eval" do - eval("__FILE__").should == "(eval)" - end - end - - ruby_version_is "3.3" do - it "equals (eval at __FILE__:__LINE__) inside an eval" do - eval("__FILE__").should == "(eval at #{__FILE__}:#{__LINE__})" - end + it "equals (eval at __FILE__:__LINE__) inside an eval" do + eval("__FILE__").should == "(eval at #{__FILE__}:#{__LINE__})" end end diff --git a/spec/ruby/language/fixtures/class_with_class_variable.rb b/spec/ruby/language/fixtures/class_with_class_variable.rb new file mode 100644 index 0000000000..0b07f16d30 --- /dev/null +++ b/spec/ruby/language/fixtures/class_with_class_variable.rb @@ -0,0 +1,9 @@ +module StringSpecs + class ClassWithClassVariable + @@a = "xxx" + + def foo + "#@@a" + end + end +end diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_across_files.rb b/spec/ruby/language/fixtures/freeze_magic_comment_across_files.rb index 3aed2f29b6..f3ef666a3c 100644 --- a/spec/ruby/language/fixtures/freeze_magic_comment_across_files.rb +++ b/spec/ruby/language/fixtures/freeze_magic_comment_across_files.rb @@ -2,4 +2,5 @@ require_relative 'freeze_magic_comment_required' -p "abc".object_id == $second_literal_id +p "abc".equal?($second_literal) +$second_literal = nil diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_across_files_diff_enc.rb b/spec/ruby/language/fixtures/freeze_magic_comment_across_files_diff_enc.rb index 53ef959970..e9ca35e7c8 100644 --- a/spec/ruby/language/fixtures/freeze_magic_comment_across_files_diff_enc.rb +++ b/spec/ruby/language/fixtures/freeze_magic_comment_across_files_diff_enc.rb @@ -2,4 +2,5 @@ require_relative 'freeze_magic_comment_required_diff_enc' -p "abc".object_id != $second_literal_id +p !"abc".equal?($second_literal) +$second_literal = nil diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_across_files_no_comment.rb b/spec/ruby/language/fixtures/freeze_magic_comment_across_files_no_comment.rb index fc6cd5bf82..c9eaab46a2 100644 --- a/spec/ruby/language/fixtures/freeze_magic_comment_across_files_no_comment.rb +++ b/spec/ruby/language/fixtures/freeze_magic_comment_across_files_no_comment.rb @@ -2,4 +2,5 @@ require_relative 'freeze_magic_comment_required_no_comment' -p "abc".object_id != $second_literal_id +p !"abc".equal?($second_literal) +$second_literal = nil diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_one_literal.rb b/spec/ruby/language/fixtures/freeze_magic_comment_one_literal.rb index d35905b332..c175b2b7a2 100644 --- a/spec/ruby/language/fixtures/freeze_magic_comment_one_literal.rb +++ b/spec/ruby/language/fixtures/freeze_magic_comment_one_literal.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true -ids = Array.new(2) { "abc".object_id } -p ids.first == ids.last +objs = Array.new(2) { "abc" } +p objs.first.equal?(objs.last) diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_required.rb b/spec/ruby/language/fixtures/freeze_magic_comment_required.rb index a4ff4459b1..f75acb2ce3 100644 --- a/spec/ruby/language/fixtures/freeze_magic_comment_required.rb +++ b/spec/ruby/language/fixtures/freeze_magic_comment_required.rb @@ -1,3 +1,3 @@ # frozen_string_literal: true -$second_literal_id = "abc".object_id +$second_literal = "abc" diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb b/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb index f72a32e879..739e96e99a 100644 --- a/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb +++ b/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb @@ -1,4 +1,4 @@ # encoding: euc-jp # built-in for old regexp option # frozen_string_literal: true -$second_literal_id = "abc".object_id +$second_literal = "abc" diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_required_no_comment.rb b/spec/ruby/language/fixtures/freeze_magic_comment_required_no_comment.rb index e09232a5f4..6fbe175b42 100644 --- a/spec/ruby/language/fixtures/freeze_magic_comment_required_no_comment.rb +++ b/spec/ruby/language/fixtures/freeze_magic_comment_required_no_comment.rb @@ -1 +1 @@ -$second_literal_id = "abc".object_id +$second_literal = "abc" diff --git a/spec/ruby/language/fixtures/module.rb b/spec/ruby/language/fixtures/module.rb index 33d323846e..75eee77791 100644 --- a/spec/ruby/language/fixtures/module.rb +++ b/spec/ruby/language/fixtures/module.rb @@ -12,13 +12,4 @@ module ModuleSpecs module Anonymous end - - module IncludedInObject - module IncludedModuleSpecs - end - end -end - -class Object - include ModuleSpecs::IncludedInObject end diff --git a/spec/ruby/language/fixtures/send.rb b/spec/ruby/language/fixtures/send.rb index 5d1d9da214..4787abee5c 100644 --- a/spec/ruby/language/fixtures/send.rb +++ b/spec/ruby/language/fixtures/send.rb @@ -81,6 +81,16 @@ module LangSendSpecs end end + class RawToProc + def initialize(to_proc) + @to_proc = to_proc + end + + def to_proc + @to_proc + end + end + class ToAry def initialize(obj) @obj = obj diff --git a/spec/ruby/language/fixtures/super.rb b/spec/ruby/language/fixtures/super.rb index c5bdcf0e40..b6d4218b03 100644 --- a/spec/ruby/language/fixtures/super.rb +++ b/spec/ruby/language/fixtures/super.rb @@ -266,7 +266,7 @@ module SuperSpecs # Use this so that we can see collect all supers that we see. # One bug that arises is that we call Alias2#name from Alias2#name - # as it's superclass. In that case, either we get a runaway recursion + # as its superclass. In that case, either we get a runaway recursion # super OR we get the return value being [:alias2, :alias2, :alias1] # rather than [:alias2, :alias1]. # diff --git a/spec/ruby/language/for_spec.rb b/spec/ruby/language/for_spec.rb index b8ddfe5f0d..b0f3aef405 100644 --- a/spec/ruby/language/for_spec.rb +++ b/spec/ruby/language/for_spec.rb @@ -129,37 +129,34 @@ describe "The for expression" do n.should == 3 end - # Segfault in MRI 3.3 and lower: https://bugs.ruby-lang.org/issues/20468 - ruby_bug "#20468", ""..."3.4" do - it "allows an attribute with safe navigation as an iterator name" do - class OFor - attr_accessor :target - end - - ofor = OFor.new - m = [1,2,3] - n = 0 - eval <<~RUBY - for ofor&.target in m - n += 1 - end - RUBY - ofor.target.should == 3 - n.should == 3 + it "allows an attribute with safe navigation as an iterator name" do + class OFor + attr_accessor :target end - it "allows an attribute with safe navigation on a nil base as an iterator name" do - ofor = nil - m = [1,2,3] - n = 0 - eval <<~RUBY - for ofor&.target in m - n += 1 - end - RUBY - ofor.should be_nil - n.should == 3 - end + ofor = OFor.new + m = [1,2,3] + n = 0 + eval <<~RUBY + for ofor&.target in m + n += 1 + end + RUBY + ofor.target.should == 3 + n.should == 3 + end + + it "allows an attribute with safe navigation on a nil base as an iterator name" do + ofor = nil + m = [1,2,3] + n = 0 + eval <<~RUBY + for ofor&.target in m + n += 1 + end + RUBY + ofor.should == nil + n.should == 3 end it "allows an array index writer as an iterator name" do @@ -218,7 +215,15 @@ describe "The for expression" do j.should == 6 end - it "executes code in containing variable scope" do + it "declares iteration variables in the surrounding variable scope" do + for a, b in [[1,2]] + end + + a.should == 1 + b.should == 2 + end + + it "declares variables in the body in the surrounding variable scope" do for i in 1..2 a = 123 end @@ -226,7 +231,7 @@ describe "The for expression" do a.should == 123 end - it "executes code in containing variable scope with 'do'" do + it "declares variables in the body in the surrounding variable scope with 'do'" do for i in 1..2 do a = 123 end @@ -234,6 +239,96 @@ describe "The for expression" do a.should == 123 end + it "declares variables inside a block as normal" do + for i in 1..2 do + proc { + inside_proc = 42 + }.call + end + local_variables.should == [:i] + end + + it "declares variables inside a lambda as normal" do + for i in 1..2 do + -> { + inside_proc = 42 + }.call + end + local_variables.should == [:i] + end + + it "can be nested" do + for a in [6] + for b in [7] + c = a * b + end + end + local_variables.sort.should == [:a, :b, :c] + c.should == 42 + end + + it "can be nested with blocks in between" do + # This is an edge case spec for Ruby implementations which have + # their own runtime scope per for loop body (like YARV and TruffleRuby) + for a in [1] + a1 = a + a1.should == a + for b in [2] + b1 = b + a1.should == a + b1.should == b + proc { + inside_proc = 42 + + a1.should == a + b1.should == b + inside_proc.should == 42 + + for c in [3].map { |enum_var| + a1.should == a + b1.should == b + inside_proc.should == 42 + enum_var + } + c1 = c + + a1.should == a + b1.should == b + c1.should == c + inside_proc.should == 42 + + for d in [4] + d1 = d + + a1.should == a + b1.should == b + c1.should == c + d1.should == d + inside_proc.should == 42 + end + end + local_variables.sort.should == [:a, :a1, :b, :b1, :c, :c1, :d, :d1, :inside_proc] + }.call + end + end + local_variables.sort.should == [:a, :a1, :b, :b1] + end + + it "can be nested with forward arguments" do + def bar(*args) + args + end + + def foo(...) + for a in [1] + r = bar(...) + end + r + end + + foo(2, 3).should == [2, 3] + end + it "does not try to access variables outside the method" do ForSpecs::ForInClassMethod.foo.should == [:bar, :baz] ForSpecs::ForInClassMethod::READER.call.should == :same_variable_set_outside diff --git a/spec/ruby/language/hash_spec.rb b/spec/ruby/language/hash_spec.rb index b119b6ca73..7a4a2e37c9 100644 --- a/spec/ruby/language/hash_spec.rb +++ b/spec/ruby/language/hash_spec.rb @@ -81,7 +81,7 @@ describe "Hash literal" do end it "with '==>' in the middle raises SyntaxError" do - -> { eval("{:a ==> 1}") }.should raise_error(SyntaxError) + -> { eval("{:a ==> 1}") }.should.raise(SyntaxError) end it "recognizes '!' at the end of the key" do @@ -93,7 +93,7 @@ describe "Hash literal" do end it "raises a SyntaxError if there is no space between `!` and `=>`" do - -> { eval("{:a!=> 1}") }.should raise_error(SyntaxError) + -> { eval("{:a!=> 1}") }.should.raise(SyntaxError) end it "recognizes '?' at the end of the key" do @@ -105,7 +105,7 @@ describe "Hash literal" do end it "raises a SyntaxError if there is no space between `?` and `=>`" do - -> { eval("{:a?=> 1}") }.should raise_error(SyntaxError) + -> { eval("{:a?=> 1}") }.should.raise(SyntaxError) end it "constructs a new hash with the given elements" do @@ -149,6 +149,37 @@ describe "Hash literal" do {a: 1, **h, c: 4}.should == {a: 1, b: 2, c: 4} end + ruby_version_is ""..."3.4" do + it "does not expand nil using ** into {} and raises TypeError" do + h = nil + -> { {a: 1, **h} }.should.raise(TypeError, "no implicit conversion of nil into Hash") + + -> { {a: 1, **nil} }.should.raise(TypeError, "no implicit conversion of nil into Hash") + end + end + + ruby_version_is "3.4" do + it "expands nil using ** into {}" do + h = nil + {**h}.should == {} + {a: 1, **h}.should == {a: 1} + + {**nil}.should == {} + {a: 1, **nil}.should == {a: 1} + end + + it "expands nil using ** into {} and provides a copy to the callable" do + ScratchPad.record [] + insert = -> key, **kw do + kw[key] = 1 + ScratchPad << kw + end + insert.call(:foo, **nil) + insert.call(:bar, **nil) + ScratchPad.recorded.should == [{ foo: 1 }, { bar: 1 }] + end + end + it "expands an '**{}' or '**obj' element with the last key/value pair taking precedence" do -> { @h = eval "{a: 1, **{a: 2, b: 3, c: 1}, c: 3}" @@ -192,13 +223,13 @@ describe "Hash literal" do obj = mock("hash splat") obj.should_receive(:to_hash).and_return(obj) - -> { {**obj} }.should raise_error(TypeError) + -> { {**obj} }.should.raise(TypeError) end it "raises a TypeError if the object does not respond to #to_hash" do obj = 42 - -> { {**obj} }.should raise_error(TypeError) - -> { {a: 1, **obj} }.should raise_error(TypeError) + -> { {**obj} }.should.raise(TypeError) + -> { {a: 1, **obj} }.should.raise(TypeError) end it "does not change encoding of literal string keys during creation" do @@ -218,7 +249,7 @@ describe "Hash literal" do ScratchPad.record [] -> { eval 'ScratchPad << 1; {:"\xC3" => 1}' - }.should raise_error(SyntaxError, /invalid symbol/) + }.should.raise(SyntaxError, /invalid symbol/) ScratchPad.recorded.should == [] end @@ -226,7 +257,7 @@ describe "Hash literal" do ScratchPad.record [] -> { eval 'ScratchPad << 1; {"\xC3": 1}' - }.should raise_error(SyntaxError, /invalid symbol/) + }.should.raise(SyntaxError, /invalid symbol/) ScratchPad.recorded.should == [] end end @@ -244,17 +275,15 @@ describe "The ** operator" do h.should == { one: 1, two: 2 } end - ruby_bug "#20012", ""..."3.3" do - it "makes a copy when calling a method taking a positional Hash" do - def m(h) - h.delete(:one); h - end - - h = { one: 1, two: 2 } - m(**h).should == { two: 2 } - m(**h).should_not.equal?(h) - h.should == { one: 1, two: 2 } + it "makes a copy when calling a method taking a positional Hash" do + def m(h) + h.delete(:one); h end + + h = { one: 1, two: 2 } + m(**h).should == { two: 2 } + m(**h).should_not.equal?(h) + h.should == { one: 1, two: 2 } end describe "hash with omitted value" do @@ -294,11 +323,11 @@ describe "The ** operator" do end it "raises a SyntaxError when the hash key ends with `!`" do - -> { eval("{a!:}") }.should raise_error(SyntaxError, /identifier a! is not valid to get/) + -> { eval("{a!:}") }.should.raise(SyntaxError, /identifier a! is not valid to get/) end it "raises a SyntaxError when the hash key ends with `?`" do - -> { eval("{a?:}") }.should raise_error(SyntaxError, /identifier a\? is not valid to get/) + -> { eval("{a?:}") }.should.raise(SyntaxError, /identifier a\? is not valid to get/) end end end diff --git a/spec/ruby/language/heredoc_spec.rb b/spec/ruby/language/heredoc_spec.rb index 47ee9c2c51..535f18cba8 100644 --- a/spec/ruby/language/heredoc_spec.rb +++ b/spec/ruby/language/heredoc_spec.rb @@ -62,7 +62,7 @@ HERE it 'raises SyntaxError if quoted HEREDOC identifier is ending not on same line' do -> { eval %{<<"HERE\n"\nraises syntax error\nHERE} - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end it "allows HEREDOC with <<~'identifier', allowing to indent identifier and content" do @@ -114,6 +114,6 @@ HERE b #{c} HERE - }.should raise_error(NameError) { |e| e.backtrace[0].should.start_with?("#{__FILE__}:#{__LINE__ - 2}") } + }.should.raise(NameError) { |e| e.backtrace[0].should.start_with?("#{__FILE__}:#{__LINE__ - 2}") } end end diff --git a/spec/ruby/language/if_spec.rb b/spec/ruby/language/if_spec.rb index 2d1a89f081..53fcb853d5 100644 --- a/spec/ruby/language/if_spec.rb +++ b/spec/ruby/language/if_spec.rb @@ -330,7 +330,7 @@ describe "The if expression" do a end RUBY - }.should raise_error(SyntaxError, /void value expression/) + }.should.raise(SyntaxError, /void value expression/) end it "does not raise SyntaxError if one branch returns a value" do diff --git a/spec/ruby/language/it_parameter_spec.rb b/spec/ruby/language/it_parameter_spec.rb new file mode 100644 index 0000000000..6ba67cbb4f --- /dev/null +++ b/spec/ruby/language/it_parameter_spec.rb @@ -0,0 +1,108 @@ +require_relative '../spec_helper' + +ruby_version_is "3.4" do + eval <<-RUBY # use eval to avoid warnings on Ruby 3.3 + describe "The `it` parameter" do + it "provides it in a block" do + -> { it }.call("a").should == "a" + proc { it }.call("a").should == "a" + lambda { it }.call("a").should == "a" + ["a"].map { it }.should == ["a"] + end + + it "assigns nil to not passed parameters" do + proc { it }.call().should == nil + end + + it "can be used in both outer and nested blocks at the same time" do + -> { it + -> { it * it }.call(2) }.call(3).should == 7 + end + + it "can be reassigned to act as a local variable" do + proc { tmp = it; it = tmp * 2; it }.call(21).should == 42 + end + + it "is a regular local variable if there is already a 'it' local variable" do + it = 0 + proc { it }.call("a").should == 0 + end + + it "is a regular local variable if there is a method `it` defined" do + o = Object.new + def o.it + 21 + end + + o.instance_eval("proc { it * 2 }").call(1).should == 2 + end + + it "is not shadowed by an reassignment in a block" do + a = nil + proc { a = it; it = 42 }.call(0) + a.should == 0 # if `it` were shadowed its value would be nil + end + + it "raises SyntaxError when block parameters are specified explicitly" do + -> { eval("-> () { it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("-> (x) { it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + + -> { eval("proc { || it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("proc { |x| it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + + -> { eval("lambda { || it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("lambda { |x| it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + + -> { eval("['a'].map { || it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("['a'].map { |x| it }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + end + + it "cannot be mixed with numbered parameters" do + -> { + eval("proc { it + _1 }") + }.should.raise(SyntaxError, /numbered parameters are not allowed when 'it' is already used|'it' is already used in/) + + -> { + eval("proc { _1 + it }") + }.should.raise(SyntaxError, /numbered parameter is already used in|'it' is not allowed when a numbered parameter is already used/) + end + + it "affects block arity" do + -> {}.arity.should == 0 + -> { it }.arity.should == 1 + end + + it "affects block parameters" do + -> { it }.parameters.should == [[:req]] + + ruby_version_is ""..."4.0" do + proc { it }.parameters.should == [[:opt, nil]] + end + ruby_version_is "4.0" do + proc { it }.parameters.should == [[:opt]] + end + end + + it "does not affect binding local variables" do + -> { it; binding.local_variables }.call("a").should == [] + end + + it "does not work in methods" do + obj = Object.new + def obj.foo; it; end + + -> { obj.foo("a") }.should.raise(ArgumentError, /wrong number of arguments/) + end + + context "given multiple arguments" do + it "provides it in a block and assigns the first argument for a block" do + proc { it }.call("a", "b").should == "a" + end + + it "raises ArgumentError for a proc" do + -> { -> { it }.call("a", "b") }.should.raise(ArgumentError, "wrong number of arguments (given 2, expected 1)") + -> { lambda { it }.call("a", "b") }.should.raise(ArgumentError, "wrong number of arguments (given 2, expected 1)") + end + end + end + RUBY +end diff --git a/spec/ruby/language/keyword_arguments_spec.rb b/spec/ruby/language/keyword_arguments_spec.rb index 3f8ddfa40d..38edc24414 100644 --- a/spec/ruby/language/keyword_arguments_spec.rb +++ b/spec/ruby/language/keyword_arguments_spec.rb @@ -55,9 +55,9 @@ describe "Keyword arguments" do end m(kw: 1).should == [] - -> { m(kw: 1, kw2: 2) }.should raise_error(ArgumentError, 'unknown keyword: :kw2') - -> { m(kw: 1, true => false) }.should raise_error(ArgumentError, 'unknown keyword: true') - -> { m(kw: 1, a: 1, b: 2, c: 3) }.should raise_error(ArgumentError, 'unknown keywords: :a, :b, :c') + -> { m(kw: 1, kw2: 2) }.should.raise(ArgumentError, 'unknown keyword: :kw2') + -> { m(kw: 1, true => false) }.should.raise(ArgumentError, 'unknown keyword: true') + -> { m(kw: 1, a: 1, b: 2, c: 3) }.should.raise(ArgumentError, 'unknown keywords: :a, :b, :c') end it "raises ArgumentError exception when required keyword argument is not passed" do @@ -65,8 +65,8 @@ describe "Keyword arguments" do [a, b, c] end - -> { m(a: 1, b: 2) }.should raise_error(ArgumentError, /missing keyword: :c/) - -> { m() }.should raise_error(ArgumentError, /missing keywords: :a, :b, :c/) + -> { m(a: 1, b: 2) }.should.raise(ArgumentError, /missing keyword: :c/) + -> { m() }.should.raise(ArgumentError, /missing keywords: :a, :b, :c/) end it "raises ArgumentError for missing keyword arguments even if there are extra ones" do @@ -74,7 +74,7 @@ describe "Keyword arguments" do a end - -> { m(b: 1) }.should raise_error(ArgumentError, /missing keyword: :a/) + -> { m(b: 1) }.should.raise(ArgumentError, /missing keyword: :a/) end it "handle * and ** at the same call site" do @@ -86,17 +86,29 @@ describe "Keyword arguments" do m(*[], 42, **{}).should == [42] end - context "**" do - ruby_version_is "3.3" do - it "copies a non-empty Hash for a method taking (*args)" do - def m(*args) - args[0] - end + context "marked as ruby2_keywords_hash" do + it "is not copied when passed as a positional argument" do + h = Hash.ruby2_keywords_hash(a:1) + + def bar(a) + a + end + + h2 = bar(h) + h2.should.equal?(h) + Hash.ruby2_keywords_hash?(h).should == true + end + end - h = {a: 1} - m(**h).should_not.equal?(h) - h.should == {a: 1} + context "**" do + it "copies a non-empty Hash for a method taking (*args)" do + def m(*args) + args[0] end + + h = {a: 1} + m(**h).should_not.equal?(h) + h.should == {a: 1} end it "copies the given Hash for a method taking (**kwargs)" do @@ -336,61 +348,23 @@ describe "Keyword arguments" do end end - ruby_version_is "3.2" do - it "does not work with call(*ruby2_keyword_args) with missing ruby2_keywords in between" do - class << self - def n(*args) # Note the missing ruby2_keywords here - target(*args) - end - - ruby2_keywords def m(*args) - n(*args) - end + it "does not work with call(*ruby2_keyword_args) with missing ruby2_keywords in between" do + class << self + def n(*args) # Note the missing ruby2_keywords here + target(*args) end - empty = {} - m(**empty).should == [[], {}] - m(empty).should == [[{}], {}] - - m(a: 1).should == [[{a: 1}], {}] - m({a: 1}).should == [[{a: 1}], {}] - end - end - - ruby_version_is ""..."3.2" do - # https://bugs.ruby-lang.org/issues/18625 - it "works with call(*ruby2_keyword_args) with missing ruby2_keywords in between due to CRuby bug #18625" do - class << self - def n(*args) # Note the missing ruby2_keywords here - target(*args) - end - - ruby2_keywords def m(*args) - n(*args) - end + ruby2_keywords def m(*args) + n(*args) end + end - empty = {} - m(**empty).should == [[], {}] - Hash.ruby2_keywords_hash?(empty).should == false - m(empty).should == [[{}], {}] - Hash.ruby2_keywords_hash?(empty).should == false - - m(a: 1).should == [[], {a: 1}] - m({a: 1}).should == [[{a: 1}], {}] - - kw = {a: 1} - - m(**kw).should == [[], {a: 1}] - m(**kw)[1].should == kw - m(**kw)[1].should_not.equal?(kw) - Hash.ruby2_keywords_hash?(kw).should == false - Hash.ruby2_keywords_hash?(m(**kw)[1]).should == false + empty = {} + m(**empty).should == [[], {}] + m(empty).should == [[{}], {}] - m(kw).should == [[{a: 1}], {}] - m(kw)[0][0].should.equal?(kw) - Hash.ruby2_keywords_hash?(kw).should == false - end + m(a: 1).should == [[{a: 1}], {}] + m({a: 1}).should == [[{a: 1}], {}] end end diff --git a/spec/ruby/language/lambda_spec.rb b/spec/ruby/language/lambda_spec.rb index ed5a1c69e8..2a2953bd97 100644 --- a/spec/ruby/language/lambda_spec.rb +++ b/spec/ruby/language/lambda_spec.rb @@ -11,23 +11,23 @@ describe "A lambda literal -> () { }" do end end - klass.new.create_lambda.should be_an_instance_of(Proc) + klass.new.create_lambda.should.instance_of?(Proc) end it "does not execute the block" do - -> { fail }.should be_an_instance_of(Proc) + -> { fail }.should.instance_of?(Proc) end it "returns a lambda" do - -> { }.lambda?.should be_true + -> { }.lambda?.should == true end it "may include a rescue clause" do - eval('-> do raise ArgumentError; rescue ArgumentError; 7; end').should be_an_instance_of(Proc) + eval('-> do raise ArgumentError; rescue ArgumentError; 7; end').should.instance_of?(Proc) end it "may include a ensure clause" do - eval('-> do 1; ensure; 2; end').should be_an_instance_of(Proc) + eval('-> do 1; ensure; 2; end').should.instance_of?(Proc) end it "has its own scope for local variables" do @@ -48,10 +48,10 @@ describe "A lambda literal -> () { }" do @d = -> do end ruby - @a.().should be_nil - @b.().should be_nil - @c.().should be_nil - @d.().should be_nil + @a.().should == nil + @b.().should == nil + @c.().should == nil + @d.().should == nil end end @@ -91,9 +91,9 @@ describe "A lambda literal -> () { }" do @a = -> (*) { } ruby - @a.().should be_nil - @a.(1).should be_nil - @a.(1, 2, 3).should be_nil + @a.().should == nil + @a.(1).should == nil + @a.(1, 2, 3).should == nil end evaluate <<-ruby do @@ -109,7 +109,7 @@ describe "A lambda literal -> () { }" do @a = -> (a:) { a } ruby - -> { @a.() }.should raise_error(ArgumentError) + -> { @a.() }.should.raise(ArgumentError) @a.(a: 1).should == 1 end @@ -125,9 +125,9 @@ describe "A lambda literal -> () { }" do @a = -> (**) { } ruby - @a.().should be_nil - @a.(a: 1, b: 2).should be_nil - -> { @a.(1) }.should raise_error(ArgumentError) + @a.().should == nil + @a.(a: 1, b: 2).should == nil + -> { @a.(1) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -142,8 +142,8 @@ describe "A lambda literal -> () { }" do @a = -> (&b) { b } ruby - @a.().should be_nil - @a.() { }.should be_an_instance_of(Proc) + @a.().should == nil + @a.() { }.should.instance_of?(Proc) end evaluate <<-ruby do @@ -151,8 +151,8 @@ describe "A lambda literal -> () { }" do ruby @a.(1, 2).should == [1, 2] - -> { @a.() }.should raise_error(ArgumentError) - -> { @a.(1) }.should raise_error(ArgumentError) + -> { @a.() }.should.raise(ArgumentError) + -> { @a.(1) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -193,9 +193,9 @@ describe "A lambda literal -> () { }" do @a = -> (*, &b) { b } ruby - @a.().should be_nil - @a.(1, 2, 3, 4).should be_nil - @a.(&(l = ->{})).should equal(l) + @a.().should == nil + @a.(1, 2, 3, 4).should == nil + @a.(&(l = ->{})).should.equal?(l) end evaluate <<-ruby do @@ -268,7 +268,7 @@ describe "A lambda literal -> () { }" do a = 1 -> { eval "-> (a=a) { a }" - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end end @@ -286,6 +286,24 @@ describe "A lambda literal -> () { }" do end end end + + evaluate <<-ruby do + @a = -> (**nil) { :ok } + ruby + + @a.call().should == :ok + -> { @a.call(a: 1) }.should.raise(ArgumentError, 'no keywords accepted') + -> { @a.call(**{a: 1}) }.should.raise(ArgumentError, 'no keywords accepted') + -> { @a.call("a" => 1) }.should.raise(ArgumentError, 'no keywords accepted') + end + + evaluate <<-ruby do + @a = -> (a, **nil) { a } + ruby + + @a.call({a: 1}).should == {a: 1} + -> { @a.call(a: 1) }.should.raise(ArgumentError, 'no keywords accepted') + end end describe "A lambda expression 'lambda { ... }'" do @@ -299,25 +317,25 @@ describe "A lambda expression 'lambda { ... }'" do lambda { } end - obj.define.should equal(obj) + obj.define.should.equal?(obj) end it "does not execute the block" do - lambda { fail }.should be_an_instance_of(Proc) + lambda { fail }.should.instance_of?(Proc) end it "returns a lambda" do - lambda { }.lambda?.should be_true + lambda { }.lambda?.should == true end it "requires a block" do suppress_warning do - lambda { lambda }.should raise_error(ArgumentError) + lambda { lambda }.should.raise(ArgumentError) end end it "may include a rescue clause" do - eval('lambda do raise ArgumentError; rescue ArgumentError; 7; end').should be_an_instance_of(Proc) + eval('lambda do raise ArgumentError; rescue ArgumentError; 7; end').should.instance_of?(Proc) end context "with an implicit block" do @@ -330,7 +348,7 @@ describe "A lambda expression 'lambda { ... }'" do suppress_warning do -> { meth { 1 } - }.should raise_error(ArgumentError, /tried to create Proc object without a block/) + }.should.raise(ArgumentError, /tried to create Proc object without a block/) end end end @@ -341,8 +359,8 @@ describe "A lambda expression 'lambda { ... }'" do @b = lambda { || } ruby - @a.().should be_nil - @b.().should be_nil + @a.().should == nil + @b.().should == nil end end @@ -359,8 +377,8 @@ describe "A lambda expression 'lambda { ... }'" do @a = lambda { |a| a } ruby - lambda { m(&@a) }.should raise_error(ArgumentError) - lambda { m(1, 2, &@a) }.should raise_error(ArgumentError) + lambda { m(&@a) }.should.raise(ArgumentError) + lambda { m(1, 2, &@a) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -370,8 +388,8 @@ describe "A lambda expression 'lambda { ... }'" do @a.(1).should == 1 @a.([1, 2]).should == [1, 2] - lambda { @a.() }.should raise_error(ArgumentError) - lambda { @a.(1, 2) }.should raise_error(ArgumentError) + lambda { @a.() }.should.raise(ArgumentError) + lambda { @a.(1, 2) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -384,7 +402,7 @@ describe "A lambda expression 'lambda { ... }'" do m(1, &@a).should == 1 m([1, 2], &@a).should == [1, 2] - lambda { m2(&@a) }.should raise_error(ArgumentError) + lambda { m2(&@a) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -415,9 +433,9 @@ describe "A lambda expression 'lambda { ... }'" do @a = lambda { |*| } ruby - @a.().should be_nil - @a.(1).should be_nil - @a.(1, 2, 3).should be_nil + @a.().should == nil + @a.(1).should == nil + @a.(1, 2, 3).should == nil end evaluate <<-ruby do @@ -433,7 +451,7 @@ describe "A lambda expression 'lambda { ... }'" do @a = lambda { |a:| a } ruby - lambda { @a.() }.should raise_error(ArgumentError) + lambda { @a.() }.should.raise(ArgumentError) @a.(a: 1).should == 1 end @@ -449,9 +467,9 @@ describe "A lambda expression 'lambda { ... }'" do @a = lambda { |**| } ruby - @a.().should be_nil - @a.(a: 1, b: 2).should be_nil - lambda { @a.(1) }.should raise_error(ArgumentError) + @a.().should == nil + @a.(a: 1, b: 2).should == nil + lambda { @a.(1) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -466,8 +484,8 @@ describe "A lambda expression 'lambda { ... }'" do @a = lambda { |&b| b } ruby - @a.().should be_nil - @a.() { }.should be_an_instance_of(Proc) + @a.().should == nil + @a.() { }.should.instance_of?(Proc) end evaluate <<-ruby do @@ -515,9 +533,9 @@ describe "A lambda expression 'lambda { ... }'" do @a = lambda { |*, &b| b } ruby - @a.().should be_nil - @a.(1, 2, 3, 4).should be_nil - @a.(&(l = ->{})).should equal(l) + @a.().should == nil + @a.(1, 2, 3, 4).should == nil + @a.(&(l = ->{})).should.equal?(l) end evaluate <<-ruby do @@ -583,5 +601,23 @@ describe "A lambda expression 'lambda { ... }'" do result = @a.(1, 2, e: 3, g: 4, h: 5, i: 6, &(l = ->{})) result.should == [1, 1, [], 2, 3, 2, 4, { h: 5, i: 6 }, l] end + + evaluate <<-ruby do + @a = lambda { |**nil| :ok } + ruby + + @a.call().should == :ok + -> { @a.call(a: 1) }.should.raise(ArgumentError, 'no keywords accepted') + -> { @a.call(**{a: 1}) }.should.raise(ArgumentError, 'no keywords accepted') + -> { @a.call("a" => 1) }.should.raise(ArgumentError, 'no keywords accepted') + end + + evaluate <<-ruby do + @a = lambda { |a, **nil| a } + ruby + + @a.call({a: 1}).should == {a: 1} + -> { @a.call(a: 1) }.should.raise(ArgumentError, 'no keywords accepted') + end end end diff --git a/spec/ruby/language/line_spec.rb b/spec/ruby/language/line_spec.rb index fcadaa71d7..2864798079 100644 --- a/spec/ruby/language/line_spec.rb +++ b/spec/ruby/language/line_spec.rb @@ -4,7 +4,7 @@ require_relative 'shared/__LINE__' describe "The __LINE__ pseudo-variable" do it "raises a SyntaxError if assigned to" do - -> { eval("__LINE__ = 1") }.should raise_error(SyntaxError) + -> { eval("__LINE__ = 1") }.should.raise(SyntaxError) end before :each do diff --git a/spec/ruby/language/loop_spec.rb b/spec/ruby/language/loop_spec.rb index fd17b53910..9b12765a5f 100644 --- a/spec/ruby/language/loop_spec.rb +++ b/spec/ruby/language/loop_spec.rb @@ -15,7 +15,7 @@ describe "The loop expression" do inner_loop = 123 break end - -> { inner_loop }.should raise_error(NameError) + -> { inner_loop }.should.raise(NameError) end it "returns the value passed to break if interrupted by break" do diff --git a/spec/ruby/language/magic_comment_spec.rb b/spec/ruby/language/magic_comment_spec.rb index f2bf3a08e5..af9c9dbfd0 100644 --- a/spec/ruby/language/magic_comment_spec.rb +++ b/spec/ruby/language/magic_comment_spec.rb @@ -45,7 +45,8 @@ end describe "Magic comments" do describe "in stdin" do - it_behaves_like :magic_comments, :locale, -> file { + default = (platform_is :windows and ruby_version_is "4.0") ? :UTF8 : :locale + it_behaves_like :magic_comments, default, -> file { print_at_exit = fixture(__FILE__, "print_magic_comment_result_at_exit.rb") ruby_exe(nil, args: "< #{fixture(__FILE__, file)}", options: "-r#{print_at_exit}") } diff --git a/spec/ruby/language/match_spec.rb b/spec/ruby/language/match_spec.rb index ebf677cabc..096ebee022 100644 --- a/spec/ruby/language/match_spec.rb +++ b/spec/ruby/language/match_spec.rb @@ -46,6 +46,14 @@ describe "The =~ operator with named captures" do matched.should == "foo" unmatched.should == nil end + + it "sets existing local variables if declared in a higher scope" do + a = 42 + 1.times do + /(?<a>foo)/ =~ @string + end + a.should == "foo" + end end describe "on syntax of 'string_literal' =~ /regexp/" do diff --git a/spec/ruby/language/metaclass_spec.rb b/spec/ruby/language/metaclass_spec.rb index fc83067977..3bee823a75 100644 --- a/spec/ruby/language/metaclass_spec.rb +++ b/spec/ruby/language/metaclass_spec.rb @@ -16,17 +16,17 @@ describe "self in a metaclass body (class << obj)" do end it "raises a TypeError for numbers" do - -> { class << 1; self; end }.should raise_error(TypeError) + -> { class << 1; self; end }.should.raise(TypeError) end it "raises a TypeError for symbols" do - -> { class << :symbol; self; end }.should raise_error(TypeError) + -> { class << :symbol; self; end }.should.raise(TypeError) end it "is a singleton Class instance" do cls = class << mock('x'); self; end cls.is_a?(Class).should == true - cls.should_not equal(Object) + cls.should_not.equal?(Object) end end @@ -57,20 +57,20 @@ describe "A constant on a metaclass" do end it "is not defined on the object's class" do - @object.class.const_defined?(:CONST).should be_false + @object.class.const_defined?(:CONST).should == false end it "is not defined in the metaclass opener's scope" do class << @object CONST end - -> { CONST }.should raise_error(NameError) + -> { CONST }.should.raise(NameError) end it "cannot be accessed via object::CONST" do -> do @object::CONST - end.should raise_error(TypeError) + end.should.raise(TypeError) end it "raises a NameError for anonymous_module::CONST" do @@ -81,16 +81,16 @@ describe "A constant on a metaclass" do -> do @object::CONST - end.should raise_error(NameError) + end.should.raise(NameError) end it "appears in the metaclass constant list" do constants = class << @object; constants; end - constants.should include(:CONST) + constants.should.include?(:CONST) end it "does not appear in the object's class constant list" do - @object.class.constants.should_not include(:CONST) + @object.class.constants.should_not.include?(:CONST) end it "is not preserved when the object is duped" do @@ -98,14 +98,14 @@ describe "A constant on a metaclass" do -> do class << @object; CONST; end - end.should raise_error(NameError) + end.should.raise(NameError) end it "is preserved when the object is cloned" do @object = @object.clone class << @object - CONST.should_not be_nil + CONST.should_not == nil end end end diff --git a/spec/ruby/language/method_spec.rb b/spec/ruby/language/method_spec.rb index b0d7058dbe..324bd6cea5 100644 --- a/spec/ruby/language/method_spec.rb +++ b/spec/ruby/language/method_spec.rb @@ -19,7 +19,7 @@ describe "A method send" do x = mock("splat argument") x.should_not_receive(:to_ary) - m(*x).should equal(x) + m(*x).should.equal?(x) end it "calls #to_a" do @@ -40,7 +40,7 @@ describe "A method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { m(*x) }.should raise_error(TypeError) + -> { m(*x) }.should.raise(TypeError) end end @@ -74,7 +74,7 @@ describe "A method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { m(*x, 2, 3) }.should raise_error(TypeError) + -> { m(*x, 2, 3) }.should.raise(TypeError) end end @@ -108,13 +108,13 @@ describe "A method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { m(1, *x, 2, 3) }.should raise_error(TypeError) + -> { m(1, *x, 2, 3) }.should.raise(TypeError) end it "copies the splatted array" do args = [3, 4] m(1, 2, *args, 4, 5).should == [1, 2, [3, 4], 4, 5] - m(1, 2, *args, 4, 5)[2].should_not equal(args) + m(1, 2, *args, 4, 5)[2].should_not.equal?(args) end it "allows an array being splatted to be modified by another argument" do @@ -153,7 +153,7 @@ describe "A method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { m(1, 2, *x) }.should raise_error(TypeError) + -> { m(1, 2, *x) }.should.raise(TypeError) end end @@ -217,7 +217,7 @@ describe "An element assignment method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { @o[*x] = 1 }.should raise_error(TypeError) + -> { @o[*x] = 1 }.should.raise(TypeError) end end @@ -255,7 +255,7 @@ describe "An element assignment method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { @o[*x, 2, 3] = 4 }.should raise_error(TypeError) + -> { @o[*x, 2, 3] = 4 }.should.raise(TypeError) end end @@ -293,7 +293,7 @@ describe "An element assignment method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { @o[1, 2, *x, 3] = 4 }.should raise_error(TypeError) + -> { @o[1, 2, *x, 3] = 4 }.should.raise(TypeError) end end @@ -331,7 +331,7 @@ describe "An element assignment method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { @o[1, 2, 3, *x] = 4 }.should raise_error(TypeError) + -> { @o[1, 2, 3, *x] = 4 }.should.raise(TypeError) end end end @@ -368,7 +368,7 @@ describe "An attribute assignment method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { @o.send :m=, *x, 1 }.should raise_error(TypeError) + -> { @o.send :m=, *x, 1 }.should.raise(TypeError) end end @@ -403,7 +403,7 @@ describe "An attribute assignment method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { @o.send :m=, *x, 2, 3, 4 }.should raise_error(TypeError) + -> { @o.send :m=, *x, 2, 3, 4 }.should.raise(TypeError) end end @@ -438,7 +438,7 @@ describe "An attribute assignment method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { @o.send :m=, 1, 2, *x, 3, 4 }.should raise_error(TypeError) + -> { @o.send :m=, 1, 2, *x, 3, 4 }.should.raise(TypeError) end end @@ -473,7 +473,7 @@ describe "An attribute assignment method send" do x = mock("splat argument") x.should_receive(:to_a).and_return(1) - -> { @o.send :m=, 1, 2, 3, *x, 4 }.should raise_error(TypeError) + -> { @o.send :m=, 1, 2, 3, *x, 4 }.should.raise(TypeError) end end end @@ -487,7 +487,7 @@ describe "A method" do end ruby - m.should be_nil + m.should == nil end evaluate <<-ruby do @@ -495,7 +495,7 @@ describe "A method" do end ruby - m.should be_nil + m.should == nil end end @@ -504,7 +504,7 @@ describe "A method" do def m(a) a end ruby - m((args = 1, 2, 3)).should equal(args) + m((args = 1, 2, 3)).should.equal?(args) end evaluate <<-ruby do @@ -535,18 +535,18 @@ describe "A method" do def m() end ruby - m().should be_nil - m(*[]).should be_nil - m(**{}).should be_nil + m().should == nil + m(*[]).should == nil + m(**{}).should == nil end evaluate <<-ruby do def m(*) end ruby - m().should be_nil - m(1).should be_nil - m(1, 2, 3).should be_nil + m().should == nil + m(1).should == nil + m(1, 2, 3).should == nil end evaluate <<-ruby do @@ -564,10 +564,10 @@ describe "A method" do def m(a:) a end ruby - -> { m() }.should raise_error(ArgumentError) + -> { m() }.should.raise(ArgumentError) m(a: 1).should == 1 suppress_keyword_warning do - -> { m("a" => 1, a: 1) }.should raise_error(ArgumentError) + -> { m("a" => 1, a: 1) }.should.raise(ArgumentError) end end @@ -575,7 +575,7 @@ describe "A method" do def m(a:, **kw) [a, kw] end ruby - -> { m(b: 1) }.should raise_error(ArgumentError) + -> { m(b: 1) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -590,9 +590,9 @@ describe "A method" do def m(**) end ruby - m().should be_nil - m(a: 1, b: 2).should be_nil - -> { m(1) }.should raise_error(ArgumentError) + m().should == nil + m(a: 1, b: 2).should == nil + -> { m(1) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -606,7 +606,7 @@ describe "A method" do suppress_warning { eval "m(**{a: 1, b: 2}, **{a: 4, c: 7})" }.should == { a: 4, b: 2, c: 7 } - -> { m(2) }.should raise_error(ArgumentError) + -> { m(2) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -620,7 +620,7 @@ describe "A method" do def m(&b) b end ruby - m { }.should be_an_instance_of(Proc) + m { }.should.instance_of?(Proc) end evaluate <<-ruby do @@ -650,9 +650,9 @@ describe "A method" do def m((*), (*)) end ruby - m(2, 3).should be_nil - m([2, 3, 4], [5, 6]).should be_nil - -> { m a: 1 }.should raise_error(ArgumentError) + m(2, 3).should == nil + m([2, 3, 4], [5, 6]).should == nil + -> { m a: 1 }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -745,7 +745,7 @@ describe "A method" do m(1, b: 2).should == [1, 2] suppress_keyword_warning do - -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError) + -> { m("a" => 1, b: 2) }.should.raise(ArgumentError) end end @@ -755,7 +755,7 @@ describe "A method" do m(2).should == [2, 1] m(1, b: 2).should == [1, 2] - -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError) + -> { m("a" => 1, b: 2) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -764,7 +764,7 @@ describe "A method" do m(1).should == 1 m(1, a: 2, b: 3).should == 1 - -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError) + -> { m("a" => 1, b: 2) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -773,7 +773,7 @@ describe "A method" do m(1).should == [1, {}] m(1, a: 2, b: 3).should == [1, {a: 2, b: 3}] - -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError) + -> { m("a" => 1, b: 2) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -848,8 +848,8 @@ describe "A method" do def m(a=1, (*b), (*c)) [a, b, c] end ruby - -> { m() }.should raise_error(ArgumentError) - -> { m(2) }.should raise_error(ArgumentError) + -> { m() }.should.raise(ArgumentError) + -> { m(2) }.should.raise(ArgumentError) m(2, 3).should == [1, [2], [3]] m(2, [3, 4], [5, 6]).should == [2, [3, 4], [5, 6]] end @@ -890,7 +890,7 @@ describe "A method" do m(b: 2).should == [1, 2] m(2, b: 1).should == [2, 1] - -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError) + -> { m("a" => 1, b: 2) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -900,7 +900,7 @@ describe "A method" do m().should == [1, 2] m(2).should == [2, 2] m(b: 3).should == [1, 3] - -> { m("a" => 1, b: 2) }.should raise_error(ArgumentError) + -> { m("a" => 1, b: 2) }.should.raise(ArgumentError) end evaluate <<-ruby do @@ -953,9 +953,9 @@ describe "A method" do def m(*, &b) b end ruby - m().should be_nil - m(1, 2, 3, 4).should be_nil - m(&(l = ->{})).should equal(l) + m().should == nil + m(1, 2, 3, 4).should == nil + m(&(l = ->{})).should.equal?(l) end evaluate <<-ruby do @@ -973,7 +973,7 @@ describe "A method" do m(a: 1, b: 2).should == [1, 2] suppress_keyword_warning do - -> { m("a" => 1, a: 1, b: 2) }.should raise_error(ArgumentError) + -> { m("a" => 1, a: 1, b: 2) }.should.raise(ArgumentError) end end @@ -984,7 +984,7 @@ describe "A method" do m(a: 1).should == [1, 1] m(a: 1, b: 2).should == [1, 2] suppress_keyword_warning do - -> { m("a" => 1, a: 1, b: 2) }.should raise_error(ArgumentError) + -> { m("a" => 1, a: 1, b: 2) }.should.raise(ArgumentError) end end @@ -1101,15 +1101,25 @@ describe "A method" do end evaluate <<-ruby do + def m(**nil); :ok; end; + ruby + + m().should == :ok + -> { m(a: 1) }.should.raise(ArgumentError, 'no keywords accepted') + -> { m(**{a: 1}) }.should.raise(ArgumentError, 'no keywords accepted') + -> { m("a" => 1) }.should.raise(ArgumentError, 'no keywords accepted') + end + + evaluate <<-ruby do def m(a, **nil); a end; ruby m({a: 1}).should == {a: 1} m({"a" => 1}).should == {"a" => 1} - -> { m(a: 1) }.should raise_error(ArgumentError, 'no keywords accepted') - -> { m(**{a: 1}) }.should raise_error(ArgumentError, 'no keywords accepted') - -> { m("a" => 1) }.should raise_error(ArgumentError, 'no keywords accepted') + -> { m(a: 1) }.should.raise(ArgumentError, 'no keywords accepted') + -> { m(**{a: 1}) }.should.raise(ArgumentError, 'no keywords accepted') + -> { m("a" => 1) }.should.raise(ArgumentError, 'no keywords accepted') end evaluate <<-ruby do @@ -1127,6 +1137,18 @@ describe "A method" do result = m(1, {foo: :bar}) result.should == [1, nil, nil, {foo: :bar}, nil, {}] end + + ruby_version_is "4.1" do + evaluate <<-ruby do + def m(a, &nil); a end; + ruby + + m(1).should == 1 + + -> { m(1) {} }.should.raise(ArgumentError, 'no block accepted') + -> { m(1, &proc {}) }.should.raise(ArgumentError, 'no block accepted') + end + end end context 'when passing an empty keyword splat to a method that does not accept keywords' do @@ -1147,7 +1169,7 @@ describe "A method" do -> do m(**h).should == {} - end.should raise_error(ArgumentError) + end.should.raise(ArgumentError) end end @@ -1159,7 +1181,7 @@ describe "A method" do options = {a: 1}.freeze -> do m(options) - end.should raise_error(ArgumentError) + end.should.raise(ArgumentError) end end @@ -1175,6 +1197,31 @@ describe "A method" do end end +context "when passing **nil into a method that accepts keyword arguments" do + ruby_version_is ""..."3.4" do + it "raises TypeError" do + def m(**kw) kw; end + + h = nil + -> { m(a: 1, **h) }.should.raise(TypeError, "no implicit conversion of nil into Hash") + -> { m(a: 1, **nil) }.should.raise(TypeError, "no implicit conversion of nil into Hash") + end + end + + ruby_version_is "3.4" do + it "expands nil using ** into {}" do + def m(**kw) kw; end + + h = nil + m(**h).should == {} + m(a: 1, **h).should == {a: 1} + + m(**nil).should == {} + m(a: 1, **nil).should == {a: 1} + end + end +end + describe "A method call with a space between method name and parentheses" do before(:each) do def m(*args) @@ -1209,10 +1256,8 @@ describe "A method call with a space between method name and parentheses" do args.should == [true] end - ruby_version_is "3.3" do - it "supports multiple statements" do - eval("m (1; 2)").should == [2] - end + it "supports multiple statements" do + eval("m (1; 2)").should == [2] end end @@ -1232,11 +1277,11 @@ describe "A method call with a space between method name and parentheses" do it "raises a syntax error" do -> { eval("m (1, 2)") - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) -> { eval("m (1, 2, 3)") - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end end @@ -1386,7 +1431,7 @@ describe "Keyword arguments are now separated from positional arguments" do -> { foo(1, 2, 3, { key: 42 }) - }.should raise_error(ArgumentError, 'wrong number of arguments (given 4, expected 3)') + }.should.raise(ArgumentError, 'wrong number of arguments (given 4, expected 3)') end end @@ -1399,7 +1444,7 @@ describe "Keyword arguments are now separated from positional arguments" do -> { foo(1, 2, 3, { key: 42 }) - }.should raise_error(ArgumentError, 'wrong number of arguments (given 4, expected 3)') + }.should.raise(ArgumentError, 'wrong number of arguments (given 4, expected 3)') end end @@ -1462,3 +1507,163 @@ describe "Inside 'endless' method definitions" do greet("Homer").should == "Hi, Homer" end end + +describe "warning about not used block argument" do + ruby_version_is "3.4" do + it "warns when passing a block argument to a method that never uses it" do + def m_that_does_not_use_block + 42 + end + + -> { + m_that_does_not_use_block { } + }.should complain( + /#{__FILE__}:#{__LINE__ - 2}: warning: the block passed to 'm_that_does_not_use_block' defined at #{__FILE__}:#{__LINE__ - 7} may be ignored/, + verbose: true) + end + + it "does not warn when passing a block argument to a method that declares a block parameter" do + def m_with_block_parameter(&block) + 42 + end + + -> { m_with_block_parameter { } }.should_not complain(verbose: true) + end + + it "does not warn when passing a block argument to a method that declares an anonymous block parameter" do + def m_with_anonymous_block_parameter(&) + 42 + end + + -> { m_with_anonymous_block_parameter { } }.should_not complain(verbose: true) + end + + it "does not warn when passing a block argument to a method that yields an implicit block parameter" do + def m_with_yield + yield 42 + end + + -> { m_with_yield { } }.should_not complain(verbose: true) + end + + it "warns when passing a block argument to a method that calls #block_given?" do + def m_with_block_given + block_given? + end + + -> { + m_with_block_given { } + }.should complain( + /#{__FILE__}:#{__LINE__ - 2}: warning: the block passed to 'm_with_block_given' defined at #{__FILE__}:#{__LINE__ - 7} may be ignored/, + verbose: true) + end + + it "does not warn when passing a block argument to a method that calls super" do + parent = Class.new do + def m + end + end + + child = Class.new(parent) do + def m + super + end + end + + obj = child.new + -> { obj.m { } }.should_not complain(verbose: true) + end + + it "does not warn when passing a block argument to a method that calls super(...)" do + parent = Class.new do + def m(a) + end + end + + child = Class.new(parent) do + def m(...) + super(...) + end + end + + obj = child.new + -> { obj.m(42) { } }.should_not complain(verbose: true) + end + + it "does not warn when called #initialize()" do + klass = Class.new do + def initialize + end + end + + -> { klass.new {} }.should_not complain(verbose: true) + end + + it "does not warn when passing a block argument to a method that calls super()" do + parent = Class.new do + def m + end + end + + child = Class.new(parent) do + def m + super() + end + end + + obj = child.new + -> { obj.m { } }.should_not complain(verbose: true) + end + + it "warns only once per call site" do + def m_that_does_not_use_block + 42 + end + + def call_m_that_does_not_use_block + m_that_does_not_use_block {} + end + + -> { + m_that_does_not_use_block { } + }.should complain(/the block passed to 'm_that_does_not_use_block' defined at .+ may be ignored/, verbose: true) + + -> { + m_that_does_not_use_block { } + }.should_not complain(verbose: true) + end + + it "can be disabled with :strict_unused_block warning category" do + def m_that_does_not_use_block + 42 + end + + # ensure that warning is emitted + -> { m_that_does_not_use_block { } }.should complain(verbose: true) + + warn_strict_unused_block = Warning[:strict_unused_block] + Warning[:strict_unused_block] = false + begin + -> { m_that_does_not_use_block { } }.should_not complain(verbose: true) + ensure + Warning[:strict_unused_block] = warn_strict_unused_block + end + end + + it "can be enabled with :strict_unused_block = true warning category in not verbose mode" do + def m_that_does_not_use_block + 42 + end + + warn_strict_unused_block = Warning[:strict_unused_block] + Warning[:strict_unused_block] = true + begin + -> { + m_that_does_not_use_block { } + }.should complain(/the block passed to 'm_that_does_not_use_block' defined at .+ may be ignored/) + ensure + Warning[:strict_unused_block] = warn_strict_unused_block + end + end + end +end diff --git a/spec/ruby/language/module_spec.rb b/spec/ruby/language/module_spec.rb index 0bfd148868..2f22e383d5 100644 --- a/spec/ruby/language/module_spec.rb +++ b/spec/ruby/language/module_spec.rb @@ -4,79 +4,94 @@ require_relative 'fixtures/module' describe "The module keyword" do it "creates a new module without semicolon" do module ModuleSpecsKeywordWithoutSemicolon end - ModuleSpecsKeywordWithoutSemicolon.should be_an_instance_of(Module) + ModuleSpecsKeywordWithoutSemicolon.should.instance_of?(Module) end it "creates a new module with a non-qualified constant name" do module ModuleSpecsToplevel; end - ModuleSpecsToplevel.should be_an_instance_of(Module) + ModuleSpecsToplevel.should.instance_of?(Module) end it "creates a new module with a qualified constant name" do module ModuleSpecs::Nested; end - ModuleSpecs::Nested.should be_an_instance_of(Module) + ModuleSpecs::Nested.should.instance_of?(Module) end it "creates a new module with a variable qualified constant name" do m = Module.new module m::N; end - m::N.should be_an_instance_of(Module) + m::N.should.instance_of?(Module) end it "reopens an existing module" do module ModuleSpecs; Reopened = true; end - ModuleSpecs::Reopened.should be_true + ModuleSpecs::Reopened.should == true ensure ModuleSpecs.send(:remove_const, :Reopened) end - ruby_version_is '3.2' do - it "does not reopen a module included in Object" do - module IncludedModuleSpecs; Reopened = true; end - ModuleSpecs::IncludedInObject::IncludedModuleSpecs.should_not == Object::IncludedModuleSpecs - ensure - IncludedModuleSpecs.send(:remove_const, :Reopened) - end - end - - ruby_version_is ''...'3.2' do - it "reopens a module included in Object" do - module IncludedModuleSpecs; Reopened = true; end - ModuleSpecs::IncludedInObject::IncludedModuleSpecs::Reopened.should be_true - end + it "does not reopen a module included in Object" do + ruby_exe(<<~RUBY).should == "false" + module IncludedInObject + module IncludedModule; end + end + class Object + include IncludedInObject + end + module IncludedModule; end + print IncludedInObject::IncludedModule == Object::IncludedModule + RUBY + end + + it "does not reopen a module included in non-Object modules" do + ruby_exe(<<~RUBY).should == "false/false" + module Included + module IncludedModule; end + end + module M + include Included + module IncludedModule; end + end + class C + include Included + module IncludedModule; end + end + print Included::IncludedModule == M::IncludedModule, "/", + Included::IncludedModule == C::IncludedModule + RUBY end it "raises a TypeError if the constant is a Class" do -> do module ModuleSpecs::Modules::Klass; end - end.should raise_error(TypeError) + end.should.raise(TypeError) end it "raises a TypeError if the constant is a String" do - -> { module ModuleSpecs::Modules::A; end }.should raise_error(TypeError) + -> { module ModuleSpecs::Modules::A; end }.should.raise(TypeError) end it "raises a TypeError if the constant is an Integer" do - -> { module ModuleSpecs::Modules::B; end }.should raise_error(TypeError) + -> { module ModuleSpecs::Modules::B; end }.should.raise(TypeError) end it "raises a TypeError if the constant is nil" do - -> { module ModuleSpecs::Modules::C; end }.should raise_error(TypeError) + -> { module ModuleSpecs::Modules::C; end }.should.raise(TypeError) end it "raises a TypeError if the constant is true" do - -> { module ModuleSpecs::Modules::D; end }.should raise_error(TypeError) + -> { module ModuleSpecs::Modules::D; end }.should.raise(TypeError) end it "raises a TypeError if the constant is false" do - -> { module ModuleSpecs::Modules::D; end }.should raise_error(TypeError) + -> { module ModuleSpecs::Modules::D; end }.should.raise(TypeError) end end describe "Assigning an anonymous module to a constant" do it "sets the name of the module" do mod = Module.new - mod.name.should be_nil + mod.name.should == nil ::ModuleSpecs_CS1 = mod mod.name.should == "ModuleSpecs_CS1" diff --git a/spec/ruby/language/next_spec.rb b/spec/ruby/language/next_spec.rb index 6fbfc4a54d..eac151eeb3 100644 --- a/spec/ruby/language/next_spec.rb +++ b/spec/ruby/language/next_spec.rb @@ -21,7 +21,7 @@ describe "The next statement from within the block" do end it "causes block to return nil if invoked with an empty expression" do - -> { next (); 456 }.call.should be_nil + -> { next (); 456 }.call.should == nil end it "returns the argument passed" do @@ -111,7 +111,7 @@ describe "The next statement" do it "is invalid and raises a SyntaxError" do -> { eval("def m; next; end") - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end end end diff --git a/spec/ruby/language/not_spec.rb b/spec/ruby/language/not_spec.rb index 052af9b256..23411a8e1d 100644 --- a/spec/ruby/language/not_spec.rb +++ b/spec/ruby/language/not_spec.rb @@ -2,50 +2,50 @@ require_relative '../spec_helper' describe "The not keyword" do it "negates a `true' value" do - (not true).should be_false - (not 'true').should be_false + (not true).should == false + (not 'true').should == false end it "negates a `false' value" do - (not false).should be_true - (not nil).should be_true + (not false).should == true + (not nil).should == true end it "accepts an argument" do - not(true).should be_false + not(true).should == false end it "returns false if the argument is true" do - (not(true)).should be_false + (not(true)).should == false end it "returns true if the argument is false" do - (not(false)).should be_true + (not(false)).should == true end it "returns true if the argument is nil" do - (not(nil)).should be_true + (not(nil)).should == true end end describe "The `!' keyword" do it "negates a `true' value" do - (!true).should be_false - (!'true').should be_false + (!true).should == false + (!'true').should == false end it "negates a `false' value" do - (!false).should be_true - (!nil).should be_true + (!false).should == true + (!nil).should == true end it "doubled turns a truthful object into `true'" do - (!!true).should be_true - (!!'true').should be_true + (!!true).should == true + (!!'true').should == true end it "doubled turns a not truthful object into `false'" do - (!!false).should be_false - (!!nil).should be_false + (!!false).should == false + (!!nil).should == false end end diff --git a/spec/ruby/language/numbered_parameters_spec.rb b/spec/ruby/language/numbered_parameters_spec.rb index 39ddd6fee8..23e89a14be 100644 --- a/spec/ruby/language/numbered_parameters_spec.rb +++ b/spec/ruby/language/numbered_parameters_spec.rb @@ -22,13 +22,13 @@ describe "Numbered parameters" do it "does not support more than 9 parameters" do -> { proc { [_10] }.call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - }.should raise_error(NameError, /undefined local variable or method [`']_10'/) + }.should.raise(NameError, /undefined local variable or method [`']_10'/) end it "can not be used in both outer and nested blocks at the same time" do -> { eval("-> { _1; -> { _2 } }") - }.should raise_error(SyntaxError, /numbered parameter is already used in/m) + }.should.raise(SyntaxError, /numbered parameter is already used in/m) end it "cannot be overwritten with local variable" do @@ -37,32 +37,32 @@ describe "Numbered parameters" do _1 = 0 proc { _1 }.call("a").should == 0 CODE - }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/) + }.should.raise(SyntaxError, /_1 is reserved for numbered parameter/) end it "errors when numbered parameter is overwritten with local variable" do -> { eval("_1 = 0") - }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/) + }.should.raise(SyntaxError, /_1 is reserved for numbered parameter/) end it "raises SyntaxError when block parameters are specified explicitly" do - -> { eval("-> () { _1 }") }.should raise_error(SyntaxError, /ordinary parameter is defined/) - -> { eval("-> (x) { _1 }") }.should raise_error(SyntaxError, /ordinary parameter is defined/) + -> { eval("-> () { _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("-> (x) { _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/) - -> { eval("proc { || _1 }") }.should raise_error(SyntaxError, /ordinary parameter is defined/) - -> { eval("proc { |x| _1 }") }.should raise_error(SyntaxError, /ordinary parameter is defined/) + -> { eval("proc { || _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("proc { |x| _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/) - -> { eval("lambda { || _1 }") }.should raise_error(SyntaxError, /ordinary parameter is defined/) - -> { eval("lambda { |x| _1 }") }.should raise_error(SyntaxError, /ordinary parameter is defined/) + -> { eval("lambda { || _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("lambda { |x| _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/) - -> { eval("['a'].map { || _1 }") }.should raise_error(SyntaxError, /ordinary parameter is defined/) - -> { eval("['a'].map { |x| _1 }") }.should raise_error(SyntaxError, /ordinary parameter is defined/) + -> { eval("['a'].map { || _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/) + -> { eval("['a'].map { |x| _1 }") }.should.raise(SyntaxError, /ordinary parameter is defined/) end describe "assigning to a numbered parameter" do it "raises SyntaxError" do - -> { eval("proc { _1 = 0 }") }.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/) + -> { eval("proc { _1 = 0 }") }.should.raise(SyntaxError, /_1 is reserved for numbered parameter/) end end @@ -90,14 +90,14 @@ describe "Numbered parameters" do proc { _2 }.parameters.should == [[:opt, :_1], [:opt, :_2]] end - ruby_version_is ""..."3.5" do + ruby_version_is ""..."4.0" do it "affects binding local variables" do -> { _1; binding.local_variables }.call("a").should == [:_1] -> { _2; binding.local_variables }.call("a", "b").should == [:_1, :_2] end end - ruby_version_is "3.5" do + ruby_version_is "4.0" do it "does not affect binding local variables" do -> { _1; binding.local_variables }.call("a").should == [] -> { _2; binding.local_variables }.call("a", "b").should == [] @@ -108,6 +108,6 @@ describe "Numbered parameters" do obj = Object.new def obj.foo; _1 end - -> { obj.foo("a") }.should raise_error(ArgumentError, /wrong number of arguments/) + -> { obj.foo("a") }.should.raise(ArgumentError, /wrong number of arguments/) end end diff --git a/spec/ruby/language/numbers_spec.rb b/spec/ruby/language/numbers_spec.rb index a8e023efb6..ed0e49c048 100644 --- a/spec/ruby/language/numbers_spec.rb +++ b/spec/ruby/language/numbers_spec.rb @@ -11,7 +11,7 @@ describe "A number literal" do end it "cannot have a leading underscore" do - -> { eval("_4_2") }.should raise_error(NameError) + -> { eval("_4_2") }.should.raise(NameError) end it "can have a decimal point" do @@ -20,8 +20,8 @@ describe "A number literal" do it "must have a digit before the decimal point" do 0.75.should == 0.75 - -> { eval(".75") }.should raise_error(SyntaxError) - -> { eval("-.75") }.should raise_error(SyntaxError) + -> { eval(".75") }.should.raise(SyntaxError) + -> { eval("-.75") }.should.raise(SyntaxError) end it "can have an exponent" do diff --git a/spec/ruby/language/optional_assignments_spec.rb b/spec/ruby/language/optional_assignments_spec.rb index 5fe3e3671b..ebb5d36351 100644 --- a/spec/ruby/language/optional_assignments_spec.rb +++ b/spec/ruby/language/optional_assignments_spec.rb @@ -603,7 +603,7 @@ describe 'Optional variable assignments' do end it 'with &&= assignments will fail with non-existent constants' do - -> { Object::A &&= 10 }.should raise_error(NameError) + -> { Object::A &&= 10 }.should.raise(NameError) end it 'with operator assignments' do @@ -615,7 +615,7 @@ describe 'Optional variable assignments' do end it 'with operator assignments will fail with non-existent constants' do - -> { Object::A += 10 }.should raise_error(NameError) + -> { Object::A += 10 }.should.raise(NameError) end end end @@ -623,7 +623,7 @@ end describe 'Optional constant assignment' do describe 'with ||=' do it "assigns a scoped constant if previously undefined" do - ConstantSpecs.should_not have_constant(:OpAssignUndefined) + ConstantSpecs.should_not.const_defined?(:OpAssignUndefined) module ConstantSpecs OpAssignUndefined ||= 42 end @@ -679,7 +679,7 @@ describe 'Optional constant assignment' do -> { (x += 1; raise Exception; ConstantSpecs::ClassA)::OR_ASSIGNED_CONSTANT3 ||= (y += 1; :assigned) - }.should raise_error(Exception) + }.should.raise(Exception) x.should == 1 y.should == 0 @@ -693,7 +693,7 @@ describe 'Optional constant assignment' do -> { (x += 1; raise Exception; ConstantSpecs::ClassA)::NIL_OR_ASSIGNED_CONSTANT3 ||= (y += 1; :assigned) - }.should raise_error(Exception) + }.should.raise(Exception) x.should == 1 y.should == 0 diff --git a/spec/ruby/language/or_spec.rb b/spec/ruby/language/or_spec.rb index fb75e788f1..8ae577a142 100644 --- a/spec/ruby/language/or_spec.rb +++ b/spec/ruby/language/or_spec.rb @@ -26,24 +26,24 @@ describe "The || operator" do end it "treats empty expressions as nil" do - (() || true).should be_true - (() || false).should be_false - (true || ()).should be_true - (false || ()).should be_nil - (() || ()).should be_nil + (() || true).should == true + (() || false).should == false + (true || ()).should == true + (false || ()).should == nil + (() || ()).should == nil end it "has a higher precedence than 'break' in 'break true || false'" do # see also 'break true or false' below - -> { break false || true }.call.should be_true + -> { break false || true }.call.should == true end it "has a higher precedence than 'next' in 'next true || false'" do - -> { next false || true }.call.should be_true + -> { next false || true }.call.should == true end it "has a higher precedence than 'return' in 'return true || false'" do - -> { return false || true }.call.should be_true + -> { return false || true }.call.should == true end end @@ -68,23 +68,23 @@ describe "The or operator" do end it "treats empty expressions as nil" do - (() or true).should be_true - (() or false).should be_false - (true or ()).should be_true - (false or ()).should be_nil - (() or ()).should be_nil + (() or true).should == true + (() or false).should == false + (true or ()).should == true + (false or ()).should == nil + (() or ()).should == nil end it "has a lower precedence than 'break' in 'break true or false'" do # see also 'break true || false' above - -> { eval "break true or false" }.should raise_error(SyntaxError, /void value expression/) + -> { eval "break true or false" }.should.raise(SyntaxError, /void value expression/) end it "has a lower precedence than 'next' in 'next true or false'" do - -> { eval "next true or false" }.should raise_error(SyntaxError, /void value expression/) + -> { eval "next true or false" }.should.raise(SyntaxError, /void value expression/) end it "has a lower precedence than 'return' in 'return true or false'" do - -> { eval "return true or false" }.should raise_error(SyntaxError, /void value expression/) + -> { eval "return true or false" }.should.raise(SyntaxError, /void value expression/) end end diff --git a/spec/ruby/language/pattern_matching_spec.rb b/spec/ruby/language/pattern_matching_spec.rb index cb4f5864d7..a24500c9fd 100644 --- a/spec/ruby/language/pattern_matching_spec.rb +++ b/spec/ruby/language/pattern_matching_spec.rb @@ -185,7 +185,7 @@ describe "Pattern matching" do in [] end RUBY - }.should raise_error(SyntaxError, /syntax error, unexpected `in'|\(eval\):3: syntax error, unexpected keyword_in|unexpected 'in'/) + }.should.raise(SyntaxError, /syntax error, unexpected `in'|\(eval\):3: syntax error, unexpected keyword_in|unexpected 'in'/) -> { eval <<~RUBY @@ -194,7 +194,7 @@ describe "Pattern matching" do when 1 == 1 end RUBY - }.should raise_error(SyntaxError, /syntax error, unexpected `when'|\(eval\):3: syntax error, unexpected keyword_when|unexpected 'when'/) + }.should.raise(SyntaxError, /syntax error, unexpected `when'|\(eval\):3: syntax error, unexpected keyword_when|unexpected 'when'/) end it "checks patterns until the first matching" do @@ -222,14 +222,14 @@ describe "Pattern matching" do case [0, 1] in [0] end - }.should raise_error(NoMatchingPatternError, /\[0, 1\]/) + }.should.raise(NoMatchingPatternError, /\[0, 1\]/) error_pattern = ruby_version_is("3.4") ? /\{a: 0, b: 1\}/ : /\{:a=>0, :b=>1\}/ -> { case {a: 0, b: 1} in a: 1, b: 1 end - }.should raise_error(NoMatchingPatternError, error_pattern) + }.should.raise(NoMatchingPatternError, error_pattern) end it "raises NoMatchingPatternError if no pattern matches and evaluates the expression only once" do @@ -238,7 +238,7 @@ describe "Pattern matching" do case (evals += 1; [0, 1]) in [0] end - }.should raise_error(NoMatchingPatternError, /\[0, 1\]/) + }.should.raise(NoMatchingPatternError, /\[0, 1\]/) evals.should == 1 end @@ -250,7 +250,7 @@ describe "Pattern matching" do true end RUBY - }.should raise_error(SyntaxError, /unexpected|expected a delimiter after the patterns of an `in` clause/) + }.should.raise(SyntaxError, /unexpected|expected a delimiter after the patterns of an `in` clause/) end it "evaluates the case expression once for multiple patterns, caching the result" do @@ -336,7 +336,7 @@ describe "Pattern matching" do case [0, 1] in [0, 1] if false end - }.should raise_error(NoMatchingPatternError, /\[0, 1\]/) + }.should.raise(NoMatchingPatternError, /\[0, 1\]/) end end @@ -438,7 +438,7 @@ describe "Pattern matching" do in [a, a] end RUBY - }.should raise_error(SyntaxError, /duplicated variable name/) + }.should.raise(SyntaxError, /duplicated variable name/) end it "supports existing variables in a pattern specified with ^ operator" do @@ -474,7 +474,7 @@ describe "Pattern matching" do false end RUBY - }.should raise_error(SyntaxError, /n: no such local variable/) + }.should.raise(SyntaxError, /n: no such local variable/) end end @@ -493,7 +493,7 @@ describe "Pattern matching" do in [0, 0] | [0, a] end RUBY - }.should raise_error(SyntaxError, /illegal variable in alternative pattern/) + }.should.raise(SyntaxError) end it "support underscore prefixed variables in alternation" do @@ -674,7 +674,7 @@ describe "Pattern matching" do in Object[] else end - }.should raise_error(TypeError, /deconstruct must return Array/) + }.should.raise(TypeError, /deconstruct must return Array/) end it "accepts a subclass of Array from #deconstruct" do @@ -870,7 +870,7 @@ describe "Pattern matching" do in {"a" => 1} end RUBY - }.should raise_error(SyntaxError, /unexpected|expected a label as the key in the hash pattern/) + }.should.raise(SyntaxError, /unexpected|expected a label as the key in the hash pattern/) end it "does not support string interpolation in keys" do @@ -880,7 +880,7 @@ describe "Pattern matching" do in {"#{x}": 1} end RUBY - }.should raise_error(SyntaxError, /symbol literal with interpolation is not allowed|expected a label as the key in the hash pattern/) + }.should.raise(SyntaxError, /symbol literal with interpolation is not allowed|expected a label as the key in the hash pattern/) end it "raise SyntaxError when keys duplicate in pattern" do @@ -890,7 +890,7 @@ describe "Pattern matching" do in {a: 1, b: 2, a: 3} end RUBY - }.should raise_error(SyntaxError, /duplicated key name/) + }.should.raise(SyntaxError, /duplicated key name/) end it "matches an object with #deconstruct_keys method which returns a Hash with equal keys and each value in Hash matches value in pattern" do @@ -969,7 +969,7 @@ describe "Pattern matching" do case obj in Object[a: 1] end - }.should raise_error(TypeError, /deconstruct_keys must return Hash/) + }.should.raise(TypeError, /deconstruct_keys must return Hash/) end it "does not match object if #deconstruct_keys method returns Hash with non-symbol keys" do diff --git a/spec/ruby/language/precedence_spec.rb b/spec/ruby/language/precedence_spec.rb index 5e606c16d8..edb990525e 100644 --- a/spec/ruby/language/precedence_spec.rb +++ b/spec/ruby/language/precedence_spec.rb @@ -251,12 +251,12 @@ describe "Operators" do end it "<=> == === != =~ !~ are non-associative" do - -> { eval("1 <=> 2 <=> 3") }.should raise_error(SyntaxError) - -> { eval("1 == 2 == 3") }.should raise_error(SyntaxError) - -> { eval("1 === 2 === 3") }.should raise_error(SyntaxError) - -> { eval("1 != 2 != 3") }.should raise_error(SyntaxError) - -> { eval("1 =~ 2 =~ 3") }.should raise_error(SyntaxError) - -> { eval("1 !~ 2 !~ 3") }.should raise_error(SyntaxError) + -> { eval("1 <=> 2 <=> 3") }.should.raise(SyntaxError) + -> { eval("1 == 2 == 3") }.should.raise(SyntaxError) + -> { eval("1 === 2 === 3") }.should.raise(SyntaxError) + -> { eval("1 != 2 != 3") }.should.raise(SyntaxError) + -> { eval("1 =~ 2 =~ 3") }.should.raise(SyntaxError) + -> { eval("1 !~ 2 !~ 3") }.should.raise(SyntaxError) end it "<=> == === != =~ !~ have higher precedence than &&" do @@ -290,8 +290,8 @@ describe "Operators" do end it ".. ... are non-associative" do - -> { eval("1..2..3") }.should raise_error(SyntaxError) - -> { eval("1...2...3") }.should raise_error(SyntaxError) + -> { eval("1..2..3") }.should.raise(SyntaxError) + -> { eval("1...2...3") }.should.raise(SyntaxError) end it ".. ... have higher precedence than ? :" do diff --git a/spec/ruby/language/predefined_spec.rb b/spec/ruby/language/predefined_spec.rb index f8645493b8..d57b924bcf 100644 --- a/spec/ruby/language/predefined_spec.rb +++ b/spec/ruby/language/predefined_spec.rb @@ -1,4 +1,5 @@ require_relative '../spec_helper' +require_relative '../core/exception/shared/set_backtrace' require 'stringio' # The following tables are excerpted from Programming Ruby: The Pragmatic Programmer's Guide' @@ -39,12 +40,12 @@ require 'stringio' describe "Predefined global $~" do it "is set to contain the MatchData object of the last match if successful" do md = /foo/.match 'foo' - $~.should be_kind_of(MatchData) - $~.should equal md + $~.should.is_a?(MatchData) + $~.should.equal? md /bar/ =~ 'bar' - $~.should be_kind_of(MatchData) - $~.should_not equal md + $~.should.is_a?(MatchData) + $~.should_not.equal? md end it "is set to nil if the last match was unsuccessful" do @@ -86,10 +87,10 @@ describe "Predefined global $~" do $~ = nil $~.should == nil $~ = /foo/.match("foo") - $~.should be_an_instance_of(MatchData) + $~.should.instance_of?(MatchData) - -> { $~ = Object.new }.should raise_error(TypeError) - -> { $~ = 1 }.should raise_error(TypeError) + -> { $~ = Object.new }.should.raise(TypeError, 'wrong argument type Object (expected MatchData)') + -> { $~ = 1 }.should.raise(TypeError, 'wrong argument type Integer (expected MatchData)') end it "changes the value of derived capture globals when assigned" do @@ -134,7 +135,20 @@ describe "Predefined global $&" do it "sets the encoding to the encoding of the source String" do "abc".dup.force_encoding(Encoding::EUC_JP) =~ /b/ - $&.encoding.should equal(Encoding::EUC_JP) + $&.encoding.should.equal?(Encoding::EUC_JP) + end + + it "is read-only" do + -> { + eval %q{$& = ""} + }.should.raise(SyntaxError, /Can't set variable \$&/) + end + + it "is read-only when aliased" do + alias $predefined_spec_ampersand $& + -> { + $predefined_spec_ampersand = "" + }.should.raise(NameError, '$predefined_spec_ampersand is a read-only variable') end end @@ -147,12 +161,25 @@ describe "Predefined global $`" do it "sets the encoding to the encoding of the source String" do "abc".dup.force_encoding(Encoding::EUC_JP) =~ /b/ - $`.encoding.should equal(Encoding::EUC_JP) + $`.encoding.should.equal?(Encoding::EUC_JP) end it "sets an empty result to the encoding of the source String" do "abc".dup.force_encoding(Encoding::ISO_8859_1) =~ /a/ - $`.encoding.should equal(Encoding::ISO_8859_1) + $`.encoding.should.equal?(Encoding::ISO_8859_1) + end + + it "is read-only" do + -> { + eval %q{$` = ""} + }.should.raise(SyntaxError, /Can't set variable \$`/) + end + + it "is read-only when aliased" do + alias $predefined_spec_backquote $` + -> { + $predefined_spec_backquote = "" + }.should.raise(NameError, '$predefined_spec_backquote is a read-only variable') end end @@ -165,12 +192,25 @@ describe "Predefined global $'" do it "sets the encoding to the encoding of the source String" do "abc".dup.force_encoding(Encoding::EUC_JP) =~ /b/ - $'.encoding.should equal(Encoding::EUC_JP) + $'.encoding.should.equal?(Encoding::EUC_JP) end it "sets an empty result to the encoding of the source String" do "abc".dup.force_encoding(Encoding::ISO_8859_1) =~ /c/ - $'.encoding.should equal(Encoding::ISO_8859_1) + $'.encoding.should.equal?(Encoding::ISO_8859_1) + end + + it "is read-only" do + -> { + eval %q{$' = ""} + }.should.raise(SyntaxError, /Can't set variable \$'/) + end + + it "is read-only when aliased" do + alias $predefined_spec_single_quote $' + -> { + $predefined_spec_single_quote = "" + }.should.raise(NameError, '$predefined_spec_single_quote is a read-only variable') end end @@ -188,7 +228,20 @@ describe "Predefined global $+" do it "sets the encoding to the encoding of the source String" do "abc".dup.force_encoding(Encoding::EUC_JP) =~ /(b)/ - $+.encoding.should equal(Encoding::EUC_JP) + $+.encoding.should.equal?(Encoding::EUC_JP) + end + + it "is read-only" do + -> { + eval %q{$+ = ""} + }.should.raise(SyntaxError, /Can't set variable \$\+/) + end + + it "is read-only when aliased" do + alias $predefined_spec_plus $+ + -> { + $predefined_spec_plus = "" + }.should.raise(NameError, '$predefined_spec_plus is a read-only variable') end end @@ -215,7 +268,7 @@ describe "Predefined globals $1..N" do it "sets the encoding to the encoding of the source String" do "abc".dup.force_encoding(Encoding::EUC_JP) =~ /(b)/ - $1.encoding.should equal(Encoding::EUC_JP) + $1.encoding.should.equal?(Encoding::EUC_JP) end end @@ -229,16 +282,16 @@ describe "Predefined global $stdout" do end it "raises TypeError error if assigned to nil" do - -> { $stdout = nil }.should raise_error(TypeError) + -> { $stdout = nil }.should.raise(TypeError, '$stdout must have write method, NilClass given') end it "raises TypeError error if assigned to object that doesn't respond to #write" do obj = mock('object') - -> { $stdout = obj }.should raise_error(TypeError) + -> { $stdout = obj }.should.raise(TypeError) obj.stub!(:write) $stdout = obj - $stdout.should equal(obj) + $stdout.should.equal?(obj) end end @@ -253,6 +306,12 @@ describe "Predefined global $!" do $!.should == nil end + it "is read-only" do + -> { + $! = [] + }.should.raise(NameError, '$! is a read-only variable') + end + # See http://jira.codehaus.org/browse/JRUBY-5550 it "remains nil after a failed core class \"checked\" coercion against a class that defines method_missing" do $!.should == nil @@ -512,6 +571,75 @@ describe "Predefined global $!" do end end +describe "Predefined global $@" do + it "is Fiber-local" do + Fiber.new do + raise "hi" + rescue + Fiber.yield + end.resume + + $@.should == nil + end + + it "is set to a backtrace of a rescued exception" do + begin + raise + rescue + $@.should.instance_of?(Array) + $@.should == $!.backtrace + end + end + + it "is cleared when an exception is rescued" do + begin + raise + rescue + end + + $@.should == nil + end + + it "is not set when there is no current exception" do + $@.should == nil + end + + it "is set to a backtrace of a rescued exception" do + begin + raise + rescue + $@.should.instance_of?(Array) + $@.should == $!.backtrace + end + end + + it "is not read-only" do + begin + raise + rescue + $@ = [] + $@.should == [] + end + end + + it_behaves_like :exception_set_backtrace, -> backtrace { + exception = nil + begin + raise + rescue + $@ = backtrace + exception = $! + end + exception + } + + it "cannot be assigned when there is no a rescued exception" do + -> { + $@ = [] + }.should.raise(ArgumentError, '$! not set') + end +end + # Input/Output Variables # --------------------------------------------------------------------------------------------------- # @@ -559,22 +687,22 @@ describe "Predefined global $/" do $VERBOSE = @verbose end - ruby_version_is ""..."3.5" do + ruby_version_is ""..."4.0" do it "can be assigned a String" do str = +"abc" $/ = str - $/.should equal(str) + $/.should.equal?(str) end end - ruby_version_is "3.5" do + ruby_version_is "4.0" do it "makes a new frozen String from the assigned String" do string_subclass = Class.new(String) str = string_subclass.new("abc") str.instance_variable_set(:@ivar, 1) $/ = str $/.should.frozen? - $/.should be_an_instance_of(String) + $/.should.instance_of?(String) $/.should_not.instance_variable_defined?(:@ivar) $/.should == str end @@ -589,12 +717,13 @@ describe "Predefined global $/" do it "assigns the given String if it's frozen and has no instance variables" do str = "abc".freeze $/ = str - $/.should equal(str) + $/.should.equal?(str) end end + it "can be assigned nil" do $/ = nil - $/.should be_nil + $/.should == nil end it "returns the value assigned" do @@ -603,22 +732,26 @@ describe "Predefined global $/" do it "changes $-0" do $/ = "xyz" - $-0.should equal($/) + $-0.should.equal?($/) end it "does not call #to_str to convert the object to a String" do obj = mock("$/ value") obj.should_not_receive(:to_str) - -> { $/ = obj }.should raise_error(TypeError) + -> { $/ = obj }.should.raise(TypeError, 'value of $/ must be String') end it "raises a TypeError if assigned an Integer" do - -> { $/ = 1 }.should raise_error(TypeError) + -> { $/ = 1 }.should.raise(TypeError, 'value of $/ must be String') end it "raises a TypeError if assigned a boolean" do - -> { $/ = true }.should raise_error(TypeError) + -> { $/ = true }.should.raise(TypeError, 'value of $/ must be String') + end + + it "warns if assigned non-nil" do + -> { $/ = "_" }.should complain(/warning: (?:non-nil )?[`']\$\/' is deprecated/) end end @@ -635,22 +768,22 @@ describe "Predefined global $-0" do $VERBOSE = @verbose end - ruby_version_is ""..."3.5" do + ruby_version_is ""..."4.0" do it "can be assigned a String" do str = +"abc" $-0 = str - $-0.should equal(str) + $-0.should.equal?(str) end end - ruby_version_is "3.5" do + ruby_version_is "4.0" do it "makes a new frozen String from the assigned String" do string_subclass = Class.new(String) str = string_subclass.new("abc") str.instance_variable_set(:@ivar, 1) $-0 = str $-0.should.frozen? - $-0.should be_an_instance_of(String) + $-0.should.instance_of?(String) $-0.should_not.instance_variable_defined?(:@ivar) $-0.should == str end @@ -665,13 +798,13 @@ describe "Predefined global $-0" do it "assigns the given String if it's frozen and has no instance variables" do str = "abc".freeze $-0 = str - $-0.should equal(str) + $-0.should.equal?(str) end end it "can be assigned nil" do $-0 = nil - $-0.should be_nil + $-0.should == nil end it "returns the value assigned" do @@ -680,22 +813,26 @@ describe "Predefined global $-0" do it "changes $/" do $-0 = "xyz" - $/.should equal($-0) + $/.should.equal?($-0) end it "does not call #to_str to convert the object to a String" do obj = mock("$-0 value") obj.should_not_receive(:to_str) - -> { $-0 = obj }.should raise_error(TypeError) + -> { $-0 = obj }.should.raise(TypeError, 'value of $-0 must be String') end it "raises a TypeError if assigned an Integer" do - -> { $-0 = 1 }.should raise_error(TypeError) + -> { $-0 = 1 }.should.raise(TypeError, 'value of $-0 must be String') end it "raises a TypeError if assigned a boolean" do - -> { $-0 = true }.should raise_error(TypeError) + -> { $-0 = true }.should.raise(TypeError, 'value of $-0 must be String') + end + + it "warns if assigned non-nil" do + -> { $-0 = "_" }.should complain(/warning: (?:non-nil )?[`']\$-0' is deprecated/) end end @@ -713,12 +850,12 @@ describe "Predefined global $\\" do it "can be assigned a String" do str = "abc" $\ = str - $\.should equal(str) + $\.should.equal?(str) end it "can be assigned nil" do $\ = nil - $\.should be_nil + $\.should == nil end it "returns the value assigned" do @@ -729,12 +866,16 @@ describe "Predefined global $\\" do obj = mock("$\\ value") obj.should_not_receive(:to_str) - -> { $\ = obj }.should raise_error(TypeError) + -> { $\ = obj }.should.raise(TypeError, 'value of $\ must be String') end it "raises a TypeError if assigned not String" do - -> { $\ = 1 }.should raise_error(TypeError) - -> { $\ = true }.should raise_error(TypeError) + -> { $\ = 1 }.should.raise(TypeError, 'value of $\ must be String') + -> { $\ = true }.should.raise(TypeError, 'value of $\ must be String') + end + + it "warns if assigned non-nil" do + -> { $\ = "_" }.should complain(/warning: (?:non-nil )?[`']\$\\' is deprecated/) end end @@ -744,15 +885,15 @@ describe "Predefined global $," do end it "defaults to nil" do - $,.should be_nil + $,.should == nil end it "raises TypeError if assigned a non-String" do - -> { $, = Object.new }.should raise_error(TypeError) + -> { $, = Object.new }.should.raise(TypeError, 'value of $, must be String') end it "warns if assigned non-nil" do - -> { $, = "_" }.should complain(/warning: [`']\$,' is deprecated/) + -> { $, = "_" }.should complain(/warning: (?:non-nil )?[`']\$,' is deprecated/) end end @@ -779,7 +920,7 @@ describe "Predefined global $." do obj = mock("bad-value") obj.should_receive(:to_int).and_return('abc') - -> { $. = obj }.should raise_error(TypeError) + -> { $. = obj }.should.raise(TypeError) end end @@ -789,7 +930,7 @@ describe "Predefined global $;" do end it "warns if assigned non-nil" do - -> { $; = "_" }.should complain(/warning: [`']\$;' is deprecated/) + -> { $; = "_" }.should complain(/warning: (?:non-nil )?[`']\$;' is deprecated/) end end @@ -844,7 +985,7 @@ describe "Predefined global $_" do end Thread.pass until running - $_.should be_nil + $_.should == nil thr.join end @@ -915,7 +1056,7 @@ describe "Execution variable $:" do end it "does not include the current directory" do - $:.should_not include(".") + $:.should_not.include?(".") end it "is the same object as $LOAD_PATH and $-I" do @@ -925,7 +1066,7 @@ describe "Execution variable $:" do it "can be changed via <<" do $: << "foo" - $:.should include("foo") + $:.should.include?("foo") ensure $:.delete("foo") end @@ -933,41 +1074,47 @@ describe "Execution variable $:" do it "is read-only" do -> { $: = [] - }.should raise_error(NameError) + }.should.raise(NameError, '$: is a read-only variable') -> { $LOAD_PATH = [] - }.should raise_error(NameError) + }.should.raise(NameError, '$LOAD_PATH is a read-only variable') -> { $-I = [] - }.should raise_error(NameError) + }.should.raise(NameError, '$-I is a read-only variable') end it "default $LOAD_PATH entries until sitelibdir included have @gem_prelude_index set" do skip "no sense in ruby itself" if MSpecScript.instance_variable_defined?(:@testing_ruby) - $:.should.include?(RbConfig::CONFIG['sitelibdir']) - idx = $:.index(RbConfig::CONFIG['sitelibdir']) + if platform_is :windows + # See https://github.com/ruby/setup-ruby/pull/762#issuecomment-2917460440 + $:.should.find { |e| File.realdirpath(e) == RbConfig::CONFIG['sitelibdir'] } + idx = $:.index { |e| File.realdirpath(e) == RbConfig::CONFIG['sitelibdir'] } + else + $:.should.include?(RbConfig::CONFIG['sitelibdir']) + idx = $:.index(RbConfig::CONFIG['sitelibdir']) + end - $:[idx..-1].all? { |p| p.instance_variable_defined?(:@gem_prelude_index) }.should be_true - $:[0...idx].all? { |p| !p.instance_variable_defined?(:@gem_prelude_index) }.should be_true + $:[idx..-1].all? { |p| p.instance_variable_defined?(:@gem_prelude_index) }.should == true + $:[0...idx].all? { |p| !p.instance_variable_defined?(:@gem_prelude_index) }.should == true end end describe "Global variable $\"" do it "is an alias for $LOADED_FEATURES" do - $".should equal $LOADED_FEATURES + $".should.equal? $LOADED_FEATURES end it "is read-only" do -> { $" = [] - }.should raise_error(NameError) + }.should.raise(NameError, '$" is a read-only variable') -> { $LOADED_FEATURES = [] - }.should raise_error(NameError) + }.should.raise(NameError, '$LOADED_FEATURES is a read-only variable') end end @@ -975,7 +1122,7 @@ describe "Global variable $<" do it "is read-only" do -> { $< = nil - }.should raise_error(NameError) + }.should.raise(NameError, '$< is a read-only variable') end end @@ -983,7 +1130,7 @@ describe "Global variable $FILENAME" do it "is read-only" do -> { $FILENAME = "-" - }.should raise_error(NameError) + }.should.raise(NameError, '$FILENAME is a read-only variable') end end @@ -991,30 +1138,30 @@ describe "Global variable $?" do it "is read-only" do -> { $? = nil - }.should raise_error(NameError) + }.should.raise(NameError, '$? is a read-only variable') end it "is thread-local" do system(ruby_cmd('exit 0')) - Thread.new { $?.should be_nil }.join + Thread.new { $?.should == nil }.join end end describe "Global variable $-a" do it "is read-only" do - -> { $-a = true }.should raise_error(NameError) + -> { $-a = true }.should.raise(NameError, '$-a is a read-only variable') end end describe "Global variable $-l" do it "is read-only" do - -> { $-l = true }.should raise_error(NameError) + -> { $-l = true }.should.raise(NameError, '$-l is a read-only variable') end end describe "Global variable $-p" do it "is read-only" do - -> { $-p = true }.should raise_error(NameError) + -> { $-p = true }.should.raise(NameError, '$-p is a read-only variable') end end @@ -1029,9 +1176,9 @@ describe "Global variable $-d" do it "is an alias of $DEBUG" do $DEBUG = true - $-d.should be_true + $-d.should == true $-d = false - $DEBUG.should be_false + $DEBUG.should == false end end @@ -1045,24 +1192,24 @@ describe "Global variable $VERBOSE" do end it "is false by default" do - $VERBOSE.should be_false + $VERBOSE.should == false end it "converts truthy values to true" do [true, 1, 0, [], ""].each do |true_value| $VERBOSE = true_value - $VERBOSE.should be_true + $VERBOSE.should == true end end it "allows false" do $VERBOSE = false - $VERBOSE.should be_false + $VERBOSE.should == false end it "allows nil without coercing to false" do $VERBOSE = nil - $VERBOSE.should be_nil + $VERBOSE.should == nil end end @@ -1077,9 +1224,9 @@ describe :verbose_global_alias, shared: true do it "is an alias of $VERBOSE" do $VERBOSE = true - eval(@method).should be_true + eval(@method).should == true eval("#{@method} = false") - $VERBOSE.should be_false + $VERBOSE.should == false end end @@ -1116,7 +1263,7 @@ describe "Global variable $0" do it "actually sets the program name" do title = "rubyspec-dollar0-test" $0 = title - `ps -ocommand= -p#{$$}`.should include(title) + `ps -ocommand= -p#{$$}`.should.include?(title) end end @@ -1125,7 +1272,7 @@ describe "Global variable $0" do end it "raises a TypeError when not given an object that can be coerced to a String" do - -> { $0 = nil }.should raise_error(TypeError) + -> { $0 = nil }.should.raise(TypeError) end end @@ -1161,37 +1308,37 @@ end describe "The predefined standard object nil" do it "is an instance of NilClass" do - nil.should be_kind_of(NilClass) + nil.should.is_a?(NilClass) end it "raises a SyntaxError if assigned to" do - -> { eval("nil = true") }.should raise_error(SyntaxError) + -> { eval("nil = true") }.should.raise(SyntaxError, /Can't assign to nil/) end end describe "The predefined standard object true" do it "is an instance of TrueClass" do - true.should be_kind_of(TrueClass) + true.should.is_a?(TrueClass) end it "raises a SyntaxError if assigned to" do - -> { eval("true = false") }.should raise_error(SyntaxError) + -> { eval("true = false") }.should.raise(SyntaxError, /Can't assign to true/) end end describe "The predefined standard object false" do it "is an instance of FalseClass" do - false.should be_kind_of(FalseClass) + false.should.is_a?(FalseClass) end it "raises a SyntaxError if assigned to" do - -> { eval("false = nil") }.should raise_error(SyntaxError) + -> { eval("false = nil") }.should.raise(SyntaxError, /Can't assign to false/) end end describe "The self pseudo-variable" do it "raises a SyntaxError if assigned to" do - -> { eval("self = 1") }.should raise_error(SyntaxError) + -> { eval("self = 1") }.should.raise(SyntaxError, /Can't change the value of self/) end end @@ -1286,21 +1433,21 @@ describe "The predefined global constant" do describe "STDIN" do platform_is_not :windows do it "has the same external encoding as Encoding.default_external" do - STDIN.external_encoding.should equal(Encoding.default_external) + STDIN.external_encoding.should.equal?(Encoding.default_external) end it "has the same external encoding as Encoding.default_external when that encoding is changed" do Encoding.default_external = Encoding::ISO_8859_16 - STDIN.external_encoding.should equal(Encoding::ISO_8859_16) + STDIN.external_encoding.should.equal?(Encoding::ISO_8859_16) end it "has nil for the internal encoding" do - STDIN.internal_encoding.should be_nil + STDIN.internal_encoding.should == nil end it "has nil for the internal encoding despite Encoding.default_internal being changed" do Encoding.default_internal = Encoding::IBM437 - STDIN.internal_encoding.should be_nil + STDIN.internal_encoding.should == nil end end @@ -1320,12 +1467,12 @@ describe "The predefined global constant" do describe "STDOUT" do it "has nil for the external encoding" do - STDOUT.external_encoding.should be_nil + STDOUT.external_encoding.should == nil end it "has nil for the external encoding despite Encoding.default_external being changed" do Encoding.default_external = Encoding::ISO_8859_1 - STDOUT.external_encoding.should be_nil + STDOUT.external_encoding.should == nil end it "has the encodings set by #set_encoding" do @@ -1335,23 +1482,23 @@ describe "The predefined global constant" do end it "has nil for the internal encoding" do - STDOUT.internal_encoding.should be_nil + STDOUT.internal_encoding.should == nil end it "has nil for the internal encoding despite Encoding.default_internal being changed" do Encoding.default_internal = Encoding::IBM437 - STDOUT.internal_encoding.should be_nil + STDOUT.internal_encoding.should == nil end end describe "STDERR" do it "has nil for the external encoding" do - STDERR.external_encoding.should be_nil + STDERR.external_encoding.should == nil end it "has nil for the external encoding despite Encoding.default_external being changed" do Encoding.default_external = Encoding::ISO_8859_1 - STDERR.external_encoding.should be_nil + STDERR.external_encoding.should == nil end it "has the encodings set by #set_encoding" do @@ -1361,12 +1508,12 @@ describe "The predefined global constant" do end it "has nil for the internal encoding" do - STDERR.internal_encoding.should be_nil + STDERR.internal_encoding.should == nil end it "has nil for the internal encoding despite Encoding.default_internal being changed" do Encoding.default_internal = Encoding::IBM437 - STDERR.internal_encoding.should be_nil + STDERR.internal_encoding.should == nil end end @@ -1382,9 +1529,9 @@ end describe "$LOAD_PATH.resolve_feature_path" do it "returns what will be loaded without actual loading, .rb file" do - extension, path = $LOAD_PATH.resolve_feature_path('set') + extension, path = $LOAD_PATH.resolve_feature_path('pp') extension.should == :rb - path.should.end_with?('/set.rb') + path.should.end_with?('/pp.rb') end it "returns what will be loaded without actual loading, .so file" do @@ -1397,7 +1544,7 @@ describe "$LOAD_PATH.resolve_feature_path" do end it "return nil if feature cannot be found" do - $LOAD_PATH.resolve_feature_path('noop').should be_nil + $LOAD_PATH.resolve_feature_path('noop').should == nil end end diff --git a/spec/ruby/language/private_spec.rb b/spec/ruby/language/private_spec.rb index b04aa25c9e..94b56fee5b 100644 --- a/spec/ruby/language/private_spec.rb +++ b/spec/ruby/language/private_spec.rb @@ -4,12 +4,12 @@ require_relative 'fixtures/private' describe "The private keyword" do it "marks following methods as being private" do a = Private::A.new - a.methods.should_not include(:bar) - -> { a.bar }.should raise_error(NoMethodError) + a.methods.should_not.include?(:bar) + -> { a.bar }.should.raise(NoMethodError) b = Private::B.new - b.methods.should_not include(:bar) - -> { b.bar }.should raise_error(NoMethodError) + b.methods.should_not.include?(:bar) + -> { b.bar }.should.raise(NoMethodError) end # def expr.meth() methods are always public @@ -19,15 +19,15 @@ describe "The private keyword" do it "is overridden when a new class is opened" do c = Private::B::C.new - c.methods.should include(:baz) + c.methods.should.include?(:baz) c.baz Private::B.public_class_method1.should == 1 - -> { Private::B.private_class_method1 }.should raise_error(NoMethodError) + -> { Private::B.private_class_method1 }.should.raise(NoMethodError) end it "is no longer in effect when the class is closed" do b = Private::B.new - b.methods.should include(:foo) + b.methods.should.include?(:foo) b.foo end @@ -42,7 +42,7 @@ describe "The private keyword" do klass.class_eval do private :foo end - -> { f.foo }.should raise_error(NoMethodError) + -> { f.foo }.should.raise(NoMethodError) end it "changes visibility of previously called methods with same send/call site" do @@ -56,12 +56,12 @@ describe "The private keyword" do end end end - }.should raise_error(NoMethodError) + }.should.raise(NoMethodError) end it "changes the visibility of the existing method in the subclass" do ::Private::A.new.foo.should == 'foo' - -> { ::Private::H.new.foo }.should raise_error(NoMethodError) + -> { ::Private::H.new.foo }.should.raise(NoMethodError) ::Private::H.new.send(:foo).should == 'foo' end end diff --git a/spec/ruby/language/proc_spec.rb b/spec/ruby/language/proc_spec.rb index ca9a13aa61..53a21d6b85 100644 --- a/spec/ruby/language/proc_spec.rb +++ b/spec/ruby/language/proc_spec.rb @@ -22,7 +22,7 @@ describe "A Proc" do end it "raises an ArgumentError if a value is passed" do - lambda { @l.call(0) }.should raise_error(ArgumentError) + lambda { @l.call(0) }.should.raise(ArgumentError) end end @@ -36,7 +36,7 @@ describe "A Proc" do end it "raises an ArgumentError if a value is passed" do - lambda { @l.call(0) }.should raise_error(ArgumentError) + lambda { @l.call(0) }.should.raise(ArgumentError) end end @@ -57,11 +57,11 @@ describe "A Proc" do obj = mock("block yield to_ary") obj.should_not_receive(:to_ary) - @l.call(obj).should equal(obj) + @l.call(obj).should.equal?(obj) end it "raises an ArgumentError if no value is passed" do - lambda { @l.call }.should raise_error(ArgumentError) + lambda { @l.call }.should.raise(ArgumentError) end end @@ -71,11 +71,11 @@ describe "A Proc" do end it "raises an ArgumentError if passed no values" do - lambda { @l.call }.should raise_error(ArgumentError) + lambda { @l.call }.should.raise(ArgumentError) end it "raises an ArgumentError if passed one value" do - lambda { @l.call(0) }.should raise_error(ArgumentError) + lambda { @l.call(0) }.should.raise(ArgumentError) end it "assigns the values passed to the arguments" do @@ -86,7 +86,7 @@ describe "A Proc" do obj = mock("proc call to_ary") obj.should_not_receive(:to_ary) - lambda { @l.call(obj) }.should raise_error(ArgumentError) + lambda { @l.call(obj) }.should.raise(ArgumentError) end end @@ -96,7 +96,7 @@ describe "A Proc" do end it "raises an ArgumentError if passed no values" do - lambda { @l.call }.should raise_error(ArgumentError) + lambda { @l.call }.should.raise(ArgumentError) end it "does not destructure a single Array value yielded" do @@ -179,11 +179,11 @@ describe "A Proc" do end it "raises an ArgumentError when passed no values" do - lambda { @l.call }.should raise_error(ArgumentError) + lambda { @l.call }.should.raise(ArgumentError) end it "raises an ArgumentError when passed more than one value" do - lambda { @l.call(1, 2) }.should raise_error(ArgumentError) + lambda { @l.call(1, 2) }.should.raise(ArgumentError) end it "assigns the argument the value passed" do @@ -208,7 +208,7 @@ describe "A Proc" do end it "raises an ArgumentError when passed no values" do - lambda { @l.call }.should raise_error(ArgumentError) + lambda { @l.call }.should.raise(ArgumentError) end it "destructures a single Array value yielded" do @@ -226,7 +226,7 @@ describe "A Proc" do obj = mock("block yield to_ary invalid") obj.should_receive(:to_ary).and_return(1) - lambda { @l.call(obj) }.should raise_error(TypeError) + lambda { @l.call(obj) }.should.raise(TypeError) end end @@ -243,7 +243,25 @@ describe "A Proc" do describe "taking |required keyword arguments, **kw| arguments" do it "raises ArgumentError for missing required argument" do p = proc { |a:, **kw| [a, kw] } - -> { p.call() }.should raise_error(ArgumentError) + -> { p.call() }.should.raise(ArgumentError) end end + + evaluate <<-ruby do + @p = proc { |**nil| :ok } + ruby + + @p.call().should == :ok + -> { @p.call(a: 1) }.should.raise(ArgumentError, 'no keywords accepted') + -> { @p.call(**{a: 1}) }.should.raise(ArgumentError, 'no keywords accepted') + -> { @p.call("a" => 1) }.should.raise(ArgumentError, 'no keywords accepted') + end + + evaluate <<-ruby do + @p = proc { |a, **nil| a } + ruby + + @p.call({a: 1}).should == {a: 1} + -> { @p.call(a: 1) }.should.raise(ArgumentError, 'no keywords accepted') + end end diff --git a/spec/ruby/language/redo_spec.rb b/spec/ruby/language/redo_spec.rb index 57532553b3..9b14c5add1 100644 --- a/spec/ruby/language/redo_spec.rb +++ b/spec/ruby/language/redo_spec.rb @@ -60,7 +60,7 @@ describe "The redo statement" do it "is invalid and raises a SyntaxError" do -> { eval("def m; redo; end") - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end end end diff --git a/spec/ruby/language/regexp/anchors_spec.rb b/spec/ruby/language/regexp/anchors_spec.rb index cdc06c0b4d..8e597b65e8 100644 --- a/spec/ruby/language/regexp/anchors_spec.rb +++ b/spec/ruby/language/regexp/anchors_spec.rb @@ -7,8 +7,8 @@ describe "Regexps with anchors" do /^foo/.match("foo").to_a.should == ["foo"] /^bar/.match("foo\nbar").to_a.should == ["bar"] # Basic non-matching - /^foo/.match(" foo").should be_nil - /foo^/.match("foo\n\n\n").should be_nil + /^foo/.match(" foo").should == nil + /foo^/.match("foo\n\n\n").should == nil # A bit advanced /^^^foo/.match("foo").to_a.should == ["foo"] @@ -16,8 +16,8 @@ describe "Regexps with anchors" do (/($^)($^)/ =~ "foo\n\n").should == "foo\n".size and $~.to_a.should == ["", "", ""] # Different start of line chars - /^bar/.match("foo\rbar").should be_nil - /^bar/.match("foo\0bar").should be_nil + /^bar/.match("foo\rbar").should == nil + /^bar/.match("foo\0bar").should == nil # Trivial /^/.match("foo").to_a.should == [""] @@ -29,7 +29,7 @@ describe "Regexps with anchors" do end it "does not match ^ after trailing \\n" do - /^(?!\A)/.match("foo\n").should be_nil # There is no (empty) line after a trailing \n + /^(?!\A)/.match("foo\n").should == nil # There is no (empty) line after a trailing \n end it "supports $ (line end anchor)" do @@ -37,16 +37,16 @@ describe "Regexps with anchors" do /foo$/.match("foo").to_a.should == ["foo"] /foo$/.match("foo\nbar").to_a.should == ["foo"] # Basic non-matching - /foo$/.match("foo ").should be_nil - /$foo/.match("\n\n\nfoo").should be_nil + /foo$/.match("foo ").should == nil + /$foo/.match("\n\n\nfoo").should == nil # A bit advanced /foo$$$/.match("foo").to_a.should == ["foo"] (/[^o]$/ =~ "foo\n\n").should == ("foo\n".size - 1) and $~.to_a.should == ["\n"] # Different end of line chars - /foo$/.match("foo\r\nbar").should be_nil - /foo$/.match("foo\0bar").should be_nil + /foo$/.match("foo\r\nbar").should == nil + /foo$/.match("foo\0bar").should == nil # Trivial (/$/ =~ "foo").should == "foo".size and $~.to_a.should == [""] @@ -61,15 +61,15 @@ describe "Regexps with anchors" do # Basic matching /\Afoo/.match("foo").to_a.should == ["foo"] # Basic non-matching - /\Abar/.match("foo\nbar").should be_nil - /\Afoo/.match(" foo").should be_nil + /\Abar/.match("foo\nbar").should == nil + /\Afoo/.match(" foo").should == nil # A bit advanced /\A\A\Afoo/.match("foo").to_a.should == ["foo"] /(\A\Z)(\A\Z)/.match("").to_a.should == ["", "", ""] # Different start of line chars - /\Abar/.match("foo\0bar").should be_nil + /\Abar/.match("foo\0bar").should == nil # Grouping /(\Afoo)/.match("foo").to_a.should == ["foo", "foo"] @@ -81,8 +81,8 @@ describe "Regexps with anchors" do /foo\Z/.match("foo").to_a.should == ["foo"] /foo\Z/.match("foo\n").to_a.should == ["foo"] # Basic non-matching - /foo\Z/.match("foo\nbar").should be_nil - /foo\Z/.match("foo ").should be_nil + /foo\Z/.match("foo\nbar").should == nil + /foo\Z/.match("foo ").should == nil # A bit advanced /foo\Z\Z\Z/.match("foo\n").to_a.should == ["foo"] @@ -90,8 +90,8 @@ describe "Regexps with anchors" do (/(\z\Z)(\z\Z)/ =~ "foo\n").should == "foo\n".size and $~.to_a.should == ["", "", ""] # Different end of line chars - /foo\Z/.match("foo\0bar").should be_nil - /foo\Z/.match("foo\r\n").should be_nil + /foo\Z/.match("foo\0bar").should == nil + /foo\Z/.match("foo\r\n").should == nil # Grouping /(foo\Z)/.match("foo").to_a.should == ["foo", "foo"] @@ -102,17 +102,17 @@ describe "Regexps with anchors" do # Basic matching /foo\z/.match("foo").to_a.should == ["foo"] # Basic non-matching - /foo\z/.match("foo\nbar").should be_nil - /foo\z/.match("foo\n").should be_nil - /foo\z/.match("foo ").should be_nil + /foo\z/.match("foo\nbar").should == nil + /foo\z/.match("foo\n").should == nil + /foo\z/.match("foo ").should == nil # A bit advanced /foo\z\z\z/.match("foo").to_a.should == ["foo"] (/($\z)($\z)/ =~ "foo").should == "foo".size and $~.to_a.should == ["", "", ""] # Different end of line chars - /foo\z/.match("foo\0bar").should be_nil - /foo\z/.match("foo\r\nbar").should be_nil + /foo\z/.match("foo\0bar").should == nil + /foo\z/.match("foo\r\nbar").should == nil # Grouping /(foo\z)/.match("foo").to_a.should == ["foo", "foo"] @@ -131,9 +131,9 @@ describe "Regexps with anchors" do end /foo\b/.match("foo\0").to_a.should == ["foo"] # Basic non-matching - /foo\b/.match("foobar").should be_nil - /foo\b/.match("foo123").should be_nil - /foo\b/.match("foo_").should be_nil + /foo\b/.match("foobar").should == nil + /foo\b/.match("foo123").should == nil + /foo\b/.match("foo_").should == nil end it "supports \\B (non-word-boundary)" do @@ -142,15 +142,15 @@ describe "Regexps with anchors" do /foo\B/.match("foo123").to_a.should == ["foo"] /foo\B/.match("foo_").to_a.should == ["foo"] # Basic non-matching - /foo\B/.match("foo").should be_nil - /foo\B/.match("foo\n").should be_nil + /foo\B/.match("foo").should == nil + /foo\B/.match("foo\n").should == nil LanguageSpecs.white_spaces.scan(/./).each do |c| - /foo\B/.match("foo" + c).should be_nil + /foo\B/.match("foo" + c).should == nil end LanguageSpecs.non_alphanum_non_space.scan(/./).each do |c| - /foo\B/.match("foo" + c).should be_nil + /foo\B/.match("foo" + c).should == nil end - /foo\B/.match("foo\0").should be_nil + /foo\B/.match("foo\0").should == nil end it "supports (?= ) (positive lookahead)" do diff --git a/spec/ruby/language/regexp/back-references_spec.rb b/spec/ruby/language/regexp/back-references_spec.rb index 627c8daace..3b4c5656a2 100644 --- a/spec/ruby/language/regexp/back-references_spec.rb +++ b/spec/ruby/language/regexp/back-references_spec.rb @@ -49,7 +49,7 @@ describe "Regexps with back-references" do it "supports \<n> (backreference to previous group match)" do /(foo.)\1/.match("foo1foo1").to_a.should == ["foo1foo1", "foo1"] - /(foo.)\1/.match("foo1foo2").should be_nil + /(foo.)\1/.match("foo1foo2").should == nil end it "resets nested \<n> backreference before match of outer subexpression" do @@ -82,7 +82,7 @@ describe "Regexps with back-references" do end it "0 is not a valid backreference" do - -> { Regexp.new("\\k<0>") }.should raise_error(RegexpError) + -> { Regexp.new("\\k<0>") }.should.raise(RegexpError) end it "allows numeric conditional backreferences" do @@ -92,7 +92,7 @@ describe "Regexps with back-references" do end it "allows either <> or '' in named conditional backreferences" do - -> { Regexp.new("(?<a>a)(?(a)a|b)") }.should raise_error(RegexpError) + -> { Regexp.new("(?<a>a)(?(a)a|b)") }.should.raise(RegexpError) /(?<a>a)(?(<a>)a|b)/.match("aa").to_a.should == [ "aa", "a" ] /(?<a>a)(?('a')a|b)/.match("aa").to_a.should == [ "aa", "a" ] end @@ -118,32 +118,32 @@ describe "Regexps with back-references" do end it "named capture groups invalidate numeric backreferences" do - -> { Regexp.new("(?<a>a)\\1") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a>a)\\k<1>") }.should raise_error(RegexpError) - -> { Regexp.new("(a)(?<a>a)\\1") }.should raise_error(RegexpError) - -> { Regexp.new("(a)(?<a>a)\\k<1>") }.should raise_error(RegexpError) + -> { Regexp.new("(?<a>a)\\1") }.should.raise(RegexpError) + -> { Regexp.new("(?<a>a)\\k<1>") }.should.raise(RegexpError) + -> { Regexp.new("(a)(?<a>a)\\1") }.should.raise(RegexpError) + -> { Regexp.new("(a)(?<a>a)\\k<1>") }.should.raise(RegexpError) end it "treats + or - as the beginning of a level specifier in \\k<> backreferences and (?(...)...|...) conditional backreferences" do - -> { Regexp.new("(?<a+>a)\\k<a+>") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a+b>a)\\k<a+b>") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a+1>a)\\k<a+1>") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a->a)\\k<a->") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a-b>a)\\k<a-b>") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a-1>a)\\k<a-1>") }.should raise_error(RegexpError) - - -> { Regexp.new("(?<a+>a)(?(<a+>)a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a+b>a)(?(<a+b>)a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a+1>a)(?(<a+1>)a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a->a)(?(<a->)a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a-b>a)(?(<a-b>)a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a-1>a)(?(<a-1>)a|b)") }.should raise_error(RegexpError) - - -> { Regexp.new("(?<a+>a)(?('a+')a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a+b>a)(?('a+b')a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a+1>a)(?('a+1')a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a->a)(?('a-')a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a-b>a)(?('a-b')a|b)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<a-1>a)(?('a-1')a|b)") }.should raise_error(RegexpError) + -> { Regexp.new("(?<a+>a)\\k<a+>") }.should.raise(RegexpError) + -> { Regexp.new("(?<a+b>a)\\k<a+b>") }.should.raise(RegexpError) + -> { Regexp.new("(?<a+1>a)\\k<a+1>") }.should.raise(RegexpError) + -> { Regexp.new("(?<a->a)\\k<a->") }.should.raise(RegexpError) + -> { Regexp.new("(?<a-b>a)\\k<a-b>") }.should.raise(RegexpError) + -> { Regexp.new("(?<a-1>a)\\k<a-1>") }.should.raise(RegexpError) + + -> { Regexp.new("(?<a+>a)(?(<a+>)a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a+b>a)(?(<a+b>)a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a+1>a)(?(<a+1>)a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a->a)(?(<a->)a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a-b>a)(?(<a-b>)a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a-1>a)(?(<a-1>)a|b)") }.should.raise(RegexpError) + + -> { Regexp.new("(?<a+>a)(?('a+')a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a+b>a)(?('a+b')a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a+1>a)(?('a+1')a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a->a)(?('a-')a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a-b>a)(?('a-b')a|b)") }.should.raise(RegexpError) + -> { Regexp.new("(?<a-1>a)(?('a-1')a|b)") }.should.raise(RegexpError) end end diff --git a/spec/ruby/language/regexp/character_classes_spec.rb b/spec/ruby/language/regexp/character_classes_spec.rb index 8e9a0b960b..c6ed92b78e 100644 --- a/spec/ruby/language/regexp/character_classes_spec.rb +++ b/spec/ruby/language/regexp/character_classes_spec.rb @@ -9,9 +9,9 @@ describe "Regexp with character classes" do /\w/.match("_").to_a.should == ["_"] # Non-matches - /\w/.match(LanguageSpecs.white_spaces).should be_nil - /\w/.match(LanguageSpecs.non_alphanum_non_space).should be_nil - /\w/.match("\0").should be_nil + /\w/.match(LanguageSpecs.white_spaces).should == nil + /\w/.match(LanguageSpecs.non_alphanum_non_space).should == nil + /\w/.match("\0").should == nil end it "supports \\W (non-word character)" do @@ -20,19 +20,19 @@ describe "Regexp with character classes" do /\W/.match("\0").to_a.should == ["\0"] # Non-matches - /\W/.match("a").should be_nil - /\W/.match("1").should be_nil - /\W/.match("_").should be_nil + /\W/.match("a").should == nil + /\W/.match("1").should == nil + /\W/.match("_").should == nil end it "supports \\s (space character)" do /\s+/.match(LanguageSpecs.white_spaces).to_a.should == [LanguageSpecs.white_spaces] # Non-matches - /\s/.match("a").should be_nil - /\s/.match("1").should be_nil - /\s/.match(LanguageSpecs.non_alphanum_non_space).should be_nil - /\s/.match("\0").should be_nil + /\s/.match("a").should == nil + /\s/.match("1").should == nil + /\s/.match(LanguageSpecs.non_alphanum_non_space).should == nil + /\s/.match("\0").should == nil end it "supports \\S (non-space character)" do @@ -42,17 +42,17 @@ describe "Regexp with character classes" do /\S/.match("\0").to_a.should == ["\0"] # Non-matches - /\S/.match(LanguageSpecs.white_spaces).should be_nil + /\S/.match(LanguageSpecs.white_spaces).should == nil end it "supports \\d (numeric digit)" do /\d/.match("1").to_a.should == ["1"] # Non-matches - /\d/.match("a").should be_nil - /\d/.match(LanguageSpecs.white_spaces).should be_nil - /\d/.match(LanguageSpecs.non_alphanum_non_space).should be_nil - /\d/.match("\0").should be_nil + /\d/.match("a").should == nil + /\d/.match(LanguageSpecs.white_spaces).should == nil + /\d/.match(LanguageSpecs.non_alphanum_non_space).should == nil + /\d/.match("\0").should == nil end it "supports \\D (non-digit)" do @@ -62,7 +62,7 @@ describe "Regexp with character classes" do /\D/.match("\0").to_a.should == ["\0"] # Non-matches - /\D/.match("1").should be_nil + /\D/.match("1").should == nil end it "supports [] (character class)" do @@ -89,7 +89,7 @@ describe "Regexp with character classes" do /[^[:lower:]A-C]+/.match("abcABCDEF123def").to_a.should == ["DEF123"] # negated character class /[:alnum:]+/.match("a:l:n:u:m").to_a.should == ["a:l:n:u:m"] # should behave like regular character class composed of the individual letters /[\[:alnum:]+/.match("[:a:l:n:u:m").to_a.should == ["[:a:l:n:u:m"] # should behave like regular character class composed of the individual letters - -> { eval('/[[:alpha:]-[:digit:]]/') }.should raise_error(SyntaxError) # can't use character class as a start value of range + -> { eval('/[[:alpha:]-[:digit:]]/') }.should.raise(SyntaxError) # can't use character class as a start value of range end it "matches ASCII characters with [[:ascii:]]" do @@ -99,8 +99,8 @@ describe "Regexp with character classes" do not_supported_on :opal do it "doesn't match non-ASCII characters with [[:ascii:]]" do - /[[:ascii:]]/.match("\u{80}").should be_nil - /[[:ascii:]]/.match("\u{9898}").should be_nil + /[[:ascii:]]/.match("\u{80}").should == nil + /[[:ascii:]]/.match("\u{9898}").should == nil end end @@ -113,7 +113,7 @@ describe "Regexp with character classes" do end it "doesn't matches Unicode marks with [[:alnum:]]" do - "\u{36F}".match(/[[:alnum:]]/).should be_nil + "\u{3099}".match(/[[:alnum:]]/).should == nil end it "doesn't match Unicode control characters with [[:alnum:]]" do @@ -133,7 +133,7 @@ describe "Regexp with character classes" do end it "doesn't matches Unicode marks with [[:alpha:]]" do - "\u{36F}".match(/[[:alpha:]]/).should be_nil + "\u{3099}".match(/[[:alpha:]]/).should == nil end it "doesn't match Unicode control characters with [[:alpha:]]" do @@ -149,39 +149,39 @@ describe "Regexp with character classes" do end it "doesn't match Unicode control characters with [[:blank:]]" do - "\u{16}".match(/[[:blank:]]/).should be_nil + "\u{16}".match(/[[:blank:]]/).should == nil end it "doesn't match Unicode punctuation characters with [[:blank:]]" do - "\u{3F}".match(/[[:blank:]]/).should be_nil + "\u{3F}".match(/[[:blank:]]/).should == nil end it "doesn't match Unicode letter characters with [[:blank:]]" do - "à".match(/[[:blank:]]/).should be_nil + "à".match(/[[:blank:]]/).should == nil end it "doesn't match Unicode digits with [[:blank:]]" do - "\u{0660}".match(/[[:blank:]]/).should be_nil + "\u{0660}".match(/[[:blank:]]/).should == nil end it "doesn't match Unicode marks with [[:blank:]]" do - "\u{36F}".match(/[[:blank:]]/).should be_nil + "\u{36F}".match(/[[:blank:]]/).should == nil end it "doesn't Unicode letter characters with [[:cntrl:]]" do - "à".match(/[[:cntrl:]]/).should be_nil + "à".match(/[[:cntrl:]]/).should == nil end it "doesn't match Unicode digits with [[:cntrl:]]" do - "\u{0660}".match(/[[:cntrl:]]/).should be_nil + "\u{0660}".match(/[[:cntrl:]]/).should == nil end it "doesn't match Unicode marks with [[:cntrl:]]" do - "\u{36F}".match(/[[:cntrl:]]/).should be_nil + "\u{36F}".match(/[[:cntrl:]]/).should == nil end it "doesn't match Unicode punctuation characters with [[:cntrl:]]" do - "\u{3F}".match(/[[:cntrl:]]/).should be_nil + "\u{3F}".match(/[[:cntrl:]]/).should == nil end it "matches Unicode control characters with [[:cntrl:]]" do @@ -189,15 +189,15 @@ describe "Regexp with character classes" do end it "doesn't match Unicode format characters with [[:cntrl:]]" do - "\u{2060}".match(/[[:cntrl:]]/).should be_nil + "\u{2060}".match(/[[:cntrl:]]/).should == nil end it "doesn't match Unicode private-use characters with [[:cntrl:]]" do - "\u{E001}".match(/[[:cntrl:]]/).should be_nil + "\u{E001}".match(/[[:cntrl:]]/).should == nil end it "doesn't match Unicode letter characters with [[:digit:]]" do - "à".match(/[[:digit:]]/).should be_nil + "à".match(/[[:digit:]]/).should == nil end it "matches Unicode digits with [[:digit:]]" do @@ -206,23 +206,23 @@ describe "Regexp with character classes" do end it "doesn't match Unicode marks with [[:digit:]]" do - "\u{36F}".match(/[[:digit:]]/).should be_nil + "\u{36F}".match(/[[:digit:]]/).should == nil end it "doesn't match Unicode punctuation characters with [[:digit:]]" do - "\u{3F}".match(/[[:digit:]]/).should be_nil + "\u{3F}".match(/[[:digit:]]/).should == nil end it "doesn't match Unicode control characters with [[:digit:]]" do - "\u{16}".match(/[[:digit:]]/).should be_nil + "\u{16}".match(/[[:digit:]]/).should == nil end it "doesn't match Unicode format characters with [[:digit:]]" do - "\u{2060}".match(/[[:digit:]]/).should be_nil + "\u{2060}".match(/[[:digit:]]/).should == nil end it "doesn't match Unicode private-use characters with [[:digit:]]" do - "\u{E001}".match(/[[:digit:]]/).should be_nil + "\u{E001}".match(/[[:digit:]]/).should == nil end it "matches Unicode letter characters with [[:graph:]]" do @@ -243,7 +243,7 @@ describe "Regexp with character classes" do end it "doesn't match Unicode control characters with [[:graph:]]" do - "\u{16}".match(/[[:graph:]]/).should be_nil + "\u{16}".match(/[[:graph:]]/).should == nil end it "match Unicode format characters with [[:graph:]]" do @@ -261,40 +261,40 @@ describe "Regexp with character classes" do end it "doesn't match Unicode uppercase letter characters with [[:lower:]]" do - "\u{100}".match(/[[:lower:]]/).should be_nil - "\u{130}".match(/[[:lower:]]/).should be_nil - "\u{405}".match(/[[:lower:]]/).should be_nil + "\u{100}".match(/[[:lower:]]/).should == nil + "\u{130}".match(/[[:lower:]]/).should == nil + "\u{405}".match(/[[:lower:]]/).should == nil end it "doesn't match Unicode title-case characters with [[:lower:]]" do - "\u{1F88}".match(/[[:lower:]]/).should be_nil - "\u{1FAD}".match(/[[:lower:]]/).should be_nil - "\u{01C5}".match(/[[:lower:]]/).should be_nil + "\u{1F88}".match(/[[:lower:]]/).should == nil + "\u{1FAD}".match(/[[:lower:]]/).should == nil + "\u{01C5}".match(/[[:lower:]]/).should == nil end it "doesn't match Unicode digits with [[:lower:]]" do - "\u{0660}".match(/[[:lower:]]/).should be_nil - "\u{FF12}".match(/[[:lower:]]/).should be_nil + "\u{0660}".match(/[[:lower:]]/).should == nil + "\u{FF12}".match(/[[:lower:]]/).should == nil end it "doesn't match Unicode marks with [[:lower:]]" do - "\u{36F}".match(/[[:lower:]]/).should be_nil + "\u{36F}".match(/[[:lower:]]/).should == nil end it "doesn't match Unicode punctuation characters with [[:lower:]]" do - "\u{3F}".match(/[[:lower:]]/).should be_nil + "\u{3F}".match(/[[:lower:]]/).should == nil end it "doesn't match Unicode control characters with [[:lower:]]" do - "\u{16}".match(/[[:lower:]]/).should be_nil + "\u{16}".match(/[[:lower:]]/).should == nil end it "doesn't match Unicode format characters with [[:lower:]]" do - "\u{2060}".match(/[[:lower:]]/).should be_nil + "\u{2060}".match(/[[:lower:]]/).should == nil end it "doesn't match Unicode private-use characters with [[:lower:]]" do - "\u{E001}".match(/[[:lower:]]/).should be_nil + "\u{E001}".match(/[[:lower:]]/).should == nil end it "matches Unicode lowercase letter characters with [[:print:]]" do @@ -329,7 +329,7 @@ describe "Regexp with character classes" do end it "doesn't match Unicode control characters with [[:print:]]" do - "\u{16}".match(/[[:print:]]/).should be_nil + "\u{16}".match(/[[:print:]]/).should == nil end it "match Unicode format characters with [[:print:]]" do @@ -342,30 +342,30 @@ describe "Regexp with character classes" do it "doesn't match Unicode lowercase letter characters with [[:punct:]]" do - "\u{FF41}".match(/[[:punct:]]/).should be_nil - "\u{1D484}".match(/[[:punct:]]/).should be_nil - "\u{E8}".match(/[[:punct:]]/).should be_nil + "\u{FF41}".match(/[[:punct:]]/).should == nil + "\u{1D484}".match(/[[:punct:]]/).should == nil + "\u{E8}".match(/[[:punct:]]/).should == nil end it "doesn't match Unicode uppercase letter characters with [[:punct:]]" do - "\u{100}".match(/[[:punct:]]/).should be_nil - "\u{130}".match(/[[:punct:]]/).should be_nil - "\u{405}".match(/[[:punct:]]/).should be_nil + "\u{100}".match(/[[:punct:]]/).should == nil + "\u{130}".match(/[[:punct:]]/).should == nil + "\u{405}".match(/[[:punct:]]/).should == nil end it "doesn't match Unicode title-case characters with [[:punct:]]" do - "\u{1F88}".match(/[[:punct:]]/).should be_nil - "\u{1FAD}".match(/[[:punct:]]/).should be_nil - "\u{01C5}".match(/[[:punct:]]/).should be_nil + "\u{1F88}".match(/[[:punct:]]/).should == nil + "\u{1FAD}".match(/[[:punct:]]/).should == nil + "\u{01C5}".match(/[[:punct:]]/).should == nil end it "doesn't match Unicode digits with [[:punct:]]" do - "\u{0660}".match(/[[:punct:]]/).should be_nil - "\u{FF12}".match(/[[:punct:]]/).should be_nil + "\u{0660}".match(/[[:punct:]]/).should == nil + "\u{FF12}".match(/[[:punct:]]/).should == nil end it "doesn't match Unicode marks with [[:punct:]]" do - "\u{36F}".match(/[[:punct:]]/).should be_nil + "\u{36F}".match(/[[:punct:]]/).should == nil end it "matches Unicode Pc characters with [[:punct:]]" do @@ -398,38 +398,38 @@ describe "Regexp with character classes" do end it "doesn't match Unicode format characters with [[:punct:]]" do - "\u{2060}".match(/[[:punct:]]/).should be_nil + "\u{2060}".match(/[[:punct:]]/).should == nil end it "doesn't match Unicode private-use characters with [[:punct:]]" do - "\u{E001}".match(/[[:punct:]]/).should be_nil + "\u{E001}".match(/[[:punct:]]/).should == nil end it "doesn't match Unicode lowercase letter characters with [[:space:]]" do - "\u{FF41}".match(/[[:space:]]/).should be_nil - "\u{1D484}".match(/[[:space:]]/).should be_nil - "\u{E8}".match(/[[:space:]]/).should be_nil + "\u{FF41}".match(/[[:space:]]/).should == nil + "\u{1D484}".match(/[[:space:]]/).should == nil + "\u{E8}".match(/[[:space:]]/).should == nil end it "doesn't match Unicode uppercase letter characters with [[:space:]]" do - "\u{100}".match(/[[:space:]]/).should be_nil - "\u{130}".match(/[[:space:]]/).should be_nil - "\u{405}".match(/[[:space:]]/).should be_nil + "\u{100}".match(/[[:space:]]/).should == nil + "\u{130}".match(/[[:space:]]/).should == nil + "\u{405}".match(/[[:space:]]/).should == nil end it "doesn't match Unicode title-case characters with [[:space:]]" do - "\u{1F88}".match(/[[:space:]]/).should be_nil - "\u{1FAD}".match(/[[:space:]]/).should be_nil - "\u{01C5}".match(/[[:space:]]/).should be_nil + "\u{1F88}".match(/[[:space:]]/).should == nil + "\u{1FAD}".match(/[[:space:]]/).should == nil + "\u{01C5}".match(/[[:space:]]/).should == nil end it "doesn't match Unicode digits with [[:space:]]" do - "\u{0660}".match(/[[:space:]]/).should be_nil - "\u{FF12}".match(/[[:space:]]/).should be_nil + "\u{0660}".match(/[[:space:]]/).should == nil + "\u{FF12}".match(/[[:space:]]/).should == nil end it "doesn't match Unicode marks with [[:space:]]" do - "\u{36F}".match(/[[:space:]]/).should be_nil + "\u{36F}".match(/[[:space:]]/).should == nil end it "matches Unicode Zs characters with [[:space:]]" do @@ -445,17 +445,17 @@ describe "Regexp with character classes" do end it "doesn't match Unicode format characters with [[:space:]]" do - "\u{2060}".match(/[[:space:]]/).should be_nil + "\u{2060}".match(/[[:space:]]/).should == nil end it "doesn't match Unicode private-use characters with [[:space:]]" do - "\u{E001}".match(/[[:space:]]/).should be_nil + "\u{E001}".match(/[[:space:]]/).should == nil end it "doesn't match Unicode lowercase characters with [[:upper:]]" do - "\u{FF41}".match(/[[:upper:]]/).should be_nil - "\u{1D484}".match(/[[:upper:]]/).should be_nil - "\u{E8}".match(/[[:upper:]]/).should be_nil + "\u{FF41}".match(/[[:upper:]]/).should == nil + "\u{1D484}".match(/[[:upper:]]/).should == nil + "\u{E8}".match(/[[:upper:]]/).should == nil end it "matches Unicode uppercase characters with [[:upper:]]" do @@ -465,40 +465,40 @@ describe "Regexp with character classes" do end it "doesn't match Unicode title-case characters with [[:upper:]]" do - "\u{1F88}".match(/[[:upper:]]/).should be_nil - "\u{1FAD}".match(/[[:upper:]]/).should be_nil - "\u{01C5}".match(/[[:upper:]]/).should be_nil + "\u{1F88}".match(/[[:upper:]]/).should == nil + "\u{1FAD}".match(/[[:upper:]]/).should == nil + "\u{01C5}".match(/[[:upper:]]/).should == nil end it "doesn't match Unicode digits with [[:upper:]]" do - "\u{0660}".match(/[[:upper:]]/).should be_nil - "\u{FF12}".match(/[[:upper:]]/).should be_nil + "\u{0660}".match(/[[:upper:]]/).should == nil + "\u{FF12}".match(/[[:upper:]]/).should == nil end it "doesn't match Unicode marks with [[:upper:]]" do - "\u{36F}".match(/[[:upper:]]/).should be_nil + "\u{36F}".match(/[[:upper:]]/).should == nil end it "doesn't match Unicode punctuation characters with [[:upper:]]" do - "\u{3F}".match(/[[:upper:]]/).should be_nil + "\u{3F}".match(/[[:upper:]]/).should == nil end it "doesn't match Unicode control characters with [[:upper:]]" do - "\u{16}".match(/[[:upper:]]/).should be_nil + "\u{16}".match(/[[:upper:]]/).should == nil end it "doesn't match Unicode format characters with [[:upper:]]" do - "\u{2060}".match(/[[:upper:]]/).should be_nil + "\u{2060}".match(/[[:upper:]]/).should == nil end it "doesn't match Unicode private-use characters with [[:upper:]]" do - "\u{E001}".match(/[[:upper:]]/).should be_nil + "\u{E001}".match(/[[:upper:]]/).should == nil end it "doesn't match Unicode letter characters [^a-fA-F] with [[:xdigit:]]" do - "à".match(/[[:xdigit:]]/).should be_nil - "g".match(/[[:xdigit:]]/).should be_nil - "X".match(/[[:xdigit:]]/).should be_nil + "à".match(/[[:xdigit:]]/).should == nil + "g".match(/[[:xdigit:]]/).should == nil + "X".match(/[[:xdigit:]]/).should == nil end it "matches Unicode letter characters [a-fA-F] with [[:xdigit:]]" do @@ -507,28 +507,28 @@ describe "Regexp with character classes" do end it "doesn't match Unicode digits [^0-9] with [[:xdigit:]]" do - "\u{0660}".match(/[[:xdigit:]]/).should be_nil - "\u{FF12}".match(/[[:xdigit:]]/).should be_nil + "\u{0660}".match(/[[:xdigit:]]/).should == nil + "\u{FF12}".match(/[[:xdigit:]]/).should == nil end it "doesn't match Unicode marks with [[:xdigit:]]" do - "\u{36F}".match(/[[:xdigit:]]/).should be_nil + "\u{36F}".match(/[[:xdigit:]]/).should == nil end it "doesn't match Unicode punctuation characters with [[:xdigit:]]" do - "\u{3F}".match(/[[:xdigit:]]/).should be_nil + "\u{3F}".match(/[[:xdigit:]]/).should == nil end it "doesn't match Unicode control characters with [[:xdigit:]]" do - "\u{16}".match(/[[:xdigit:]]/).should be_nil + "\u{16}".match(/[[:xdigit:]]/).should == nil end it "doesn't match Unicode format characters with [[:xdigit:]]" do - "\u{2060}".match(/[[:xdigit:]]/).should be_nil + "\u{2060}".match(/[[:xdigit:]]/).should == nil end it "doesn't match Unicode private-use characters with [[:xdigit:]]" do - "\u{E001}".match(/[[:xdigit:]]/).should be_nil + "\u{E001}".match(/[[:xdigit:]]/).should == nil end it "matches Unicode lowercase characters with [[:word:]]" do @@ -562,23 +562,30 @@ describe "Regexp with character classes" do "\u{16EE}".match(/[[:word:]]/).to_a.should == ["\u{16EE}"] end + ruby_bug "#19417", ""..."3.4.6" do + it "matches Unicode join control characters with [[:word:]]" do + "\u{200C}".match(/[[:word:]]/).to_a.should == ["\u{200C}"] + "\u{200D}".match(/[[:word:]]/).to_a.should == ["\u{200D}"] + end + end + it "doesn't match Unicode No characters with [[:word:]]" do - "\u{17F0}".match(/[[:word:]]/).should be_nil + "\u{17F0}".match(/[[:word:]]/).should == nil end it "doesn't match Unicode punctuation characters with [[:word:]]" do - "\u{3F}".match(/[[:word:]]/).should be_nil + "\u{3F}".match(/[[:word:]]/).should == nil end it "doesn't match Unicode control characters with [[:word:]]" do - "\u{16}".match(/[[:word:]]/).should be_nil + "\u{16}".match(/[[:word:]]/).should == nil end it "doesn't match Unicode format characters with [[:word:]]" do - "\u{2060}".match(/[[:word:]]/).should be_nil + "\u{2060}".match(/[[:word:]]/).should == nil end it "doesn't match Unicode private-use characters with [[:word:]]" do - "\u{E001}".match(/[[:word:]]/).should be_nil + "\u{E001}".match(/[[:word:]]/).should == nil end it "matches unicode named character properties" do @@ -610,12 +617,12 @@ describe "Regexp with character classes" do end it "supports negated property condition" do - "a".match(eval("/\P{L}/")).should be_nil - "1".match(eval("/\P{N}/")).should be_nil + "a".match(eval("/\P{L}/")).should == nil + "1".match(eval("/\P{N}/")).should == nil end it "raises a RegexpError for an unterminated unicode property" do - -> { Regexp.new('\p{') }.should raise_error(RegexpError) + -> { Regexp.new('\p{') }.should.raise(RegexpError) end it "supports \\X (unicode 9.0 with UTR #51 workarounds)" do diff --git a/spec/ruby/language/regexp/encoding_spec.rb b/spec/ruby/language/regexp/encoding_spec.rb index 0571b2d3cf..81e845af0c 100644 --- a/spec/ruby/language/regexp/encoding_spec.rb +++ b/spec/ruby/language/regexp/encoding_spec.rb @@ -1,4 +1,4 @@ -# -*- encoding: binary -*- +# encoding: binary require_relative '../../spec_helper' require_relative '../fixtures/classes' @@ -39,7 +39,11 @@ describe "Regexps with encoding modifiers" do end it "warns when using /n with a match string with non-ASCII characters and an encoding other than ASCII-8BIT" do - -> { /./n.match("\303\251".dup.force_encoding('utf-8')) }.should complain(%r{historical binary regexp match /.../n against UTF-8 string}) + -> { + eval <<~RUBY + /./n.match("\303\251".dup.force_encoding('utf-8')) + RUBY + }.should complain(%r{historical binary regexp match /.../n against UTF-8 string}) end it 'uses US-ASCII as /n encoding if all chars are 7-bit' do @@ -110,28 +114,28 @@ describe "Regexps with encoding modifiers" do end it "raises Encoding::CompatibilityError when trying match against different encodings" do - -> { /\A[[:space:]]*\z/.match(" ".encode("UTF-16LE")) }.should raise_error(Encoding::CompatibilityError) + -> { /\A[[:space:]]*\z/.match(" ".encode("UTF-16LE")) }.should.raise(Encoding::CompatibilityError) end it "raises Encoding::CompatibilityError when trying match? against different encodings" do - -> { /\A[[:space:]]*\z/.match?(" ".encode("UTF-16LE")) }.should raise_error(Encoding::CompatibilityError) + -> { /\A[[:space:]]*\z/.match?(" ".encode("UTF-16LE")) }.should.raise(Encoding::CompatibilityError) end it "raises Encoding::CompatibilityError when trying =~ against different encodings" do - -> { /\A[[:space:]]*\z/ =~ " ".encode("UTF-16LE") }.should raise_error(Encoding::CompatibilityError) + -> { /\A[[:space:]]*\z/ =~ " ".encode("UTF-16LE") }.should.raise(Encoding::CompatibilityError) end it "raises Encoding::CompatibilityError when the regexp has a fixed, non-ASCII-compatible encoding" do - -> { Regexp.new("".dup.force_encoding("UTF-16LE"), Regexp::FIXEDENCODING) =~ " ".encode("UTF-8") }.should raise_error(Encoding::CompatibilityError) + -> { Regexp.new("".dup.force_encoding("UTF-16LE"), Regexp::FIXEDENCODING) =~ " ".encode("UTF-8") }.should.raise(Encoding::CompatibilityError) end it "raises Encoding::CompatibilityError when the regexp has a fixed encoding and the match string has non-ASCII characters" do - -> { Regexp.new("".dup.force_encoding("US-ASCII"), Regexp::FIXEDENCODING) =~ "\303\251".dup.force_encoding('UTF-8') }.should raise_error(Encoding::CompatibilityError) + -> { Regexp.new("".dup.force_encoding("US-ASCII"), Regexp::FIXEDENCODING) =~ "\303\251".dup.force_encoding('UTF-8') }.should.raise(Encoding::CompatibilityError) end it "raises ArgumentError when trying to match a broken String" do s = "\x80".dup.force_encoding('UTF-8') - -> { s =~ /./ }.should raise_error(ArgumentError, "invalid byte sequence in UTF-8") + -> { s =~ /./ }.should.raise(ArgumentError, "invalid byte sequence in UTF-8") end it "computes the Regexp Encoding for each interpolated Regexp instance" do diff --git a/spec/ruby/language/regexp/escapes_spec.rb b/spec/ruby/language/regexp/escapes_spec.rb index 16a4d8c23b..4a0e611540 100644 --- a/spec/ruby/language/regexp/escapes_spec.rb +++ b/spec/ruby/language/regexp/escapes_spec.rb @@ -1,4 +1,4 @@ -# -*- encoding: binary -*- +# encoding: binary require_relative '../../spec_helper' require_relative '../fixtures/classes' @@ -116,11 +116,11 @@ describe "Regexps with escape characters" do it "supports \\x (hex characters)" do /\xA/.match("\nxyz").to_a.should == ["\n"] /\x0A/.match("\n").to_a.should == ["\n"] - /\xAA/.match("\nA").should be_nil + /\xAA/.match("\nA").should == nil /\x0AA/.match("\nA").to_a.should == ["\nA"] /\xAG/.match("\nG").to_a.should == ["\nG"] # Non-matches - -> { eval('/\xG/') }.should raise_error(SyntaxError) + -> { eval('/\xG/') }.should.raise(SyntaxError) # \x{7HHHHHHH} wide hexadecimal char (character code point value) end @@ -136,14 +136,14 @@ describe "Regexps with escape characters" do /\c,\cL\cl/.match("\f\f\f").to_a.should == ["\f\f\f"] /\c-\cM\cm/.match("\r\r\r").to_a.should == ["\r\r\r"] - /\cJ/.match("\r").should be_nil + /\cJ/.match("\r").should == nil # Parsing precedence /\cJ+/.match("\n\n").to_a.should == ["\n\n"] # Quantifiers apply to entire escape sequence /\\cJ/.match("\\cJ").to_a.should == ["\\cJ"] - -> { eval('/[abc\x]/') }.should raise_error(SyntaxError) # \x is treated as a escape sequence even inside a character class + -> { eval('/[abc\x]/') }.should.raise(SyntaxError) # \x is treated as a escape sequence even inside a character class # Syntax error - -> { eval('/\c/') }.should raise_error(SyntaxError) + -> { eval('/\c/') }.should.raise(SyntaxError) # \cx control char (character code point value) # \C-x control char (character code point value) diff --git a/spec/ruby/language/regexp/grouping_spec.rb b/spec/ruby/language/regexp/grouping_spec.rb index 313858f714..80ad7460da 100644 --- a/spec/ruby/language/regexp/grouping_spec.rb +++ b/spec/ruby/language/regexp/grouping_spec.rb @@ -12,7 +12,7 @@ describe "Regexps with grouping" do end it "raises a SyntaxError when parentheses aren't balanced" do - -> { eval "/(hay(st)ack/" }.should raise_error(SyntaxError) + -> { eval "/(hay(st)ack/" }.should.raise(SyntaxError) end it "supports (?: ) (non-capturing group)" do @@ -22,8 +22,8 @@ describe "Regexps with grouping" do end it "group names cannot start with digits or minus" do - -> { Regexp.new("(?<1a>a)") }.should raise_error(RegexpError) - -> { Regexp.new("(?<-a>a)") }.should raise_error(RegexpError) + -> { Regexp.new("(?<1a>a)") }.should.raise(RegexpError) + -> { Regexp.new("(?<-a>a)") }.should.raise(RegexpError) end it "ignore capture groups in line comments" do diff --git a/spec/ruby/language/regexp/interpolation_spec.rb b/spec/ruby/language/regexp/interpolation_spec.rb index 6951fd38ca..f771d0a395 100644 --- a/spec/ruby/language/regexp/interpolation_spec.rb +++ b/spec/ruby/language/regexp/interpolation_spec.rb @@ -36,14 +36,14 @@ describe "Regexps with interpolation" do it "gives precedence to escape sequences over substitution" do str = "J" - /\c#{str}/.to_s.should include('{str}') + /\c#{str}/.to_s.should.include?('{str}') end it "throws RegexpError for malformed interpolation" do s = "" - -> { /(#{s}/ }.should raise_error(RegexpError) + -> { /(#{s}/ }.should.raise(RegexpError) s = "(" - -> { /#{s}/ }.should raise_error(RegexpError) + -> { /#{s}/ }.should.raise(RegexpError) end it "allows interpolation in extended mode" do diff --git a/spec/ruby/language/regexp/modifiers_spec.rb b/spec/ruby/language/regexp/modifiers_spec.rb index 2f5522bc8a..c96fbfa983 100644 --- a/spec/ruby/language/regexp/modifiers_spec.rb +++ b/spec/ruby/language/regexp/modifiers_spec.rb @@ -8,7 +8,7 @@ describe "Regexps with modifiers" do it "supports /m (multiline)" do /foo.bar/m.match("foo\nbar").to_a.should == ["foo\nbar"] - /foo.bar/.match("foo\nbar").should be_nil + /foo.bar/.match("foo\nbar").should == nil end it "supports /x (extended syntax)" do @@ -36,7 +36,7 @@ describe "Regexps with modifiers" do /foo/imox.match("foo").to_a.should == ["foo"] /foo/imoximox.match("foo").to_a.should == ["foo"] - -> { eval('/foo/a') }.should raise_error(SyntaxError) + -> { eval('/foo/a') }.should.raise(SyntaxError) end it "supports (?~) (absent operator)" do @@ -46,57 +46,57 @@ describe "Regexps with modifiers" do it "supports (?imx-imx) (inline modifiers)" do /(?i)foo/.match("FOO").to_a.should == ["FOO"] - /foo(?i)/.match("FOO").should be_nil + /foo(?i)/.match("FOO").should == nil # Interaction with /i - /(?-i)foo/i.match("FOO").should be_nil + /(?-i)foo/i.match("FOO").should == nil /foo(?-i)/i.match("FOO").to_a.should == ["FOO"] # Multiple uses /foo (?i)bar (?-i)baz/.match("foo BAR baz").to_a.should == ["foo BAR baz"] - /foo (?i)bar (?-i)baz/.match("foo BAR BAZ").should be_nil + /foo (?i)bar (?-i)baz/.match("foo BAR BAZ").should == nil /(?m)./.match("\n").to_a.should == ["\n"] - /.(?m)/.match("\n").should be_nil + /.(?m)/.match("\n").should == nil # Interaction with /m - /(?-m)./m.match("\n").should be_nil + /(?-m)./m.match("\n").should == nil /.(?-m)/m.match("\n").to_a.should == ["\n"] # Multiple uses /. (?m). (?-m)./.match(". \n .").to_a.should == [". \n ."] - /. (?m). (?-m)./.match(". \n \n").should be_nil + /. (?m). (?-m)./.match(". \n \n").should == nil /(?x) foo /.match("foo").to_a.should == ["foo"] - / foo (?x)/.match("foo").should be_nil + / foo (?x)/.match("foo").should == nil # Interaction with /x - /(?-x) foo /x.match("foo").should be_nil + /(?-x) foo /x.match("foo").should == nil / foo (?-x)/x.match("foo").to_a.should == ["foo"] # Multiple uses /( foo )(?x)( bar )(?-x)( baz )/.match(" foo bar baz ").to_a.should == [" foo bar baz ", " foo ", "bar", " baz "] - /( foo )(?x)( bar )(?-x)( baz )/.match(" foo barbaz").should be_nil + /( foo )(?x)( bar )(?-x)( baz )/.match(" foo barbaz").should == nil # Parsing - /(?i-i)foo/.match("FOO").should be_nil + /(?i-i)foo/.match("FOO").should == nil /(?ii)foo/.match("FOO").to_a.should == ["FOO"] /(?-)foo/.match("foo").to_a.should == ["foo"] - -> { eval('/(?o)/') }.should raise_error(SyntaxError) + -> { eval('/(?o)/') }.should.raise(SyntaxError) end it "supports (?imx-imx:expr) (scoped inline modifiers)" do /foo (?i:bar) baz/.match("foo BAR baz").to_a.should == ["foo BAR baz"] - /foo (?i:bar) baz/.match("foo BAR BAZ").should be_nil - /foo (?-i:bar) baz/i.match("foo BAR BAZ").should be_nil + /foo (?i:bar) baz/.match("foo BAR BAZ").should == nil + /foo (?-i:bar) baz/i.match("foo BAR BAZ").should == nil /. (?m:.) ./.match(". \n .").to_a.should == [". \n ."] - /. (?m:.) ./.match(". \n \n").should be_nil - /. (?-m:.) ./m.match("\n \n \n").should be_nil + /. (?m:.) ./.match(". \n \n").should == nil + /. (?-m:.) ./m.match("\n \n \n").should == nil /( foo )(?x: bar )( baz )/.match(" foo bar baz ").to_a.should == [" foo bar baz ", " foo ", " baz "] - /( foo )(?x: bar )( baz )/.match(" foo barbaz").should be_nil + /( foo )(?x: bar )( baz )/.match(" foo barbaz").should == nil /( foo )(?-x: bar )( baz )/x.match("foo bar baz").to_a.should == ["foo bar baz", "foo", "baz"] # Parsing - /(?i-i:foo)/.match("FOO").should be_nil + /(?i-i:foo)/.match("FOO").should == nil /(?ii:foo)/.match("FOO").to_a.should == ["FOO"] /(?-:)foo/.match("foo").to_a.should == ["foo"] - -> { eval('/(?o:)/') }.should raise_error(SyntaxError) + -> { eval('/(?o:)/') }.should.raise(SyntaxError) end it "supports . with /m" do diff --git a/spec/ruby/language/regexp/repetition_spec.rb b/spec/ruby/language/regexp/repetition_spec.rb index d76619688f..f24323de5c 100644 --- a/spec/ruby/language/regexp/repetition_spec.rb +++ b/spec/ruby/language/regexp/repetition_spec.rb @@ -15,7 +15,7 @@ describe "Regexps with repetition" do it "supports + (1 or more of previous subexpression)" do /a+/.match("aaa").to_a.should == ["aaa"] - /a+/.match("bbb").should be_nil + /a+/.match("bbb").should == nil /<.+>/.match("<a>foo</a>").to_a.should == ["<a>foo</a>"] # it is greedy end diff --git a/spec/ruby/language/regexp_spec.rb b/spec/ruby/language/regexp_spec.rb index 0cd9584549..1452b01935 100644 --- a/spec/ruby/language/regexp_spec.rb +++ b/spec/ruby/language/regexp_spec.rb @@ -15,7 +15,7 @@ describe "Literal Regexps" do end it "yields a Regexp" do - /Hello/.should be_kind_of(Regexp) + /Hello/.should.is_a?(Regexp) end it "is frozen" do @@ -27,11 +27,11 @@ describe "Literal Regexps" do 2.times do |i| rs << /foo/ end - rs[0].should equal(rs[1]) + rs[0].should.equal?(rs[1]) end it "throws SyntaxError for malformed literals" do - -> { eval('/(/') }.should raise_error(SyntaxError) + -> { eval('/(/') }.should.raise(SyntaxError) end ############################################################################# @@ -58,7 +58,7 @@ describe "Literal Regexps" do it "disallows first part of paired delimiters to be used as non-paired delimiters" do LanguageSpecs.paired_delimiters.each do |p0, p1| - -> { eval("%r#{p0} foo #{p0}") }.should raise_error(SyntaxError) + -> { eval("%r#{p0} foo #{p0}") }.should.raise(SyntaxError) end end @@ -69,11 +69,11 @@ describe "Literal Regexps" do end it "disallows alphabets as non-paired delimiter with %r" do - -> { eval('%ra foo a') }.should raise_error(SyntaxError) + -> { eval('%ra foo a') }.should.raise(SyntaxError) end it "disallows spaces after %r and delimiter" do - -> { eval('%r !foo!') }.should raise_error(SyntaxError) + -> { eval('%r !foo!') }.should.raise(SyntaxError) end it "allows unescaped / to be used with %r" do @@ -89,8 +89,8 @@ describe "Literal Regexps" do # Basic matching /./.match("foo").to_a.should == ["f"] # Basic non-matching - /./.match("").should be_nil - /./.match("\n").should be_nil + /./.match("").should == nil + /./.match("\n").should == nil /./.match("\0").to_a.should == ["\0"] end @@ -100,7 +100,7 @@ describe "Literal Regexps" do it "supports (?> ) (embedded subexpression)" do /(?>foo)(?>bar)/.match("foobar").to_a.should == ["foobar"] - /(?>foo*)obar/.match("foooooooobar").should be_nil # it is possessive + /(?>foo*)obar/.match("foooooooobar").should == nil # it is possessive end it "supports (?# )" do @@ -112,7 +112,7 @@ describe "Literal Regexps" do /foo.(?<=\d)/.match("fooA foo1").to_a.should == ["foo1"] end - ruby_bug "#13671", ""..."3.6" do # https://bugs.ruby-lang.org/issues/13671 + ruby_bug "#13671", ""..."4.0" do # https://bugs.ruby-lang.org/issues/13671 it "handles a lookbehind with ss characters" do r = Regexp.new("(?<!dss)", Regexp::IGNORECASE) r.should =~ "✨" @@ -135,9 +135,9 @@ describe "Literal Regexps" do it "supports possessive quantifiers" do /fooA++bar/.match("fooAAAbar").to_a.should == ["fooAAAbar"] - /fooA++Abar/.match("fooAAAbar").should be_nil - /fooA?+Abar/.match("fooAAAbar").should be_nil - /fooA*+Abar/.match("fooAAAbar").should be_nil + /fooA++Abar/.match("fooAAAbar").should == nil + /fooA?+Abar/.match("fooAAAbar").should == nil + /fooA*+Abar/.match("fooAAAbar").should == nil end it "supports conditional regular expressions with positional capture groups" do diff --git a/spec/ruby/language/rescue_spec.rb b/spec/ruby/language/rescue_spec.rb index 79571d689f..cf16d8f6f8 100644 --- a/spec/ruby/language/rescue_spec.rb +++ b/spec/ruby/language/rescue_spec.rb @@ -59,7 +59,7 @@ describe "The rescue keyword" do rescue SpecificExampleException => target&.captured_error :caught end.should == :caught - target.should be_nil + target.should == nil end it 'using a setter method' do @@ -136,10 +136,14 @@ describe "The rescue keyword" do it 'captures successfully at the top-level' do ScratchPad.record [] + loaded_features = $".dup + begin + require_relative 'fixtures/rescue/top_level' - require_relative 'fixtures/rescue/top_level' - - ScratchPad.recorded.should == ["message"] + ScratchPad.recorded.should == ["message"] + ensure + $".replace loaded_features + end end end @@ -182,7 +186,7 @@ describe "The rescue keyword" do rescue *exception_list caught_it = true end - caught_it.should be_true + caught_it.should == true caught = [] [->{raise ArbitraryException}, ->{raise SpecificExampleException}].each do |block| begin @@ -193,7 +197,7 @@ describe "The rescue keyword" do end caught.size.should == 2 exception_list.each do |exception_class| - caught.map{|e| e.class}.should include(exception_class) + caught.map{|e| e.class}.should.include?(exception_class) end end @@ -206,7 +210,7 @@ describe "The rescue keyword" do rescue *exceptions caught_it = true end - caught_it.should be_true + caught_it.should == true end it "can combine a splatted list of exceptions with a literal list of exceptions" do @@ -216,7 +220,7 @@ describe "The rescue keyword" do rescue ArbitraryException, *exception_list caught_it = true end - caught_it.should be_true + caught_it.should == true caught = [] [->{raise ArbitraryException}, ->{raise SpecificExampleException}].each do |block| begin @@ -227,7 +231,7 @@ describe "The rescue keyword" do end caught.size.should == 2 exception_list.each do |exception_class| - caught.map{|e| e.class}.should include(exception_class) + caught.map{|e| e.class}.should.include?(exception_class) end end @@ -237,7 +241,7 @@ describe "The rescue keyword" do raise OtherCustomException, "not rescued!" rescue *exception_list end - end.should raise_error(OtherCustomException) + end.should.raise(OtherCustomException) end it "can rescue different types of exceptions in different ways" do @@ -341,7 +345,7 @@ describe "The rescue keyword" do ScratchPad << :else end ruby - }.should raise_error(SyntaxError, /else without rescue is useless/) + }.should.raise(SyntaxError, /else without rescue is useless/) end it "will not execute an else block if an exception was raised" do @@ -409,7 +413,7 @@ describe "The rescue keyword" do ScratchPad << :two raise SpecificExampleException, "an error from else" end - end.should raise_error(SpecificExampleException) + end.should.raise(SpecificExampleException) ScratchPad.recorded.should == [:one, :two] end @@ -441,7 +445,7 @@ describe "The rescue keyword" do rescue ScratchPad << :caught end - }.should raise_error(exception.class) + }.should.raise(exception.class) end ScratchPad.recorded.should == [] end @@ -472,7 +476,7 @@ describe "The rescue keyword" do raise "error" rescue rescuer end - }.should raise_error(TypeError) { |e| + }.should.raise(TypeError) { |e| e.message.should =~ /class or module required for rescue clause/ } end @@ -484,7 +488,7 @@ describe "The rescue keyword" do raise "error" rescue *rescuer end - }.should raise_error(TypeError) { |e| + }.should.raise(TypeError) { |e| e.message.should =~ /class or module required for rescue clause/ } end @@ -504,7 +508,7 @@ describe "The rescue keyword" do raise "from block" rescue (raise "from rescue expression") end - }.should raise_error(RuntimeError, "from rescue expression") { |e| + }.should.raise(RuntimeError, "from rescue expression") { |e| e.cause.message.should == "from block" } end @@ -538,7 +542,7 @@ describe "The rescue keyword" do :caught } ruby - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end it "allows rescue in 'do end' block" do @@ -559,7 +563,7 @@ describe "The rescue keyword" do end it "requires the 'rescue' in method arguments to be wrapped in parens" do - -> { eval '1.+(1 rescue 1)' }.should raise_error(SyntaxError) + -> { eval '1.+(1 rescue 1)' }.should.raise(SyntaxError) eval('1.+((1 rescue 1))').should == 2 end @@ -589,7 +593,7 @@ describe "The rescue keyword" do eval <<-ruby a = 1 rescue RuntimeError 2 ruby - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end it "rescues only StandardError and its subclasses" do @@ -598,7 +602,7 @@ describe "The rescue keyword" do -> { a = raise(Exception) rescue 1 - }.should raise_error(Exception) + }.should.raise(Exception) end it "rescues with multiple assignment" do diff --git a/spec/ruby/language/reserved_keywords.rb b/spec/ruby/language/reserved_keywords.rb new file mode 100644 index 0000000000..bd1a55feec --- /dev/null +++ b/spec/ruby/language/reserved_keywords.rb @@ -0,0 +1,149 @@ +require_relative '../spec_helper' + +describe "Ruby's reserved keywords" do + # Copied from https://github.com/ruby/ruby/blob/master/defs/keywords + keywords = %w[ + alias + and + begin + BEGIN + break + case + class + def + defined? + do + else + elsif + end + END + ensure + false + for + if + in + module + next + nil + not + or + redo + rescue + retry + return + self + super + then + true + undef + unless + until + when + while + yield + __ENCODING__ + __FILE__ + __LINE__ + ] + + keywords.each do |name| + describe "keyword '#{name}'" do + it "can't be used as local variable name" do + -> { eval(<<~RUBY) }.should.raise(SyntaxError) + #{name} = :local_variable + RUBY + end + + if name == "defined?" + it "can't be used as an instance variable name" do + -> { eval(<<~RUBY) }.should.raise(SyntaxError) + @#{name} = :instance_variable + RUBY + end + + it "can't be used as a class variable name" do + -> { eval(<<~RUBY) }.should.raise(SyntaxError) + class C + @@#{name} = :class_variable + end + RUBY + end + + it "can't be used as a global variable name" do + -> { eval(<<~RUBY) }.should.raise(SyntaxError) + $#{name} = :global_variable + RUBY + end + else + it "can be used as an instance variable name" do + result = eval <<~RUBY + @#{name} = :instance_variable + @#{name} + RUBY + + result.should == :instance_variable + end + + it "can be used as a class variable name" do + result = eval <<~RUBY + class C + @@#{name} = :class_variable + @@#{name} + end + RUBY + + result.should == :class_variable + end + + it "can be used as a global variable name" do + result = eval <<~RUBY + $#{name} = :global_variable + $#{name} + RUBY + + result.should == :global_variable + end + end + + it "can't be used as a positional parameter name" do + -> { eval(<<~RUBY) }.should.raise(SyntaxError) + def x(#{name}); end + RUBY + end + + invalid_kw_param_names = ["BEGIN","END","defined?"] + + if invalid_kw_param_names.include?(name) + it "can't be used a keyword parameter name" do + -> { eval(<<~RUBY) }.should.raise(SyntaxError) + def m(#{name}:); end + RUBY + end + else + it "can be used a keyword parameter name" do + result = instance_eval <<~RUBY + def m(#{name}:) + binding.local_variable_get(:#{name}) + end + + m(#{name}: :argument) + RUBY + + result.should == :argument + end + end + + it "can be used as a method name" do + result = instance_eval <<~RUBY + def #{name} + :method_return_value + end + + send(:#{name}) + RUBY + + result.should == :method_return_value + end + end + end +end diff --git a/spec/ruby/language/retry_spec.rb b/spec/ruby/language/retry_spec.rb index 669d5f0ff5..39e58b7b5d 100644 --- a/spec/ruby/language/retry_spec.rb +++ b/spec/ruby/language/retry_spec.rb @@ -32,10 +32,10 @@ describe "The retry statement" do end it "raises a SyntaxError when used outside of a rescue statement" do - -> { eval 'retry' }.should raise_error(SyntaxError) - -> { eval 'begin; retry; end' }.should raise_error(SyntaxError) - -> { eval 'def m; retry; end' }.should raise_error(SyntaxError) - -> { eval 'module RetrySpecs; retry; end' }.should raise_error(SyntaxError) + -> { eval 'retry' }.should.raise(SyntaxError) + -> { eval 'begin; retry; end' }.should.raise(SyntaxError) + -> { eval 'def m; retry; end' }.should.raise(SyntaxError) + -> { eval 'module RetrySpecs; retry; end' }.should.raise(SyntaxError) end end diff --git a/spec/ruby/language/return_spec.rb b/spec/ruby/language/return_spec.rb index a62ed1242d..36a3cba4d7 100644 --- a/spec/ruby/language/return_spec.rb +++ b/spec/ruby/language/return_spec.rb @@ -19,7 +19,7 @@ describe "The return keyword" do it "returns nil by default" do def r; return; end - r().should be_nil + r().should == nil end describe "in a Thread" do @@ -31,7 +31,7 @@ describe "The return keyword" do e end } - t.value.should be_an_instance_of(LocalJumpError) + t.value.should.instance_of?(LocalJumpError) end end @@ -176,11 +176,11 @@ describe "The return keyword" do end it "causes lambda to return nil if invoked without any arguments" do - -> { return; 456 }.call.should be_nil + -> { return; 456 }.call.should == nil end it "causes lambda to return nil if invoked with an empty expression" do - -> { return (); 456 }.call.should be_nil + -> { return (); 456 }.call.should == nil end it "causes lambda to return the value passed to return" do @@ -229,7 +229,7 @@ describe "The return keyword" do def f 1.times { 1.times {return true}; false}; false end - f.should be_true + f.should == true end end @@ -417,7 +417,7 @@ describe "The return keyword" do end END_OF_CODE - -> { load @filename }.should raise_error(SyntaxError) + -> { load @filename }.should.raise(SyntaxError) end end @@ -431,7 +431,7 @@ describe "The return keyword" do end END_OF_CODE - -> { load @filename }.should raise_error(LocalJumpError) + -> { load @filename }.should.raise(LocalJumpError) end end diff --git a/spec/ruby/language/safe_navigator_spec.rb b/spec/ruby/language/safe_navigator_spec.rb index b1e28c3963..e8b429631d 100644 --- a/spec/ruby/language/safe_navigator_spec.rb +++ b/spec/ruby/language/safe_navigator_spec.rb @@ -2,7 +2,7 @@ require_relative '../spec_helper' describe "Safe navigator" do it "requires a method name to be provided" do - -> { eval("obj&. {}") }.should raise_error(SyntaxError) + -> { eval("obj&. {}") }.should.raise(SyntaxError) end context "when context is nil" do @@ -26,7 +26,7 @@ describe "Safe navigator" do it "calls the method" do false&.to_s.should == "false" - -> { false&.unknown }.should raise_error(NoMethodError) + -> { false&.unknown }.should.raise(NoMethodError) end end @@ -34,7 +34,7 @@ describe "Safe navigator" do it "calls the method" do 1&.to_s.should == "1" - -> { 1&.unknown }.should raise_error(NoMethodError) + -> { 1&.unknown }.should.raise(NoMethodError) end end @@ -140,7 +140,7 @@ describe "Safe navigator" do -> { obj&.foo += 3 - }.should raise_error(NoMethodError) { |e| + }.should.raise(NoMethodError) { |e| e.name.should == :+ } end diff --git a/spec/ruby/language/send_spec.rb b/spec/ruby/language/send_spec.rb index aaccdf0998..f56a77d529 100644 --- a/spec/ruby/language/send_spec.rb +++ b/spec/ruby/language/send_spec.rb @@ -22,7 +22,7 @@ describe "Invoking a method" do it "raises ArgumentError if the method has a positive arity" do -> { specs.fooM1 - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end end @@ -38,7 +38,7 @@ describe "Invoking a method" do it "raises ArgumentError if the methods arity doesn't match" do -> { specs.fooM1(1,2) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end end @@ -54,7 +54,7 @@ describe "Invoking a method" do it "raises ArgumentError if extra arguments are passed" do -> { specs.fooM0O1(2,3) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end end @@ -66,13 +66,13 @@ describe "Invoking a method" do it "raises an ArgumentError if there are no values for the mandatory args" do -> { specs.fooM1O1 - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end it "raises an ArgumentError if too many values are passed" do -> { specs.fooM1O1(1,2,3) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end end @@ -94,7 +94,7 @@ describe "Invoking a method" do it "with a block converts the block to a Proc" do prc = specs.makeproc { "hello" } - prc.should be_kind_of(Proc) + prc.should.is_a?(Proc) prc.call.should == "hello" end @@ -106,10 +106,28 @@ describe "Invoking a method" do specs.yield_now(&o).should == :from_to_proc end + ruby_version_is "4.0" do + it "raises TypeError if 'to_proc' doesn't return a Proc" do + o = LangSendSpecs::RawToProc.new(42) + + -> { + specs.makeproc(&o) + }.should raise_consistent_error(TypeError, "can't convert LangSendSpecs::RawToProc into Proc (LangSendSpecs::RawToProc#to_proc gives Integer)") + end + + it "raises TypeError if block object isn't a Proc and doesn't respond to `to_proc`" do + o = Object.new + + -> { + specs.makeproc(&o) + }.should.raise(TypeError, "no implicit conversion of Object into Proc") + end + end + it "raises a SyntaxError with both a literal block and an object as block" do -> { eval "specs.oneb(10, &l){ 42 }" - }.should raise_error(SyntaxError) + }.should.raise(SyntaxError) end it "with same names as existing variables is ok" do @@ -194,21 +212,42 @@ describe "Invoking a method" do o.args.should == [1,2] end - it "raises NameError if invoked as a vcall" do - -> { no_such_method }.should raise_error NameError + describe "if invoked as a vcall" do + it "raises NameError" do + -> { no_such_method }.should.raise NameError + end + + it "raises NameError with $! as a cause" do + begin + raise RuntimeError.new + rescue => cause + -> { no_such_method }.should.raise(NameError, cause:) + end + end end it "should omit the method_missing call from the backtrace for NameError" do - -> { no_such_method }.should raise_error { |e| e.backtrace.first.should_not include("method_missing") } + -> { no_such_method }.should.raise { |e| e.backtrace.first.should_not.include?("method_missing") } end - it "raises NoMethodError if invoked as an unambiguous method call" do - -> { no_such_method() }.should raise_error NoMethodError - -> { no_such_method(1,2,3) }.should raise_error NoMethodError + describe "if invoked as an unambiguous method call" do + it "raises NoMethodError" do + -> { no_such_method() }.should.raise NoMethodError + -> { no_such_method(1,2,3) }.should.raise NoMethodError + end + + it "raises NoMethodError with $! as a cause" do + begin + raise + rescue => cause + -> { no_such_method() }.should.raise(NoMethodError, cause:) + -> { no_such_method(1,2,3) }.should.raise(NoMethodError, cause:) + end + end end it "should omit the method_missing call from the backtrace for NoMethodError" do - -> { no_such_method() }.should raise_error { |e| e.backtrace.first.should_not include("method_missing") } + -> { no_such_method() }.should.raise { |e| e.backtrace.first.should_not.include?("method_missing") } end end @@ -337,7 +376,7 @@ describe "Invoking a method" do it "with splat operator * and non-Array value uses value unchanged if it does not respond_to?(:to_ary)" do obj = Object.new - obj.should_not respond_to(:to_a) + obj.should_not.respond_to?(:to_a) specs.fooM0R(*obj).should == [obj] specs.fooM1R(1,*obj).should == [1, [obj]] diff --git a/spec/ruby/language/shared/__FILE__.rb b/spec/ruby/language/shared/__FILE__.rb index 3e4f5c958d..7e2e871932 100644 --- a/spec/ruby/language/shared/__FILE__.rb +++ b/spec/ruby/language/shared/__FILE__.rb @@ -9,14 +9,14 @@ describe :language___FILE__, shared: true do end it "equals the absolute path of a file loaded by an absolute path" do - @object.send(@method, @path).should be_true + @object.send(@method, @path).should == true ScratchPad.recorded.should == [@path] end it "equals the absolute path of a file loaded by a relative path" do $LOAD_PATH << "." Dir.chdir CODE_LOADING_DIR do - @object.send(@method, "file_fixture.rb").should be_true + @object.send(@method, "file_fixture.rb").should == true end ScratchPad.recorded.should == [@path] end diff --git a/spec/ruby/language/shared/__LINE__.rb b/spec/ruby/language/shared/__LINE__.rb index 076b74b3ba..6bfc8c1c17 100644 --- a/spec/ruby/language/shared/__LINE__.rb +++ b/spec/ruby/language/shared/__LINE__.rb @@ -9,7 +9,7 @@ describe :language___LINE__, shared: true do end it "equals the line number of the text in a loaded file" do - @object.send(@method, @path).should be_true + @object.send(@method, @path).should == true ScratchPad.recorded.should == [1, 5] end end diff --git a/spec/ruby/language/singleton_class_spec.rb b/spec/ruby/language/singleton_class_spec.rb index 45e1f7f3ad..20256a323c 100644 --- a/spec/ruby/language/singleton_class_spec.rb +++ b/spec/ruby/language/singleton_class_spec.rb @@ -15,39 +15,39 @@ describe "A singleton class" do end it "raises a TypeError for Integer's" do - -> { 1.singleton_class }.should raise_error(TypeError) + -> { 1.singleton_class }.should.raise(TypeError) end it "raises a TypeError for symbols" do - -> { :symbol.singleton_class }.should raise_error(TypeError) + -> { :symbol.singleton_class }.should.raise(TypeError) end it "is a singleton Class instance" do o = mock('x') - o.singleton_class.should be_kind_of(Class) - o.singleton_class.should_not equal(Object) - o.should be_kind_of(o.singleton_class) + o.singleton_class.should.is_a?(Class) + o.singleton_class.should_not.equal?(Object) + o.should.is_a?(o.singleton_class) end it "is a Class for classes" do - ClassSpecs::A.singleton_class.should be_kind_of(Class) + ClassSpecs::A.singleton_class.should.is_a?(Class) end it "inherits from Class for classes" do - Class.should be_ancestor_of(Object.singleton_class) + Object.singleton_class.ancestors.should.include?(Class) end it "is a subclass of Class's singleton class" do ec = ClassSpecs::A.singleton_class - ec.should be_kind_of(Class.singleton_class) + ec.should.is_a?(Class.singleton_class) end it "is a subclass of the same level of Class's singleton class" do ecec = ClassSpecs::A.singleton_class.singleton_class class_ec = Class.singleton_class - ecec.should be_kind_of(class_ec.singleton_class) - ecec.should be_kind_of(class_ec) + ecec.should.is_a?(class_ec.singleton_class) + ecec.should.is_a?(class_ec) end it "is a subclass of a superclass's singleton class" do @@ -60,7 +60,7 @@ describe "A singleton class" do ClassSpecs::H.singleton_class.singleton_class end - it "for BasicObject has Class as it's superclass" do + it "for BasicObject has Class as its superclass" do BasicObject.singleton_class.superclass.should == Class end @@ -74,7 +74,7 @@ describe "A singleton class" do end it "doesn't have singleton class" do - -> { bignum_value.singleton_class }.should raise_error(TypeError) + -> { bignum_value.singleton_class }.should.raise(TypeError) end end @@ -105,20 +105,20 @@ describe "A constant on a singleton class" do end it "is not defined on the object's class" do - @object.class.const_defined?(:CONST).should be_false + @object.class.const_defined?(:CONST).should == false end it "is not defined in the singleton class opener's scope" do class << @object CONST end - -> { CONST }.should raise_error(NameError) + -> { CONST }.should.raise(NameError) end it "cannot be accessed via object::CONST" do -> do @object::CONST - end.should raise_error(TypeError) + end.should.raise(TypeError) end it "raises a NameError for anonymous_module::CONST" do @@ -129,15 +129,15 @@ describe "A constant on a singleton class" do -> do @object::CONST - end.should raise_error(NameError) + end.should.raise(NameError) end it "appears in the singleton class constant list" do - @object.singleton_class.should have_constant(:CONST) + @object.singleton_class.should.const_defined?(:CONST, false) end it "does not appear in the object's class constant list" do - @object.class.should_not have_constant(:CONST) + @object.class.should_not.const_defined?(:CONST) end it "is not preserved when the object is duped" do @@ -145,14 +145,14 @@ describe "A constant on a singleton class" do -> do class << @object; CONST; end - end.should raise_error(NameError) + end.should.raise(NameError) end it "is preserved when the object is cloned" do @object = @object.clone class << @object - CONST.should_not be_nil + CONST.should_not == nil end end end @@ -168,7 +168,7 @@ describe "Defining instance methods on a singleton class" do end it "defines public methods" do - @k_sc.should have_public_instance_method(:singleton_method) + @k_sc.public_instance_methods(false).should.include?(:singleton_method) end end @@ -181,46 +181,46 @@ describe "Instance methods of a singleton class" do end it "include ones of the object's class" do - @k_sc.should have_instance_method(:example_instance_method) + @k_sc.should.method_defined?(:example_instance_method, true) end it "does not include class methods of the object's class" do - @k_sc.should_not have_instance_method(:example_class_method) + @k_sc.should_not.method_defined?(:example_class_method) end it "include instance methods of Object" do - @a_sc.should have_instance_method(:example_instance_method_of_object) + @a_sc.should.method_defined?(:example_instance_method_of_object, true) end it "does not include class methods of Object" do - @a_sc.should_not have_instance_method(:example_class_method_of_object) + @a_sc.should_not.method_defined?(:example_class_method_of_object) end describe "for a class" do it "include instance methods of Class" do - @a_c_sc.should have_instance_method(:example_instance_method_of_class) + @a_c_sc.should.method_defined?(:example_instance_method_of_class, true) end it "does not include class methods of Class" do - @a_c_sc.should_not have_instance_method(:example_class_method_of_class) + @a_c_sc.should_not.method_defined?(:example_class_method_of_class) end it "does not include instance methods of the singleton class of Class" do - @a_c_sc.should_not have_instance_method(:example_instance_method_of_singleton_class) + @a_c_sc.should_not.method_defined?(:example_instance_method_of_singleton_class) end it "does not include class methods of the singleton class of Class" do - @a_c_sc.should_not have_instance_method(:example_class_method_of_singleton_class) + @a_c_sc.should_not.method_defined?(:example_class_method_of_singleton_class) end end describe "for a singleton class" do it "includes instance methods of the singleton class of Class" do - @a_c_sc.singleton_class.should have_instance_method(:example_instance_method_of_singleton_class) + @a_c_sc.singleton_class.should.method_defined?(:example_instance_method_of_singleton_class, true) end it "does not include class methods of the singleton class of Class" do - @a_c_sc.singleton_class.should_not have_instance_method(:example_class_method_of_singleton_class) + @a_c_sc.singleton_class.should_not.method_defined?(:example_class_method_of_singleton_class) end end end @@ -234,46 +234,46 @@ describe "Class methods of a singleton class" do end it "include ones of the object's class" do - @k_sc.should have_method(:example_class_method) + @k_sc.should.respond_to?(:example_class_method) end it "does not include instance methods of the object's class" do - @k_sc.should_not have_method(:example_instance_method) + @k_sc.should_not.respond_to?(:example_instance_method) end it "include instance methods of Class" do - @a_sc.should have_method(:example_instance_method_of_class) + @a_sc.should.respond_to?(:example_instance_method_of_class) end it "does not include class methods of Class" do - @a_sc.should_not have_method(:example_class_method_of_class) + @a_sc.should_not.respond_to?(:example_class_method_of_class) end describe "for a class" do it "include instance methods of Class" do - @a_c_sc.should have_method(:example_instance_method_of_class) + @a_c_sc.should.respond_to?(:example_instance_method_of_class) end it "include class methods of Class" do - @a_c_sc.should have_method(:example_class_method_of_class) + @a_c_sc.should.respond_to?(:example_class_method_of_class) end it "include instance methods of the singleton class of Class" do - @a_c_sc.should have_method(:example_instance_method_of_singleton_class) + @a_c_sc.should.respond_to?(:example_instance_method_of_singleton_class) end it "does not include class methods of the singleton class of Class" do - @a_c_sc.should_not have_method(:example_class_method_of_singleton_class) + @a_c_sc.should_not.respond_to?(:example_class_method_of_singleton_class) end end describe "for a singleton class" do it "include instance methods of the singleton class of Class" do - @a_c_sc.singleton_class.should have_method(:example_instance_method_of_singleton_class) + @a_c_sc.singleton_class.should.respond_to?(:example_instance_method_of_singleton_class) end it "include class methods of the singleton class of Class" do - @a_c_sc.singleton_class.should have_method(:example_class_method_of_singleton_class) + @a_c_sc.singleton_class.should.respond_to?(:example_class_method_of_singleton_class) end end end @@ -282,13 +282,13 @@ describe "Instantiating a singleton class" do it "raises a TypeError when new is called" do -> { Object.new.singleton_class.new - }.should raise_error(TypeError) + }.should.raise(TypeError) end it "raises a TypeError when allocate is called" do -> { Object.new.singleton_class.allocate - }.should raise_error(TypeError) + }.should.raise(TypeError) end end diff --git a/spec/ruby/language/source_encoding_spec.rb b/spec/ruby/language/source_encoding_spec.rb index 7135bc0a70..5a243fa2c3 100644 --- a/spec/ruby/language/source_encoding_spec.rb +++ b/spec/ruby/language/source_encoding_spec.rb @@ -29,7 +29,7 @@ describe "Source files" do touch(path, "wb") { |f| f.write source } begin - ruby_exe(path, args: "2>&1", exit_status: 1).should =~ /invalid multibyte char/ + ruby_exe(path, args: "2>&1", exit_status: 1).b.should =~ /invalid multibyte char/ ensure rm_r path end @@ -51,7 +51,7 @@ describe "Source files" do touch(path, "wb") { |f| f.write source } begin - ruby_exe(path, args: "2>&1", exit_status: 1).should =~ /invalid multibyte char/ + ruby_exe(path, args: "2>&1", exit_status: 1).b.should =~ /invalid multibyte char/ ensure rm_r path end diff --git a/spec/ruby/language/string_spec.rb b/spec/ruby/language/string_spec.rb index 083a7f5db5..163063032f 100644 --- a/spec/ruby/language/string_spec.rb +++ b/spec/ruby/language/string_spec.rb @@ -1,6 +1,7 @@ -# -*- encoding: binary -*- +# encoding: binary require_relative '../spec_helper' +require_relative 'fixtures/class_with_class_variable' # TODO: rewrite these horrid specs. it "are..." seriously?! @@ -27,6 +28,11 @@ describe "Ruby character strings" do "#$ip".should == 'xxx' end + it "interpolate class variables just with the # character" do + object = StringSpecs::ClassWithClassVariable.new + object.foo.should == 'xxx' + end + it "allows underscore as part of a variable name in a simple interpolation" do @my_ip = 'xxx' "#@my_ip".should == 'xxx' @@ -127,6 +133,12 @@ describe "Ruby character strings" do "#{obj}".should == '42' end + it "raise NoMethodError when #to_s is not defined for the object" do + obj = BasicObject.new + + -> { "#{obj}" }.should.raise(NoMethodError) + end + it "uses an internal representation when #to_s doesn't return a String" do obj = mock('to_s') obj.stub!(:to_s).and_return(42) @@ -137,7 +149,7 @@ describe "Ruby character strings" do # is that if you interpolate an object that fails to return # a String, you will still get a String and not raise an # exception. - "#{obj}".should be_an_instance_of(String) + "#{obj}".should.instance_of?(String) end it "allows a dynamic string to parse a nested do...end block as an argument to a call without parens, interpolated" do @@ -275,20 +287,20 @@ describe "Ruby String interpolation" do a = "\u3042" b = "\xff".dup.force_encoding "binary" - -> { "#{a} #{b}" }.should raise_error(Encoding::CompatibilityError) + -> { "#{a} #{b}" }.should.raise(Encoding::CompatibilityError) end it "creates a non-frozen String" do code = <<~'RUBY' - "a#{6*7}c" + "a#{6*7}c" RUBY eval(code).should_not.frozen? end it "creates a non-frozen String when # frozen-string-literal: true is used" do code = <<~'RUBY' - # frozen-string-literal: true - "a#{6*7}c" + # frozen-string-literal: true + "a#{6*7}c" RUBY eval(code).should_not.frozen? end diff --git a/spec/ruby/language/super_spec.rb b/spec/ruby/language/super_spec.rb index 7d9e896d8b..f595d49395 100644 --- a/spec/ruby/language/super_spec.rb +++ b/spec/ruby/language/super_spec.rb @@ -83,8 +83,8 @@ describe "The super keyword" do end end - -> {sub_normal.new.foo}.should raise_error(NoMethodError, /super/) - -> {sub_zsuper.new.foo}.should raise_error(NoMethodError, /super/) + -> {sub_normal.new.foo}.should.raise(NoMethodError, /super/) + -> {sub_zsuper.new.foo}.should.raise(NoMethodError, /super/) end it "uses given block even if arguments are passed explicitly" do @@ -130,7 +130,7 @@ describe "The super keyword" do end end - c2.new.m('a') { raise }.should be_false + c2.new.m('a') { raise }.should == false end it "uses block argument given to method when used in a block" do @@ -200,7 +200,7 @@ describe "The super keyword" do end end - -> { klass.new.a(:a_called) }.should raise_error(RuntimeError) + -> { klass.new.a(:a_called) }.should.raise(RuntimeError) end it "is able to navigate to super, when a method is defined dynamically on the singleton class" do @@ -461,4 +461,18 @@ describe "The super keyword" do @all.foo('a', b: 'b').should == [['a'], {b: 'b'}] end end + + it "works in method definitions using **nil" do + parent = Class.new do + def m(*args, **kwargs) + [args, kwargs] + end + end + child = Class.new(parent) do + def m(*args, **nil) + super + end + end + child.new.m(1, 2).should == [[1, 2], {}] + end end diff --git a/spec/ruby/language/symbol_spec.rb b/spec/ruby/language/symbol_spec.rb index 0801d3223e..81fe06b50b 100644 --- a/spec/ruby/language/symbol_spec.rb +++ b/spec/ruby/language/symbol_spec.rb @@ -3,7 +3,7 @@ require_relative '../spec_helper' describe "A Symbol literal" do it "is a ':' followed by any number of valid characters" do a = :foo - a.should be_kind_of(Symbol) + a.should.is_a?(Symbol) a.inspect.should == ':foo' end @@ -21,7 +21,7 @@ describe "A Symbol literal" do :_Foo, :&, :_9 - ].each { |s| s.should be_kind_of(Symbol) } + ].each { |s| s.should.is_a?(Symbol) } end it "is a ':' followed by a single- or double-quoted string that may contain otherwise invalid characters" do @@ -31,7 +31,7 @@ describe "A Symbol literal" do [:"foo #{1 + 1}", ':"foo 2"'], [:"foo\nbar", ':"foo\nbar"'], ].each { |sym, str| - sym.should be_kind_of(Symbol) + sym.should.is_a?(Symbol) sym.inspect.should == str } end @@ -42,22 +42,22 @@ describe "A Symbol literal" do end it "may contain '::' in the string" do - :'Some::Class'.should be_kind_of(Symbol) + :'Some::Class'.should.is_a?(Symbol) end it "is converted to a literal, unquoted representation if the symbol contains only valid characters" do a, b, c = :'foo', :'+', :'Foo__9' - a.should be_kind_of(Symbol) + a.should.is_a?(Symbol) a.inspect.should == ':foo' - b.should be_kind_of(Symbol) + b.should.is_a?(Symbol) b.inspect.should == ':+' - c.should be_kind_of(Symbol) + c.should.is_a?(Symbol) c.inspect.should == ':Foo__9' end it "can be created by the %s-delimited expression" do a, b = :'foo bar', %s{foo bar} - b.should be_kind_of(Symbol) + b.should.is_a?(Symbol) b.inspect.should == ':"foo bar"' b.should == a end @@ -68,7 +68,7 @@ describe "A Symbol literal" do [:'a string', :'a string'], [:"#{var}", :"#{var}"] ].each { |a, b| - a.should equal(b) + a.should.equal?(b) } end @@ -78,7 +78,7 @@ describe "A Symbol literal" do it "can be an empty string" do c = :'' - c.should be_kind_of(Symbol) + c.should.is_a?(Symbol) c.inspect.should == ':""' end @@ -101,7 +101,7 @@ describe "A Symbol literal" do ScratchPad.record [] -> { eval 'ScratchPad << 1; :"\xC3"' - }.should raise_error(SyntaxError, /invalid symbol/) + }.should.raise(SyntaxError, /invalid symbol/) ScratchPad.recorded.should == [] end end diff --git a/spec/ruby/language/throw_spec.rb b/spec/ruby/language/throw_spec.rb index d723843688..73f64de17d 100644 --- a/spec/ruby/language/throw_spec.rb +++ b/spec/ruby/language/throw_spec.rb @@ -35,7 +35,7 @@ describe "The throw keyword" do throw :exit end end - $!.should be_nil + $!.should == nil end it "allows any object as its argument" do @@ -45,7 +45,7 @@ describe "The throw keyword" do end it "does not convert strings to a symbol" do - -> { catch(:exit) { throw "exit" } }.should raise_error(ArgumentError) + -> { catch(:exit) { throw "exit" } }.should.raise(ArgumentError) end it "unwinds stack from within a method" do @@ -64,8 +64,8 @@ describe "The throw keyword" do end it "raises an ArgumentError if outside of scope of a matching catch" do - -> { throw :test, 5 }.should raise_error(ArgumentError) - -> { catch(:different) { throw :test, 5 } }.should raise_error(ArgumentError) + -> { throw :test, 5 }.should.raise(ArgumentError) + -> { catch(:different) { throw :test, 5 } }.should.raise(ArgumentError) end it "raises an UncaughtThrowError if used to exit a thread" do @@ -73,7 +73,7 @@ describe "The throw keyword" do t = Thread.new { -> { throw :what - }.should raise_error(UncaughtThrowError) + }.should.raise(UncaughtThrowError) } t.join end diff --git a/spec/ruby/language/undef_spec.rb b/spec/ruby/language/undef_spec.rb index 268c0b84c3..98ecd99c21 100644 --- a/spec/ruby/language/undef_spec.rb +++ b/spec/ruby/language/undef_spec.rb @@ -14,42 +14,42 @@ describe "The undef keyword" do @undef_class.class_eval do undef meth end - -> { @obj.meth(5) }.should raise_error(NoMethodError) + -> { @obj.meth(5) }.should.raise(NoMethodError) end it "with a simple symbol" do @undef_class.class_eval do undef :meth end - -> { @obj.meth(5) }.should raise_error(NoMethodError) + -> { @obj.meth(5) }.should.raise(NoMethodError) end it "with a single quoted symbol" do @undef_class.class_eval do undef :'meth' end - -> { @obj.meth(5) }.should raise_error(NoMethodError) + -> { @obj.meth(5) }.should.raise(NoMethodError) end it "with a double quoted symbol" do @undef_class.class_eval do undef :"meth" end - -> { @obj.meth(5) }.should raise_error(NoMethodError) + -> { @obj.meth(5) }.should.raise(NoMethodError) end it "with an interpolated symbol" do @undef_class.class_eval do undef :"#{'meth'}" end - -> { @obj.meth(5) }.should raise_error(NoMethodError) + -> { @obj.meth(5) }.should.raise(NoMethodError) end it "with an interpolated symbol when interpolated expression is not a String literal" do @undef_class.class_eval do undef :"#{'meth'.to_sym}" end - -> { @obj.meth(5) }.should raise_error(NoMethodError) + -> { @obj.meth(5) }.should.raise(NoMethodError) end end @@ -70,7 +70,7 @@ describe "The undef keyword" do Class.new do -> { undef not_exist - }.should raise_error(NameError) { |e| + }.should.raise(NameError) { |e| # a NameError and not a NoMethodError e.class.should == NameError } diff --git a/spec/ruby/language/variables_spec.rb b/spec/ruby/language/variables_spec.rb index eb080eea55..e01e03f01e 100644 --- a/spec/ruby/language/variables_spec.rb +++ b/spec/ruby/language/variables_spec.rb @@ -91,7 +91,7 @@ describe "Multiple assignment" do x = mock("multi-assign single RHS") x.should_receive(:to_ary).and_return(1) - -> { a, b, c = x }.should raise_error(TypeError) + -> { a, b, c = x }.should.raise(TypeError) end it "does not call #to_a to convert an Object RHS when assigning a simple MLHS" do @@ -122,7 +122,7 @@ describe "Multiple assignment" do ary = [1, 2] x = (a, b = ary) - x.should equal(ary) + x.should.equal?(ary) end it "returns the RHS when it is an Array subclass" do @@ -130,7 +130,7 @@ describe "Multiple assignment" do ary = cls.new [1, 2] x = (a, b = ary) - x.should equal(ary) + x.should.equal?(ary) end it "does not call #to_ary on an Array subclass instance" do @@ -172,7 +172,7 @@ describe "Multiple assignment" do x = mock("multi-assign splat") x.should_receive(:to_ary).and_return(1) - -> { *a = x }.should raise_error(TypeError) + -> { *a = x }.should.raise(TypeError) end it "does not call #to_ary on an Array subclass" do @@ -189,8 +189,8 @@ describe "Multiple assignment" do ary = cls.new [1, 2] x = (*a = ary) - x.should equal(ary) - a.should be_an_instance_of(Array) + x.should.equal?(ary) + a.should.instance_of?(Array) end it "calls #to_ary to convert an Object RHS with MLHS" do @@ -205,7 +205,7 @@ describe "Multiple assignment" do x = mock("multi-assign splat") x.should_receive(:to_ary).and_return(1) - -> { a, *b, c = x }.should raise_error(TypeError) + -> { a, *b, c = x }.should.raise(TypeError) end it "does not call #to_a to convert an Object RHS with a MLHS" do @@ -301,7 +301,7 @@ describe "Multiple assignment" do x = mock("multi-assign attributes") x.should_receive(:m).and_return(y) - -> { a, b = x.m }.should raise_error(TypeError) + -> { a, b = x.m }.should.raise(TypeError) end it "assigns values from a RHS method call with receiver and arguments" do @@ -363,7 +363,7 @@ describe "Multiple assignment" do a.should == [] end - ruby_version_is "3.5" do + ruby_version_is "4.0" do it "converts nil to empty array without calling a method" do nil.should_not_receive(:to_a) @@ -372,7 +372,7 @@ describe "Multiple assignment" do end end - ruby_version_is ""..."3.5" do + ruby_version_is ""..."4.0" do it "calls #to_a to convert nil to an empty Array" do nil.should_receive(:to_a).and_return([]) @@ -393,7 +393,7 @@ describe "Multiple assignment" do ary = [1, 2] (a = *ary).should == [1, 2] - a.should_not equal(ary) + a.should_not.equal?(ary) end it "does not call #to_a on an Array subclass" do @@ -412,10 +412,10 @@ describe "Multiple assignment" do x = (a = *ary) x.should == [1, 2] - x.should be_an_instance_of(Array) + x.should.instance_of?(Array) a.should == [1, 2] - a.should be_an_instance_of(Array) + a.should.instance_of?(Array) end it "unfreezes the array returned from calling 'to_a' on the splatted value" do @@ -481,7 +481,7 @@ describe "Multiple assignment" do x = mock("multi-assign RHS splat") x.should_receive(:to_a).and_return(1) - -> { *a = *x }.should raise_error(TypeError) + -> { *a = *x }.should.raise(TypeError) end it "does not call #to_ary to convert an Object RHS with a single splat LHS" do @@ -527,7 +527,7 @@ describe "Multiple assignment" do x = mock("multi-assign splat") x.should_receive(:to_a).and_return(1) - -> { a = *x }.should raise_error(TypeError) + -> { a = *x }.should.raise(TypeError) end it "calls #to_a to convert an Object splat RHS when assigned to a simple MLHS" do @@ -542,7 +542,7 @@ describe "Multiple assignment" do x = mock("multi-assign splat") x.should_receive(:to_a).and_return(1) - -> { a, b, c = *x }.should raise_error(TypeError) + -> { a, b, c = *x }.should.raise(TypeError) end it "does not call #to_ary to convert an Object splat RHS when assigned to a simple MLHS" do @@ -565,7 +565,7 @@ describe "Multiple assignment" do x = mock("multi-assign splat") x.should_receive(:to_a).and_return(1) - -> { a, *b, c = *x }.should raise_error(TypeError) + -> { a, *b, c = *x }.should.raise(TypeError) end it "does not call #to_ary to convert an Object RHS with a MLHS" do @@ -645,7 +645,7 @@ describe "Multiple assignment" do x = mock("multi-assign splat MRHS") x.should_receive(:to_a).and_return(1) - -> { a, *b = 1, *x }.should raise_error(TypeError) + -> { a, *b = 1, *x }.should.raise(TypeError) end it "does not call #to_ary to convert a splatted Object as part of a MRHS with a splat MRHS" do @@ -668,7 +668,7 @@ describe "Multiple assignment" do x = mock("multi-assign splat MRHS") x.should_receive(:to_a).and_return(1) - -> { a, *b = *x, 1 }.should raise_error(TypeError) + -> { a, *b = *x, 1 }.should.raise(TypeError) end it "does not call #to_ary to convert a splatted Object with a splat MRHS" do @@ -717,7 +717,7 @@ describe "Multiple assignment" do x = mock("multi-assign mixed RHS") x.should_receive(:to_ary).and_return(x) - -> { a, (b, c), d = 1, x, 3, 4 }.should raise_error(TypeError) + -> { a, (b, c), d = 1, x, 3, 4 }.should.raise(TypeError) end it "calls #to_a to convert a splatted Object value in a MRHS" do @@ -741,7 +741,7 @@ describe "Multiple assignment" do x = mock("multi-assign mixed splatted RHS") x.should_receive(:to_ary).and_return(x) - -> { a, *b, (c, d) = 1, 2, 3, *x }.should raise_error(TypeError) + -> { a, *b, (c, d) = 1, 2, 3, *x }.should.raise(TypeError) end it "does not call #to_ary to convert an Object when the position receiving the value is a simple variable" do @@ -889,7 +889,7 @@ describe 'Allowed characters' do ἍBB = 1 end CODE - end.should raise_error(SyntaxError, /dynamic constant assignment/) + end.should.raise(SyntaxError, /dynamic constant assignment/) end end diff --git a/spec/ruby/language/while_spec.rb b/spec/ruby/language/while_spec.rb index e172453ca6..b9bf32047d 100644 --- a/spec/ruby/language/while_spec.rb +++ b/spec/ruby/language/while_spec.rb @@ -88,7 +88,7 @@ describe "The while expression" do break if c c = false ) - end.should be_nil + end.should == nil end it "stops running body if interrupted by break in a begin ... end element op-assign-or value" do @@ -99,7 +99,7 @@ describe "The while expression" do break if c c = false end - end.should be_nil + end.should == nil end it "stops running body if interrupted by break in a parenthesized element op-assign value" do @@ -111,7 +111,7 @@ describe "The while expression" do break if c c = false ) - end.should be_nil + end.should == nil a.should == [1, 2] end @@ -123,7 +123,7 @@ describe "The while expression" do break if c c = false end - end.should be_nil + end.should == nil a.should == [1, 2] end @@ -139,7 +139,7 @@ describe "The while expression" do break unless d d = false ) - end.should be_nil + end.should == nil end it "stops running body if interrupted by break with unless in a begin ... end attribute op-assign-or value" do @@ -153,7 +153,7 @@ describe "The while expression" do break unless d d = false end - end.should be_nil + end.should == nil end it "stops running body if interrupted by break in a parenthesized attribute op-assign-or value" do @@ -168,7 +168,7 @@ describe "The while expression" do break if c c = false ) - end.should be_nil + end.should == nil end it "stops running body if interrupted by break in a begin ... end attribute op-assign-or value" do @@ -182,7 +182,7 @@ describe "The while expression" do break if c c = false end - end.should be_nil + end.should == nil end it "returns value passed to break if interrupted by break" do diff --git a/spec/ruby/language/yield_spec.rb b/spec/ruby/language/yield_spec.rb index e125cf8e73..3173f41b0c 100644 --- a/spec/ruby/language/yield_spec.rb +++ b/spec/ruby/language/yield_spec.rb @@ -13,7 +13,7 @@ describe "The yield call" do describe "taking no arguments" do it "raises a LocalJumpError when the method is not passed a block" do - -> { @y.z }.should raise_error(LocalJumpError) + -> { @y.z }.should.raise(LocalJumpError) end it "ignores assignment to the explicit block argument and calls the passed block" do @@ -28,7 +28,7 @@ describe "The yield call" do describe "taking a single argument" do describe "when no block is given" do it "raises a LocalJumpError" do - -> { @y.s(1) }.should raise_error(LocalJumpError) + -> { @y.s(1) }.should.raise(LocalJumpError) end end @@ -48,6 +48,12 @@ describe "The yield call" do it "passes a single, multi-value Array" do @y.s([1, 2, 3]) { |*a| a }.should == [[1, 2, 3]] end + + describe "with optional argument" do + it "does not destructure a single array argument" do + @y.s([1, 2, 3]) { |a = 99| a }.should == [1, 2, 3] + end + end end describe "yielding to a lambda" do @@ -70,20 +76,20 @@ describe "The yield call" do it "raises an ArgumentError if too few arguments are passed" do -> { @y.s(1, &-> a, b { [a,b] }) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end it "should not destructure an Array into multiple arguments" do -> { @y.s([1, 2], &-> a, b { [a,b] }) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end end end describe "taking multiple arguments" do it "raises a LocalJumpError when the method is not passed a block" do - -> { @y.m(1, 2, 3) }.should raise_error(LocalJumpError) + -> { @y.m(1, 2, 3) }.should.raise(LocalJumpError) end it "passes the arguments to the block" do @@ -97,19 +103,19 @@ describe "The yield call" do it "raises an ArgumentError if too many arguments are passed to a lambda" do -> { @y.m(1, 2, 3, &-> a { }) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end it "raises an ArgumentError if too few arguments are passed to a lambda" do -> { @y.m(1, 2, 3, &-> a, b, c, d { }) - }.should raise_error(ArgumentError) + }.should.raise(ArgumentError) end end describe "taking a single splatted argument" do it "raises a LocalJumpError when the method is not passed a block" do - -> { @y.r(0) }.should raise_error(LocalJumpError) + -> { @y.r(0) }.should.raise(LocalJumpError) end it "passes a single value" do @@ -141,7 +147,7 @@ describe "The yield call" do describe "taking multiple arguments with a splat" do it "raises a LocalJumpError when the method is not passed a block" do - -> { @y.rs(1, 2, [3, 4]) }.should raise_error(LocalJumpError) + -> { @y.rs(1, 2, [3, 4]) }.should.raise(LocalJumpError) end it "passes the arguments to the block" do @@ -166,7 +172,7 @@ describe "The yield call" do describe "taking matching arguments with splats and post args" do it "raises a LocalJumpError when the method is not passed a block" do - -> { @y.rs(1, 2, [3, 4]) }.should raise_error(LocalJumpError) + -> { @y.rs(1, 2, [3, 4]) }.should.raise(LocalJumpError) end it "passes the arguments to the block" do @@ -193,7 +199,7 @@ describe "Using yield in a singleton class literal" do end RUBY - -> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/) + -> { eval(code) }.should.raise(SyntaxError, /Invalid yield/) end end @@ -203,7 +209,7 @@ describe "Using yield in non-lambda block" do 1.times { yield } RUBY - -> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/) + -> { eval(code) }.should.raise(SyntaxError, /Invalid yield/) end end @@ -215,6 +221,6 @@ describe "Using yield in a module literal" do end RUBY - -> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/) + -> { eval(code) }.should.raise(SyntaxError, /Invalid yield/) end end |
