summaryrefslogtreecommitdiff
path: root/spec/ruby/language/case_spec.rb
diff options
context:
space:
mode:
authoreregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-20 20:18:52 +0000
committereregon <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-09-20 20:18:52 +0000
commit1d15d5f08032acf1b7bceacbb450d617ff6e0931 (patch)
treea3785a79899302bc149e4a6e72f624ac27dc1f10 /spec/ruby/language/case_spec.rb
parent75bfc6440d595bf339007f4fb280fd4d743e89c1 (diff)
Move spec/rubyspec to spec/ruby for consistency
* Other ruby implementations use the spec/ruby directory. [Misc #13792] [ruby-core:82287] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/ruby/language/case_spec.rb')
-rw-r--r--spec/ruby/language/case_spec.rb382
1 files changed, 382 insertions, 0 deletions
diff --git a/spec/ruby/language/case_spec.rb b/spec/ruby/language/case_spec.rb
new file mode 100644
index 0000000000..cb0e8150bf
--- /dev/null
+++ b/spec/ruby/language/case_spec.rb
@@ -0,0 +1,382 @@
+require File.expand_path('../../spec_helper', __FILE__)
+
+describe "The 'case'-construct" do
+ it "evaluates the body of the when clause matching the case target expression" do
+ case 1
+ when 2; false
+ when 1; true
+ end.should == true
+ end
+
+ it "evaluates the body of the when clause whose array expression includes the case target expression" do
+ case 2
+ when 3, 4; false
+ when 1, 2; true
+ end.should == true
+ end
+
+ it "evaluates the body of the when clause in left-to-right order if it's an array expression" do
+ @calls = []
+ def foo; @calls << :foo; end
+ def bar; @calls << :bar; end
+
+ case true
+ when foo, bar;
+ end
+
+ @calls.should == [:foo, :bar]
+ end
+
+ it "evaluates the body of the when clause whose range expression includes the case target expression" do
+ case 5
+ when 21..30; false
+ when 1..20; true
+ end.should == true
+ end
+
+ it "returns nil when no 'then'-bodies are given" do
+ case "a"
+ when "a"
+ when "b"
+ end.should == nil
+ end
+
+ it "evaluates the 'else'-body when no other expression matches" do
+ case "c"
+ when "a"; 'foo'
+ when "b"; 'bar'
+ else 'zzz'
+ end.should == 'zzz'
+ end
+
+ it "returns nil when no expression matches and 'else'-body is empty" do
+ case "c"
+ when "a"; "a"
+ when "b"; "b"
+ else
+ end.should == nil
+ end
+
+ it "returns 2 when a then body is empty" do
+ case Object.new
+ when Numeric then
+ 1
+ when String then
+ # ok
+ else
+ 2
+ end.should == 2
+ end
+
+ it "returns the statement following 'then'" do
+ case "a"
+ when "a" then 'foo'
+ when "b" then 'bar'
+ end.should == 'foo'
+ end
+
+ it "tests classes with case equality" do
+ case "a"
+ when String
+ 'foo'
+ when Symbol
+ 'bar'
+ end.should == 'foo'
+ end
+
+ it "tests with matching regexps" do
+ case "hello"
+ when /abc/; false
+ when /^hell/; true
+ end.should == true
+ end
+
+ it "does not test with equality when given classes" do
+ case :symbol.class
+ when Symbol
+ "bar"
+ when String
+ "bar"
+ else
+ "foo"
+ end.should == "foo"
+ end
+
+ it "takes lists of values" do
+ case 'z'
+ when 'a', 'b', 'c', 'd'
+ "foo"
+ when 'x', 'y', 'z'
+ "bar"
+ end.should == "bar"
+
+ case 'b'
+ when 'a', 'b', 'c', 'd'
+ "foo"
+ when 'x', 'y', 'z'
+ "bar"
+ end.should == "foo"
+ end
+
+ it "expands arrays to lists of values" do
+ case 'z'
+ when *['a', 'b', 'c', 'd']
+ "foo"
+ when *['x', 'y', 'z']
+ "bar"
+ end.should == "bar"
+ end
+
+ it "takes an expanded array in addition to a list of values" do
+ case 'f'
+ when 'f', *['a', 'b', 'c', 'd']
+ "foo"
+ when *['x', 'y', 'z']
+ "bar"
+ end.should == "foo"
+
+ case 'b'
+ when 'f', *['a', 'b', 'c', 'd']
+ "foo"
+ when *['x', 'y', 'z']
+ "bar"
+ end.should == "foo"
+ end
+
+ it "takes an expanded array before additional listed values" do
+ case 'f'
+ when *['a', 'b', 'c', 'd'], 'f'
+ "foo"
+ when *['x', 'y', 'z']
+ "bar"
+ end.should == 'foo'
+ end
+
+ it "expands arrays from variables before additional listed values" do
+ a = ['a', 'b', 'c']
+ case 'a'
+ when *a, 'd', 'e'
+ "foo"
+ when 'x'
+ "bar"
+ end.should == "foo"
+ end
+
+ it "expands arrays from variables before a single additional listed value" do
+ a = ['a', 'b', 'c']
+ case 'a'
+ when *a, 'd'
+ "foo"
+ when 'x'
+ "bar"
+ end.should == "foo"
+ end
+
+ it "expands multiple arrays from variables before additional listed values" do
+ a = ['a', 'b', 'c']
+ b = ['d', 'e', 'f']
+
+ case 'f'
+ when *a, *b, 'g', 'h'
+ "foo"
+ when 'x'
+ "bar"
+ end.should == "foo"
+ end
+
+ # MR: critical
+ it "concats arrays before expanding them" do
+ a = ['a', 'b', 'c', 'd']
+ b = ['f']
+
+ case 'f'
+ when 'f', *a|b
+ "foo"
+ when *['x', 'y', 'z']
+ "bar"
+ end.should == "foo"
+ end
+
+ it "never matches when clauses with no values" do
+ case nil
+ when *[]
+ "foo"
+ end.should == nil
+ end
+
+ it "lets you define a method after the case statement" do
+ case (def foo; 'foo'; end; 'f')
+ when 'a'
+ 'foo'
+ when 'f'
+ 'bar'
+ end.should == 'bar'
+ end
+
+ it "raises a SyntaxError when 'else' is used when no 'when' is given" do
+ lambda {
+ eval <<-CODE
+ case 4
+ else
+ true
+ end
+ CODE
+ }.should raise_error(SyntaxError)
+ end
+
+ it "raises a SyntaxError when 'else' is used before a 'when' was given" do
+ lambda {
+ eval <<-CODE
+ case 4
+ else
+ true
+ when 4; false
+ end
+ CODE
+ }.should raise_error(SyntaxError)
+ end
+
+ it "supports nested case statements" do
+ result = false
+ case :x
+ when Symbol
+ case :y
+ when Symbol
+ result = true
+ end
+ end
+ result.should == true
+ end
+
+ it "supports nested case statements followed by a when with a splatted array" do
+ result = false
+ case :x
+ when Symbol
+ case :y
+ when Symbol
+ result = true
+ end
+ when *[Symbol]
+ result = false
+ end
+ result.should == true
+ end
+
+ it "supports nested case statements followed by a when with a splatted non-array" do
+ result = false
+ case :x
+ when Symbol
+ case :y
+ when Symbol
+ result = true
+ end
+ when *Symbol
+ result = false
+ end
+ result.should == true
+ end
+
+ it "works even if there's only one when statement" do
+ case 1
+ when 1
+ 100
+ end.should == 100
+ end
+end
+
+describe "The 'case'-construct with no target expression" do
+ it "evaluates the body of the first clause when at least one of its condition expressions is true" do
+ case
+ when true, false; 'foo'
+ end.should == 'foo'
+ end
+
+ it "evaluates the body of the first when clause that is not false/nil" do
+ case
+ when false; 'foo'
+ when 2; 'bar'
+ when 1 == 1; 'baz'
+ end.should == 'bar'
+
+ case
+ when false; 'foo'
+ when nil; 'foo'
+ when 1 == 1; 'bar'
+ end.should == 'bar'
+ end
+
+ it "evaluates the body of the else clause if all when clauses are false/nil" do
+ case
+ when false; 'foo'
+ when nil; 'foo'
+ when 1 == 2; 'bar'
+ else 'baz'
+ end.should == 'baz'
+ end
+
+ it "evaluates multiple conditional expressions as a boolean disjunction" do
+ case
+ when true, false; 'foo'
+ else 'bar'
+ end.should == 'foo'
+
+ case
+ when false, true; 'foo'
+ else 'bar'
+ end.should == 'foo'
+ end
+
+ it "evaluates true as only 'true' when true is the first clause" do
+ case 1
+ when true; "bad"
+ when Integer; "good"
+ end.should == "good"
+ end
+
+ it "evaluates false as only 'false' when false is the first clause" do
+ case nil
+ when false; "bad"
+ when nil; "good"
+ end.should == "good"
+ end
+
+ it "treats a literal array as its own when argument, rather than a list of arguments" do
+ case 'foo'
+ when ['foo', 'foo']; 'bad'
+ when 'foo'; 'good'
+ end.should == 'good'
+ end
+
+ it "takes multiple expanded arrays" do
+ a1 = ['f', 'o', 'o']
+ a2 = ['b', 'a', 'r']
+
+ case 'f'
+ when *a1, *['x', 'y', 'z']
+ "foo"
+ when *a2, *['x', 'y', 'z']
+ "bar"
+ end.should == "foo"
+
+ case 'b'
+ when *a1, *['x', 'y', 'z']
+ "foo"
+ when *a2, *['x', 'y', 'z']
+ "bar"
+ end.should == "bar"
+ end
+
+ it "calls === even when private" do
+ klass = Class.new do
+ def ===(o)
+ true
+ end
+ private :===
+ end
+
+ case 1
+ when klass.new
+ :called
+ end.should == :called
+ end
+end