aboutsummaryrefslogtreecommitdiffstats
path: root/spec/ruby/language
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2021-03-27 13:02:41 +0100
committerBenoit Daloze <eregontp@gmail.com>2021-03-27 13:02:41 +0100
commit95d9fe9538441eb57ee6752aa1c5088fc6608e34 (patch)
tree9a0bb070fd8042b83470f7a0bf9cd462c919c7c0 /spec/ruby/language
parent44736a6b7a2b3475db2d05187f33e3c1a7b4b4e5 (diff)
downloadruby-95d9fe9538441eb57ee6752aa1c5088fc6608e34.tar.gz
Update to ruby/spec@fd6eddd
Diffstat (limited to 'spec/ruby/language')
-rw-r--r--spec/ruby/language/constants_spec.rb46
-rw-r--r--spec/ruby/language/ensure_spec.rb4
-rw-r--r--spec/ruby/language/hash_spec.rb39
-rw-r--r--spec/ruby/language/method_spec.rb11
-rw-r--r--spec/ruby/language/optional_assignments_spec.rb105
-rw-r--r--spec/ruby/language/regexp/grouping_spec.rb7
-rw-r--r--spec/ruby/language/rescue_spec.rb4
-rw-r--r--spec/ruby/language/string_spec.rb10
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