diff options
Diffstat (limited to 'spec/ruby/language/assignments_spec.rb')
| -rw-r--r-- | spec/ruby/language/assignments_spec.rb | 199 |
1 files changed, 148 insertions, 51 deletions
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 |
