diff options
author | Benoit Daloze <[email protected]> | 2021-03-27 13:02:41 +0100 |
---|---|---|
committer | Benoit Daloze <[email protected]> | 2021-03-27 13:02:41 +0100 |
commit | 95d9fe9538441eb57ee6752aa1c5088fc6608e34 (patch) | |
tree | 9a0bb070fd8042b83470f7a0bf9cd462c919c7c0 /spec/ruby/language | |
parent | 44736a6b7a2b3475db2d05187f33e3c1a7b4b4e5 (diff) |
Update to ruby/spec@fd6eddd
Diffstat (limited to 'spec/ruby/language')
-rw-r--r-- | spec/ruby/language/constants_spec.rb | 46 | ||||
-rw-r--r-- | spec/ruby/language/ensure_spec.rb | 4 | ||||
-rw-r--r-- | spec/ruby/language/hash_spec.rb | 39 | ||||
-rw-r--r-- | spec/ruby/language/method_spec.rb | 11 | ||||
-rw-r--r-- | spec/ruby/language/optional_assignments_spec.rb | 105 | ||||
-rw-r--r-- | spec/ruby/language/regexp/grouping_spec.rb | 7 | ||||
-rw-r--r-- | spec/ruby/language/rescue_spec.rb | 4 | ||||
-rw-r--r-- | spec/ruby/language/string_spec.rb | 10 |
8 files changed, 176 insertions, 50 deletions
diff --git a/spec/ruby/language/constants_spec.rb b/spec/ruby/language/constants_spec.rb index 6d3b1a5dd7..760b9d4a24 100644 --- a/spec/ruby/language/constants_spec.rb +++ b/spec/ruby/language/constants_spec.rb @@ -381,52 +381,6 @@ describe "Constant resolution within methods" do ConstantSpecs::ClassA.constx.should == :CS_CONSTX ConstantSpecs::ClassA.new.constx.should == :CS_CONSTX end - - describe "with ||=" do - it "assigns a scoped constant if previously undefined" do - ConstantSpecs.should_not have_constant(:OpAssignUndefined) - module ConstantSpecs - OpAssignUndefined ||= 42 - end - ConstantSpecs::OpAssignUndefined.should == 42 - ConstantSpecs::OpAssignUndefinedOutside ||= 42 - ConstantSpecs::OpAssignUndefinedOutside.should == 42 - ConstantSpecs.send(:remove_const, :OpAssignUndefined) - ConstantSpecs.send(:remove_const, :OpAssignUndefinedOutside) - end - - it "assigns a global constant if previously undefined" do - OpAssignGlobalUndefined ||= 42 - ::OpAssignGlobalUndefinedExplicitScope ||= 42 - OpAssignGlobalUndefined.should == 42 - ::OpAssignGlobalUndefinedExplicitScope.should == 42 - Object.send :remove_const, :OpAssignGlobalUndefined - Object.send :remove_const, :OpAssignGlobalUndefinedExplicitScope - end - - end - - describe "with &&=" do - it "re-assigns a scoped constant if already true" do - module ConstantSpecs - OpAssignTrue = true - end - suppress_warning do - ConstantSpecs::OpAssignTrue &&= 1 - end - ConstantSpecs::OpAssignTrue.should == 1 - ConstantSpecs.send :remove_const, :OpAssignTrue - end - - it "leaves scoped constant if not true" do - module ConstantSpecs - OpAssignFalse = false - end - ConstantSpecs::OpAssignFalse &&= 1 - ConstantSpecs::OpAssignFalse.should == false - ConstantSpecs.send :remove_const, :OpAssignFalse - end - end end describe "Constant resolution within a singleton class (class << obj)" do diff --git a/spec/ruby/language/ensure_spec.rb b/spec/ruby/language/ensure_spec.rb index e94c523e82..e893904bcb 100644 --- a/spec/ruby/language/ensure_spec.rb +++ b/spec/ruby/language/ensure_spec.rb @@ -74,9 +74,9 @@ describe "An ensure block inside a begin block" do ensure raise "from ensure" end - }.should raise_error(RuntimeError, "from ensure") do |e| + }.should raise_error(RuntimeError, "from ensure") { |e| e.cause.message.should == "from block" - end + } end end diff --git a/spec/ruby/language/hash_spec.rb b/spec/ruby/language/hash_spec.rb index d6600ddb4a..afc0df12a2 100644 --- a/spec/ruby/language/hash_spec.rb +++ b/spec/ruby/language/hash_spec.rb @@ -167,3 +167,42 @@ describe "Hash literal" do usascii_hash.keys.first.encoding.should == Encoding::US_ASCII end end + +describe "The ** operator" do + it "makes a copy when calling a method taking a keyword rest argument" 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 + + ruby_version_is ""..."3.0" do + it "makes a caller-side 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 + end + + ruby_version_is "3.0" do + it "does not 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.equal?(h) + h.should == { two: 2 } + end + end +end diff --git a/spec/ruby/language/method_spec.rb b/spec/ruby/language/method_spec.rb index 462a182b3d..449d5e6f1b 100644 --- a/spec/ruby/language/method_spec.rb +++ b/spec/ruby/language/method_spec.rb @@ -1758,6 +1758,17 @@ describe "A method" do end end end + + it "assigns the last Hash to the last optional argument if the Hash contains non-Symbol keys and is not passed as keywords" do + def m(a = nil, b = {}, v: false) + [a, b, v] + end + + h = { "key" => "value" } + m(:a, h).should == [:a, h, false] + m(:a, h, v: true).should == [:a, h, true] + m(v: true).should == [nil, {}, true] + end end describe "A method call with a space between method name and parentheses" do diff --git a/spec/ruby/language/optional_assignments_spec.rb b/spec/ruby/language/optional_assignments_spec.rb index 3d9e0dbb65..217dcab74b 100644 --- a/spec/ruby/language/optional_assignments_spec.rb +++ b/spec/ruby/language/optional_assignments_spec.rb @@ -1,4 +1,5 @@ require_relative '../spec_helper' +require_relative '../fixtures/constants' describe 'Optional variable assignments' do describe 'using ||=' do @@ -351,3 +352,107 @@ describe 'Optional variable assignments' do end end end + +describe 'Optional constant assignment' do + describe 'with ||=' do + it "assigns a scoped constant if previously undefined" do + ConstantSpecs.should_not have_constant(:OpAssignUndefined) + module ConstantSpecs + OpAssignUndefined ||= 42 + end + ConstantSpecs::OpAssignUndefined.should == 42 + ConstantSpecs::OpAssignUndefinedOutside ||= 42 + ConstantSpecs::OpAssignUndefinedOutside.should == 42 + ConstantSpecs.send(:remove_const, :OpAssignUndefined) + ConstantSpecs.send(:remove_const, :OpAssignUndefinedOutside) + end + + it "assigns a global constant if previously undefined" do + OpAssignGlobalUndefined ||= 42 + ::OpAssignGlobalUndefinedExplicitScope ||= 42 + OpAssignGlobalUndefined.should == 42 + ::OpAssignGlobalUndefinedExplicitScope.should == 42 + Object.send :remove_const, :OpAssignGlobalUndefined + Object.send :remove_const, :OpAssignGlobalUndefinedExplicitScope + end + + it 'correctly defines non-existing constants' do + ConstantSpecs::ClassA::OR_ASSIGNED_CONSTANT1 ||= :assigned + ConstantSpecs::ClassA::OR_ASSIGNED_CONSTANT1.should == :assigned + end + + it 'correctly overwrites nil constants' do + suppress_warning do # already initialized constant + ConstantSpecs::ClassA::NIL_OR_ASSIGNED_CONSTANT1 = nil + ConstantSpecs::ClassA::NIL_OR_ASSIGNED_CONSTANT1 ||= :assigned + ConstantSpecs::ClassA::NIL_OR_ASSIGNED_CONSTANT1.should == :assigned + end + end + + it 'causes side-effects of the module part to be applied only once (for undefined constant)' do + x = 0 + (x += 1; ConstantSpecs::ClassA)::OR_ASSIGNED_CONSTANT2 ||= :assigned + x.should == 1 + ConstantSpecs::ClassA::OR_ASSIGNED_CONSTANT2.should == :assigned + end + + it 'causes side-effects of the module part to be applied (for nil constant)' do + suppress_warning do # already initialized constant + ConstantSpecs::ClassA::NIL_OR_ASSIGNED_CONSTANT2 = nil + x = 0 + (x += 1; ConstantSpecs::ClassA)::NIL_OR_ASSIGNED_CONSTANT2 ||= :assigned + x.should == 1 + ConstantSpecs::ClassA::NIL_OR_ASSIGNED_CONSTANT2.should == :assigned + end + end + + it 'does not evaluate the right-hand side if the module part raises an exception (for undefined constant)' do + x = 0 + y = 0 + + -> { + (x += 1; raise Exception; ConstantSpecs::ClassA)::OR_ASSIGNED_CONSTANT3 ||= (y += 1; :assigned) + }.should raise_error(Exception) + + x.should == 1 + y.should == 0 + defined?(ConstantSpecs::ClassA::OR_ASSIGNED_CONSTANT3).should == nil + end + + it 'does not evaluate the right-hand side if the module part raises an exception (for nil constant)' do + ConstantSpecs::ClassA::NIL_OR_ASSIGNED_CONSTANT3 = nil + x = 0 + y = 0 + + -> { + (x += 1; raise Exception; ConstantSpecs::ClassA)::NIL_OR_ASSIGNED_CONSTANT3 ||= (y += 1; :assigned) + }.should raise_error(Exception) + + x.should == 1 + y.should == 0 + ConstantSpecs::ClassA::NIL_OR_ASSIGNED_CONSTANT3.should == nil + end + end + + describe "with &&=" do + it "re-assigns a scoped constant if already true" do + module ConstantSpecs + OpAssignTrue = true + end + suppress_warning do + ConstantSpecs::OpAssignTrue &&= 1 + end + ConstantSpecs::OpAssignTrue.should == 1 + ConstantSpecs.send :remove_const, :OpAssignTrue + end + + it "leaves scoped constant if not true" do + module ConstantSpecs + OpAssignFalse = false + end + ConstantSpecs::OpAssignFalse &&= 1 + ConstantSpecs::OpAssignFalse.should == false + ConstantSpecs.send :remove_const, :OpAssignFalse + end + end +end diff --git a/spec/ruby/language/regexp/grouping_spec.rb b/spec/ruby/language/regexp/grouping_spec.rb index 2fecf2d2cb..e2abe71d0d 100644 --- a/spec/ruby/language/regexp/grouping_spec.rb +++ b/spec/ruby/language/regexp/grouping_spec.rb @@ -25,4 +25,11 @@ describe "Regexps with grouping" do -> { Regexp.new("(?<1a>a)") }.should raise_error(RegexpError) -> { Regexp.new("(?<-a>a)") }.should raise_error(RegexpError) end + + it "ignore capture groups in line comments" do + /^ + (a) # there is a capture group on this line + b # there is no capture group on this line (not even here) + $/x.match("ab").to_a.should == [ "ab", "a" ] + end end diff --git a/spec/ruby/language/rescue_spec.rb b/spec/ruby/language/rescue_spec.rb index 54cbae1440..1c78f3935a 100644 --- a/spec/ruby/language/rescue_spec.rb +++ b/spec/ruby/language/rescue_spec.rb @@ -428,9 +428,9 @@ describe "The rescue keyword" do raise "from block" rescue (raise "from rescue expression") end - }.should raise_error(RuntimeError, "from rescue expression") do |e| + }.should raise_error(RuntimeError, "from rescue expression") { |e| e.cause.message.should == "from block" - end + } end it "should splat the handling Error classes" do diff --git a/spec/ruby/language/string_spec.rb b/spec/ruby/language/string_spec.rb index 0178083f58..ce4941569e 100644 --- a/spec/ruby/language/string_spec.rb +++ b/spec/ruby/language/string_spec.rb @@ -308,4 +308,14 @@ describe "Ruby String interpolation" do eval(code).should_not.frozen? end end + + ruby_version_is ""..."3.0" do + it "creates a frozen String when # frozen-string-literal: true is used" do + code = <<~'RUBY' + # frozen-string-literal: true + "a#{6*7}c" + RUBY + eval(code).should.frozen? + end + end end |