diff options
Diffstat (limited to 'spec/ruby/language')
-rw-r--r-- | spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb | 1 | ||||
-rw-r--r-- | spec/ruby/language/fixtures/variables.rb | 72 | ||||
-rw-r--r-- | spec/ruby/language/pattern_matching_spec.rb | 16 | ||||
-rw-r--r-- | spec/ruby/language/predefined_spec.rb | 4 | ||||
-rw-r--r-- | spec/ruby/language/proc_spec.rb | 12 | ||||
-rw-r--r-- | spec/ruby/language/singleton_class_spec.rb | 17 | ||||
-rw-r--r-- | spec/ruby/language/variables_spec.rb | 80 |
7 files changed, 199 insertions, 3 deletions
diff --git a/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb b/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb index 7a1f872e05..f72a32e879 100644 --- a/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb +++ b/spec/ruby/language/fixtures/freeze_magic_comment_required_diff_enc.rb @@ -2,4 +2,3 @@ # frozen_string_literal: true $second_literal_id = "abc".object_id - diff --git a/spec/ruby/language/fixtures/variables.rb b/spec/ruby/language/fixtures/variables.rb index 07265dbb2b..527caa7a78 100644 --- a/spec/ruby/language/fixtures/variables.rb +++ b/spec/ruby/language/fixtures/variables.rb @@ -82,4 +82,76 @@ module VariablesSpecs def self.false false end + + class EvalOrder + attr_reader :order + + def initialize + @order = [] + end + + def reset + @order = [] + end + + def foo + self << "foo" + FooClass.new(self) + end + + def bar + self << "bar" + BarClass.new(self) + end + + def a + self << "a" + end + + def b + self << "b" + end + + def node + self << "node" + + node = Node.new + node.left = Node.new + node.left.right = Node.new + + node + end + + def <<(value) + order << value + end + + class FooClass + attr_reader :evaluator + + def initialize(evaluator) + @evaluator = evaluator + end + + def []=(_index, _value) + evaluator << "foo[]=" + end + end + + class BarClass + attr_reader :evaluator + + def initialize(evaluator) + @evaluator = evaluator + end + + def baz=(_value) + evaluator << "bar.baz=" + end + end + + class Node + attr_accessor :left, :right + end + end end diff --git a/spec/ruby/language/pattern_matching_spec.rb b/spec/ruby/language/pattern_matching_spec.rb index f3cc86fa0b..e4b7a5105e 100644 --- a/spec/ruby/language/pattern_matching_spec.rb +++ b/spec/ruby/language/pattern_matching_spec.rb @@ -205,7 +205,7 @@ describe "Pattern matching" do in [] end RUBY - }.should raise_error(SyntaxError, /syntax error, unexpected `in'/) + }.should raise_error(SyntaxError, /syntax error, unexpected `in'|\(eval\):3: syntax error, unexpected keyword_in/) -> { eval <<~RUBY @@ -214,7 +214,7 @@ describe "Pattern matching" do when 1 == 1 end RUBY - }.should raise_error(SyntaxError, /syntax error, unexpected `when'/) + }.should raise_error(SyntaxError, /syntax error, unexpected `when'|\(eval\):3: syntax error, unexpected keyword_when/) end it "checks patterns until the first matching" do @@ -251,6 +251,18 @@ describe "Pattern matching" do }.should raise_error(NoMatchingPatternError, /\[0, 1\]/) end + it "raises NoMatchingPatternError if no pattern matches and evaluates the expression only once" do + evals = 0 + -> { + eval <<~RUBY + case (evals += 1; [0, 1]) + in [0] + end + RUBY + }.should raise_error(NoMatchingPatternError, /\[0, 1\]/) + evals.should == 1 + end + it "does not allow calculation or method calls in a pattern" do -> { eval <<~RUBY diff --git a/spec/ruby/language/predefined_spec.rb b/spec/ruby/language/predefined_spec.rb index d1cda25918..f6cec5fa75 100644 --- a/spec/ruby/language/predefined_spec.rb +++ b/spec/ruby/language/predefined_spec.rb @@ -979,6 +979,10 @@ describe "Global variable $VERBOSE" do $VERBOSE = @verbose end + it "is false by default" do + $VERBOSE.should be_false + end + it "converts truthy values to true" do [true, 1, 0, [], ""].each do |true_value| $VERBOSE = true_value diff --git a/spec/ruby/language/proc_spec.rb b/spec/ruby/language/proc_spec.rb index f8a29962b0..c5876fb2ed 100644 --- a/spec/ruby/language/proc_spec.rb +++ b/spec/ruby/language/proc_spec.rb @@ -161,6 +161,18 @@ describe "A Proc" do end end + describe "taking |*a, b| arguments" do + it "assigns [] to the argument when passed no values" do + proc { |*a, b| [a, b] }.call.should == [[], nil] + end + end + + describe "taking |a, *b, c| arguments" do + it "assigns [] to the argument when passed no values" do + proc { |a, *b, c| [a, b, c] }.call.should == [nil, [], nil] + end + end + describe "taking |a, | arguments" do before :each do @l = lambda { |a, | a } diff --git a/spec/ruby/language/singleton_class_spec.rb b/spec/ruby/language/singleton_class_spec.rb index c1fb682ea0..7512f0eb39 100644 --- a/spec/ruby/language/singleton_class_spec.rb +++ b/spec/ruby/language/singleton_class_spec.rb @@ -291,3 +291,20 @@ describe "Instantiating a singleton class" do }.should raise_error(TypeError) end end + +describe "Frozen properties" do + it "is frozen if the object it is created from is frozen" do + o = Object.new + o.freeze + klass = o.singleton_class + klass.frozen?.should == true + end + + it "will be frozen if the object it is created from becomes frozen" do + o = Object.new + klass = o.singleton_class + klass.frozen?.should == false + o.freeze + klass.frozen?.should == true + end +end diff --git a/spec/ruby/language/variables_spec.rb b/spec/ruby/language/variables_spec.rb index c900c03d37..cd862727ac 100644 --- a/spec/ruby/language/variables_spec.rb +++ b/spec/ruby/language/variables_spec.rb @@ -1,6 +1,86 @@ require_relative '../spec_helper' require_relative 'fixtures/variables' +describe "Evaluation order during assignment" do + context "with single assignment" do + it "evaluates from left to right" do + obj = VariablesSpecs::EvalOrder.new + obj.instance_eval do + foo[0] = a + end + + obj.order.should == ["foo", "a", "foo[]="] + end + end + + context "with multiple assignment" do + ruby_version_is ""..."3.1" do + it "does not evaluate from left to right" do + obj = VariablesSpecs::EvalOrder.new + + obj.instance_eval do + foo[0], bar.baz = a, b + end + + obj.order.should == ["a", "b", "foo", "foo[]=", "bar", "bar.baz="] + end + + it "cannot be used to swap variables with nested method calls" do + node = VariablesSpecs::EvalOrder.new.node + + original_node = node + original_node_left = node.left + original_node_left_right = node.left.right + + node.left, node.left.right, node = node.left.right, node, node.left + # Should evaluate in the order of: + # RHS: node.left.right, node, node.left + # LHS: + # * node(original_node), original_node.left = original_node_left_right + # * node(original_node), node.left(changed in the previous assignment to original_node_left_right), + # original_node_left_right.right = original_node + # * node = original_node_left + + node.should == original_node_left + node.right.should_not == original_node + node.right.left.should_not == original_node_left_right + end + end + + ruby_version_is "3.1" do + it "evaluates from left to right, receivers first then methods" do + obj = VariablesSpecs::EvalOrder.new + obj.instance_eval do + foo[0], bar.baz = a, b + end + + obj.order.should == ["foo", "bar", "a", "b", "foo[]=", "bar.baz="] + end + + it "can be used to swap variables with nested method calls" do + node = VariablesSpecs::EvalOrder.new.node + + original_node = node + original_node_left = node.left + original_node_left_right = node.left.right + + node.left, node.left.right, node = node.left.right, node, node.left + # Should evaluate in the order of: + # LHS: node, node.left(original_node_left) + # RHS: original_node_left_right, original_node, original_node_left + # Ops: + # * node(original_node), original_node.left = original_node_left_right + # * original_node_left.right = original_node + # * node = original_node_left + + node.should == original_node_left + node.right.should == original_node + node.right.left.should == original_node_left_right + end + end + end +end + describe "Multiple assignment" do context "with a single RHS value" do it "assigns a simple MLHS" do |