aboutsummaryrefslogtreecommitdiffstats
path: root/spec/ruby/language
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/language')
-rw-r--r--spec/ruby/language/README2
-rw-r--r--spec/ruby/language/block_spec.rb2
-rw-r--r--spec/ruby/language/break_spec.rb13
-rw-r--r--spec/ruby/language/case_spec.rb7
-rw-r--r--spec/ruby/language/class_spec.rb22
-rw-r--r--spec/ruby/language/constants_spec.rb17
-rw-r--r--spec/ruby/language/defined_spec.rb2
-rw-r--r--spec/ruby/language/ensure_spec.rb4
-rw-r--r--spec/ruby/language/fixtures/binary_symbol.rb4
-rw-r--r--spec/ruby/language/fixtures/super.rb133
-rw-r--r--spec/ruby/language/if_spec.rb19
-rw-r--r--spec/ruby/language/method_spec.rb10
-rw-r--r--spec/ruby/language/optional_assignments_spec.rb4
-rw-r--r--spec/ruby/language/predefined_spec.rb19
-rw-r--r--spec/ruby/language/regexp/character_classes_spec.rb23
-rw-r--r--spec/ruby/language/regexp/modifiers_spec.rb7
-rw-r--r--spec/ruby/language/rescue_spec.rb7
-rw-r--r--spec/ruby/language/return_spec.rb223
-rw-r--r--spec/ruby/language/super_spec.rb119
-rw-r--r--spec/ruby/language/symbol_spec.rb13
-rw-r--r--spec/ruby/language/throw_spec.rb15
21 files changed, 586 insertions, 79 deletions
diff --git a/spec/ruby/language/README b/spec/ruby/language/README
index b9d969ba1e..74eaf58709 100644
--- a/spec/ruby/language/README
+++ b/spec/ruby/language/README
@@ -6,7 +6,7 @@ execution like 'if' and 'unless', exceptional execution control like 'rescue',
etc. There are also literals for the basic "types" like String, Regexp, Array
and Fixnum.
-Behavorial specifications describe the behavior of concrete entities. Rather
+Behavioral specifications describe the behavior of concrete entities. Rather
than using concepts of computation to organize these spec files, we use
entities of the Ruby language. Consider looking at any syntactic element of a
Ruby program. With (almost) no ambiguity, one can identify it as a literal,
diff --git a/spec/ruby/language/block_spec.rb b/spec/ruby/language/block_spec.rb
index 219d61e2bf..733e90211c 100644
--- a/spec/ruby/language/block_spec.rb
+++ b/spec/ruby/language/block_spec.rb
@@ -687,7 +687,7 @@ describe "Block-local variables" do
end.should raise_error(SyntaxError)
end
- it "need not be preceeded by standard parameters" do
+ it "need not be preceded by standard parameters" do
[1].map {|; foo| foo }.should == [nil]
[1].map {|; glark, bar| [glark, bar] }.should == [[nil, nil]]
end
diff --git a/spec/ruby/language/break_spec.rb b/spec/ruby/language/break_spec.rb
index 794eed2dd9..da3c3bd272 100644
--- a/spec/ruby/language/break_spec.rb
+++ b/spec/ruby/language/break_spec.rb
@@ -63,15 +63,14 @@ describe "The break statement in a captured block" do
describe "from another thread" do
it "raises a LocalJumpError when getting the value from another thread" do
- ScratchPad << :a
thread_with_break = Thread.new do
- ScratchPad << :b
- break :break
- ScratchPad << :c
+ begin
+ break :break
+ rescue LocalJumpError => e
+ e
+ end
end
-
- lambda { thread_with_break.value }.should raise_error(LocalJumpError)
- ScratchPad.recorded.should == [:a, :b]
+ thread_with_break.value.should be_an_instance_of(LocalJumpError)
end
end
end
diff --git a/spec/ruby/language/case_spec.rb b/spec/ruby/language/case_spec.rb
index cb0e8150bf..25f5d0efc4 100644
--- a/spec/ruby/language/case_spec.rb
+++ b/spec/ruby/language/case_spec.rb
@@ -379,4 +379,11 @@ describe "The 'case'-construct with no target expression" do
:called
end.should == :called
end
+
+ it "accepts complex expressions within ()" do
+ case 'a'
+ when (raise if 2+2 == 3; /a/)
+ :called
+ end.should == :called
+ end
end
diff --git a/spec/ruby/language/class_spec.rb b/spec/ruby/language/class_spec.rb
index 354570e5e9..ba4af3d880 100644
--- a/spec/ruby/language/class_spec.rb
+++ b/spec/ruby/language/class_spec.rb
@@ -88,19 +88,17 @@ describe "A class definition" do
end
# [Bug #12367] [ruby-core:75446]
- ruby_version_is "2.4" do # Until backported
- it "raises an error when reopening a class with Object as superclass" do
- module ClassSpecs
- class SuperclassReopenedObject < A
- end
- SuperclassReopenedObject.superclass.should == A
-
- lambda {
- class SuperclassReopenedObject < Object
- end
- }.should raise_error(TypeError, /superclass mismatch/)
- SuperclassReopenedObject.superclass.should == A
+ it "raises an error when reopening a class with Object as superclass" do
+ module ClassSpecs
+ class SuperclassReopenedObject < A
end
+ SuperclassReopenedObject.superclass.should == A
+
+ lambda {
+ class SuperclassReopenedObject < Object
+ end
+ }.should raise_error(TypeError, /superclass mismatch/)
+ SuperclassReopenedObject.superclass.should == A
end
end
diff --git a/spec/ruby/language/constants_spec.rb b/spec/ruby/language/constants_spec.rb
index e68ba495be..1d3cecd9c6 100644
--- a/spec/ruby/language/constants_spec.rb
+++ b/spec/ruby/language/constants_spec.rb
@@ -353,16 +353,27 @@ describe "Constant resolution within methods" do
end
describe "with ||=" do
- it "assignes constant if previously undefined" do
+ it "assigns a scoped constant if previously undefined" do
ConstantSpecs.should_not have_constant(:OpAssignUndefined)
- # Literally opening the module is required to avoid content
- # re-assignment error
module ConstantSpecs
OpAssignUndefined ||= 42
end
ConstantSpecs::OpAssignUndefined.should == 42
+ ConstantSpecs::OpAssignUndefinedOutside ||= 42
+ ConstantSpecs::OpAssignUndefinedOutside.should == 42
ConstantSpecs.send(:remove_const, :OpAssignUndefined)
+ ConstantSpecs.send(:remove_const, :OpAssignUndefinedOutside)
end
+
+ it "assigns a global constant if previously undefined" do
+ OpAssignGlobalUndefined ||= 42
+ ::OpAssignGlobalUndefinedExplicitScope ||= 42
+ OpAssignGlobalUndefined.should == 42
+ ::OpAssignGlobalUndefinedExplicitScope.should == 42
+ Object.send :remove_const, :OpAssignGlobalUndefined
+ Object.send :remove_const, :OpAssignGlobalUndefinedExplicitScope
+ end
+
end
end
diff --git a/spec/ruby/language/defined_spec.rb b/spec/ruby/language/defined_spec.rb
index 458c74258f..1247658381 100644
--- a/spec/ruby/language/defined_spec.rb
+++ b/spec/ruby/language/defined_spec.rb
@@ -725,7 +725,7 @@ describe "The defined? keyword for a top-level constant" do
defined?(::DefinedSpecs).should == "constant"
end
- it "retuns nil if the constant is not defined" do
+ it "returns nil if the constant is not defined" do
defined?(::DefinedSpecsUndefined).should be_nil
end
diff --git a/spec/ruby/language/ensure_spec.rb b/spec/ruby/language/ensure_spec.rb
index 13575fccc5..ae04feb739 100644
--- a/spec/ruby/language/ensure_spec.rb
+++ b/spec/ruby/language/ensure_spec.rb
@@ -11,7 +11,7 @@ describe "An ensure block inside a begin block" do
lambda {
begin
ScratchPad << :begin
- raise "An exception occured!"
+ raise "An exception occurred!"
ensure
ScratchPad << :ensure
end
@@ -25,7 +25,7 @@ describe "An ensure block inside a begin block" do
begin
begin
ScratchPad << :begin
- raise "An exception occured!"
+ raise "An exception occurred!"
rescue
ScratchPad << :rescue
ensure
diff --git a/spec/ruby/language/fixtures/binary_symbol.rb b/spec/ruby/language/fixtures/binary_symbol.rb
new file mode 100644
index 0000000000..2ddf565820
--- /dev/null
+++ b/spec/ruby/language/fixtures/binary_symbol.rb
@@ -0,0 +1,4 @@
+# encoding: binary
+
+p :il_était.to_s.bytes
+puts :il_était.encoding.name
diff --git a/spec/ruby/language/fixtures/super.rb b/spec/ruby/language/fixtures/super.rb
index 4e89d59bed..09a454bdf4 100644
--- a/spec/ruby/language/fixtures/super.rb
+++ b/spec/ruby/language/fixtures/super.rb
@@ -478,20 +478,129 @@ module Super
end
end
- module KeywordArguments
- class A
+ module Keywords
+ class Arguments
def foo(**args)
args
end
end
- class B < A
- def foo(**)
+ # ----
+
+ class RequiredArguments < Arguments
+ def foo(a:)
super
end
end
- class C < A
+ class OptionalArguments < Arguments
+ def foo(b: 'b')
+ super
+ end
+ end
+
+ class PlaceholderArguments < Arguments
+ def foo(**args)
+ super
+ end
+ end
+
+ # ----
+
+ class RequiredAndOptionalArguments < Arguments
+ def foo(a:, b: 'b')
+ super
+ end
+ end
+
+ class RequiredAndPlaceholderArguments < Arguments
+ def foo(a:, **args)
+ super
+ end
+ end
+
+ class OptionalAndPlaceholderArguments < Arguments
+ def foo(b: 'b', **args)
+ super
+ end
+ end
+
+ # ----
+
+ class RequiredAndOptionalAndPlaceholderArguments < Arguments
+ def foo(a:, b: 'b', **args)
+ super
+ end
+ end
+ end
+
+ module RegularAndKeywords
+ class Arguments
+ def foo(a, **options)
+ [a, options]
+ end
+ end
+
+ # -----
+
+ class RequiredArguments < Arguments
+ def foo(a, b:)
+ super
+ end
+ end
+
+ class OptionalArguments < Arguments
+ def foo(a, c: 'c')
+ super
+ end
+ end
+
+ class PlaceholderArguments < Arguments
+ def foo(a, **options)
+ super
+ end
+ end
+
+ # -----
+
+ class RequiredAndOptionalArguments < Arguments
+ def foo(a, b:, c: 'c')
+ super
+ end
+ end
+
+ class RequiredAndPlaceholderArguments < Arguments
+ def foo(a, b:, **options)
+ super
+ end
+ end
+
+ class OptionalAndPlaceholderArguments < Arguments
+ def foo(a, c: 'c', **options)
+ super
+ end
+ end
+
+ # -----
+
+ class RequiredAndOptionalAndPlaceholderArguments < Arguments
+ def foo(a, b:, c: 'c', **options)
+ super
+ end
+ end
+ end
+
+ module SplatAndKeywords
+ class Arguments
+ def foo(*args, **options)
+ [args, options]
+ end
+ end
+
+ class AllArguments < Arguments
+ def foo(*args, **options)
+ super
+ end
end
end
@@ -552,18 +661,4 @@ module Super
end
end
end
-
- module SplatAndKeyword
- class A
- def foo(*args, **options)
- [args, options]
- end
- end
-
- class B < A
- def foo(*args, **options)
- super
- end
- end
- end
end
diff --git a/spec/ruby/language/if_spec.rb b/spec/ruby/language/if_spec.rb
index bd4fdcae81..284d852462 100644
--- a/spec/ruby/language/if_spec.rb
+++ b/spec/ruby/language/if_spec.rb
@@ -1,6 +1,25 @@
require File.expand_path('../../spec_helper', __FILE__)
describe "The if expression" do
+ ruby_version_is '2.4' do
+ describe "accepts multiple assignments in conditional expression" do
+ before(:each) { ScratchPad.record([]) }
+ after(:each) { ScratchPad.clear }
+
+ it 'with non-nil values' do
+ ary = [1, 2]
+ eval "if (a, b = ary); ScratchPad.record [a, b]; end"
+ ScratchPad.recorded.should == [1, 2]
+ end
+
+ it 'with nil values' do
+ ary = nil
+ eval "if (a, b = ary); else; ScratchPad.record [a, b]; end"
+ ScratchPad.recorded.should == [nil, nil]
+ end
+ end
+ end
+
it "evaluates body if expression is true" do
a = []
if true
diff --git a/spec/ruby/language/method_spec.rb b/spec/ruby/language/method_spec.rb
index c92a8ee51b..ca939dbab6 100644
--- a/spec/ruby/language/method_spec.rb
+++ b/spec/ruby/language/method_spec.rb
@@ -1178,7 +1178,7 @@ describe "A method" do
end
evaluate <<-ruby do
- def m a, b=1, *c, d, e:, f: 2, g:, **k, &l
+ def m(a, b=1, *c, d, e:, f: 2, g:, **k, &l)
[a, b, c, d, e, f, g, k, l]
end
ruby
@@ -1188,13 +1188,19 @@ describe "A method" do
end
evaluate <<-ruby do
- def m (a, b = nil, c = nil, d, e: nil, **f)
+ def m(a, b = nil, c = nil, d, e: nil, **f)
[a, b, c, d, e, f]
end
ruby
result = m(1, 2)
result.should == [1, nil, nil, 2, nil, {}]
+
+ result = m(1, 2, {foo: :bar})
+ result.should == [1, nil, nil, 2, nil, {foo: :bar}]
+
+ result = m(1, {foo: :bar})
+ result.should == [1, nil, nil, {foo: :bar}, nil, {}]
end
end
end
diff --git a/spec/ruby/language/optional_assignments_spec.rb b/spec/ruby/language/optional_assignments_spec.rb
index c104d08253..0ab28985ed 100644
--- a/spec/ruby/language/optional_assignments_spec.rb
+++ b/spec/ruby/language/optional_assignments_spec.rb
@@ -207,7 +207,7 @@ describe 'Optional variable assignments' do
Object::A.should == 10
end
- it 'with &&= assignments will fail with non-existant constants' do
+ it 'with &&= assignments will fail with non-existent constants' do
lambda { Object::A &&= 10 }.should raise_error(NameError)
end
@@ -219,7 +219,7 @@ describe 'Optional variable assignments' do
Object::A.should == 30
end
- it 'with operator assignments will fail with non-existant constants' do
+ it 'with operator assignments will fail with non-existent constants' do
lambda { Object::A += 10 }.should raise_error(NameError)
end
end
diff --git a/spec/ruby/language/predefined_spec.rb b/spec/ruby/language/predefined_spec.rb
index a0930eb214..f827fb2eb5 100644
--- a/spec/ruby/language/predefined_spec.rb
+++ b/spec/ruby/language/predefined_spec.rb
@@ -879,6 +879,25 @@ describe "Global variable $-d" do
end
end
+describe "Global variable $VERBOSE" do
+ it "converts truthy values to true" do
+ [true, 1, 0, [], ""].each do |true_value|
+ $VERBOSE = true_value
+ $VERBOSE.should be_true
+ end
+ end
+
+ it "allows false" do
+ $VERBOSE = false
+ $VERBOSE.should be_false
+ end
+
+ it "allows nil without coercing to false" do
+ $VERBOSE = nil
+ $VERBOSE.should be_nil
+ end
+end
+
describe :verbose_global_alias, shared: true do
before :each do
@verbose = $VERBOSE
diff --git a/spec/ruby/language/regexp/character_classes_spec.rb b/spec/ruby/language/regexp/character_classes_spec.rb
index 74568a0beb..ce66d8e65f 100644
--- a/spec/ruby/language/regexp/character_classes_spec.rb
+++ b/spec/ruby/language/regexp/character_classes_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../../fixtures/classes', __FILE__)
@@ -607,4 +608,26 @@ describe "Regexp with character classes" do
it "matches unicode Hangul properties" do
"루비(Ruby)".match(/\p{Hangul}+/u).to_a.should == ["루비"]
end
+
+ ruby_version_is "2.4" do
+ it "supports \\X (unicode 9.0 with UTR #51 workarounds)" do
+ # simple emoji without any fancy modifier or ZWJ
+ /\X/.match("\u{1F98A}").to_a.should == ["🦊"]
+
+ # skin tone modifier
+ /\X/.match("\u{1F918}\u{1F3FD}").to_a.should == ["🤘🏽"]
+
+ # emoji joined with ZWJ
+ /\X/.match("\u{1F3F3}\u{FE0F}\u{200D}\u{1F308}").to_a.should == ["🏳️‍🌈"]
+ /\X/.match("\u{1F469}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}").to_a.should == ["👩‍👩‍👧‍👦"]
+
+ # without the ZWJ
+ /\X+/.match("\u{1F3F3}\u{FE0F}\u{1F308}").to_a.should == ["🏳️🌈"]
+ /\X+/.match("\u{1F469}\u{1F469}\u{1F467}\u{1F466}").to_a.should == ["👩👩👧👦"]
+
+ # both of the ZWJ combined
+ /\X+/.match("\u{1F3F3}\u{FE0F}\u{200D}\u{1F308}\u{1F469}\u{200D}\u{1F469}\u{200D}\u{1F467}\u{200D}\u{1F466}")
+ .to_a.should == ["🏳️‍🌈👩‍👩‍👧‍👦"]
+ end
+ end
end
diff --git a/spec/ruby/language/regexp/modifiers_spec.rb b/spec/ruby/language/regexp/modifiers_spec.rb
index 03dec26f3f..a7052a941c 100644
--- a/spec/ruby/language/regexp/modifiers_spec.rb
+++ b/spec/ruby/language/regexp/modifiers_spec.rb
@@ -39,6 +39,13 @@ describe "Regexps with modifers" do
lambda { eval('/foo/a') }.should raise_error(SyntaxError)
end
+ ruby_version_is "2.4" do
+ it "supports (?~) (absent operator)" do
+ Regexp.new("(?~foo)").match("hello").to_a.should == ["hello"]
+ "foo".scan(Regexp.new("(?~foo)")).should == ["fo","o",""]
+ end
+ end
+
it "supports (?imx-imx) (inline modifiers)" do
/(?i)foo/.match("FOO").to_a.should == ["FOO"]
/foo(?i)/.match("FOO").should be_nil
diff --git a/spec/ruby/language/rescue_spec.rb b/spec/ruby/language/rescue_spec.rb
index 66366cd1a0..281bb8fde8 100644
--- a/spec/ruby/language/rescue_spec.rb
+++ b/spec/ruby/language/rescue_spec.rb
@@ -290,4 +290,11 @@ describe "The rescue keyword" do
:expected
end.should == :expected
end
+
+ ruby_version_is "2.4" do
+ it "allows 'rescue' in method arguments" do
+ two = eval '1.+ (raise("Error") rescue 1)'
+ two.should == 2
+ end
+ end
end
diff --git a/spec/ruby/language/return_spec.rb b/spec/ruby/language/return_spec.rb
index 323f74aad3..6a98fa6d12 100644
--- a/spec/ruby/language/return_spec.rb
+++ b/spec/ruby/language/return_spec.rb
@@ -24,7 +24,14 @@ describe "The return keyword" do
describe "in a Thread" do
it "raises a LocalJumpError if used to exit a thread" do
- lambda { Thread.new { return }.join }.should raise_error(LocalJumpError)
+ t = Thread.new {
+ begin
+ return
+ rescue LocalJumpError => e
+ e
+ end
+ }
+ t.value.should be_an_instance_of(LocalJumpError)
end
end
@@ -242,4 +249,218 @@ describe "The return keyword" do
ReturnSpecs::MethodWithBlock.new.method2.should == [0, 1, 2]
end
end
+
+ ruby_version_is '2.4.2' do
+ describe "at top level" do
+ before :each do
+ @filename = tmp("top_return.rb")
+ ScratchPad.record []
+ end
+
+ after do
+ rm_r @filename
+ end
+
+ it "stops file execution" do
+ ruby_exe(<<-END_OF_CODE).should == "before return\n"
+ puts "before return"
+ return
+
+ puts "after return"
+ END_OF_CODE
+
+ $?.exitstatus.should == 0
+ end
+
+ describe "within if" do
+ it "is allowed" do
+ File.write(@filename, <<-END_OF_CODE)
+ ScratchPad << "before if"
+ if true
+ return
+ end
+
+ ScratchPad << "after if"
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before if"]
+ end
+ end
+
+ describe "within while loop" do
+ it "is allowed" do
+ File.write(@filename, <<-END_OF_CODE)
+ ScratchPad << "before while"
+ while true
+ return
+ end
+
+ ScratchPad << "after while"
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before while"]
+ end
+ end
+
+ describe "within a begin" do
+ it "is allowed in begin block" do
+ File.write(@filename, <<-END_OF_CODE)
+ ScratchPad << "before begin"
+ begin
+ return
+ end
+
+ ScratchPad << "after begin"
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before begin"]
+ end
+
+ it "is allowed in ensure block" do
+ File.write(@filename, <<-END_OF_CODE)
+ ScratchPad << "before begin"
+ begin
+ ensure
+ return
+ end
+
+ ScratchPad << "after begin"
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before begin"]
+ end
+
+ it "is allowed in rescue block" do
+ File.write(@filename, <<-END_OF_CODE)
+ ScratchPad << "before begin"
+ begin
+ raise
+ rescue RuntimeError
+ return
+ end
+
+ ScratchPad << "after begin"
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before begin"]
+ end
+
+ it "fires ensure block before returning" do
+ ruby_exe(<<-END_OF_CODE).should == "within ensure\n"
+ begin
+ return
+ ensure
+ puts "within ensure"
+ end
+
+ puts "after begin"
+ END_OF_CODE
+ end
+
+ ruby_bug "#14061", "2.4"..."2.6" do
+ it "fires ensure block before returning while loads file" do
+ File.write(@filename, <<-END_OF_CODE)
+ ScratchPad << "before begin"
+ begin
+ return
+ ensure
+ ScratchPad << "within ensure"
+ end
+
+ ScratchPad << "after begin"
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before begin", "within ensure"]
+ end
+ end
+
+ it "swallows exception if returns in ensure block" do
+ File.write(@filename, <<-END_OF_CODE)
+ begin
+ raise
+ ensure
+ ScratchPad << "before return"
+ return
+ end
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before return"]
+ end
+ end
+
+ describe "within a block" do
+ it "is allowed" do
+ File.write(@filename, <<-END_OF_CODE)
+ ScratchPad << "before call"
+ proc { return }.call
+
+ ScratchPad << "after call"
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before call"]
+ end
+ end
+
+ describe "within a class" do
+ it "is allowed" do
+ File.write(@filename, <<-END_OF_CODE)
+ class A
+ ScratchPad << "before return"
+ return
+
+ ScratchPad << "after return"
+ end
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before return"]
+ end
+ end
+
+ describe "file loading" do
+ it "stops file loading and execution" do
+ File.write(@filename, <<-END_OF_CODE)
+ ScratchPad << "before return"
+ return
+ ScratchPad << "after return"
+ END_OF_CODE
+
+ load @filename
+ ScratchPad.recorded.should == ["before return"]
+ end
+ end
+
+ describe "file requiring" do
+ it "stops file loading and execution" do
+ File.write(@filename, <<-END_OF_CODE)
+ ScratchPad << "before return"
+ return
+ ScratchPad << "after return"
+ END_OF_CODE
+
+ require @filename
+ ScratchPad.recorded.should == ["before return"]
+ end
+ end
+
+ describe "return with argument" do
+ # https://bugs.ruby-lang.org/issues/14062
+ it "does not affect exit status" do
+ ruby_exe(<<-END_OF_CODE).should == ""
+ return 10
+ END_OF_CODE
+
+ $?.exitstatus.should == 0
+ end
+ end
+ end
+ end
end
diff --git a/spec/ruby/language/super_spec.rb b/spec/ruby/language/super_spec.rb
index fb7e089fb4..3d3f5d6f74 100644
--- a/spec/ruby/language/super_spec.rb
+++ b/spec/ruby/language/super_spec.rb
@@ -9,7 +9,7 @@ describe "The super keyword" do
Super::S1::B.new.bar([]).should == ["B#bar","A#bar"]
end
- it "searches the full inheritence chain" do
+ it "searches the full inheritance chain" do
Super::S2::B.new.foo([]).should == ["B#foo","A#baz"]
Super::S2::B.new.baz([]).should == ["A#baz"]
Super::S2::C.new.foo([]).should == ["B#foo","C#baz","A#baz"]
@@ -32,7 +32,7 @@ describe "The super keyword" do
Super::MS1::B.new.bar([]).should == ["ModB#bar","ModA#bar"]
end
- it "searches the full inheritence chain including modules" do
+ it "searches the full inheritance chain including modules" do
Super::MS2::B.new.foo([]).should == ["ModB#foo","A#baz"]
Super::MS2::B.new.baz([]).should == ["A#baz"]
Super::MS2::C.new.baz([]).should == ["C#baz","A#baz"]
@@ -248,35 +248,112 @@ describe "The super keyword" do
end
describe 'when using keyword arguments' do
- it 'passes any given keyword arguments to the parent' do
- b = Super::KeywordArguments::B.new
- b.foo(:number => 10).should == {:number => 10}
+ before :each do
+ @req = Super::Keywords::RequiredArguments.new
+ @opts = Super::Keywords::OptionalArguments.new
+ @etc = Super::Keywords::PlaceholderArguments.new
+
+ @req_and_opts = Super::Keywords::RequiredAndOptionalArguments.new
+ @req_and_etc = Super::Keywords::RequiredAndPlaceholderArguments.new
+ @opts_and_etc = Super::Keywords::OptionalAndPlaceholderArguments.new
+
+ @req_and_opts_and_etc = Super::Keywords::RequiredAndOptionalAndPlaceholderArguments.new
end
- it "passes any given keyword arguments including optional and required ones to the parent" do
- class Super::KeywordArguments::C
- eval <<-RUBY
- def foo(a:, b: 'b', **)
- super
- end
- RUBY
+ it 'does not pass any arguments to the parent when none are given' do
+ @etc.foo.should == {}
+ end
+
+ it 'passes only required arguments to the parent when no optional arguments are given' do
+ [@req, @req_and_etc].each do |obj|
+ obj.foo(a: 'a').should == {a: 'a'}
+ end
+ end
+
+ it 'passes default argument values to the parent' do
+ [@opts, @opts_and_etc].each do |obj|
+ obj.foo.should == {b: 'b'}
+ end
+
+ [@req_and_opts, @opts_and_etc, @req_and_opts_and_etc].each do |obj|
+ obj.foo(a: 'a').should == {a: 'a', b: 'b'}
+ end
+ end
+
+ it 'passes any given arguments including optional keyword arguments to the parent' do
+ [@etc, @req_and_opts, @req_and_etc, @opts_and_etc, @req_and_opts_and_etc].each do |obj|
+ obj.foo(a: 'a', b: 'b').should == {a: 'a', b: 'b'}
end
- c = Super::KeywordArguments::C.new
- c.foo(a: 'a', c: 'c').should == {a: 'a', b: 'b', c: 'c'}
+ [@etc, @req_and_etc, @opts_and_etc, @req_and_opts_and_etc].each do |obj|
+ obj.foo(a: 'a', b: 'b', c: 'c').should == {a: 'a', b: 'b', c: 'c'}
+ end
end
+ end
- it 'does not pass any keyword arguments to the parent when none are given' do
- b = Super::KeywordArguments::B.new
- b.foo.should == {}
+ describe 'when using regular and keyword arguments' do
+ before :each do
+ @req = Super::RegularAndKeywords::RequiredArguments.new
+ @opts = Super::RegularAndKeywords::OptionalArguments.new
+ @etc = Super::RegularAndKeywords::PlaceholderArguments.new
+
+ @req_and_opts = Super::RegularAndKeywords::RequiredAndOptionalArguments.new
+ @req_and_etc = Super::RegularAndKeywords::RequiredAndPlaceholderArguments.new
+ @opts_and_etc = Super::RegularAndKeywords::OptionalAndPlaceholderArguments.new
+
+ @req_and_opts_and_etc = Super::RegularAndKeywords::RequiredAndOptionalAndPlaceholderArguments.new
end
- describe 'when using splat arguments' do
- it 'passes splat arguments and keyword arguments to the parent' do
- b = Super::SplatAndKeyword::B.new
+ it 'passes only required regular arguments to the parent when no optional keyword arguments are given' do
+ @etc.foo('a').should == ['a', {}]
+ end
- b.foo('bar', baz: true).should == [['bar'], {baz: true}]
+ it 'passes only required regular and keyword arguments to the parent when no optional keyword arguments are given' do
+ [@req, @req_and_etc].each do |obj|
+ obj.foo('a', b: 'b').should == ['a', {b: 'b'}]
end
end
+
+ it 'passes default argument values to the parent' do
+ [@opts, @opts_and_etc].each do |obj|
+ obj.foo('a').should == ['a', {c: 'c'}]
+ end
+
+ [@req_and_opts, @opts_and_etc, @req_and_opts_and_etc].each do |obj|
+ obj.foo('a', b: 'b').should == ['a', {b: 'b', c: 'c'}]
+ end
+ end
+
+ it 'passes any given regular and keyword arguments including optional keyword arguments to the parent' do
+ [@etc, @req_and_opts, @req_and_etc, @opts_and_etc, @req_and_opts_and_etc].each do |obj|
+ obj.foo('a', b: 'b', c: 'c').should == ['a', {b: 'b', c: 'c'}]
+ end
+
+ [@etc, @req_and_etc, @opts_and_etc, @req_and_opts_and_etc].each do |obj|
+ obj.foo('a', b: 'b', c: 'c', d: 'd').should == ['a', {b: 'b', c: 'c', d: 'd'}]
+ end
+ end
+ end
+
+ describe 'when using splat and keyword arguments' do
+ before :each do
+ @all = Super::SplatAndKeywords::AllArguments.new
+ end
+
+ it 'does not pass any arguments to the parent when none are given' do
+ @all.foo.should == [[], {}]
+ end
+
+ it 'passes only splat arguments to the parent when no keyword arguments are given' do
+ @all.foo('a').should == [['a'], {}]
+ end
+
+ it 'passes only keyword arguments to the parent when no splat arguments are given' do
+ @all.foo(b: 'b').should == [[], {b: 'b'}]
+ end
+
+ it 'passes any given splat and keyword arguments to the parent' do
+ @all.foo('a', b: 'b').should == [['a'], {b: 'b'}]
+ end
end
end
diff --git a/spec/ruby/language/symbol_spec.rb b/spec/ruby/language/symbol_spec.rb
index 41be5b2236..90540f7d1d 100644
--- a/spec/ruby/language/symbol_spec.rb
+++ b/spec/ruby/language/symbol_spec.rb
@@ -36,6 +36,11 @@ describe "A Symbol literal" do
}
end
+ it 'inherits the encoding of the magic comment and can have a binary encoding' do
+ ruby_exe(fixture(__FILE__, "binary_symbol.rb"))
+ .should == "[105, 108, 95, 195, 169, 116, 97, 105, 116]\nASCII-8BIT\n"
+ end
+
it "may contain '::' in the string" do
:'Some::Class'.should be_kind_of(Symbol)
end
@@ -90,4 +95,12 @@ describe "A Symbol literal" do
it "can be created from list syntax %I{a b c} with interpolation" do
%I{a b #{"c"}}.should == [:a, :b, :c]
end
+
+ it "with invalid bytes raises an EncodingError at parse time" do
+ ScratchPad.record []
+ -> {
+ eval 'ScratchPad << 1; :"\xC3"'
+ }.should raise_error(EncodingError, /invalid/)
+ ScratchPad.recorded.should == []
+ end
end
diff --git a/spec/ruby/language/throw_spec.rb b/spec/ruby/language/throw_spec.rb
index d78c137708..92f699350c 100644
--- a/spec/ruby/language/throw_spec.rb
+++ b/spec/ruby/language/throw_spec.rb
@@ -68,13 +68,14 @@ describe "The throw keyword" do
lambda { catch(:different) { throw :test, 5 } }.should raise_error(ArgumentError)
end
- it "raises an ArgumentError if used to exit a thread" do
- lambda {
- catch(:what) do
- Thread.new {
+ it "raises an UncaughtThrowError if used to exit a thread" do
+ catch(:what) do
+ t = Thread.new {
+ -> {
throw :what
- }.join
- end
- }.should raise_error(ArgumentError)
+ }.should raise_error(UncaughtThrowError)
+ }
+ t.join
+ end
end
end