diff options
Diffstat (limited to 'spec/ruby/language/predefined_spec.rb')
| -rw-r--r-- | spec/ruby/language/predefined_spec.rb | 218 |
1 files changed, 182 insertions, 36 deletions
diff --git a/spec/ruby/language/predefined_spec.rb b/spec/ruby/language/predefined_spec.rb index 5acfa6d0ab..fc1667a38f 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' @@ -88,8 +89,8 @@ describe "Predefined global $~" do $~ = /foo/.match("foo") $~.should be_an_instance_of(MatchData) - -> { $~ = Object.new }.should raise_error(TypeError) - -> { $~ = 1 }.should raise_error(TypeError) + -> { $~ = Object.new }.should raise_error(TypeError, 'wrong argument type Object (expected MatchData)') + -> { $~ = 1 }.should raise_error(TypeError, 'wrong argument type Integer (expected MatchData)') end it "changes the value of derived capture globals when assigned" do @@ -136,6 +137,19 @@ describe "Predefined global $&" do "abc".dup.force_encoding(Encoding::EUC_JP) =~ /b/ $&.encoding.should equal(Encoding::EUC_JP) end + + it "is read-only" do + -> { + eval %q{$& = ""} + }.should raise_error(SyntaxError, /Can't set variable \$&/) + end + + it "is read-only when aliased" do + alias $predefined_spec_ampersand $& + -> { + $predefined_spec_ampersand = "" + }.should raise_error(NameError, '$predefined_spec_ampersand is a read-only variable') + end end describe "Predefined global $`" do @@ -154,6 +168,19 @@ describe "Predefined global $`" do "abc".dup.force_encoding(Encoding::ISO_8859_1) =~ /a/ $`.encoding.should equal(Encoding::ISO_8859_1) end + + it "is read-only" do + -> { + eval %q{$` = ""} + }.should raise_error(SyntaxError, /Can't set variable \$`/) + end + + it "is read-only when aliased" do + alias $predefined_spec_backquote $` + -> { + $predefined_spec_backquote = "" + }.should raise_error(NameError, '$predefined_spec_backquote is a read-only variable') + end end describe "Predefined global $'" do @@ -172,6 +199,19 @@ describe "Predefined global $'" do "abc".dup.force_encoding(Encoding::ISO_8859_1) =~ /c/ $'.encoding.should equal(Encoding::ISO_8859_1) end + + it "is read-only" do + -> { + eval %q{$' = ""} + }.should raise_error(SyntaxError, /Can't set variable \$'/) + end + + it "is read-only when aliased" do + alias $predefined_spec_single_quote $' + -> { + $predefined_spec_single_quote = "" + }.should raise_error(NameError, '$predefined_spec_single_quote is a read-only variable') + end end describe "Predefined global $+" do @@ -190,6 +230,19 @@ describe "Predefined global $+" do "abc".dup.force_encoding(Encoding::EUC_JP) =~ /(b)/ $+.encoding.should equal(Encoding::EUC_JP) end + + it "is read-only" do + -> { + eval %q{$+ = ""} + }.should raise_error(SyntaxError, /Can't set variable \$\+/) + end + + it "is read-only when aliased" do + alias $predefined_spec_plus $+ + -> { + $predefined_spec_plus = "" + }.should raise_error(NameError, '$predefined_spec_plus is a read-only variable') + end end describe "Predefined globals $1..N" do @@ -229,7 +282,7 @@ 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_error(TypeError, '$stdout must have write method, NilClass given') end it "raises TypeError error if assigned to object that doesn't respond to #write" do @@ -253,6 +306,12 @@ describe "Predefined global $!" do $!.should == nil end + it "is read-only" do + -> { + $! = [] + }.should raise_error(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 be_an_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 be_an_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_error(ArgumentError, '$! not set') + end +end + # Input/Output Variables # --------------------------------------------------------------------------------------------------- # @@ -559,7 +687,7 @@ 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 @@ -567,7 +695,7 @@ describe "Predefined global $/" do 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") @@ -610,15 +738,19 @@ describe "Predefined global $/" do obj = mock("$/ value") obj.should_not_receive(:to_str) - -> { $/ = obj }.should raise_error(TypeError) + -> { $/ = obj }.should raise_error(TypeError, 'value of $/ must be String') end it "raises a TypeError if assigned an Integer" do - -> { $/ = 1 }.should raise_error(TypeError) + -> { $/ = 1 }.should raise_error(TypeError, 'value of $/ must be String') end it "raises a TypeError if assigned a boolean" do - -> { $/ = true }.should raise_error(TypeError) + -> { $/ = true }.should raise_error(TypeError, 'value of $/ must be String') + end + + it "warns if assigned non-nil" do + -> { $/ = "_" }.should complain(/warning: (?:non-nil )?[`']\$\/' is deprecated/) end end @@ -635,7 +767,7 @@ 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 @@ -643,7 +775,7 @@ describe "Predefined global $-0" do 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") @@ -687,15 +819,19 @@ describe "Predefined global $-0" do obj = mock("$-0 value") obj.should_not_receive(:to_str) - -> { $-0 = obj }.should raise_error(TypeError) + -> { $-0 = obj }.should raise_error(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_error(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_error(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 @@ -729,12 +865,16 @@ describe "Predefined global $\\" do obj = mock("$\\ value") obj.should_not_receive(:to_str) - -> { $\ = obj }.should raise_error(TypeError) + -> { $\ = obj }.should raise_error(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_error(TypeError, 'value of $\ must be String') + -> { $\ = true }.should raise_error(TypeError, 'value of $\ must be String') + end + + it "warns if assigned non-nil" do + -> { $\ = "_" }.should complain(/warning: (?:non-nil )?[`']\$\\' is deprecated/) end end @@ -748,11 +888,11 @@ describe "Predefined global $," do end it "raises TypeError if assigned a non-String" do - -> { $, = Object.new }.should raise_error(TypeError) + -> { $, = Object.new }.should raise_error(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 @@ -789,7 +929,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 @@ -933,22 +1073,28 @@ describe "Execution variable $:" do it "is read-only" do -> { $: = [] - }.should raise_error(NameError) + }.should raise_error(NameError, '$: is a read-only variable') -> { $LOAD_PATH = [] - }.should raise_error(NameError) + }.should raise_error(NameError, '$LOAD_PATH is a read-only variable') -> { $-I = [] - }.should raise_error(NameError) + }.should raise_error(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 @@ -963,11 +1109,11 @@ describe "Global variable $\"" do it "is read-only" do -> { $" = [] - }.should raise_error(NameError) + }.should raise_error(NameError, '$" is a read-only variable') -> { $LOADED_FEATURES = [] - }.should raise_error(NameError) + }.should raise_error(NameError, '$LOADED_FEATURES is a read-only variable') end end @@ -975,7 +1121,7 @@ describe "Global variable $<" do it "is read-only" do -> { $< = nil - }.should raise_error(NameError) + }.should raise_error(NameError, '$< is a read-only variable') end end @@ -983,7 +1129,7 @@ describe "Global variable $FILENAME" do it "is read-only" do -> { $FILENAME = "-" - }.should raise_error(NameError) + }.should raise_error(NameError, '$FILENAME is a read-only variable') end end @@ -991,7 +1137,7 @@ describe "Global variable $?" do it "is read-only" do -> { $? = nil - }.should raise_error(NameError) + }.should raise_error(NameError, '$? is a read-only variable') end it "is thread-local" do @@ -1002,19 +1148,19 @@ end describe "Global variable $-a" do it "is read-only" do - -> { $-a = true }.should raise_error(NameError) + -> { $-a = true }.should raise_error(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_error(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_error(NameError, '$-p is a read-only variable') end end @@ -1165,7 +1311,7 @@ describe "The predefined standard object nil" do end it "raises a SyntaxError if assigned to" do - -> { eval("nil = true") }.should raise_error(SyntaxError) + -> { eval("nil = true") }.should raise_error(SyntaxError, /Can't assign to nil/) end end @@ -1175,7 +1321,7 @@ describe "The predefined standard object true" do end it "raises a SyntaxError if assigned to" do - -> { eval("true = false") }.should raise_error(SyntaxError) + -> { eval("true = false") }.should raise_error(SyntaxError, /Can't assign to true/) end end @@ -1185,13 +1331,13 @@ describe "The predefined standard object false" do end it "raises a SyntaxError if assigned to" do - -> { eval("false = nil") }.should raise_error(SyntaxError) + -> { eval("false = nil") }.should raise_error(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_error(SyntaxError, /Can't change the value of self/) end end |
