1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/spec/ruby/language/predefined_spec.rb
2021-10-05 19:41:44 +02:00

1333 lines
38 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

require_relative '../spec_helper'
require 'stringio'
# The following tables are excerpted from Programming Ruby: The Pragmatic Programmer's Guide'
# Second Edition by Dave Thomas, Chad Fowler, and Andy Hunt, page 319-22.
#
# Entries marked [r/o] are read-only and an error will be raised of the program attempts to
# modify them. Entries marked [thread] are thread local.
=begin
Exception Information
---------------------------------------------------------------------------------------------------
$! Exception The exception object passed to raise. [thread]
$@ Array The stack backtrace generated by the last exception. [thread]
=end
=begin
Pattern Matching Variables
---------------------------------------------------------------------------------------------------
These variables are set to nil after an unsuccessful pattern match.
$& String The string matched (following a successful pattern match). This variable is
local to the current scope. [r/o, thread]
$+ String The contents of the highest-numbered group matched following a successful
pattern match. Thus, in "cat" =~/(c|a)(t|z)/, $+ will be set to “t”. This
variable is local to the current scope. [r/o, thread]
$` String The string preceding the match in a successful pattern match. This variable
is local to the current scope. [r/o, thread]
$' String The string following the match in a successful pattern match. This variable
is local to the current scope. [r/o, thread]
$1 to $<N> String The contents of successive groups matched in a successful pattern match. In
"cat" =~/(c|a)(t|z)/, $1 will be set to “a” and $2 to “t”. This variable
is local to the current scope. [r/o, thread]
$~ MatchData An object that encapsulates the results of a successful pattern match. The
variables $&, $`, $', and $1 to $<N> are all derived from $~. Assigning to $~
changes the values of these derived variables. This variable is local to the
current scope. [thread]
=end
describe "Predefined global $~" do
it "is set to contain the MatchData object of the last match if successful" do
md = /foo/.match 'foo'
$~.should be_kind_of(MatchData)
$~.should equal md
/bar/ =~ 'bar'
$~.should be_kind_of(MatchData)
$~.should_not equal md
end
it "is set to nil if the last match was unsuccessful" do
/foo/ =~ 'foo'
$~.should_not.nil?
/foo/ =~ 'bar'
$~.should.nil?
end
it "is set at the method-scoped level rather than block-scoped" do
obj = Object.new
def obj.foo; yield; end
def obj.foo2(&proc); proc.call; end
match2 = nil
match3 = nil
match4 = nil
match1 = /foo/.match "foo"
obj.foo { match2 = /bar/.match("bar") }
match2.should_not == nil
$~.should == match2
eval 'match3 = /baz/.match("baz")'
match3.should_not == nil
$~.should == match3
obj.foo2 { match4 = /qux/.match("qux") }
match4.should_not == nil
$~.should == match4
end
it "raises an error if assigned an object not nil or instanceof MatchData" do
$~ = nil
$~.should == nil
$~ = /foo/.match("foo")
$~.should be_an_instance_of(MatchData)
-> { $~ = Object.new }.should raise_error(TypeError)
-> { $~ = 1 }.should raise_error(TypeError)
end
it "changes the value of derived capture globals when assigned" do
"foo" =~ /(f)oo/
foo_match = $~
"bar" =~ /(b)ar/
$~ = foo_match
$1.should == "f"
end
it "changes the value of the derived preceding match global" do
"foo hello" =~ /hello/
foo_match = $~
"bar" =~ /(bar)/
$~ = foo_match
$`.should == "foo "
end
it "changes the value of the derived following match global" do
"foo hello" =~ /foo/
foo_match = $~
"bar" =~ /(bar)/
$~ = foo_match
$'.should == " hello"
end
it "changes the value of the derived full match global" do
"foo hello" =~ /foo/
foo_match = $~
"bar" =~ /(bar)/
$~ = foo_match
$&.should == "foo"
end
end
describe "Predefined global $&" do
it "is equivalent to MatchData#[0] on the last match $~" do
/foo/ =~ 'barfoobaz'
$&.should == $~[0]
$&.should == 'foo'
end
it "sets the encoding to the encoding of the source String" do
"abc".force_encoding(Encoding::EUC_JP) =~ /b/
$&.encoding.should equal(Encoding::EUC_JP)
end
end
describe "Predefined global $`" do
it "is equivalent to MatchData#pre_match on the last match $~" do
/foo/ =~ 'barfoobaz'
$`.should == $~.pre_match
$`.should == 'bar'
end
it "sets the encoding to the encoding of the source String" do
"abc".force_encoding(Encoding::EUC_JP) =~ /b/
$`.encoding.should equal(Encoding::EUC_JP)
end
it "sets an empty result to the encoding of the source String" do
"abc".force_encoding(Encoding::ISO_8859_1) =~ /a/
$`.encoding.should equal(Encoding::ISO_8859_1)
end
end
describe "Predefined global $'" do
it "is equivalent to MatchData#post_match on the last match $~" do
/foo/ =~ 'barfoobaz'
$'.should == $~.post_match
$'.should == 'baz'
end
it "sets the encoding to the encoding of the source String" do
"abc".force_encoding(Encoding::EUC_JP) =~ /b/
$'.encoding.should equal(Encoding::EUC_JP)
end
it "sets an empty result to the encoding of the source String" do
"abc".force_encoding(Encoding::ISO_8859_1) =~ /c/
$'.encoding.should equal(Encoding::ISO_8859_1)
end
end
describe "Predefined global $+" do
it "is equivalent to $~.captures.last" do
/(f(o)o)/ =~ 'barfoobaz'
$+.should == $~.captures.last
$+.should == 'o'
end
it "captures the last non nil capture" do
/(a)|(b)/ =~ 'a'
$+.should == 'a'
end
it "sets the encoding to the encoding of the source String" do
"abc".force_encoding(Encoding::EUC_JP) =~ /(b)/
$+.encoding.should equal(Encoding::EUC_JP)
end
end
describe "Predefined globals $1..N" do
it "are equivalent to $~[N]" do
/(f)(o)(o)/ =~ 'foo'
$1.should == $~[1]
$2.should == $~[2]
$3.should == $~[3]
$4.should == $~[4]
[$1, $2, $3, $4].should == ['f', 'o', 'o', nil]
end
it "are nil unless a match group occurs" do
def test(arg)
case arg
when /-(.)?/
$1
end
end
test("-").should == nil
end
it "sets the encoding to the encoding of the source String" do
"abc".force_encoding(Encoding::EUC_JP) =~ /(b)/
$1.encoding.should equal(Encoding::EUC_JP)
end
end
describe "Predefined global $stdout" do
before :each do
@old_stdout = $stdout
end
after :each do
$stdout = @old_stdout
end
it "raises TypeError error if assigned to nil" do
-> { $stdout = nil }.should raise_error(TypeError)
end
it "raises TypeError error if assigned to object that doesn't respond to #write" do
obj = mock('object')
-> { $stdout = obj }.should raise_error(TypeError)
obj.stub!(:write)
$stdout = obj
$stdout.should equal(obj)
end
end
describe "Predefined global $!" do
# 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
obj = Class.new do
def method_missing(*args)
super
end
end.new
[obj, 'foo'].join
$!.should == nil
end
it "should be set to the value of $! before the begin after a successful rescue" do
outer = StandardError.new 'outer'
inner = StandardError.new 'inner'
begin
raise outer
rescue
$!.should == outer
# nested rescue
begin
$!.should == outer
raise inner
rescue
$!.should == inner
ensure
$!.should == outer
end
$!.should == outer
end
$!.should == nil
end
it "should be set to the value of $! before the begin after a rescue which returns" do
def foo
outer = StandardError.new 'outer'
inner = StandardError.new 'inner'
begin
raise outer
rescue
$!.should == outer
# nested rescue
begin
$!.should == outer
raise inner
rescue
$!.should == inner
return
ensure
$!.should == outer
end
$!.should == outer
end
$!.should == nil
end
foo
end
it "should be set to the value of $! before the begin after a successful rescue within an ensure" do
outer = StandardError.new 'outer'
inner = StandardError.new 'inner'
begin
begin
raise outer
ensure
$!.should == outer
# nested rescue
begin
$!.should == outer
raise inner
rescue
$!.should == inner
ensure
$!.should == outer
end
$!.should == outer
end
flunk "outer should be raised after the ensure"
rescue
$!.should == outer
end
$!.should == nil
end
it "should be set to the new exception after a throwing rescue" do
outer = StandardError.new 'outer'
inner = StandardError.new 'inner'
begin
raise outer
rescue
$!.should == outer
begin
# nested rescue
begin
$!.should == outer
raise inner
rescue # the throwing rescue
$!.should == inner
raise inner
ensure
$!.should == inner
end
rescue # do not make the exception fail the example
$!.should == inner
end
$!.should == outer
end
$!.should == nil
end
describe "in bodies without ensure" do
it "should be cleared when an exception is rescued" do
e = StandardError.new 'foo'
begin
raise e
rescue
$!.should == e
end
$!.should == nil
end
it "should be cleared when an exception is rescued even when a non-local return is present" do
def foo(e)
$!.should == e
yield
end
def bar
e = StandardError.new 'foo'
begin
raise e
rescue
$!.should == e
foo(e) { return }
end
end
bar
$!.should == nil
end
it "should be cleared when an exception is rescued even when a non-local return from block" do
def foo
[ 1 ].each do
begin
raise StandardError.new('err')
rescue => e
$!.should == e
return
end
end
end
foo
$!.should == nil
end
it "should not be cleared when an exception is not rescued" do
e = StandardError.new
begin
begin
begin
raise e
rescue TypeError
flunk
end
ensure
$!.should == e
end
rescue
$!.should == e
end
$!.should == nil
end
it "should not be cleared when an exception is rescued and rethrown" do
e = StandardError.new 'foo'
begin
begin
begin
raise e
rescue => e
$!.should == e
raise e
end
ensure
$!.should == e
end
rescue
$!.should == e
end
$!.should == nil
end
end
describe "in ensure-protected bodies" do
it "should be cleared when an exception is rescued" do
e = StandardError.new 'foo'
begin
raise e
rescue
$!.should == e
ensure
$!.should == nil
end
$!.should == nil
end
it "should not be cleared when an exception is not rescued" do
e = StandardError.new
begin
begin
begin
raise e
rescue TypeError
flunk
ensure
$!.should == e
end
ensure
$!.should == e
end
rescue
$!.should == e
end
end
it "should not be cleared when an exception is rescued and rethrown" do
e = StandardError.new
begin
begin
begin
raise e
rescue => e
$!.should == e
raise e
ensure
$!.should == e
end
ensure
$!.should == e
end
rescue
$!.should == e
end
end
end
end
=begin
Input/Output Variables
---------------------------------------------------------------------------------------------------
$/ String The input record separator (newline by default). This is the value that rou-
tines such as Kernel#gets use to determine record boundaries. If set to
nil, gets will read the entire file.
$-0 String Synonym for $/.
$\ String The string appended to the output of every call to methods such as
Kernel#print and IO#write. The default value is nil.
$, String The separator string output between the parameters to methods such as
Kernel#print and Array#join. Defaults to nil, which adds no text.
$. Integer The number of the last line read from the current input file.
$; String The default separator pattern used by String#split. May be set from the
command line using the -F flag.
$< Object An object that provides access to the concatenation of the contents of all
the files given as command-line arguments or $stdin (in the case where
there are no arguments). $< supports methods similar to a File object:
binmode, close, closed?, each, each_byte, each_line, eof, eof?,
file, filename, fileno, getc, gets, lineno, lineno=, path, pos, pos=,
read, readchar, readline, readlines, rewind, seek, skip, tell, to_a,
to_i, to_io, to_s, along with the methods in Enumerable. The method
file returns a File object for the file currently being read. This may change
as $< reads through the files on the command line. [r/o]
$> IO The destination of output for Kernel#print and Kernel#printf. The
default value is $stdout.
$_ String The last line read by Kernel#gets or Kernel#readline. Many string-
related functions in the Kernel module operate on $_ by default. The vari-
able is local to the current scope. [thread]
$-F String Synonym for $;.
$stderr IO The current standard error output.
$stdin IO The current standard input.
$stdout IO The current standard output. Assignment to $stdout is deprecated: use
$stdout.reopen instead.
=end
describe "Predefined global $/" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
@dollar_slash = $/
@dollar_dash_zero = $-0
end
after :each do
$/ = @dollar_slash
$-0 = @dollar_dash_zero
$VERBOSE = @verbose
end
it "can be assigned a String" do
str = "abc"
$/ = str
$/.should equal(str)
end
it "can be assigned nil" do
$/ = nil
$/.should be_nil
end
it "returns the value assigned" do
($/ = "xyz").should == "xyz"
end
it "changes $-0" do
$/ = "xyz"
$-0.should equal($/)
end
it "does not call #to_str to convert the object to a String" do
obj = mock("$/ value")
obj.should_not_receive(:to_str)
-> { $/ = obj }.should raise_error(TypeError)
end
it "raises a TypeError if assigned an Integer" do
-> { $/ = 1 }.should raise_error(TypeError)
end
it "raises a TypeError if assigned a boolean" do
-> { $/ = true }.should raise_error(TypeError)
end
end
describe "Predefined global $-0" do
before :each do
@verbose, $VERBOSE = $VERBOSE, nil
@dollar_slash = $/
@dollar_dash_zero = $-0
end
after :each do
$/ = @dollar_slash
$-0 = @dollar_dash_zero
$VERBOSE = @verbose
end
it "can be assigned a String" do
str = "abc"
$-0 = str
$-0.should equal(str)
end
it "can be assigned nil" do
$-0 = nil
$-0.should be_nil
end
it "returns the value assigned" do
($-0 = "xyz").should == "xyz"
end
it "changes $/" do
$-0 = "xyz"
$/.should equal($-0)
end
it "does not call #to_str to convert the object to a String" do
obj = mock("$-0 value")
obj.should_not_receive(:to_str)
-> { $-0 = obj }.should raise_error(TypeError)
end
it "raises a TypeError if assigned an Integer" do
-> { $-0 = 1 }.should raise_error(TypeError)
end
it "raises a TypeError if assigned a boolean" do
-> { $-0 = true }.should raise_error(TypeError)
end
end
describe "Predefined global $," do
after :each do
$, = nil
end
it "defaults to nil" do
$,.should be_nil
end
it "raises TypeError if assigned a non-String" do
-> { $, = Object.new }.should raise_error(TypeError)
end
ruby_version_is "2.7" do
it "warns if assigned non-nil" do
-> { $, = "_" }.should complain(/warning: `\$,' is deprecated/)
end
end
end
describe "Predefined global $." do
it "can be assigned an Integer" do
$. = 123
$..should == 123
end
it "can be assigned a Float" do
$. = 123.5
$..should == 123
end
it "should call #to_int to convert the object to an Integer" do
obj = mock("good-value")
obj.should_receive(:to_int).and_return(321)
$. = obj
$..should == 321
end
it "raises TypeError if object can't be converted to an Integer" do
obj = mock("bad-value")
obj.should_receive(:to_int).and_return('abc')
-> { $. = obj }.should raise_error(TypeError)
end
end
describe "Predefined global $;" do
after :each do
$; = nil
end
ruby_version_is "2.7" do
it "warns if assigned non-nil" do
-> { $; = "_" }.should complain(/warning: `\$;' is deprecated/)
end
end
end
describe "Predefined global $_" do
it "is set to the last line read by e.g. StringIO#gets" do
stdin = StringIO.new("foo\nbar\n", "r")
read = stdin.gets
read.should == "foo\n"
$_.should == read
read = stdin.gets
read.should == "bar\n"
$_.should == read
read = stdin.gets
read.should == nil
$_.should == read
end
it "is set at the method-scoped level rather than block-scoped" do
obj = Object.new
def obj.foo; yield; end
def obj.foo2; yield; end
stdin = StringIO.new("foo\nbar\nbaz\nqux\n", "r")
match = stdin.gets
obj.foo { match = stdin.gets }
match.should == "bar\n"
$_.should == match
eval 'match = stdin.gets'
match.should == "baz\n"
$_.should == match
obj.foo2 { match = stdin.gets }
match.should == "qux\n"
$_.should == match
end
it "is Thread-local" do
$_ = nil
running = false
thr = Thread.new do
$_ = "last line"
running = true
end
Thread.pass until running
$_.should be_nil
thr.join
end
it "can be assigned any value" do
$_ = nil
$_.should == nil
$_ = "foo"
$_.should == "foo"
o = Object.new
$_ = o
$_.should == o
$_ = 1
$_.should == 1
end
end
=begin
Execution Environment Variables
---------------------------------------------------------------------------------------------------
$0 String The name of the top-level Ruby program being executed. Typically this will
be the programs filename. On some operating systems, assigning to this
variable will change the name of the process reported (for example) by the
ps(1) command.
$* Array An array of strings containing the command-line options from the invoca-
tion of the program. Options used by the Ruby interpreter will have been
removed. [r/o]
$" Array An array containing the filenames of modules loaded by require. [r/o]
$$ Integer The process number of the program being executed. [r/o]
$? Process::Status The exit status of the last child process to terminate. [r/o, thread]
$: Array An array of strings, where each string specifies a directory to be searched for
Ruby scripts and binary extensions used by the load and require methods.
The initial value is the value of the arguments passed via the -I command-
line option, followed by an installation-defined standard library location, fol-
lowed by the current directory (“.”). This variable may be set from within a
program to alter the default search path; typically, programs use $: << dir
to append dir to the path. [r/o]
$-a Object True if the -a option is specified on the command line. [r/o]
$-d Object Synonym for $DEBUG.
$DEBUG Object Set to true if the -d command-line option is specified.
__FILE__ String The name of the current source file. [r/o]
$F Array The array that receives the split input line if the -a command-line option is
used.
$FILENAME String The name of the current input file. Equivalent to $<.filename. [r/o]
$-i String If in-place edit mode is enabled (perhaps using the -i command-line
option), $-i holds the extension used when creating the backup file. If you
set a value into $-i, enables in-place edit mode.
$-I Array Synonym for $:. [r/o]
$-K String Sets the multibyte coding system for strings and regular expressions. Equiv-
alent to the -K command-line option.
$-l Object Set to true if the -l option (which enables line-end processing) is present
on the command line. [r/o]
__LINE__ String The current line number in the source file. [r/o]
$LOAD_PATH Array A synonym for $:. [r/o]
$-p Object Set to true if the -p option (which puts an implicit while gets . . . end
loop around your program) is present on the command line. [r/o]
$VERBOSE Object Set to true if the -v, --version, -W, or -w option is specified on the com-
mand line. Set to false if no option, or -W1 is given. Set to nil if -W0
was specified. Setting this option to true causes the interpreter and some
library routines to report additional information. Setting to nil suppresses
all warnings (including the output of Kernel.warn).
$-v Object Synonym for $VERBOSE.
$-w Object Synonym for $VERBOSE.
=end
describe "Execution variable $:" do
it "is initialized to an array of strings" do
$:.is_a?(Array).should == true
($:.length > 0).should == true
end
it "does not include the current directory" do
$:.should_not include(".")
end
it "is the same object as $LOAD_PATH and $-I" do
$:.__id__.should == $LOAD_PATH.__id__
$:.__id__.should == $-I.__id__
end
it "can be changed via <<" do
$: << "foo"
$:.should include("foo")
end
it "is read-only" do
-> {
$: = []
}.should raise_error(NameError)
-> {
$LOAD_PATH = []
}.should raise_error(NameError)
-> {
$-I = []
}.should raise_error(NameError)
end
end
describe "Global variable $\"" do
it "is an alias for $LOADED_FEATURES" do
$".should equal $LOADED_FEATURES
end
it "is read-only" do
-> {
$" = []
}.should raise_error(NameError)
-> {
$LOADED_FEATURES = []
}.should raise_error(NameError)
end
end
describe "Global variable $<" do
it "is read-only" do
-> {
$< = nil
}.should raise_error(NameError)
end
end
describe "Global variable $FILENAME" do
it "is read-only" do
-> {
$FILENAME = "-"
}.should raise_error(NameError)
end
end
describe "Global variable $?" do
it "is read-only" do
-> {
$? = nil
}.should raise_error(NameError)
end
it "is thread-local" do
system(ruby_cmd('exit 0'))
Thread.new { $?.should be_nil }.join
end
end
describe "Global variable $-a" do
it "is read-only" do
-> { $-a = true }.should raise_error(NameError)
end
end
describe "Global variable $-l" do
it "is read-only" do
-> { $-l = true }.should raise_error(NameError)
end
end
describe "Global variable $-p" do
it "is read-only" do
-> { $-p = true }.should raise_error(NameError)
end
end
describe "Global variable $-d" do
before :each do
@debug = $DEBUG
end
after :each do
$DEBUG = @debug
end
it "is an alias of $DEBUG" do
$DEBUG = true
$-d.should be_true
$-d = false
$DEBUG.should be_false
end
end
describe "Global variable $VERBOSE" do
before :each do
@verbose = $VERBOSE
end
after :each do
$VERBOSE = @verbose
end
it "converts truthy values to true" do
[true, 1, 0, [], ""].each do |true_value|
$VERBOSE = true_value
$VERBOSE.should be_true
end
end
it "allows false" do
$VERBOSE = false
$VERBOSE.should be_false
end
it "allows nil without coercing to false" do
$VERBOSE = nil
$VERBOSE.should be_nil
end
end
describe :verbose_global_alias, shared: true do
before :each do
@verbose = $VERBOSE
end
after :each do
$VERBOSE = @verbose
end
it "is an alias of $VERBOSE" do
$VERBOSE = true
eval(@method).should be_true
eval("#{@method} = false")
$VERBOSE.should be_false
end
end
describe "Global variable $-v" do
it_behaves_like :verbose_global_alias, '$-v'
end
describe "Global variable $-w" do
it_behaves_like :verbose_global_alias, '$-w'
end
describe "Global variable $0" do
before :each do
@orig_program_name = $0
end
after :each do
$0 = @orig_program_name
end
it "is the path given as the main script and the same as __FILE__" do
script = "fixtures/dollar_zero.rb"
Dir.chdir(File.dirname(__FILE__)) do
ruby_exe(script).should == "#{script}\n#{script}\nOK"
end
end
it "returns the program name" do
$0 = "rbx"
$0.should == "rbx"
end
platform_is :linux, :darwin do
it "actually sets the program name" do
title = "rubyspec-dollar0-test"
$0 = title
`ps -ocommand= -p#{$$}`.should include(title)
end
end
it "returns the given value when set" do
($0 = "rbx").should == "rbx"
end
it "raises a TypeError when not given an object that can be coerced to a String" do
-> { $0 = nil }.should raise_error(TypeError)
end
end
=begin
Standard Objects
---------------------------------------------------------------------------------------------------
ARGF Object A synonym for $<.
ARGV Array A synonym for $*.
ENV Object A hash-like object containing the programs environment variables. An
instance of class Object, ENV implements the full set of Hash methods. Used
to query and set the value of an environment variable, as in ENV["PATH"]
and ENV["term"]="ansi".
false FalseClass Singleton instance of class FalseClass. [r/o]
nil NilClass The singleton instance of class NilClass. The value of uninitialized
instance and global variables. [r/o]
self Object The receiver (object) of the current method. [r/o]
true TrueClass Singleton instance of class TrueClass. [r/o]
=end
describe "The predefined standard objects" do
it "includes ARGF" do
Object.const_defined?(:ARGF).should == true
end
it "includes ARGV" do
Object.const_defined?(:ARGV).should == true
end
it "includes a hash-like object ENV" do
Object.const_defined?(:ENV).should == true
ENV.respond_to?(:[]).should == true
end
end
describe "The predefined standard object nil" do
it "is an instance of NilClass" do
nil.should be_kind_of(NilClass)
end
it "raises a SyntaxError if assigned to" do
-> { eval("nil = true") }.should raise_error(SyntaxError)
end
end
describe "The predefined standard object true" do
it "is an instance of TrueClass" do
true.should be_kind_of(TrueClass)
end
it "raises a SyntaxError if assigned to" do
-> { eval("true = false") }.should raise_error(SyntaxError)
end
end
describe "The predefined standard object false" do
it "is an instance of FalseClass" do
false.should be_kind_of(FalseClass)
end
it "raises a SyntaxError if assigned to" do
-> { eval("false = nil") }.should raise_error(SyntaxError)
end
end
describe "The self pseudo-variable" do
it "raises a SyntaxError if assigned to" do
-> { eval("self = 1") }.should raise_error(SyntaxError)
end
end
=begin
Global Constants
---------------------------------------------------------------------------------------------------
The following constants are defined by the Ruby interpreter.
DATA IO If the main program file contains the directive __END__, then
the constant DATA will be initialized so that reading from it will
return lines following __END__ from the source file.
FALSE FalseClass Synonym for false (deprecated, removed in Ruby 3).
NIL NilClass Synonym for nil (deprecated, removed in Ruby 3).
RUBY_PLATFORM String The identifier of the platform running this program. This string
is in the same form as the platform identifier used by the GNU
configure utility (which is not a coincidence).
RUBY_RELEASE_DATE String The date of this release.
RUBY_VERSION String The version number of the interpreter.
STDERR IO The actual standard error stream for the program. The initial
value of $stderr.
STDIN IO The actual standard input stream for the program. The initial
value of $stdin.
STDOUT IO The actual standard output stream for the program. The initial
value of $stdout.
SCRIPT_LINES__ Hash If a constant SCRIPT_LINES__ is defined and references a Hash,
Ruby will store an entry containing the contents of each file it
parses, with the files name as the key and an array of strings as
the value.
TOPLEVEL_BINDING Binding A Binding object representing the binding at Rubys top level—
the level where programs are initially executed.
TRUE TrueClass Synonym for true (deprecated, removed in Ruby 3).
=end
describe "The predefined global constants" do
describe "TRUE" do
ruby_version_is "3.0" do
it "is no longer defined" do
Object.const_defined?(:TRUE).should == false
end
end
ruby_version_is ""..."3.0" do
it "includes TRUE" do
Object.const_defined?(:TRUE).should == true
-> { TRUE }.should complain(/constant ::TRUE is deprecated/)
end
end
end
describe "FALSE" do
ruby_version_is "3.0" do
it "is no longer defined" do
Object.const_defined?(:FALSE).should == false
end
end
ruby_version_is ""..."3.0" do
it "includes FALSE" do
Object.const_defined?(:FALSE).should == true
-> { FALSE }.should complain(/constant ::FALSE is deprecated/)
end
end
end
describe "NIL" do
ruby_version_is "3.0" do
it "is no longer defined" do
Object.const_defined?(:NIL).should == false
end
end
ruby_version_is ""..."3.0" do
it "includes NIL" do
Object.const_defined?(:NIL).should == true
-> { NIL }.should complain(/constant ::NIL is deprecated/)
end
end
end
it "includes STDIN" do
Object.const_defined?(:STDIN).should == true
end
it "includes STDOUT" do
Object.const_defined?(:STDOUT).should == true
end
it "includes STDERR" do
Object.const_defined?(:STDERR).should == true
end
it "includes RUBY_VERSION" do
Object.const_defined?(:RUBY_VERSION).should == true
end
it "includes RUBY_RELEASE_DATE" do
Object.const_defined?(:RUBY_RELEASE_DATE).should == true
end
it "includes RUBY_PLATFORM" do
Object.const_defined?(:RUBY_PLATFORM).should == true
end
it "includes TOPLEVEL_BINDING" do
Object.const_defined?(:TOPLEVEL_BINDING).should == true
end
end
describe "The predefined global constant" do
before :each do
@external = Encoding.default_external
@internal = Encoding.default_internal
end
after :each do
Encoding.default_external = @external
Encoding.default_internal = @internal
end
describe "STDIN" do
it "has the same external encoding as Encoding.default_external" do
STDIN.external_encoding.should equal(Encoding.default_external)
end
it "has the same external encoding as Encoding.default_external when that encoding is changed" do
Encoding.default_external = Encoding::ISO_8859_16
STDIN.external_encoding.should equal(Encoding::ISO_8859_16)
end
it "has the encodings set by #set_encoding" do
code = "STDIN.set_encoding Encoding::IBM775, Encoding::IBM866; " \
"p [STDIN.external_encoding.name, STDIN.internal_encoding.name]"
ruby_exe(code).chomp.should == %{["IBM775", "IBM866"]}
end
it "retains the encoding set by #set_encoding when Encoding.default_external is changed" do
code = "STDIN.set_encoding Encoding::IBM775, Encoding::IBM866; " \
"Encoding.default_external = Encoding::ISO_8859_16;" \
"p [STDIN.external_encoding.name, STDIN.internal_encoding.name]"
ruby_exe(code).chomp.should == %{["IBM775", "IBM866"]}
end
it "has nil for the internal encoding" do
STDIN.internal_encoding.should be_nil
end
it "has nil for the internal encoding despite Encoding.default_internal being changed" do
Encoding.default_internal = Encoding::IBM437
STDIN.internal_encoding.should be_nil
end
end
describe "STDOUT" do
it "has nil for the external encoding" do
STDOUT.external_encoding.should be_nil
end
it "has nil for the external encoding despite Encoding.default_external being changed" do
Encoding.default_external = Encoding::ISO_8859_1
STDOUT.external_encoding.should be_nil
end
it "has the encodings set by #set_encoding" do
code = "STDOUT.set_encoding Encoding::IBM775, Encoding::IBM866; " \
"p [STDOUT.external_encoding.name, STDOUT.internal_encoding.name]"
ruby_exe(code).chomp.should == %{["IBM775", "IBM866"]}
end
it "has nil for the internal encoding" do
STDOUT.internal_encoding.should be_nil
end
it "has nil for the internal encoding despite Encoding.default_internal being changed" do
Encoding.default_internal = Encoding::IBM437
STDOUT.internal_encoding.should be_nil
end
end
describe "STDERR" do
it "has nil for the external encoding" do
STDERR.external_encoding.should be_nil
end
it "has nil for the external encoding despite Encoding.default_external being changed" do
Encoding.default_external = Encoding::ISO_8859_1
STDERR.external_encoding.should be_nil
end
it "has the encodings set by #set_encoding" do
code = "STDERR.set_encoding Encoding::IBM775, Encoding::IBM866; " \
"p [STDERR.external_encoding.name, STDERR.internal_encoding.name]"
ruby_exe(code).chomp.should == %{["IBM775", "IBM866"]}
end
it "has nil for the internal encoding" do
STDERR.internal_encoding.should be_nil
end
it "has nil for the internal encoding despite Encoding.default_internal being changed" do
Encoding.default_internal = Encoding::IBM437
STDERR.internal_encoding.should be_nil
end
end
describe "ARGV" do
it "contains Strings encoded in locale Encoding" do
code = fixture __FILE__, "argv_encoding.rb"
result = ruby_exe(code, args: "a b")
encoding = Encoding.default_external
result.chomp.should == %{["#{encoding}", "#{encoding}"]}
end
end
end
ruby_version_is "2.7" do
describe "$LOAD_PATH.resolve_feature_path" do
it "returns what will be loaded without actual loading, .rb file" do
extension, path = $LOAD_PATH.resolve_feature_path('set')
extension.should == :rb
path.should.end_with?('/set.rb')
end
it "returns what will be loaded without actual loading, .so file" do
require 'rbconfig'
extension, path = $LOAD_PATH.resolve_feature_path('etc')
extension.should == :so
path.should.end_with?("/etc.#{RbConfig::CONFIG['DLEXT']}")
end
ruby_version_is "2.7"..."3.1" do
it "raises LoadError if feature cannot be found" do
-> { $LOAD_PATH.resolve_feature_path('noop') }.should raise_error(LoadError)
end
end
ruby_version_is "3.1" do
it "return nil if feature cannot be found" do
$LOAD_PATH.resolve_feature_path('noop').should be_nil
end
end
end
end