summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2020-07-27 21:41:08 +0200
committerBenoit Daloze <eregontp@gmail.com>2020-07-27 21:41:08 +0200
commit126fd5f15cff0d3bf314d90d8c21a3ae25ae8e68 (patch)
tree33350f7170436c32ed4c8e79f0be2c334c7bc8a9 /spec
parent7429841ab6494b849106e6d3b119f147adfee3b7 (diff)
Update to ruby/spec@07164da
Diffstat (limited to 'spec')
-rw-r--r--spec/ruby/.mspec.constants1
-rw-r--r--spec/ruby/.rubocop.yml1
-rw-r--r--spec/ruby/.rubocop_todo.yml2
-rw-r--r--spec/ruby/CONTRIBUTING.md4
-rw-r--r--spec/ruby/command_line/dash_r_spec.rb19
-rw-r--r--spec/ruby/command_line/fixtures/test_file.rb2
-rw-r--r--spec/ruby/core/array/fill_spec.rb3
-rw-r--r--spec/ruby/core/exception/backtrace_spec.rb2
-rw-r--r--spec/ruby/core/kernel/__dir___spec.rb7
-rw-r--r--spec/ruby/core/kernel/at_exit_spec.rb31
-rw-r--r--spec/ruby/core/kernel/fixtures/__dir__.rb2
-rw-r--r--spec/ruby/core/kernel/fixtures/at_exit.rb3
-rw-r--r--spec/ruby/core/kernel/fixtures/warn_require.rb1
-rw-r--r--spec/ruby/core/kernel/fixtures/warn_require_caller.rb2
-rw-r--r--spec/ruby/core/kernel/raise_spec.rb21
-rw-r--r--spec/ruby/core/kernel/warn_spec.rb13
-rw-r--r--spec/ruby/core/module/fixtures/refine.rb12
-rw-r--r--spec/ruby/core/module/refine_spec.rb300
-rw-r--r--spec/ruby/core/string/split_spec.rb68
-rw-r--r--spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb7
-rw-r--r--spec/ruby/core/thread/backtrace/location/fixtures/absolute_path_main.rb2
-rw-r--r--spec/ruby/core/thread/backtrace/location/lineno_spec.rb10
-rw-r--r--spec/ruby/core/thread/backtrace/location/path_spec.rb12
-rw-r--r--spec/ruby/core/thread/raise_spec.rb2
-rw-r--r--spec/ruby/language/break_spec.rb18
-rw-r--r--spec/ruby/language/numbered_parameters_spec.rb4
-rw-r--r--spec/ruby/library/bigdecimal/to_s_spec.rb16
-rw-r--r--spec/ruby/library/digest/instance/new_spec.rb19
-rw-r--r--spec/ruby/library/ripper/lex_spec.rb23
-rw-r--r--spec/ruby/library/ripper/sexp_spec.rb13
-rw-r--r--spec/ruby/optional/capi/encoding_spec.rb38
-rw-r--r--spec/ruby/optional/capi/ext/encoding_spec.c37
-rw-r--r--spec/ruby/optional/capi/ext/typed_data_spec.c15
-rw-r--r--spec/ruby/optional/capi/object_spec.rb2
-rw-r--r--spec/ruby/optional/capi/spec_helper.rb1
-rw-r--r--spec/ruby/optional/capi/typed_data_spec.rb17
-rw-r--r--spec/ruby/shared/kernel/raise.rb27
-rw-r--r--spec/ruby/shared/process/exit.rb20
38 files changed, 733 insertions, 44 deletions
diff --git a/spec/ruby/.mspec.constants b/spec/ruby/.mspec.constants
index d7e09ca2d9..3e3bdbef8a 100644
--- a/spec/ruby/.mspec.constants
+++ b/spec/ruby/.mspec.constants
@@ -152,6 +152,7 @@ RegexpSpecsSubclassTwo
Reline
RescueInClassExample
Resolv
+Ripper
SHA1Constants
SHA256Constants
SHA384Constants
diff --git a/spec/ruby/.rubocop.yml b/spec/ruby/.rubocop.yml
index 5370d996b8..5db9256572 100644
--- a/spec/ruby/.rubocop.yml
+++ b/spec/ruby/.rubocop.yml
@@ -92,6 +92,7 @@ Lint/UnreachableCode:
Exclude:
- 'core/enumerator/lazy/fixtures/classes.rb'
- 'core/kernel/catch_spec.rb'
+ - 'core/kernel/raise_spec.rb'
- 'core/kernel/throw_spec.rb'
- 'language/break_spec.rb'
- 'language/fixtures/break.rb'
diff --git a/spec/ruby/.rubocop_todo.yml b/spec/ruby/.rubocop_todo.yml
index 8d9cd82f0b..7a5f9f74c5 100644
--- a/spec/ruby/.rubocop_todo.yml
+++ b/spec/ruby/.rubocop_todo.yml
@@ -59,6 +59,7 @@ Lint/InheritException:
- 'core/enumerator/lazy/fixtures/classes.rb'
- 'core/exception/fixtures/common.rb'
- 'core/module/fixtures/autoload_ex1.rb'
+ - 'shared/kernel/raise.rb'
# Offense count: 72
# Cop supports --auto-correct.
@@ -115,6 +116,7 @@ Lint/RescueException:
- 'core/exception/cause_spec.rb'
- 'core/exception/no_method_error_spec.rb'
- 'core/kernel/fixtures/autoload_frozen.rb'
+ - 'core/kernel/raise_spec.rb'
- 'core/module/autoload_spec.rb'
- 'core/mutex/sleep_spec.rb'
- 'core/thread/abort_on_exception_spec.rb'
diff --git a/spec/ruby/CONTRIBUTING.md b/spec/ruby/CONTRIBUTING.md
index 8d18f1102d..9a2a341ae7 100644
--- a/spec/ruby/CONTRIBUTING.md
+++ b/spec/ruby/CONTRIBUTING.md
@@ -136,11 +136,11 @@ Here is a list of the most commonly-used guards:
#### Version guards
```ruby
-ruby_version_is ""..."2.6 do
+ruby_version_is ""..."2.6" do
# Specs for RUBY_VERSION < 2.6
end
-ruby_version_is "2.6 do
+ruby_version_is "2.6" do
# Specs for RUBY_VERSION >= 2.6
end
```
diff --git a/spec/ruby/command_line/dash_r_spec.rb b/spec/ruby/command_line/dash_r_spec.rb
index b29895bd26..46c000b9e7 100644
--- a/spec/ruby/command_line/dash_r_spec.rb
+++ b/spec/ruby/command_line/dash_r_spec.rb
@@ -7,7 +7,22 @@ describe "The -r command line option" do
end
it "requires the specified file" do
- result = ruby_exe(@script, options: "-r #{@test_file}")
- result.should include(@test_file + ".rb")
+ out = ruby_exe(@script, options: "-r #{@test_file}")
+ out.should include("REQUIRED")
+ out.should include(@test_file + ".rb")
+ end
+
+ it "requires the file before parsing the main script" do
+ out = ruby_exe(fixture(__FILE__, "bad_syntax.rb"), options: "-r #{@test_file}", args: "2>&1")
+ $?.should_not.success?
+ out.should include("REQUIRED")
+ out.should include("syntax error")
+ end
+
+ it "does not require the file if the main script file does not exist" do
+ out = `#{ruby_exe.to_a.join(' ')} -r #{@test_file} #{fixture(__FILE__, "does_not_exist.rb")} 2>&1`
+ $?.should_not.success?
+ out.should_not.include?("REQUIRED")
+ out.should.include?("No such file or directory")
end
end
diff --git a/spec/ruby/command_line/fixtures/test_file.rb b/spec/ruby/command_line/fixtures/test_file.rb
index 961e3c0b0c..30a832299e 100644
--- a/spec/ruby/command_line/fixtures/test_file.rb
+++ b/spec/ruby/command_line/fixtures/test_file.rb
@@ -1 +1 @@
-"test file"
+puts "REQUIRED"
diff --git a/spec/ruby/core/array/fill_spec.rb b/spec/ruby/core/array/fill_spec.rb
index 96c8862208..6745bc8d09 100644
--- a/spec/ruby/core/array/fill_spec.rb
+++ b/spec/ruby/core/array/fill_spec.rb
@@ -207,8 +207,9 @@ describe "Array#fill with (filler, index, length)" do
not_supported_on :opal do
it "raises an ArgumentError or RangeError for too-large sizes" do
+ error_types = [RangeError, ArgumentError]
arr = [1, 2, 3]
- -> { arr.fill(10, 1, fixnum_max) }.should raise_error(ArgumentError)
+ -> { arr.fill(10, 1, fixnum_max) }.should raise_error { |err| error_types.should include(err.class) }
-> { arr.fill(10, 1, bignum_value) }.should raise_error(RangeError)
end
end
diff --git a/spec/ruby/core/exception/backtrace_spec.rb b/spec/ruby/core/exception/backtrace_spec.rb
index 2d6825180a..3f74c4cefe 100644
--- a/spec/ruby/core/exception/backtrace_spec.rb
+++ b/spec/ruby/core/exception/backtrace_spec.rb
@@ -43,7 +43,7 @@ describe "Exception#backtrace" do
# This regexp is deliberately imprecise to account for the need to abstract out
# the paths of the included mspec files and the desire to avoid specifying in any
# detail what the in `...' portion looks like.
- line.should =~ /^[^ ]+\:\d+(:in `[^`]+')?$/
+ line.should =~ /^.+:\d+:in `[^`]+'$/
end
end
diff --git a/spec/ruby/core/kernel/__dir___spec.rb b/spec/ruby/core/kernel/__dir___spec.rb
index 64b439161f..0686b31e97 100644
--- a/spec/ruby/core/kernel/__dir___spec.rb
+++ b/spec/ruby/core/kernel/__dir___spec.rb
@@ -5,6 +5,13 @@ describe "Kernel#__dir__" do
__dir__.should == File.realpath(File.dirname(__FILE__))
end
+ it "returns the expanded path of the directory when used in the main script" do
+ fixtures_dir = File.dirname(fixture(__FILE__, '__dir__.rb'))
+ Dir.chdir(fixtures_dir) do
+ ruby_exe("__dir__.rb").should == "__dir__.rb\n#{fixtures_dir}\n"
+ end
+ end
+
context "when used in eval with a given filename" do
it "returns File.dirname(filename)" do
eval("__dir__", nil, "foo.rb").should == "."
diff --git a/spec/ruby/core/kernel/at_exit_spec.rb b/spec/ruby/core/kernel/at_exit_spec.rb
index 21149f965b..7bdb5391fe 100644
--- a/spec/ruby/core/kernel/at_exit_spec.rb
+++ b/spec/ruby/core/kernel/at_exit_spec.rb
@@ -23,7 +23,7 @@ describe "Kernel.at_exit" do
it "gives access to the last raised exception" do
code = <<-EOC
at_exit do
- puts "The exception matches: \#{$! == $exception}"
+ puts "The exception matches: \#{$! == $exception} (message=\#{$!.message})"
end
begin
@@ -33,10 +33,35 @@ describe "Kernel.at_exit" do
end
EOC
- result = ruby_exe(code, args: "2>&1", escape: true)
- result.should =~ /The exception matches: true/
+ result = ruby_exe(code, args: "2>&1")
+ result.lines.should.include?("The exception matches: true (message=foo)\n")
end
+ it "both exceptions in at_exit and in the main script are printed" do
+ result = ruby_exe('at_exit { raise "at_exit_error" }; raise "main_script_error"', args: "2>&1")
+ result.should.include?('at_exit_error (RuntimeError)')
+ result.should.include?('main_script_error (RuntimeError)')
+ end
+
+ it "decides the exit status if both at_exit and the main script raise SystemExit" do
+ ruby_exe('at_exit { exit 43 }; exit 42', args: "2>&1")
+ $?.exitstatus.should == 43
+ end
+
+ it "runs all at_exit even if some raise exceptions" do
+ code = 'at_exit { STDERR.puts "last" }; at_exit { exit 43 }; at_exit { STDERR.puts "first" }; exit 42'
+ result = ruby_exe(code, args: "2>&1")
+ result.should == "first\nlast\n"
+ $?.exitstatus.should == 43
+ end
+
+ it "runs at_exit handlers even if the main script fails to parse" do
+ script = fixture(__FILE__, "at_exit.rb")
+ result = ruby_exe('{', options: "-r#{script}", args: "2>&1")
+ $?.should_not.success?
+ result.should.include?("at_exit ran\n")
+ result.should.include?("syntax error")
+ end
end
describe "Kernel#at_exit" do
diff --git a/spec/ruby/core/kernel/fixtures/__dir__.rb b/spec/ruby/core/kernel/fixtures/__dir__.rb
new file mode 100644
index 0000000000..bf9a15e3c8
--- /dev/null
+++ b/spec/ruby/core/kernel/fixtures/__dir__.rb
@@ -0,0 +1,2 @@
+puts __FILE__
+puts __dir__
diff --git a/spec/ruby/core/kernel/fixtures/at_exit.rb b/spec/ruby/core/kernel/fixtures/at_exit.rb
new file mode 100644
index 0000000000..9c11a7ad6c
--- /dev/null
+++ b/spec/ruby/core/kernel/fixtures/at_exit.rb
@@ -0,0 +1,3 @@
+at_exit do
+ STDERR.puts "at_exit ran"
+end
diff --git a/spec/ruby/core/kernel/fixtures/warn_require.rb b/spec/ruby/core/kernel/fixtures/warn_require.rb
new file mode 100644
index 0000000000..c4b0733233
--- /dev/null
+++ b/spec/ruby/core/kernel/fixtures/warn_require.rb
@@ -0,0 +1 @@
+warn 'warn-require-warning', uplevel: 1
diff --git a/spec/ruby/core/kernel/fixtures/warn_require_caller.rb b/spec/ruby/core/kernel/fixtures/warn_require_caller.rb
new file mode 100644
index 0000000000..35a0f969f9
--- /dev/null
+++ b/spec/ruby/core/kernel/fixtures/warn_require_caller.rb
@@ -0,0 +1,2 @@
+# Use a different line than just 1
+require "#{__dir__}/warn_require"
diff --git a/spec/ruby/core/kernel/raise_spec.rb b/spec/ruby/core/kernel/raise_spec.rb
index bf26560246..591daa03cf 100644
--- a/spec/ruby/core/kernel/raise_spec.rb
+++ b/spec/ruby/core/kernel/raise_spec.rb
@@ -6,6 +6,27 @@ describe "Kernel#raise" do
it "is a private method" do
Kernel.should have_private_instance_method(:raise)
end
+
+ it "re-raises the previously rescued exception if no exception is specified" do
+ ScratchPad.record nil
+
+ -> do
+ begin
+ raise Exception, "outer"
+ ScratchPad.record :no_abort
+ rescue Exception
+ begin
+ raise StandardError, "inner"
+ rescue StandardError
+ end
+
+ raise
+ ScratchPad.record :no_reraise
+ end
+ end.should raise_error(Exception, "outer")
+
+ ScratchPad.recorded.should be_nil
+ end
end
describe "Kernel#raise" do
diff --git a/spec/ruby/core/kernel/warn_spec.rb b/spec/ruby/core/kernel/warn_spec.rb
index 84cfa78672..79e78dd4a3 100644
--- a/spec/ruby/core/kernel/warn_spec.rb
+++ b/spec/ruby/core/kernel/warn_spec.rb
@@ -101,6 +101,19 @@ describe "Kernel#warn" do
-> { w.f4("foo", 3) }.should output(nil, %r|core/kernel/fixtures/classes.rb:#{w.f3_call_lineno}: warning: foo|)
end
+ # Test both explicitly without and with RubyGems as RubyGems overrides Kernel#warn
+ it "shows the caller of #require and not #require itself without RubyGems" do
+ file = fixture(__FILE__ , "warn_require_caller.rb")
+ ruby_exe(file, options: "--disable-gems", args: "2>&1").should == "#{file}:2: warning: warn-require-warning\n"
+ end
+
+ ruby_version_is "2.6" do
+ it "shows the caller of #require and not #require itself with RubyGems loaded" do
+ file = fixture(__FILE__ , "warn_require_caller.rb")
+ ruby_exe(file, options: "-rrubygems", args: "2>&1").should == "#{file}:2: warning: warn-require-warning\n"
+ end
+ end
+
it "converts first arg using to_s" do
w = KernelSpecs::WarnInNestedCall.new
diff --git a/spec/ruby/core/module/fixtures/refine.rb b/spec/ruby/core/module/fixtures/refine.rb
index 79e2e80197..e8215aa640 100644
--- a/spec/ruby/core/module/fixtures/refine.rb
+++ b/spec/ruby/core/module/fixtures/refine.rb
@@ -3,6 +3,10 @@ module ModuleSpecs
def foo; "foo" end
end
+ class ClassWithSuperFoo
+ def foo; [:C] end
+ end
+
module PrependedModule
def foo; "foo from prepended module"; end
end
@@ -11,7 +15,11 @@ module ModuleSpecs
def foo; "foo from included module"; end
end
- def self.build_refined_class
- Class.new(ClassWithFoo)
+ def self.build_refined_class(for_super: false)
+ if for_super
+ Class.new(ClassWithSuperFoo)
+ else
+ Class.new(ClassWithFoo)
+ end
end
end
diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb
index ca12d5d13b..ebb7111d82 100644
--- a/spec/ruby/core/module/refine_spec.rb
+++ b/spec/ruby/core/module/refine_spec.rb
@@ -731,16 +731,67 @@ describe "Module#refine" do
result.should == "foo"
end
+ it "looks in the refined class from included module" do
+ refined_class = ModuleSpecs.build_refined_class(for_super: true)
+
+ a = Module.new do
+ def foo
+ [:A] + super
+ end
+ end
+
+ refinement = Module.new do
+ refine refined_class do
+ include a
+ end
+ end
+
+ result = nil
+ Module.new do
+ using refinement
+
+ result = refined_class.new.foo
+ end
+
+ result.should == [:A, :C]
+ end
+
+ it "looks in the refined ancestors from included module" do
+ refined_class = ModuleSpecs.build_refined_class(for_super: true)
+ subclass = Class.new(refined_class)
+
+ a = Module.new do
+ def foo
+ [:A] + super
+ end
+ end
+
+ refinement = Module.new do
+ refine refined_class do
+ include a
+ end
+ end
+
+ result = nil
+ Module.new do
+ using refinement
+
+ result = subclass.new.foo
+ end
+
+ result.should == [:A, :C]
+ end
+
# super in a method of a refinement invokes the method in the refined
# class even if there is another refinement which has been activated
# in the same context.
- it "looks in the refined class even if there is another active refinement" do
- refined_class = ModuleSpecs.build_refined_class
+ it "looks in the refined class first if called from refined method" do
+ refined_class = ModuleSpecs.build_refined_class(for_super: true)
refinement = Module.new do
refine refined_class do
def foo
- "foo from refinement"
+ [:R1]
end
end
end
@@ -748,7 +799,7 @@ describe "Module#refine" do
refinement_with_super = Module.new do
refine refined_class do
def foo
- super
+ [:R2] + super
end
end
end
@@ -760,7 +811,246 @@ describe "Module#refine" do
result = refined_class.new.foo
end
- result.should == "foo"
+ result.should == [:R2, :C]
+ end
+
+ it "looks only in the refined class even if there is another active refinement" do
+ refined_class = ModuleSpecs.build_refined_class(for_super: true)
+
+ refinement = Module.new do
+ refine refined_class do
+ def bar
+ "you cannot see me from super because I belong to another active R"
+ end
+ end
+ end
+
+ refinement_with_super = Module.new do
+ refine refined_class do
+ def bar
+ super
+ end
+ end
+ end
+
+
+ Module.new do
+ using refinement
+ using refinement_with_super
+ -> {
+ refined_class.new.bar
+ }.should raise_error(NoMethodError)
+ end
+ end
+
+ it "does't have access to active refinements for C from included module" do
+ refined_class = ModuleSpecs.build_refined_class
+
+ a = Module.new do
+ def foo
+ super + bar
+ end
+ end
+
+ refinement = Module.new do
+ refine refined_class do
+ include a
+
+ def bar
+ "bar is not seen from A methods"
+ end
+ end
+ end
+
+ Module.new do
+ using refinement
+ -> {
+ refined_class.new.foo
+ }.should raise_error(NameError) { |e| e.name.should == :bar }
+ end
+ end
+
+ it "does't have access to other active refinements from included module" do
+ refined_class = ModuleSpecs.build_refined_class
+
+ refinement_integer = Module.new do
+ refine Integer do
+ def bar
+ "bar is not seen from A methods"
+ end
+ end
+ end
+
+ a = Module.new do
+ def foo
+ super + 1.bar
+ end
+ end
+
+ refinement = Module.new do
+ refine refined_class do
+ include a
+ end
+ end
+
+ Module.new do
+ using refinement
+ using refinement_integer
+ -> {
+ refined_class.new.foo
+ }.should raise_error(NameError) { |e| e.name.should == :bar }
+ end
+ end
+
+ # https://bugs.ruby-lang.org/issues/16977
+ it "looks in the another active refinement if super called from included modules" do
+ refined_class = ModuleSpecs.build_refined_class(for_super: true)
+
+ a = Module.new do
+ def foo
+ [:A] + super
+ end
+ end
+
+ b = Module.new do
+ def foo
+ [:B] + super
+ end
+ end
+
+ refinement_a = Module.new do
+ refine refined_class do
+ include a
+ end
+ end
+
+ refinement_b = Module.new do
+ refine refined_class do
+ include b
+ end
+ end
+
+ result = nil
+ Module.new do
+ using refinement_a
+ using refinement_b
+ result = refined_class.new.foo
+ end
+
+ result.should == [:B, :A, :C]
+ end
+
+ it "looks in the current active refinement from included modules" do
+ refined_class = ModuleSpecs.build_refined_class(for_super: true)
+
+ a = Module.new do
+ def foo
+ [:A] + super
+ end
+ end
+
+ b = Module.new do
+ def foo
+ [:B] + super
+ end
+ end
+
+ refinement = Module.new do
+ refine refined_class do
+ def foo
+ [:LAST] + super
+ end
+ end
+ end
+
+ refinement_a_b = Module.new do
+ refine refined_class do
+ include a
+ include b
+ end
+ end
+
+ result = nil
+ Module.new do
+ using refinement
+ using refinement_a_b
+ result = refined_class.new.foo
+ end
+
+ result.should == [:B, :A, :LAST, :C]
+ end
+
+ ruby_version_is ""..."2.8" do
+ it "looks in the lexical scope refinements before other active refinements" do
+ refined_class = ModuleSpecs.build_refined_class(for_super: true)
+
+ refinement_local = Module.new do
+ refine refined_class do
+ def foo
+ [:LOCAL] + super
+ end
+ end
+ end
+
+ a = Module.new do
+ using refinement_local
+
+ def foo
+ [:A] + super
+ end
+ end
+
+ refinement = Module.new do
+ refine refined_class do
+ include a
+ end
+ end
+
+ result = nil
+ Module.new do
+ using refinement
+ result = refined_class.new.foo
+ end
+
+ result.should == [:A, :LOCAL, :C]
+ end
+ end
+
+ ruby_version_is "2.8" do
+ # https://bugs.ruby-lang.org/issues/17007
+ it "does not look in the lexical scope refinements before other active refinements" do
+ refined_class = ModuleSpecs.build_refined_class(for_super: true)
+
+ refinement_local = Module.new do
+ refine refined_class do
+ def foo
+ [:LOCAL] + super
+ end
+ end
+ end
+
+ a = Module.new do
+ using refinement_local
+
+ def foo
+ [:A] + super
+ end
+ end
+
+ refinement = Module.new do
+ refine refined_class do
+ include a
+ end
+ end
+
+ result = nil
+ Module.new do
+ using refinement
+ result = refined_class.new.foo
+ end
+
+ result.should == [:A, :C]
+ end
end
end
diff --git a/spec/ruby/core/string/split_spec.rb b/spec/ruby/core/string/split_spec.rb
index 34a50a5f13..7ac8d7815c 100644
--- a/spec/ruby/core/string/split_spec.rb
+++ b/spec/ruby/core/string/split_spec.rb
@@ -426,12 +426,70 @@ describe "String#split with Regexp" do
end
ruby_version_is "2.6" do
- it "yields each split substrings if a block is given" do
- a = []
- returned_object = "chunky bacon".split(" ") { |str| a << str.capitalize }
+ context "when a block is given" do
+ it "yields each split substring with default pattern" do
+ a = []
+ returned_object = "chunky bacon".split { |str| a << str.capitalize }
+
+ returned_object.should == "chunky bacon"
+ a.should == ["Chunky", "Bacon"]
+ end
+
+ it "yields the string when limit is 1" do
+ a = []
+ returned_object = "chunky bacon".split("", 1) { |str| a << str.capitalize }
+
+ returned_object.should == "chunky bacon"
+ a.should == ["Chunky bacon"]
+ end
+
+ it "yields each split letter" do
+ a = []
+ returned_object = "chunky".split("", 0) { |str| a << str.capitalize }
+
+ returned_object.should == "chunky"
+ a.should == %w(C H U N K Y)
+ end
+
+ it "yields each split substring with a pattern" do
+ a = []
+ returned_object = "chunky-bacon".split("-", 0) { |str| a << str.capitalize }
+
+ returned_object.should == "chunky-bacon"
+ a.should == ["Chunky", "Bacon"]
+ end
- returned_object.should == "chunky bacon"
- a.should == ["Chunky", "Bacon"]
+ it "yields each split substring with empty regexp pattern" do
+ a = []
+ returned_object = "chunky".split(//) { |str| a << str.capitalize }
+
+ returned_object.should == "chunky"
+ a.should == %w(C H U N K Y)
+ end
+
+ it "yields each split substring with empty regexp pattern and limit" do
+ a = []
+ returned_object = "chunky".split(//, 3) { |str| a << str.capitalize }
+
+ returned_object.should == "chunky"
+ a.should == %w(C H Unky)
+ end
+
+ it "yields each split substring with a regexp pattern" do
+ a = []
+ returned_object = "chunky:bacon".split(/:/) { |str| a << str.capitalize }
+
+ returned_object.should == "chunky:bacon"
+ a.should == ["Chunky", "Bacon"]
+ end
+
+ it "returns a string as is (and doesn't call block) if it is empty" do
+ a = []
+ returned_object = "".split { |str| a << str.capitalize }
+
+ returned_object.should == ""
+ a.should == []
+ end
end
describe "for a String subclass" do
diff --git a/spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb b/spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb
index 67f9274f32..90839baa0f 100644
--- a/spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb
+++ b/spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb
@@ -10,6 +10,13 @@ describe 'Thread::Backtrace::Location#absolute_path' do
@frame.absolute_path.should == File.realpath(__FILE__)
end
+ it 'returns an absolute path when using a relative main script path' do
+ script = fixture(__FILE__, 'absolute_path_main.rb')
+ Dir.chdir(File.dirname(script)) do
+ ruby_exe('absolute_path_main.rb').should == "absolute_path_main.rb\n#{script}\n"
+ end
+ end
+
context "when used in eval with a given filename" do
it "returns filename" do
code = "caller_locations(0)[0].absolute_path"
diff --git a/spec/ruby/core/thread/backtrace/location/fixtures/absolute_path_main.rb b/spec/ruby/core/thread/backtrace/location/fixtures/absolute_path_main.rb
new file mode 100644
index 0000000000..d2b23393d4
--- /dev/null
+++ b/spec/ruby/core/thread/backtrace/location/fixtures/absolute_path_main.rb
@@ -0,0 +1,2 @@
+puts __FILE__
+puts caller_locations(0)[0].absolute_path
diff --git a/spec/ruby/core/thread/backtrace/location/lineno_spec.rb b/spec/ruby/core/thread/backtrace/location/lineno_spec.rb
index dc93d32d75..d14cf17514 100644
--- a/spec/ruby/core/thread/backtrace/location/lineno_spec.rb
+++ b/spec/ruby/core/thread/backtrace/location/lineno_spec.rb
@@ -10,4 +10,14 @@ describe 'Thread::Backtrace::Location#lineno' do
it 'returns the absolute path of the call frame' do
@frame.lineno.should == @line
end
+
+ it 'should be the same line number as in #to_s, including for core methods' do
+ # Get the caller_locations from a call made into a core library method
+ locations = [:non_empty].map { caller_locations }[0]
+
+ locations.each do |location|
+ line_number = location.to_s[/:(\d+):/, 1]
+ location.lineno.should == Integer(line_number)
+ end
+ end
end
diff --git a/spec/ruby/core/thread/backtrace/location/path_spec.rb b/spec/ruby/core/thread/backtrace/location/path_spec.rb
index 93eb4982d8..7863c055d3 100644
--- a/spec/ruby/core/thread/backtrace/location/path_spec.rb
+++ b/spec/ruby/core/thread/backtrace/location/path_spec.rb
@@ -87,6 +87,18 @@ describe 'Thread::Backtrace::Location#path' do
end
end
+ it 'should be the same path as in #to_s, including for core methods' do
+ # Get the caller_locations from a call made into a core library method
+ locations = [:non_empty].map { caller_locations }[0]
+
+ locations.each do |location|
+ filename = location.to_s[/^(.+):\d+:/, 1]
+ path = location.path
+
+ path.should == filename
+ end
+ end
+
context "canonicalization" do
platform_is_not :windows do
before :each do
diff --git a/spec/ruby/core/thread/raise_spec.rb b/spec/ruby/core/thread/raise_spec.rb
index 88a96d5f4e..27de3cc627 100644
--- a/spec/ruby/core/thread/raise_spec.rb
+++ b/spec/ruby/core/thread/raise_spec.rb
@@ -203,6 +203,6 @@ describe "Thread#raise on same thread" do
Thread.current.raise
end
end
- -> { t.value }.should raise_error(RuntimeError)
+ -> { t.value }.should raise_error(RuntimeError, '')
end
end
diff --git a/spec/ruby/language/break_spec.rb b/spec/ruby/language/break_spec.rb
index 754d5d3c49..627cb4a071 100644
--- a/spec/ruby/language/break_spec.rb
+++ b/spec/ruby/language/break_spec.rb
@@ -362,4 +362,22 @@ describe "Executing break from within a block" do
bt2.three
ScratchPad.recorded.should == [:two_ensure, :three_post, :three_ensure]
end
+
+ it "works when passing through a super call" do
+ cls1 = Class.new { def foo; yield; end }
+ cls2 = Class.new(cls1) { def foo; super { break 1 }; end }
+
+ -> do
+ cls2.new.foo.should == 1
+ end.should_not raise_error
+ end
+
+ it "raises LocalJumpError when converted into a proc during a a super call" do
+ cls1 = Class.new { def foo(&b); b; end }
+ cls2 = Class.new(cls1) { def foo; super { break 1 }.call; end }
+
+ -> do
+ cls2.new.foo
+ end.should raise_error(LocalJumpError)
+ end
end
diff --git a/spec/ruby/language/numbered_parameters_spec.rb b/spec/ruby/language/numbered_parameters_spec.rb
index 5b0f74b3ab..9dd79f44b8 100644
--- a/spec/ruby/language/numbered_parameters_spec.rb
+++ b/spec/ruby/language/numbered_parameters_spec.rb
@@ -42,7 +42,7 @@ ruby_version_is "2.7" do
end
end
- it "warns when numbered parameter is overriten with local variable" do
+ it "warns when numbered parameter is overwritten with local variable" do
-> {
eval("_1 = 0")
}.should complain(/warning: `_1' is reserved for numbered parameter; consider another name/)
@@ -59,7 +59,7 @@ ruby_version_is "2.7" do
}.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/)
end
- it "errors when numbered parameter is overriten with local variable" do
+ it "errors when numbered parameter is overwritten with local variable" do
-> {
eval("_1 = 0")
}.should raise_error(SyntaxError, /_1 is reserved for numbered parameter/)
diff --git a/spec/ruby/library/bigdecimal/to_s_spec.rb b/spec/ruby/library/bigdecimal/to_s_spec.rb
index 7f741ca8b6..f2851976e2 100644
--- a/spec/ruby/library/bigdecimal/to_s_spec.rb
+++ b/spec/ruby/library/bigdecimal/to_s_spec.rb
@@ -8,6 +8,11 @@ describe "BigDecimal#to_s" do
@bigneg_str = "-3.1415926535897932384626433832795028841971693993"
@bigdec = BigDecimal(@bigdec_str)
@bigneg = BigDecimal(@bigneg_str)
+ @internal = Encoding.default_internal
+ end
+
+ after :each do
+ Encoding.default_internal = @internal
end
it "return type is of class String" do
@@ -78,4 +83,15 @@ describe "BigDecimal#to_s" do
end
end
+ ruby_version_is "2.8" do
+ it "returns a String in US-ASCII encoding when Encoding.default_internal is nil" do
+ Encoding.default_internal = nil
+ BigDecimal('1.23').to_s.encoding.should equal(Encoding::US_ASCII)
+ end
+
+ it "returns a String in US-ASCII encoding when Encoding.default_internal is not nil" do
+ Encoding.default_internal = Encoding::IBM437
+ BigDecimal('1.23').to_s.encoding.should equal(Encoding::US_ASCII)
+ end
+ end
end
diff --git a/spec/ruby/library/digest/instance/new_spec.rb b/spec/ruby/library/digest/instance/new_spec.rb
new file mode 100644
index 0000000000..3f7939844b
--- /dev/null
+++ b/spec/ruby/library/digest/instance/new_spec.rb
@@ -0,0 +1,19 @@
+require_relative '../../../spec_helper'
+require 'digest'
+require_relative '../md5/shared/constants'
+
+describe "Digest::Instance#new" do
+ it "returns a copy of the digest instance" do
+ digest = Digest::MD5.new
+ copy = digest.new
+ copy.should_not.equal?(digest)
+ end
+
+ it "calls reset" do
+ digest = Digest::MD5.new
+ digest << "test"
+ digest.hexdigest.should != MD5Constants::BlankHexdigest
+ copy = digest.new
+ copy.hexdigest.should == MD5Constants::BlankHexdigest
+ end
+end
diff --git a/spec/ruby/library/ripper/lex_spec.rb b/spec/ruby/library/ripper/lex_spec.rb
new file mode 100644
index 0000000000..97cfb06904
--- /dev/null
+++ b/spec/ruby/library/ripper/lex_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../spec_helper'
+require 'ripper'
+
+describe "Ripper.lex" do
+ it "lexes a simple method declaration" do
+ expected = [
+ [[1, 0], :on_kw, "def", 'FNAME'],
+ [[1, 3], :on_sp, " ", 'FNAME'],
+ [[1, 4], :on_ident, "m", 'ENDFN'],
+ [[1, 5], :on_lparen, "(", 'BEG|LABEL'],
+ [[1, 6], :on_ident, "a", 'ARG'],
+ [[1, 7], :on_rparen, ")", 'ENDFN'],
+ [[1, 8], :on_sp, " ", 'BEG'],
+ [[1, 9], :on_kw, "nil", 'END'],
+ [[1, 12], :on_sp, " ", 'END'],
+ [[1, 13], :on_kw, "end", 'END']
+ ]
+ lexed = Ripper.lex("def m(a) nil end")
+ lexed.map { |e|
+ e[0...-1] + [e[-1].to_s.split('|').map { |s| s.sub(/^EXPR_/, '') }.join('|')]
+ }.should == expected
+ end
+end
diff --git a/spec/ruby/library/ripper/sexp_spec.rb b/spec/ruby/library/ripper/sexp_spec.rb
new file mode 100644
index 0000000000..6c69624c65
--- /dev/null
+++ b/spec/ruby/library/ripper/sexp_spec.rb
@@ -0,0 +1,13 @@
+require_relative '../../spec_helper'
+require 'ripper'
+
+describe "Ripper.sexp" do
+ it "returns an s-expression for a method declaration" do
+ expected = [:program,
+ [[:def,
+ [:@ident, "hello", [1, 4]],
+ [:params, nil, nil, nil, nil, nil, nil, nil],
+ [:bodystmt, [[:@int, "42", [1, 11]]], nil, nil, nil]]]]
+ Ripper.sexp("def hello; 42; end").should == expected
+ end
+end
diff --git a/spec/ruby/optional/capi/encoding_spec.rb b/spec/ruby/optional/capi/encoding_spec.rb
index 8e59ee8b1b..93bde54069 100644
--- a/spec/ruby/optional/capi/encoding_spec.rb
+++ b/spec/ruby/optional/capi/encoding_spec.rb
@@ -58,6 +58,15 @@ describe "C-API Encoding function" do
end
end
+ describe "rb_enc_codelen" do
+ it "returns the correct length for the given codepoint" do
+ @s.rb_enc_codelen(0x24, Encoding::UTF_8).should == 1
+ @s.rb_enc_codelen(0xA2, Encoding::UTF_8).should == 2
+ @s.rb_enc_codelen(0x20AC, Encoding::UTF_8).should == 3
+ @s.rb_enc_codelen(0x24B62, Encoding::UTF_8).should == 4
+ end
+ end
+
describe "rb_enc_find" do
it "returns the encoding of an Encoding" do
@s.rb_enc_find("UTF-8").should == "UTF-8"
@@ -130,6 +139,18 @@ describe "C-API Encoding function" do
end
end
+ describe "rb_enc_mbcput" do
+ it "writes the correct bytes to the buffer" do
+ @s.rb_enc_mbcput(0x24, Encoding::UTF_8).should == "$"
+ @s.rb_enc_mbcput(0xA2, Encoding::UTF_8).should == "¢"
+ @s.rb_enc_mbcput(0x20AC, Encoding::UTF_8).should == "€"
+ @s.rb_enc_mbcput(0x24B62, Encoding::UTF_8).should == "𤭢"
+
+ @s.rb_enc_mbcput(0x24, Encoding::UTF_16BE).bytes.should == [0, 0x24]
+ @s.rb_enc_mbcput(0x24B62, Encoding::UTF_16LE).bytes.should == [82, 216, 98, 223]
+ end
+ end
+
describe "rb_usascii_encoding" do
it "returns the encoding for Encoding::US_ASCII" do
@s.rb_usascii_encoding.should == "US-ASCII"
@@ -610,4 +631,21 @@ describe "C-API Encoding function" do
end
end
end
+
+ describe "ONIGENC_MBC_CASE_FOLD" do
+ it "returns the correct case fold for the given string" do
+ @s.ONIGENC_MBC_CASE_FOLD("lower").should == ["l", 1]
+ @s.ONIGENC_MBC_CASE_FOLD("Upper").should == ["u", 1]
+ end
+
+ it "works with other encodings" do
+ @s.ONIGENC_MBC_CASE_FOLD("lower".force_encoding("binary")).should == ["l", 1]
+ @s.ONIGENC_MBC_CASE_FOLD("Upper".force_encoding("binary")).should == ["u", 1]
+ @s.ONIGENC_MBC_CASE_FOLD("É").should == ["é", 2]
+
+ str, length = @s.ONIGENC_MBC_CASE_FOLD('$'.encode(Encoding::UTF_16BE))
+ length.should == 2
+ str.bytes.should == [0, 0x24]
+ end
+ end
end
diff --git a/spec/ruby/optional/capi/ext/encoding_spec.c b/spec/ruby/optional/capi/ext/encoding_spec.c
index 8935db966e..cde4d0c351 100644
--- a/spec/ruby/optional/capi/ext/encoding_spec.c
+++ b/spec/ruby/optional/capi/ext/encoding_spec.c
@@ -127,6 +127,18 @@ static VALUE encoding_spec_rb_enc_mbc_to_codepoint(VALUE self, VALUE str, VALUE
return INT2FIX(rb_enc_mbc_to_codepoint(p, e, rb_enc_get(str)));
}
+static VALUE encoding_spec_rb_enc_mbcput(VALUE self, VALUE code, VALUE encoding) {
+ unsigned int c = FIX2UINT(code);
+ rb_encoding *enc = rb_to_encoding(encoding);
+ char buf[ONIGENC_CODE_TO_MBC_MAXLEN];
+ memset(buf, '\1', sizeof(buf));
+ int len = rb_enc_mbcput(c, buf, enc);
+ if (buf[len] != '\1') {
+ rb_raise(rb_eRuntimeError, "should not change bytes after len");
+ }
+ return rb_enc_str_new(buf, len, enc);
+}
+
static VALUE encoding_spec_rb_enc_from_encoding(VALUE self, VALUE name) {
return rb_enc_from_encoding(rb_enc_find(RSTRING_PTR(name)));
}
@@ -266,6 +278,28 @@ static VALUE encoding_spec_rb_uv_to_utf8(VALUE self, VALUE buf, VALUE num) {
return INT2NUM(rb_uv_to_utf8(RSTRING_PTR(buf), NUM2INT(num)));
}
+static VALUE encoding_spec_ONIGENC_MBC_CASE_FOLD(VALUE self, VALUE str) {
+ char *beg = RSTRING_PTR(str);
+ char *beg_initial = beg;
+ char *end = beg + 2;
+ OnigUChar fold[ONIGENC_GET_CASE_FOLD_CODES_MAX_NUM];
+ memset(fold, '\1', sizeof(fold));
+ rb_encoding *enc = rb_enc_get(str);
+ int r = ONIGENC_MBC_CASE_FOLD(enc, ONIGENC_CASE_FOLD, &beg, (const OnigUChar *)end, fold);
+ if (r > 0 && fold[r] != '\1') {
+ rb_raise(rb_eRuntimeError, "should not change bytes after len");
+ }
+ VALUE str_result = r <= 0 ? Qnil : rb_enc_str_new((char *)fold, r, enc);
+ long bytes_used = beg - beg_initial;
+ return rb_ary_new3(2, str_result, INT2FIX(bytes_used));
+}
+
+static VALUE encoding_spec_rb_enc_codelen(VALUE self, VALUE code, VALUE encoding) {
+ unsigned int c = FIX2UINT(code);
+ rb_encoding *enc = rb_to_encoding(encoding);
+ return INT2FIX(rb_enc_codelen(c, enc));
+}
+
void Init_encoding_spec(void) {
VALUE cls;
native_rb_encoding_pointer = (rb_encoding**) malloc(sizeof(rb_encoding*));
@@ -299,12 +333,14 @@ void Init_encoding_spec(void) {
rb_define_method(cls, "rb_enc_associate_index", encoding_spec_rb_enc_associate_index, 2);
rb_define_method(cls, "rb_enc_compatible", encoding_spec_rb_enc_compatible, 2);
rb_define_method(cls, "rb_enc_copy", encoding_spec_rb_enc_copy, 2);
+ rb_define_method(cls, "rb_enc_codelen", encoding_spec_rb_enc_codelen, 2);
rb_define_method(cls, "rb_enc_find", encoding_spec_rb_enc_find, 1);
rb_define_method(cls, "rb_enc_find_index", encoding_spec_rb_enc_find_index, 1);
rb_define_method(cls, "rb_enc_isalnum", encoding_spec_rb_enc_isalnum, 2);
rb_define_method(cls, "rb_enc_isspace", encoding_spec_rb_enc_isspace, 2);
rb_define_method(cls, "rb_enc_from_index", encoding_spec_rb_enc_from_index, 1);
rb_define_method(cls, "rb_enc_mbc_to_codepoint", encoding_spec_rb_enc_mbc_to_codepoint, 2);
+ rb_define_method(cls, "rb_enc_mbcput", encoding_spec_rb_enc_mbcput, 2);
rb_define_method(cls, "rb_enc_from_encoding", encoding_spec_rb_enc_from_encoding, 1);
rb_define_method(cls, "rb_enc_get", encoding_spec_rb_enc_get, 1);
rb_define_method(cls, "rb_enc_precise_mbclen", encoding_spec_rb_enc_precise_mbclen, 2);
@@ -326,6 +362,7 @@ void Init_encoding_spec(void) {
rb_define_method(cls, "rb_enc_codepoint_len", encoding_spec_rb_enc_codepoint_len, 1);
rb_define_method(cls, "rb_enc_str_asciionly_p", encoding_spec_rb_enc_str_asciionly_p, 1);
rb_define_method(cls, "rb_uv_to_utf8", encoding_spec_rb_uv_to_utf8, 2);
+ rb_define_method(cls, "ONIGENC_MBC_CASE_FOLD", encoding_spec_ONIGENC_MBC_CASE_FOLD, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/ext/typed_data_spec.c b/spec/ruby/optional/capi/ext/typed_data_spec.c
index 6eb91b76bf..70f21ce36f 100644
--- a/spec/ruby/optional/capi/ext/typed_data_spec.c
+++ b/spec/ruby/optional/capi/ext/typed_data_spec.c
@@ -148,6 +148,18 @@ VALUE sws_typed_change_struct(VALUE self, VALUE obj, VALUE new_val) {
return Qnil;
}
+VALUE sws_typed_rb_check_typeddata_same_type(VALUE self, VALUE obj) {
+ return rb_check_typeddata(obj, &sample_typed_wrapped_struct_data_type) == DATA_PTR(obj) ? Qtrue : Qfalse;
+}
+
+VALUE sws_typed_rb_check_typeddata_same_type_parent(VALUE self, VALUE obj) {
+ return rb_check_typeddata(obj, &sample_typed_wrapped_struct_parent_data_type) == DATA_PTR(obj) ? Qtrue : Qfalse;
+}
+
+VALUE sws_typed_rb_check_typeddata_different_type(VALUE self, VALUE obj) {
+ return rb_check_typeddata(obj, &sample_typed_wrapped_struct_other_data_type) == DATA_PTR(obj) ? Qtrue : Qfalse;
+}
+
void Init_typed_data_spec(void) {
VALUE cls = rb_define_class("CApiAllocTypedSpecs", rb_cObject);
rb_define_alloc_func(cls, sdaf_alloc_typed_func);
@@ -160,6 +172,9 @@ void Init_typed_data_spec(void) {
rb_define_method(cls, "typed_get_struct_rdata", sws_typed_get_struct_rdata, 1);
rb_define_method(cls, "typed_get_struct_data_ptr", sws_typed_get_struct_data_ptr, 1);
rb_define_method(cls, "typed_change_struct", sws_typed_change_struct, 2);
+ rb_define_method(cls, "rb_check_typeddata_same_type", sws_typed_rb_check_typeddata_same_type, 1);
+ rb_define_method(cls, "rb_check_typeddata_same_type_parent", sws_typed_rb_check_typeddata_same_type_parent, 1);
+ rb_define_method(cls, "rb_check_typeddata_different_type", sws_typed_rb_check_typeddata_different_type, 1);
}
#ifdef __cplusplus
diff --git a/spec/ruby/optional/capi/object_spec.rb b/spec/ruby/optional/capi/object_spec.rb
index bbcaec2ba8..484dfb851c 100644
--- a/spec/ruby/optional/capi/object_spec.rb
+++ b/spec/ruby/optional/capi/object_spec.rb
@@ -831,6 +831,7 @@ describe "CApiObject" do
it "returns nil if the instance variable has not been initialized and is not a valid Ruby name" do
@o.rb_ivar_get(@test, :bar).should == nil
+ @o.rb_ivar_get(@test, :mesg).should == nil
end
it 'returns the instance variable when it is not a valid Ruby name' do
@@ -866,6 +867,7 @@ describe "CApiObject" do
it "does not throw an error if the instance variable is not a valid Ruby name" do
@o.rb_ivar_defined(@test, :bar).should == false
+ @o.rb_ivar_defined(@test, :mesg).should == false
end
end
diff --git a/spec/ruby/optional/capi/spec_helper.rb b/spec/ruby/optional/capi/spec_helper.rb
index a7029a74ed..3b13e0854d 100644
--- a/spec/ruby/optional/capi/spec_helper.rb
+++ b/spec/ruby/optional/capi/spec_helper.rb
@@ -76,6 +76,7 @@ def compile_extension(name)
$ruby = ENV.values_at('RUBY_EXE', 'RUBY_FLAGS').join(' ')
# MRI magic to consider building non-bundled extensions
$extout = nil
+ $warnflags << ' -Wno-declaration-after-statement'
create_makefile(#{ext.inspect})
RUBY
output = ruby_exe("extconf.rb")
diff --git a/spec/ruby/optional/capi/typed_data_spec.rb b/spec/ruby/optional/capi/typed_data_spec.rb
index da56a050fd..9ccfa562d1 100644
--- a/spec/ruby/optional/capi/typed_data_spec.rb
+++ b/spec/ruby/optional/capi/typed_data_spec.rb
@@ -57,4 +57,21 @@ describe "CApiWrappedTypedStruct" do
@s.typed_get_struct_data_ptr(a).should == 1024
end
end
+
+ describe "rb_check_typeddata" do
+ it "returns data pointer when the struct has the given type" do
+ a = @s.typed_wrap_struct(1024)
+ @s.rb_check_typeddata_same_type(a).should == true
+ end
+
+ it "returns data pointer when the parent struct has the given type" do
+ a = @s.typed_wrap_struct(1024)
+ @s.rb_check_typeddata_same_type_parent(a).should == true
+ end
+
+ it "raises an error for different types" do
+ a = @s.typed_wrap_struct(1024)
+ -> { @s.rb_check_typeddata_different_type(a) }.should raise_error(TypeError)
+ end
+ end
end
diff --git a/spec/ruby/shared/kernel/raise.rb b/spec/ruby/shared/kernel/raise.rb
index d4553775f4..7d9954e29a 100644
--- a/spec/ruby/shared/kernel/raise.rb
+++ b/spec/ruby/shared/kernel/raise.rb
@@ -25,6 +25,14 @@ describe :kernel_raise, shared: true do
-> { @object.raise("a bad thing") }.should raise_error(RuntimeError)
end
+ it "passes no arguments to the constructor when given only an exception class" do
+ klass = Class.new(Exception) do
+ def initialize
+ end
+ end
+ -> { @object.raise(klass) }.should raise_error(klass) { |e| e.message.should == klass.to_s }
+ end
+
it "raises a TypeError when passed a non-Exception object" do
-> { @object.raise(Object.new) }.should raise_error(TypeError)
end
@@ -41,25 +49,6 @@ describe :kernel_raise, shared: true do
-> { @object.raise(nil) }.should raise_error(TypeError)
end
- it "re-raises the previously rescued exception if no exception is specified" do
- -> do
- begin
- @object.raise Exception, "outer"
- ScratchPad.record :no_abort
- rescue
- begin
- @object.raise StandardError, "inner"
- rescue
- end
-
- @object.raise
- ScratchPad.record :no_reraise
- end
- end.should raise_error(Exception, "outer")
-
- ScratchPad.recorded.should be_nil
- end
-
it "re-raises a previously rescued exception without overwriting the backtrace" do
begin
initial_raise_line = __LINE__; @object.raise 'raised'
diff --git a/spec/ruby/shared/process/exit.rb b/spec/ruby/shared/process/exit.rb
index 1820dd17fd..e633afc73a 100644
--- a/spec/ruby/shared/process/exit.rb
+++ b/spec/ruby/shared/process/exit.rb
@@ -91,4 +91,24 @@ describe :process_exit!, shared: true do
out.should == ""
$?.exitstatus.should == 21
end
+
+ it "skips at_exit handlers" do
+ out = ruby_exe("at_exit { STDERR.puts 'at_exit' }; #{@object}.send(:exit!, 21)", args: '2>&1')
+ out.should == ""
+ $?.exitstatus.should == 21
+ end
+
+ it "overrides the original exception and exit status when called from #at_exit" do
+ code = <<-RUBY
+ at_exit do
+ STDERR.puts 'in at_exit'
+ STDERR.puts "$! is \#{$!.class}:\#{$!.message}"
+ #{@object}.send(:exit!, 21)
+ end
+ raise 'original error'
+ RUBY
+ out = ruby_exe(code, args: '2>&1')
+ out.should == "in at_exit\n$! is RuntimeError:original error\n"
+ $?.exitstatus.should == 21
+ end
end