summaryrefslogtreecommitdiff
path: root/spec/ruby/core/kernel/eval_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/kernel/eval_spec.rb')
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb128
1 files changed, 117 insertions, 11 deletions
diff --git a/spec/ruby/core/kernel/eval_spec.rb b/spec/ruby/core/kernel/eval_spec.rb
index cf3cd47a43..e027294347 100644
--- a/spec/ruby/core/kernel/eval_spec.rb
+++ b/spec/ruby/core/kernel/eval_spec.rb
@@ -135,7 +135,7 @@ describe "Kernel#eval" do
it "includes file and line information in syntax error" do
expected = 'speccing.rb'
-> {
- eval('if true',TOPLEVEL_BINDING, expected)
+ eval('if true', TOPLEVEL_BINDING, expected)
}.should raise_error(SyntaxError) { |e|
e.message.should =~ /#{expected}:1:.+/
}
@@ -144,7 +144,7 @@ describe "Kernel#eval" do
it "evaluates string with given filename and negative linenumber" do
expected_file = 'speccing.rb'
-> {
- eval('if true',TOPLEVEL_BINDING, expected_file, -100)
+ eval('if true', TOPLEVEL_BINDING, expected_file, -100)
}.should raise_error(SyntaxError) { |e|
e.message.should =~ /#{expected_file}:-100:.+/
}
@@ -175,6 +175,75 @@ describe "Kernel#eval" do
end
end
+ context "parameter forwarding" do
+ it "allows anonymous rest parameter forwarding" do
+ object = Object.new
+ def object.foo(a, b, c)
+ [a, b, c]
+ end
+ def object.bar(*)
+ eval "foo(*)"
+ end
+
+ object.bar(1, 2, 3).should == [1, 2, 3]
+ end
+
+ it "allows anonymous keyword parameters forwarding" do
+ object = Object.new
+ def object.foo(a:, b:, c:)
+ [a, b, c]
+ end
+ def object.bar(**)
+ eval "foo(**)"
+ end
+
+ object.bar(a: 1, b: 2, c: 3).should == [1, 2, 3]
+ end
+
+ it "allows anonymous block parameter forwarding" do
+ object = Object.new
+ def object.foo(&block)
+ block.call
+ end
+ def object.bar(&)
+ eval "foo(&)"
+ end
+
+ object.bar { :foobar }.should == :foobar
+ end
+
+ it "allows ... forwarding" do
+ object = Object.new
+ def object.foo(a, b:, &block)
+ [a, b, block.call]
+ end
+ def object.bar(...)
+ eval "foo(...)"
+ end
+
+ object.bar(1, b: 2) { 3 }.should == [1, 2, 3]
+ end
+
+ it "allows parameter forwarding to super" do
+ m = Module.new do
+ def foo(a, b:, &block)
+ [a, b, block.call]
+ end
+ end
+
+ c = Class.new do
+ include m
+
+ def foo(a, b:, &block)
+ eval "super"
+ end
+ end
+
+ object = c.new
+ object.foo(1, b: 2) { 3 }.should == [1, 2, 3]
+ end
+ end
+
ruby_version_is "3.3" do
it "uses (eval at __FILE__:__LINE__) if none is provided" do
eval("__FILE__").should == "(eval at #{__FILE__}:#{__LINE__})"
@@ -274,6 +343,26 @@ describe "Kernel#eval" do
eval("").should == nil
end
+ context "with shebang" do
+ it "ignores shebang with ruby interpreter" do
+ pid = eval(<<~CODE.b)
+ #!/usr/bin/env ruby
+ Process.pid
+ CODE
+
+ pid.should == Process.pid
+ end
+
+ it "ignores shebang with non-ruby interpreter" do
+ pid = eval(<<~CODE.b)
+ #!/usr/bin/env puma
+ Process.pid
+ CODE
+
+ pid.should == Process.pid
+ end
+ end
+
# See language/magic_comment_spec.rb for more magic comments specs
describe "with a magic encoding comment" do
it "uses the magic comment encoding for the encoding of literal strings" do
@@ -293,6 +382,8 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπ")
EvalSpecs::Vπ.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπ)
end
it "allows an emacs-style magic comment encoding" do
@@ -306,6 +397,8 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπemacs")
EvalSpecs::Vπemacs.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπemacs)
end
it "allows spaces before the magic encoding comment" do
@@ -319,6 +412,8 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπspaces")
EvalSpecs::Vπspaces.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπspaces)
end
it "allows a shebang line before the magic encoding comment" do
@@ -333,6 +428,8 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπshebang")
EvalSpecs::Vπshebang.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπshebang)
end
it "allows a shebang line and some spaces before the magic encoding comment" do
@@ -347,15 +444,16 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπshebang_spaces")
EvalSpecs::Vπshebang_spaces.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπshebang_spaces)
end
it "allows a magic encoding comment and a subsequent frozen_string_literal magic comment" do
- # Make sure frozen_string_literal is not default true
- eval("'foo'".b).frozen?.should be_false
+ frozen_string_default = "test".frozen?
code = <<CODE.b
# encoding: UTF-8
-# frozen_string_literal: true
+# frozen_string_literal: #{!frozen_string_default}
class EvalSpecs
Vπstring = "frozen"
end
@@ -365,7 +463,9 @@ CODE
EvalSpecs.constants(false).should include(:"Vπstring")
EvalSpecs::Vπstring.should == "frozen"
EvalSpecs::Vπstring.encoding.should == Encoding::UTF_8
- EvalSpecs::Vπstring.frozen?.should be_true
+ EvalSpecs::Vπstring.frozen?.should == !frozen_string_default
+ ensure
+ EvalSpecs.send(:remove_const, :Vπstring)
end
it "allows a magic encoding comment and a frozen_string_literal magic comment on the same line in emacs style" do
@@ -381,11 +481,14 @@ CODE
EvalSpecs::Vπsame_line.should == "frozen"
EvalSpecs::Vπsame_line.encoding.should == Encoding::UTF_8
EvalSpecs::Vπsame_line.frozen?.should be_true
+ ensure
+ EvalSpecs.send(:remove_const, :Vπsame_line)
end
it "ignores the magic encoding comment if it is after a frozen_string_literal magic comment" do
+ frozen_string_default = "test".frozen?
code = <<CODE.b
-# frozen_string_literal: true
+# frozen_string_literal: #{!frozen_string_default}
# encoding: UTF-8
class EvalSpecs
Vπfrozen_first = "frozen"
@@ -399,23 +502,26 @@ CODE
value = EvalSpecs.const_get(binary_constant)
value.should == "frozen"
value.encoding.should == Encoding::BINARY
- value.frozen?.should be_true
+ value.frozen?.should == !frozen_string_default
+ ensure
+ EvalSpecs.send(:remove_const, binary_constant)
end
it "ignores the frozen_string_literal magic comment if it appears after a token and warns if $VERBOSE is true" do
+ frozen_string_default = "test".frozen?
code = <<CODE
some_token_before_magic_comment = :anything
-# frozen_string_literal: true
+# frozen_string_literal: #{!frozen_string_default}
class EvalSpecs
Vπstring_not_frozen = "not frozen"
end
CODE
-> { eval(code) }.should complain(/warning: [`']frozen_string_literal' is ignored after any tokens/, verbose: true)
- EvalSpecs::Vπstring_not_frozen.frozen?.should be_false
+ EvalSpecs::Vπstring_not_frozen.frozen?.should == frozen_string_default
EvalSpecs.send :remove_const, :Vπstring_not_frozen
-> { eval(code) }.should_not complain(verbose: false)
- EvalSpecs::Vπstring_not_frozen.frozen?.should be_false
+ EvalSpecs::Vπstring_not_frozen.frozen?.should == frozen_string_default
EvalSpecs.send :remove_const, :Vπstring_not_frozen
end
end