aboutsummaryrefslogtreecommitdiffstats
path: root/spec/ruby/language
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/language')
-rw-r--r--spec/ruby/language/fixtures/bytes_magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/case_magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/emacs_magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/magic_comment.rb2
-rw-r--r--spec/ruby/language/fixtures/no_magic_comment.rb1
-rw-r--r--spec/ruby/language/fixtures/print_magic_comment_result_at_exit.rb3
-rw-r--r--spec/ruby/language/fixtures/second_line_magic_comment.rb3
-rw-r--r--spec/ruby/language/fixtures/second_token_magic_comment.rb2
-rwxr-xr-xspec/ruby/language/fixtures/shebang_magic_comment.rb3
-rw-r--r--spec/ruby/language/fixtures/utf16-be-bom.rbbin0 -> 70 bytes
-rw-r--r--spec/ruby/language/fixtures/utf16-be-nobom.rbbin0 -> 68 bytes
-rw-r--r--spec/ruby/language/fixtures/utf16-le-bom.rbbin0 -> 70 bytes
-rw-r--r--spec/ruby/language/fixtures/utf16-le-nobom.rbbin0 -> 69 bytes
-rw-r--r--spec/ruby/language/fixtures/utf8-bom.rb2
-rw-r--r--spec/ruby/language/fixtures/utf8-nobom.rb2
-rw-r--r--spec/ruby/language/fixtures/vim_magic_comment.rb2
-rw-r--r--spec/ruby/language/magic_comment_spec.rb108
-rw-r--r--spec/ruby/language/optional_assignments_spec.rb6
-rw-r--r--spec/ruby/language/predefined/data_spec.rb12
-rw-r--r--spec/ruby/language/predefined/fixtures/data_offset.rb12
-rw-r--r--spec/ruby/language/predefined/fixtures/empty_data.rb3
-rw-r--r--spec/ruby/language/predefined/fixtures/no_newline_data.rb3
-rw-r--r--spec/ruby/language/safe_spec.rb97
-rw-r--r--spec/ruby/language/source_encoding_spec.rb41
24 files changed, 266 insertions, 42 deletions
diff --git a/spec/ruby/language/fixtures/bytes_magic_comment.rb b/spec/ruby/language/fixtures/bytes_magic_comment.rb
new file mode 100644
index 0000000000..2bc2bcfb07
--- /dev/null
+++ b/spec/ruby/language/fixtures/bytes_magic_comment.rb
@@ -0,0 +1,2 @@
+# encoding: big5
+$magic_comment_result = '§A¦n'.bytes.inspect
diff --git a/spec/ruby/language/fixtures/case_magic_comment.rb b/spec/ruby/language/fixtures/case_magic_comment.rb
new file mode 100644
index 0000000000..96f35a7c94
--- /dev/null
+++ b/spec/ruby/language/fixtures/case_magic_comment.rb
@@ -0,0 +1,2 @@
+# CoDiNg: bIg5
+$magic_comment_result = __ENCODING__.name
diff --git a/spec/ruby/language/fixtures/emacs_magic_comment.rb b/spec/ruby/language/fixtures/emacs_magic_comment.rb
new file mode 100644
index 0000000000..2b09f3e74c
--- /dev/null
+++ b/spec/ruby/language/fixtures/emacs_magic_comment.rb
@@ -0,0 +1,2 @@
+# -*- encoding: big5 -*-
+$magic_comment_result = __ENCODING__.name
diff --git a/spec/ruby/language/fixtures/magic_comment.rb b/spec/ruby/language/fixtures/magic_comment.rb
new file mode 100644
index 0000000000..120ef6ff4a
--- /dev/null
+++ b/spec/ruby/language/fixtures/magic_comment.rb
@@ -0,0 +1,2 @@
+# encoding: big5
+$magic_comment_result = __ENCODING__.name
diff --git a/spec/ruby/language/fixtures/no_magic_comment.rb b/spec/ruby/language/fixtures/no_magic_comment.rb
new file mode 100644
index 0000000000..743a0f9503
--- /dev/null
+++ b/spec/ruby/language/fixtures/no_magic_comment.rb
@@ -0,0 +1 @@
+$magic_comment_result = __ENCODING__.name
diff --git a/spec/ruby/language/fixtures/print_magic_comment_result_at_exit.rb b/spec/ruby/language/fixtures/print_magic_comment_result_at_exit.rb
new file mode 100644
index 0000000000..aa82cf4471
--- /dev/null
+++ b/spec/ruby/language/fixtures/print_magic_comment_result_at_exit.rb
@@ -0,0 +1,3 @@
+at_exit {
+ print $magic_comment_result
+}
diff --git a/spec/ruby/language/fixtures/second_line_magic_comment.rb b/spec/ruby/language/fixtures/second_line_magic_comment.rb
new file mode 100644
index 0000000000..a3dd50393b
--- /dev/null
+++ b/spec/ruby/language/fixtures/second_line_magic_comment.rb
@@ -0,0 +1,3 @@
+
+# encoding: big5
+$magic_comment_result = __ENCODING__.name
diff --git a/spec/ruby/language/fixtures/second_token_magic_comment.rb b/spec/ruby/language/fixtures/second_token_magic_comment.rb
new file mode 100644
index 0000000000..8d443e68f3
--- /dev/null
+++ b/spec/ruby/language/fixtures/second_token_magic_comment.rb
@@ -0,0 +1,2 @@
+1 + 1 # encoding: big5
+$magic_comment_result = __ENCODING__.name
diff --git a/spec/ruby/language/fixtures/shebang_magic_comment.rb b/spec/ruby/language/fixtures/shebang_magic_comment.rb
new file mode 100755
index 0000000000..f8e5e7d8e4
--- /dev/null
+++ b/spec/ruby/language/fixtures/shebang_magic_comment.rb
@@ -0,0 +1,3 @@
+#!/usr/bin/ruby
+# encoding: big5
+$magic_comment_result = __ENCODING__.name
diff --git a/spec/ruby/language/fixtures/utf16-be-bom.rb b/spec/ruby/language/fixtures/utf16-be-bom.rb
new file mode 100644
index 0000000000..8cb31e42f0
--- /dev/null
+++ b/spec/ruby/language/fixtures/utf16-be-bom.rb
Binary files differ
diff --git a/spec/ruby/language/fixtures/utf16-be-nobom.rb b/spec/ruby/language/fixtures/utf16-be-nobom.rb
new file mode 100644
index 0000000000..99e2ce8ce8
--- /dev/null
+++ b/spec/ruby/language/fixtures/utf16-be-nobom.rb
Binary files differ
diff --git a/spec/ruby/language/fixtures/utf16-le-bom.rb b/spec/ruby/language/fixtures/utf16-le-bom.rb
new file mode 100644
index 0000000000..981016ea52
--- /dev/null
+++ b/spec/ruby/language/fixtures/utf16-le-bom.rb
Binary files differ
diff --git a/spec/ruby/language/fixtures/utf16-le-nobom.rb b/spec/ruby/language/fixtures/utf16-le-nobom.rb
new file mode 100644
index 0000000000..98de9697ca
--- /dev/null
+++ b/spec/ruby/language/fixtures/utf16-le-nobom.rb
Binary files differ
diff --git a/spec/ruby/language/fixtures/utf8-bom.rb b/spec/ruby/language/fixtures/utf8-bom.rb
new file mode 100644
index 0000000000..50c223a922
--- /dev/null
+++ b/spec/ruby/language/fixtures/utf8-bom.rb
@@ -0,0 +1,2 @@
+# encoding: utf-8
+puts 'hello'
diff --git a/spec/ruby/language/fixtures/utf8-nobom.rb b/spec/ruby/language/fixtures/utf8-nobom.rb
new file mode 100644
index 0000000000..75f5563b95
--- /dev/null
+++ b/spec/ruby/language/fixtures/utf8-nobom.rb
@@ -0,0 +1,2 @@
+# encoding: utf-8
+puts 'hello'
diff --git a/spec/ruby/language/fixtures/vim_magic_comment.rb b/spec/ruby/language/fixtures/vim_magic_comment.rb
new file mode 100644
index 0000000000..60cbe7a3bf
--- /dev/null
+++ b/spec/ruby/language/fixtures/vim_magic_comment.rb
@@ -0,0 +1,2 @@
+# vim: filetype=ruby, fileencoding=big5, tabsize=3, shiftwidth=3
+$magic_comment_result = __ENCODING__.name
diff --git a/spec/ruby/language/magic_comment_spec.rb b/spec/ruby/language/magic_comment_spec.rb
index 3042a3f3df..c3abf3cc94 100644
--- a/spec/ruby/language/magic_comment_spec.rb
+++ b/spec/ruby/language/magic_comment_spec.rb
@@ -1,62 +1,88 @@
require_relative '../spec_helper'
-describe "Magic comment" do
- it "is optional" do
- eval("__ENCODING__").should be_an_instance_of(Encoding)
+# See core/kernel/eval_spec.rb for more magic comments specs for eval()
+describe :magic_comments, shared: true do
+ it "are optional" do
+ @object.call('no_magic_comment.rb').should == Encoding::UTF_8.name
end
- it "determines __ENCODING__" do
- eval(<<EOS.force_encoding("US-ASCII")).should == Encoding::ASCII_8BIT
-# encoding: ASCII-8BIT
-__ENCODING__
-EOS
- end
-
- it "is case-insensitive" do
- eval(<<EOS.force_encoding("US-ASCII")).should == Encoding::ASCII_8BIT
-# CoDiNg: aScIi-8bIt
-__ENCODING__
-EOS
+ it "are case-insensitive" do
+ @object.call('case_magic_comment.rb').should == Encoding::Big5.name
end
it "must be at the first line" do
- eval(<<EOS.force_encoding("US-ASCII")).should == Encoding::US_ASCII
-
-# encoding: ASCII-8BIT
-__ENCODING__
-EOS
+ @object.call('second_line_magic_comment.rb').should == Encoding::UTF_8.name
end
it "must be the first token of the line" do
- eval(<<EOS.force_encoding("US-ASCII")).should == Encoding::US_ASCII
-1+1 # encoding: ASCII-8BIT
-__ENCODING__
-EOS
- eval(<<EOS.force_encoding("US-ASCII")).should == Encoding::ASCII_8BIT
- # encoding: ASCII-8BIT
-__ENCODING__
-EOS
+ @object.call('second_token_magic_comment.rb').should == Encoding::UTF_8.name
end
it "can be after the shebang" do
- eval(<<EOS.force_encoding("US-ASCII")).should == Encoding::ASCII_8BIT
-#!/usr/bin/ruby -Ku
-# encoding: ASCII-8BIT
-__ENCODING__
-EOS
+ @object.call('shebang_magic_comment.rb').should == Encoding::Big5.name
end
it "can take Emacs style" do
- eval(<<EOS.force_encoding("US-ASCII")).should == Encoding::ASCII_8BIT
-# -*- encoding: ascii-8bit -*-
-__ENCODING__
-EOS
+ @object.call('emacs_magic_comment.rb').should == Encoding::Big5.name
end
it "can take vim style" do
- eval(<<EOS.force_encoding("US-ASCII")).should == Encoding::ASCII_8BIT
-# vim: filetype=ruby, fileencoding=ascii-8bit, tabsize=3, shiftwidth=3
-__ENCODING__
-EOS
+ @object.call('vim_magic_comment.rb').should == Encoding::Big5.name
+ end
+
+ it "determine __ENCODING__" do
+ @object.call('magic_comment.rb').should == Encoding::Big5.name
+ end
+
+ it "do not cause bytes to be mangled by passing them through the wrong encoding" do
+ @object.call('bytes_magic_comment.rb').should == [167, 65, 166, 110].inspect
+ end
+end
+
+describe "Magic comments" do
+ platform_is_not :windows do
+ describe "in stdin" do
+ it_behaves_like :magic_comments, nil, -> file {
+ print_at_exit = fixture(__FILE__, "print_magic_comment_result_at_exit.rb")
+ ruby_exe(nil, args: "< #{fixture(__FILE__, file)}", options: "-r#{print_at_exit}")
+ }
+ end
+
+ describe "in an -e argument" do
+ it_behaves_like :magic_comments, nil, -> file {
+ print_at_exit = fixture(__FILE__, "print_magic_comment_result_at_exit.rb")
+ # Use UTF-8, as it is the default source encoding for files
+ code = File.read(fixture(__FILE__, file), encoding: 'utf-8')
+ IO.popen([*ruby_exe, "-r", print_at_exit, "-e", code], &:read)
+ }
+ end
+ end
+
+ describe "in the main file" do
+ it_behaves_like :magic_comments, nil, -> file {
+ print_at_exit = fixture(__FILE__, "print_magic_comment_result_at_exit.rb")
+ ruby_exe(fixture(__FILE__, file), options: "-r#{print_at_exit}")
+ }
+ end
+
+ describe "in a loaded file" do
+ it_behaves_like :magic_comments, nil, -> file {
+ load fixture(__FILE__, file)
+ $magic_comment_result
+ }
+ end
+
+ describe "in a required file" do
+ it_behaves_like :magic_comments, nil, -> file {
+ require fixture(__FILE__, file)
+ $magic_comment_result
+ }
+ end
+
+ describe "in an eval" do
+ it_behaves_like :magic_comments, nil, -> file {
+ # Use UTF-8, as it is the default source encoding for files
+ eval(File.read(fixture(__FILE__, file), encoding: 'utf-8'))
+ }
end
end
diff --git a/spec/ruby/language/optional_assignments_spec.rb b/spec/ruby/language/optional_assignments_spec.rb
index 91b580e084..2f50136ba9 100644
--- a/spec/ruby/language/optional_assignments_spec.rb
+++ b/spec/ruby/language/optional_assignments_spec.rb
@@ -252,7 +252,11 @@ describe 'Optional variable assignments' do
end
describe 'using compunded constants' do
- before do
+ before :each do
+ Object.send(:remove_const, :A) if defined? Object::A
+ end
+
+ after :each do
Object.send(:remove_const, :A) if defined? Object::A
end
diff --git a/spec/ruby/language/predefined/data_spec.rb b/spec/ruby/language/predefined/data_spec.rb
index 1b636967d2..e57184ce99 100644
--- a/spec/ruby/language/predefined/data_spec.rb
+++ b/spec/ruby/language/predefined/data_spec.rb
@@ -23,6 +23,18 @@ describe "The DATA constant" do
str.chomp.should == "data only"
end
+ it "returns a File object with the right offset" do
+ ruby_exe(fixture(__FILE__, "data_offset.rb")).should == "File\n121\n"
+ end
+
+ it "is set even if there is no data after __END__" do
+ ruby_exe(fixture(__FILE__, "empty_data.rb")).should == "31\n\"\"\n"
+ end
+
+ it "is set even if there is no newline after __END__" do
+ ruby_exe(fixture(__FILE__, "no_newline_data.rb")).should == "30\n\"\"\n"
+ end
+
it "rewinds to the head of the main script" do
ruby_exe(fixture(__FILE__, "data5.rb")).chomp.should == "DATA.rewind"
end
diff --git a/spec/ruby/language/predefined/fixtures/data_offset.rb b/spec/ruby/language/predefined/fixtures/data_offset.rb
new file mode 100644
index 0000000000..9829b3f87f
--- /dev/null
+++ b/spec/ruby/language/predefined/fixtures/data_offset.rb
@@ -0,0 +1,12 @@
+# some comment
+
+foo = <<HEREDOC
+some heredoc to make the
+spec more interesting
+HEREDOC
+
+p DATA.class
+p DATA.pos
+
+__END__
+data offset
diff --git a/spec/ruby/language/predefined/fixtures/empty_data.rb b/spec/ruby/language/predefined/fixtures/empty_data.rb
new file mode 100644
index 0000000000..c6d9bc6f1f
--- /dev/null
+++ b/spec/ruby/language/predefined/fixtures/empty_data.rb
@@ -0,0 +1,3 @@
+p DATA.pos
+p DATA.read
+__END__
diff --git a/spec/ruby/language/predefined/fixtures/no_newline_data.rb b/spec/ruby/language/predefined/fixtures/no_newline_data.rb
new file mode 100644
index 0000000000..95522c26c7
--- /dev/null
+++ b/spec/ruby/language/predefined/fixtures/no_newline_data.rb
@@ -0,0 +1,3 @@
+p DATA.pos
+p DATA.read
+__END__ \ No newline at end of file
diff --git a/spec/ruby/language/safe_spec.rb b/spec/ruby/language/safe_spec.rb
new file mode 100644
index 0000000000..305965c1a7
--- /dev/null
+++ b/spec/ruby/language/safe_spec.rb
@@ -0,0 +1,97 @@
+require_relative '../spec_helper'
+
+describe "The $SAFE variable" do
+
+ ruby_version_is "2.6" do
+ after :each do
+ $SAFE = 0
+ end
+ end
+
+ it "is 0 by default" do
+ $SAFE.should == 0
+ proc {
+ $SAFE.should == 0
+ }.call
+ end
+
+ it "can be set to 0" do
+ proc {
+ $SAFE = 0
+ $SAFE.should == 0
+ }.call
+ end
+
+ it "can be set to 1" do
+ proc {
+ $SAFE = 1
+ $SAFE.should == 1
+ }.call
+ end
+
+ [2, 3, 4].each do |n|
+ it "cannot be set to #{n}" do
+ lambda {
+ proc {
+ $SAFE = n
+ }.call
+ }.should raise_error(ArgumentError, /\$SAFE=2 to 4 are obsolete/)
+ end
+ end
+
+ ruby_version_is ""..."2.6" do
+ it "cannot be set to values below 0" do
+ lambda {
+ proc {
+ $SAFE = -100
+ }.call
+ }.should raise_error(SecurityError, /tried to downgrade safe level from 0 to -100/)
+ end
+ end
+
+ it "cannot be set to values above 4" do
+ lambda {
+ proc {
+ $SAFE = 100
+ }.call
+ }.should raise_error(ArgumentError, /\$SAFE=2 to 4 are obsolete/)
+ end
+
+ ruby_version_is ""..."2.6" do
+ it "cannot be manually lowered" do
+ proc {
+ $SAFE = 1
+ lambda {
+ $SAFE = 0
+ }.should raise_error(SecurityError, /tried to downgrade safe level from 1 to 0/)
+ }.call
+ end
+
+ it "is automatically lowered when leaving a proc" do
+ $SAFE.should == 0
+ proc {
+ $SAFE = 1
+ }.call
+ $SAFE.should == 0
+ end
+
+ it "is automatically lowered when leaving a lambda" do
+ $SAFE.should == 0
+ lambda {
+ $SAFE = 1
+ }.call
+ $SAFE.should == 0
+ end
+ end
+
+ it "can be read when default from Thread#safe_level" do
+ Thread.current.safe_level.should == 0
+ end
+
+ it "can be read when modified from Thread#safe_level" do
+ proc {
+ $SAFE = 1
+ Thread.current.safe_level.should == 1
+ }.call
+ end
+end
diff --git a/spec/ruby/language/source_encoding_spec.rb b/spec/ruby/language/source_encoding_spec.rb
new file mode 100644
index 0000000000..d4240cee39
--- /dev/null
+++ b/spec/ruby/language/source_encoding_spec.rb
@@ -0,0 +1,41 @@
+require_relative '../spec_helper'
+
+describe "Source files" do
+
+ describe "encoded in UTF-8 without a BOM" do
+ it "can be parsed" do
+ ruby_exe(fixture(__FILE__, "utf8-nobom.rb"), args: "2>&1").should == "hello\n"
+ end
+ end
+
+ describe "encoded in UTF-8 with a BOM" do
+ it "can be parsed" do
+ ruby_exe(fixture(__FILE__, "utf8-bom.rb"), args: "2>&1").should == "hello\n"
+ end
+ end
+
+ describe "encoded in UTF-16 LE without a BOM" do
+ it "are parsed because empty as they contain a NUL byte before the encoding comment" do
+ ruby_exe(fixture(__FILE__, "utf16-le-nobom.rb"), args: "2>&1").should == ""
+ end
+ end
+
+ describe "encoded in UTF-16 LE with a BOM" do
+ it "are invalid because they contain an invalid UTF-8 sequence before the encoding comment" do
+ ruby_exe(fixture(__FILE__, "utf16-le-bom.rb"), args: "2>&1").should =~ /invalid multibyte char/
+ end
+ end
+
+ describe "encoded in UTF-16 BE without a BOM" do
+ it "are parsed as empty because they contain a NUL byte before the encoding comment" do
+ ruby_exe(fixture(__FILE__, "utf16-be-nobom.rb"), args: "2>&1").should == ""
+ end
+ end
+
+ describe "encoded in UTF-16 BE with a BOM" do
+ it "are invalid because they contain an invalid UTF-8 sequence before the encoding comment" do
+ ruby_exe(fixture(__FILE__, "utf16-be-bom.rb"), args: "2>&1").should =~ /invalid multibyte char/
+ end
+ end
+
+end