diff options
54 files changed, 601 insertions, 106 deletions
diff --git a/spec/ruby/.rubocop.yml b/spec/ruby/.rubocop.yml index 58529f15b2..d90310b077 100644 --- a/spec/ruby/.rubocop.yml +++ b/spec/ruby/.rubocop.yml @@ -5,6 +5,8 @@ AllCops: DisplayCopNames: true Exclude: - command_line/fixtures/bad_syntax.rb + - language/fixtures/utf16-le-bom.rb + - language/fixtures/utf16-be-bom.rb DisabledByDefault: true Layout/TrailingWhitespace: diff --git a/spec/ruby/.rubocop_todo.yml b/spec/ruby/.rubocop_todo.yml index 181e4003a4..25c67ade02 100644 --- a/spec/ruby/.rubocop_todo.yml +++ b/spec/ruby/.rubocop_todo.yml @@ -110,12 +110,6 @@ Lint/RescueException: - 'language/rescue_spec.rb' - 'library/erb/filename_spec.rb' -# Offense count: 1 -# Cop supports --auto-correct. -Lint/ScriptPermission: - Exclude: - - 'command_line/fixtures/bin/launcher.rb' - # Offense count: 2 # Configuration parameters: IgnoreImplicitReferences. Lint/ShadowedArgument: diff --git a/spec/ruby/command_line/dash_a_spec.rb b/spec/ruby/command_line/dash_a_spec.rb index 65f79ec208..9ea135dc76 100644 --- a/spec/ruby/command_line/dash_a_spec.rb +++ b/spec/ruby/command_line/dash_a_spec.rb @@ -1,3 +1,5 @@ +require_relative '../spec_helper' + describe "The -a command line option" do before :each do @names = fixture __FILE__, "full_names.txt" diff --git a/spec/ruby/command_line/dash_encoding_spec.rb b/spec/ruby/command_line/dash_encoding_spec.rb new file mode 100644 index 0000000000..e7889b4def --- /dev/null +++ b/spec/ruby/command_line/dash_encoding_spec.rb @@ -0,0 +1,33 @@ +require_relative '../spec_helper' + +describe 'The --encoding command line option' do + before :each do + @test_string = "print [Encoding.default_external.name, Encoding.default_internal&.name].inspect" + end + + describe 'sets Encoding.default_external and optionally Encoding.default_internal' do + it "if given a single encoding with an =" do + ruby_exe(@test_string, options: '--disable-gems --encoding=big5').should == [Encoding::Big5.name, nil].inspect + end + + it "if given a single encoding as a separate argument" do + ruby_exe(@test_string, options: '--disable-gems --encoding big5').should == [Encoding::Big5.name, nil].inspect + end + + it "if given two encodings with an =" do + ruby_exe(@test_string, options: '--disable-gems --encoding=big5:utf-32be').should == [Encoding::Big5.name, Encoding::UTF_32BE.name].inspect + end + + it "if given two encodings as a separate argument" do + ruby_exe(@test_string, options: '--disable-gems --encoding big5:utf-32be').should == [Encoding::Big5.name, Encoding::UTF_32BE.name].inspect + end + + it "if given two encodings as a separate argument" do + ruby_exe(@test_string, options: '--disable-gems --encoding big5:utf-32be').should == [Encoding::Big5.name, Encoding::UTF_32BE.name].inspect + end + end + + it "does not accept a third encoding" do + ruby_exe(@test_string, options: '--disable-gems --encoding big5:utf-32be:utf-32le', args: '2>&1').should =~ /extra argument for --encoding: utf-32le/ + end +end diff --git a/spec/ruby/command_line/dash_external_encoding_spec.rb b/spec/ruby/command_line/dash_external_encoding_spec.rb new file mode 100644 index 0000000000..f052674dc8 --- /dev/null +++ b/spec/ruby/command_line/dash_external_encoding_spec.rb @@ -0,0 +1,15 @@ +require_relative '../spec_helper' + +describe 'The --external-encoding command line option sets Encoding.default_external' do + before :each do + @test_string = "print Encoding.default_external.name" + end + + it "if given an encoding with an =" do + ruby_exe(@test_string, options: '--external-encoding=big5').should == Encoding::Big5.name + end + + it "if given an encoding as a separate argument" do + ruby_exe(@test_string, options: '--external-encoding big5').should == Encoding::Big5.name + end +end diff --git a/spec/ruby/command_line/dash_internal_encoding_spec.rb b/spec/ruby/command_line/dash_internal_encoding_spec.rb new file mode 100644 index 0000000000..3049040bb4 --- /dev/null +++ b/spec/ruby/command_line/dash_internal_encoding_spec.rb @@ -0,0 +1,15 @@ +require_relative '../spec_helper' + +describe 'The --internal-encoding command line option sets Encoding.default_internal' do + before :each do + @test_string = "print Encoding.default_internal.name" + end + + it "if given an encoding with an =" do + ruby_exe(@test_string, options: '--internal-encoding=big5').should == Encoding::Big5.name + end + + it "if given an encoding as a separate argument" do + ruby_exe(@test_string, options: '--internal-encoding big5').should == Encoding::Big5.name + end +end diff --git a/spec/ruby/command_line/dash_n_spec.rb b/spec/ruby/command_line/dash_n_spec.rb index f4dd9f1851..9d331d6065 100644 --- a/spec/ruby/command_line/dash_n_spec.rb +++ b/spec/ruby/command_line/dash_n_spec.rb @@ -1,3 +1,5 @@ +require_relative '../spec_helper' + describe "The -n command line option" do before :each do @names = fixture __FILE__, "names.txt" diff --git a/spec/ruby/command_line/dash_p_spec.rb b/spec/ruby/command_line/dash_p_spec.rb index 67562b5bc3..39827c3868 100644 --- a/spec/ruby/command_line/dash_p_spec.rb +++ b/spec/ruby/command_line/dash_p_spec.rb @@ -1,3 +1,5 @@ +require_relative '../spec_helper' + describe "The -p command line option" do before :each do @names = fixture __FILE__, "names.txt" diff --git a/spec/ruby/command_line/dash_upper_e_spec.rb b/spec/ruby/command_line/dash_upper_e_spec.rb index 39ffa001a3..b3c6ce262b 100644 --- a/spec/ruby/command_line/dash_upper_e_spec.rb +++ b/spec/ruby/command_line/dash_upper_e_spec.rb @@ -1,3 +1,5 @@ +require_relative '../spec_helper' + describe "ruby -E" do it "sets the external encoding with '-E external'" do result = ruby_exe("print Encoding.default_external", options: '-E euc-jp') diff --git a/spec/ruby/command_line/dash_upper_f_spec.rb b/spec/ruby/command_line/dash_upper_f_spec.rb index 020968b1f9..967acc2ece 100644 --- a/spec/ruby/command_line/dash_upper_f_spec.rb +++ b/spec/ruby/command_line/dash_upper_f_spec.rb @@ -1,3 +1,5 @@ +require_relative '../spec_helper' + describe "the -F command line option" do before :each do @passwd = fixture __FILE__, "passwd_file.txt" diff --git a/spec/ruby/command_line/dash_upper_k_spec.rb b/spec/ruby/command_line/dash_upper_k_spec.rb index 3c3b9fa4d3..d7e16d6ede 100644 --- a/spec/ruby/command_line/dash_upper_k_spec.rb +++ b/spec/ruby/command_line/dash_upper_k_spec.rb @@ -1,33 +1,66 @@ -describe 'The -K command line option sets __ENCODING__' do - it "to Encoding::ASCII_8BIT with -Ka" do - ruby_exe("print __ENCODING__", options: '-Ka').should == Encoding::ASCII_8BIT.to_s - end +require_relative '../spec_helper' - it "to Encoding::ASCII_8BIT with -KA" do - ruby_exe("print __ENCODING__", options: '-KA').should == Encoding::ASCII_8BIT.to_s +describe 'The -K command line option' do + before :each do + @test_string = "print [__ENCODING__&.name, Encoding.default_external&.name, Encoding.default_internal&.name].inspect" end - it "to Encoding::EUC_JP with -Ke" do - ruby_exe("print __ENCODING__", options: '-Ke').should == Encoding::EUC_JP.to_s - end + describe 'sets __ENCODING__ and Encoding.default_external' do + it "to Encoding::ASCII_8BIT with -Ka" do + ruby_exe(@test_string, options: '-Ka').should == + [Encoding::ASCII_8BIT.name, Encoding::ASCII_8BIT.name, nil].inspect + end - it "to Encoding::EUC_JP with -KE" do - ruby_exe("print __ENCODING__", options: '-KE').should == Encoding::EUC_JP.to_s - end + it "to Encoding::ASCII_8BIT with -KA" do + ruby_exe(@test_string, options: '-KA').should == + [Encoding::ASCII_8BIT.name, Encoding::ASCII_8BIT.name, nil].inspect + end - it "to Encoding::UTF_8 with -Ku" do - ruby_exe("print __ENCODING__", options: '-Ku').should == Encoding::UTF_8.to_s - end + it "to Encoding::ASCII_8BIT with -Kn" do + ruby_exe(@test_string, options: '-Kn').should == + [Encoding::ASCII_8BIT.name, Encoding::ASCII_8BIT.name, nil].inspect + end - it "to Encoding::UTF_8 with -KU" do - ruby_exe("print __ENCODING__", options: '-KU').should == Encoding::UTF_8.to_s - end + it "to Encoding::ASCII_8BIT with -KN" do + ruby_exe(@test_string, options: '-KN').should == + [Encoding::ASCII_8BIT.name, Encoding::ASCII_8BIT.name, nil].inspect + end + + it "to Encoding::EUC_JP with -Ke" do + ruby_exe(@test_string, options: '-Ke').should == + [Encoding::EUC_JP.name, Encoding::EUC_JP.name, nil].inspect + end + + it "to Encoding::EUC_JP with -KE" do + ruby_exe(@test_string, options: '-KE').should == + [Encoding::EUC_JP.name, Encoding::EUC_JP.name, nil].inspect + end + + it "to Encoding::UTF_8 with -Ku" do + ruby_exe(@test_string, options: '-Ku').should == + [Encoding::UTF_8.name, Encoding::UTF_8.name, nil].inspect + end + + it "to Encoding::UTF_8 with -KU" do + ruby_exe(@test_string, options: '-KU').should == + [Encoding::UTF_8.name, Encoding::UTF_8.name, nil].inspect + end + + it "to Encoding::Windows_31J with -Ks" do + ruby_exe(@test_string, options: '-Ks').should == + [Encoding::Windows_31J.name, Encoding::Windows_31J.name, nil].inspect + end - it "to Encoding::Windows_31J with -Ks" do - ruby_exe("print __ENCODING__", options: '-Ks').should == Encoding::Windows_31J.to_s + it "to Encoding::Windows_31J with -KS" do + ruby_exe(@test_string, options: '-KS').should == + [Encoding::Windows_31J.name, Encoding::Windows_31J.name, nil].inspect + end end - it "to Encoding::Windows_31J with -KS" do - ruby_exe("print __ENCODING__", options: '-KS').should == Encoding::Windows_31J.to_s + platform_is_not :windows do + it "ignores unknown codes" do + ruby_exe(@test_string, options: '-KZ').should == + [Encoding::UTF_8.name, Encoding::UTF_8.name, nil].inspect + end end end diff --git a/spec/ruby/command_line/dash_upper_u_spec.rb b/spec/ruby/command_line/dash_upper_u_spec.rb index 6cd52a3647..2546b5b9f4 100644 --- a/spec/ruby/command_line/dash_upper_u_spec.rb +++ b/spec/ruby/command_line/dash_upper_u_spec.rb @@ -1,3 +1,5 @@ +require_relative '../spec_helper' + describe "ruby -U" do it "sets Encoding.default_internal to UTF-8" do ruby_exe('print Encoding.default_internal.name', diff --git a/spec/ruby/command_line/dash_x_spec.rb b/spec/ruby/command_line/dash_x_spec.rb index a5306b4f75..ad6be23063 100644 --- a/spec/ruby/command_line/dash_x_spec.rb +++ b/spec/ruby/command_line/dash_x_spec.rb @@ -1,3 +1,5 @@ +require_relative '../spec_helper' + describe "The -x command line option" do it "runs code after the first /\#!.*ruby.*/-ish line in target file" do embedded_ruby = fixture __FILE__, "bin/embedded_ruby.txt" diff --git a/spec/ruby/command_line/fixtures/bin/launcher.rb b/spec/ruby/command_line/fixtures/bin/launcher.rb index 92a0ee2b49..92a0ee2b49 100644..100755 --- a/spec/ruby/command_line/fixtures/bin/launcher.rb +++ b/spec/ruby/command_line/fixtures/bin/launcher.rb diff --git a/spec/ruby/core/kernel/eval_spec.rb b/spec/ruby/core/kernel/eval_spec.rb index fbae8ff3c7..46158628a3 100644 --- a/spec/ruby/core/kernel/eval_spec.rb +++ b/spec/ruby/core/kernel/eval_spec.rb @@ -214,6 +214,7 @@ describe "Kernel#eval" do ruby_exe(code).chomp.should == "a,b,c,e,LocalJumpError,f" 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 code = "# encoding: UTF-8\n'é'.encoding".b diff --git a/spec/ruby/core/kernel/fixtures/singleton_methods.rb b/spec/ruby/core/kernel/fixtures/singleton_methods.rb new file mode 100644 index 0000000000..32ea0adf89 --- /dev/null +++ b/spec/ruby/core/kernel/fixtures/singleton_methods.rb @@ -0,0 +1,13 @@ +module SingletonMethodsSpecs + module Prepended + def mspec_test_kernel_singleton_methods + end + public :mspec_test_kernel_singleton_methods + end + + ::Module.prepend Prepended + + module SelfExtending + extend self + end +end diff --git a/spec/ruby/core/kernel/singleton_methods_spec.rb b/spec/ruby/core/kernel/singleton_methods_spec.rb index 74fd4a9608..eb4cede110 100644 --- a/spec/ruby/core/kernel/singleton_methods_spec.rb +++ b/spec/ruby/core/kernel/singleton_methods_spec.rb @@ -36,6 +36,19 @@ describe :kernel_singleton_methods_modules, shared: true do it "does not return any included methods for a class including a module" do ReflectSpecs::D.singleton_methods(*@object).should include(:ds_pro, :ds_pub) end + + it "for a module does not return methods in a module prepended to Module itself" do + require_relative 'fixtures/singleton_methods' + mod = SingletonMethodsSpecs::SelfExtending + mod.method(:mspec_test_kernel_singleton_methods).owner.should == SingletonMethodsSpecs::Prepended + + ancestors = mod.singleton_class.ancestors + ancestors[0...2].should == [ mod.singleton_class, mod ] + ancestors.should include(SingletonMethodsSpecs::Prepended) + + # Do not search prepended modules of `Module`, as that's a non-singleton class + mod.singleton_methods.should == [] + end end describe :kernel_singleton_methods_supers, shared: true do @@ -145,7 +158,6 @@ describe "Kernel#singleton_methods" do it_behaves_like :kernel_singleton_methods_supers, nil, true it_behaves_like :kernel_singleton_methods_modules, nil, true it_behaves_like :kernel_singleton_methods_private_supers, nil, true - end describe "when passed false" do diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb index e36b17cf15..287aa601a9 100644 --- a/spec/ruby/core/module/refine_spec.rb +++ b/spec/ruby/core/module/refine_spec.rb @@ -594,6 +594,30 @@ describe "Module#refine" do end end + it 'and alias aliases a method within a refinement module, but not outside it' do + Module.new do + using Module.new { + refine Array do + alias :orig_count :count + end + } + [1,2].orig_count.should == 2 + end + lambda { [1,2].orig_count }.should raise_error(NoMethodError) + end + + it 'and alias_method aliases a method within a refinement module, but not outside it' do + Module.new do + using Module.new { + refine Array do + alias_method :orig_count, :count + end + } + [1,2].orig_count.should == 2 + end + lambda { [1,2].orig_count }.should raise_error(NoMethodError) + end + # Refinements are inherited by module inclusion. # That is, using activates all refinements in the ancestors of the specified module. # Refinements in a descendant have priority over refinements in an ancestor. diff --git a/spec/ruby/core/signal/trap_spec.rb b/spec/ruby/core/signal/trap_spec.rb index 867094d6dd..c11c900add 100644 --- a/spec/ruby/core/signal/trap_spec.rb +++ b/spec/ruby/core/signal/trap_spec.rb @@ -158,9 +158,28 @@ platform_is_not :windows do $?.exitstatus.should == 0 end + it "returns 'DEFAULT' for the initial SIGINT handler" do + ruby_exe('print trap(:INT) { abort }').should == 'DEFAULT' + end + it "returns SYSTEM_DEFAULT if passed DEFAULT and no handler was ever set" do Signal.trap("PROF", "DEFAULT").should == "SYSTEM_DEFAULT" end + + it "accepts 'SYSTEM_DEFAULT' and uses the OS handler for SIGPIPE" do + code = <<-RUBY + p Signal.trap('PIPE', 'SYSTEM_DEFAULT') + r, w = IO.pipe + r.close + loop { w.write("a"*1024) } + RUBY + out = ruby_exe(code) + status = $? + out.should == "nil\n" + status.signaled?.should == true + status.termsig.should be_kind_of(Integer) + Signal.signame(status.termsig).should == "PIPE" + end end end diff --git a/spec/ruby/default.mspec b/spec/ruby/default.mspec index 2bc50869c8..f5e5f7685d 100644 --- a/spec/ruby/default.mspec +++ b/spec/ruby/default.mspec @@ -44,6 +44,11 @@ class MSpecScript [/_spec.rb$/, '_tags.txt'] ] + set :toplevel_constants_excludes, [ + /\wSpecs?$/, + /^CS_CONST\d/, + ] + # Enable features MSpec.enable_feature :fiber MSpec.enable_feature :fiber_library 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 Binary files differnew file mode 100644 index 0000000000..8cb31e42f0 --- /dev/null +++ b/spec/ruby/language/fixtures/utf16-be-bom.rb diff --git a/spec/ruby/language/fixtures/utf16-be-nobom.rb b/spec/ruby/language/fixtures/utf16-be-nobom.rb Binary files differnew file mode 100644 index 0000000000..99e2ce8ce8 --- /dev/null +++ b/spec/ruby/language/fixtures/utf16-be-nobom.rb diff --git a/spec/ruby/language/fixtures/utf16-le-bom.rb b/spec/ruby/language/fixtures/utf16-le-bom.rb Binary files differnew file mode 100644 index 0000000000..981016ea52 --- /dev/null +++ b/spec/ruby/language/fixtures/utf16-le-bom.rb diff --git a/spec/ruby/language/fixtures/utf16-le-nobom.rb b/spec/ruby/language/fixtures/utf16-le-nobom.rb Binary files differnew file mode 100644 index 0000000000..98de9697ca --- /dev/null +++ b/spec/ruby/language/fixtures/utf16-le-nobom.rb 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 diff --git a/spec/ruby/library/etc/confstr_spec.rb b/spec/ruby/library/etc/confstr_spec.rb new file mode 100644 index 0000000000..0c922a3a77 --- /dev/null +++ b/spec/ruby/library/etc/confstr_spec.rb @@ -0,0 +1,14 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require 'etc' + +platform_is_not :windows do + describe "Etc.confstr" do + it "returns a String for Etc::CS_PATH" do + Etc.confstr(Etc::CS_PATH).should be_an_instance_of(String) + end + + it "raises Errno::EINVAL for unknown configuration variables" do + -> { Etc.confstr(-1) }.should raise_error(Errno::EINVAL) + end + end +end diff --git a/spec/ruby/library/etc/group_spec.rb b/spec/ruby/library/etc/group_spec.rb index 1524454333..fdd39bda16 100644 --- a/spec/ruby/library/etc/group_spec.rb +++ b/spec/ruby/library/etc/group_spec.rb @@ -6,6 +6,15 @@ describe "Etc.group" do it_behaves_like :etc_on_windows, :group platform_is_not :windows do + it "returns a Etc::Group struct" do + group = Etc.group + begin + group.should be_an_instance_of(Etc::Group) + ensure + Etc.endgrent + end + end + it "raises a RuntimeError for parallel iteration" do proc { Etc.group do | group | diff --git a/spec/ruby/library/etc/passwd_spec.rb b/spec/ruby/library/etc/passwd_spec.rb new file mode 100644 index 0000000000..d61dada451 --- /dev/null +++ b/spec/ruby/library/etc/passwd_spec.rb @@ -0,0 +1,15 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require 'etc' + +platform_is_not :windows do + describe "Etc.passwd" do + it "returns a Etc::Passwd struct" do + passwd = Etc.passwd + begin + passwd.should be_an_instance_of(Etc::Passwd) + ensure + Etc.endpwent + end + end + end +end diff --git a/spec/ruby/library/etc/sysconf_spec.rb b/spec/ruby/library/etc/sysconf_spec.rb new file mode 100644 index 0000000000..34dcf6e470 --- /dev/null +++ b/spec/ruby/library/etc/sysconf_spec.rb @@ -0,0 +1,31 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require 'etc' + +platform_is_not :windows do + describe "Etc.sysconf" do + def should_be_integer_or_nil(value) + if value.nil? + value.should == nil + else + value.should be_kind_of(Integer) + end + end + + it "returns the value of POSIX.1 system configuration variables" do + Etc.sysconf(Etc::SC_ARG_MAX).should be_kind_of(Integer) + should_be_integer_or_nil(Etc.sysconf(Etc::SC_CHILD_MAX)) + Etc.sysconf(Etc::SC_HOST_NAME_MAX).should be_kind_of(Integer) + Etc.sysconf(Etc::SC_LOGIN_NAME_MAX).should be_kind_of(Integer) + Etc.sysconf(Etc::SC_NGROUPS_MAX).should be_kind_of(Integer) + Etc.sysconf(Etc::SC_CLK_TCK).should be_kind_of(Integer) + Etc.sysconf(Etc::SC_OPEN_MAX).should be_kind_of(Integer) + Etc.sysconf(Etc::SC_PAGESIZE).should be_kind_of(Integer) + Etc.sysconf(Etc::SC_RE_DUP_MAX).should be_kind_of(Integer) + Etc.sysconf(Etc::SC_STREAM_MAX).should be_kind_of(Integer) + should_be_integer_or_nil(Etc.sysconf(Etc::SC_SYMLOOP_MAX)) + Etc.sysconf(Etc::SC_TTY_NAME_MAX).should be_kind_of(Integer) + Etc.sysconf(Etc::SC_TZNAME_MAX).should be_kind_of(Integer) + Etc.sysconf(Etc::SC_VERSION).should be_kind_of(Integer) + end + end +end diff --git a/spec/ruby/library/etc/sysconfdir_spec.rb b/spec/ruby/library/etc/sysconfdir_spec.rb new file mode 100644 index 0000000000..d54299c513 --- /dev/null +++ b/spec/ruby/library/etc/sysconfdir_spec.rb @@ -0,0 +1,8 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require 'etc' + +describe "Etc.sysconfdir" do + it "returns a String" do + Etc.sysconfdir.should be_an_instance_of(String) + end +end diff --git a/spec/ruby/library/etc/systmpdir_spec.rb b/spec/ruby/library/etc/systmpdir_spec.rb new file mode 100644 index 0000000000..99c82903f8 --- /dev/null +++ b/spec/ruby/library/etc/systmpdir_spec.rb @@ -0,0 +1,8 @@ +require File.expand_path('../../../spec_helper', __FILE__) +require 'etc' + +describe "Etc.systmpdir" do + it "returns a String" do + Etc.systmpdir.should be_an_instance_of(String) + end +end diff --git a/spec/ruby/library/socket/basicsocket/connect_address_spec.rb b/spec/ruby/library/socket/basicsocket/connect_address_spec.rb index cb05d3bfe1..03e456b620 100644 --- a/spec/ruby/library/socket/basicsocket/connect_address_spec.rb +++ b/spec/ruby/library/socket/basicsocket/connect_address_spec.rb @@ -53,42 +53,44 @@ describe 'Socket#connect_address' do end end - describe 'using a socket bound to ::' do - before do - @sock = Socket.new(:INET6, :STREAM) - @sock.bind(Socket.sockaddr_in(0, '::')) - end + guard -> { SocketSpecs.ipv6_available? } do + describe 'using a socket bound to ::' do + before do + @sock = Socket.new(:INET6, :STREAM) + @sock.bind(Socket.sockaddr_in(0, '::')) + end - after do - @sock.close - end + after do + @sock.close + end - it 'returns an Addrinfo' do - @sock.connect_address.should be_an_instance_of(Addrinfo) - end + it 'returns an Addrinfo' do + @sock.connect_address.should be_an_instance_of(Addrinfo) + end - it 'uses ::1 as the IP address' do - @sock.connect_address.ip_address.should == '::1' - end + it 'uses ::1 as the IP address' do + @sock.connect_address.ip_address.should == '::1' + end - it 'uses the correct port number' do - @sock.connect_address.ip_port.should > 0 - end + it 'uses the correct port number' do + @sock.connect_address.ip_port.should > 0 + end - it 'uses AF_INET6 as the address family' do - @sock.connect_address.afamily.should == Socket::AF_INET6 - end + it 'uses AF_INET6 as the address family' do + @sock.connect_address.afamily.should == Socket::AF_INET6 + end - it 'uses PF_INET6 as the address family' do - @sock.connect_address.pfamily.should == Socket::PF_INET6 - end + it 'uses PF_INET6 as the address family' do + @sock.connect_address.pfamily.should == Socket::PF_INET6 + end - it 'uses SOCK_STREAM as the socket type' do - @sock.connect_address.socktype.should == Socket::SOCK_STREAM - end + it 'uses SOCK_STREAM as the socket type' do + @sock.connect_address.socktype.should == Socket::SOCK_STREAM + end - it 'uses 0 as the protocol' do - @sock.connect_address.protocol.should == 0 + it 'uses 0 as the protocol' do + @sock.connect_address.protocol.should == 0 + end end end diff --git a/spec/ruby/library/socket/fixtures/classes.rb b/spec/ruby/library/socket/fixtures/classes.rb index 1098b04a5e..8167b879fd 100644 --- a/spec/ruby/library/socket/fixtures/classes.rb +++ b/spec/ruby/library/socket/fixtures/classes.rb @@ -50,7 +50,7 @@ module SocketSpecs def self.ipv6_available? @ipv6_available ||= begin server = TCPServer.new('::1', 0) - rescue Errno::EADDRNOTAVAIL + rescue Errno::EADDRNOTAVAIL, SocketError :no else server.close diff --git a/spec/ruby/optional/capi/ext/data_spec.c b/spec/ruby/optional/capi/ext/data_spec.c index 52adeee59f..ac6b51b454 100644 --- a/spec/ruby/optional/capi/ext/data_spec.c +++ b/spec/ruby/optional/capi/ext/data_spec.c @@ -20,7 +20,7 @@ void sample_wrapped_struct_mark(void* st) { } VALUE sdaf_alloc_func(VALUE klass) { - struct sample_wrapped_struct* bar = (struct sample_wrapped_struct *)malloc(sizeof(struct sample_wrapped_struct)); + struct sample_wrapped_struct* bar = malloc(sizeof(struct sample_wrapped_struct)); bar->foo = 42; return Data_Wrap_Struct(klass, &sample_wrapped_struct_mark, &sample_wrapped_struct_free, bar); } @@ -33,7 +33,7 @@ VALUE sdaf_get_struct(VALUE self) { } VALUE sws_wrap_struct(VALUE self, VALUE val) { - struct sample_wrapped_struct* bar = (struct sample_wrapped_struct *)malloc(sizeof(struct sample_wrapped_struct)); + struct sample_wrapped_struct* bar = malloc(sizeof(struct sample_wrapped_struct)); bar->foo = FIX2INT(val); return Data_Wrap_Struct(rb_cObject, &sample_wrapped_struct_mark, &sample_wrapped_struct_free, bar); } @@ -59,7 +59,7 @@ VALUE sws_get_struct_data_ptr(VALUE self, VALUE obj) { VALUE sws_change_struct(VALUE self, VALUE obj, VALUE new_val) { struct sample_wrapped_struct *old_struct, *new_struct; - new_struct = (struct sample_wrapped_struct *)malloc(sizeof(struct sample_wrapped_struct)); + new_struct = malloc(sizeof(struct sample_wrapped_struct)); new_struct->foo = FIX2INT(new_val); old_struct = RDATA(obj)->data; free(old_struct); diff --git a/spec/ruby/optional/capi/struct_spec.rb b/spec/ruby/optional/capi/struct_spec.rb index 06fb189b58..b3acd02b61 100644 --- a/spec/ruby/optional/capi/struct_spec.rb +++ b/spec/ruby/optional/capi/struct_spec.rb @@ -64,7 +64,7 @@ end describe "C-API Struct function" do before :each do @s = CApiStructSpecs.new - @struct = @s.rb_struct_define_under(CApiStructSpecs, "CAPIStruct", "a", "b", "c") + @struct = @s.rb_struct_define_under(CApiStructSpecs, "CAPIStructUnder", "a", "b", "c") end describe "rb_struct_define_under" do @@ -80,11 +80,15 @@ describe "C-API Struct function" do it "has a value of nil for the member of a newly created instance" do # Verify that attributes are on an instance basis - CApiStructSpecs::CAPIStruct.new.b.should be_nil + CApiStructSpecs::CAPIStructUnder.new.b.should be_nil + end + + it "does not create a constant scoped under Struct for the named Struct" do + Struct.should_not have_constant(:CAPIStructUnder) end it "creates a constant scoped under the namespace of the given class" do - CApiStructSpecs.should have_constant(:CAPIStruct) + CApiStructSpecs.should have_constant(:CAPIStructUnder) end it "returns the member names as Symbols" do |