diff options
Diffstat (limited to 'spec/ruby/core/binding')
| -rw-r--r-- | spec/ruby/core/binding/clone_spec.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/core/binding/dup_spec.rb | 23 | ||||
| -rw-r--r-- | spec/ruby/core/binding/eval_spec.rb | 74 | ||||
| -rw-r--r-- | spec/ruby/core/binding/fixtures/classes.rb | 26 | ||||
| -rw-r--r-- | spec/ruby/core/binding/fixtures/location.rb | 6 | ||||
| -rw-r--r-- | spec/ruby/core/binding/local_variable_defined_spec.rb | 2 | ||||
| -rw-r--r-- | spec/ruby/core/binding/local_variable_get_spec.rb | 16 | ||||
| -rw-r--r-- | spec/ruby/core/binding/local_variable_set_spec.rb | 8 | ||||
| -rw-r--r-- | spec/ruby/core/binding/local_variables_spec.rb | 2 | ||||
| -rw-r--r-- | spec/ruby/core/binding/location_spec.rb | 46 | ||||
| -rw-r--r-- | spec/ruby/core/binding/shared/clone.rb | 22 | ||||
| -rw-r--r-- | spec/ruby/core/binding/source_location_spec.rb | 14 |
12 files changed, 182 insertions, 63 deletions
diff --git a/spec/ruby/core/binding/clone_spec.rb b/spec/ruby/core/binding/clone_spec.rb index ebd40f5377..f1769ac6de 100644 --- a/spec/ruby/core/binding/clone_spec.rb +++ b/spec/ruby/core/binding/clone_spec.rb @@ -4,4 +4,10 @@ require_relative 'shared/clone' describe "Binding#clone" do it_behaves_like :binding_clone, :clone + + it "preserves frozen status" do + bind = binding.freeze + bind.frozen?.should == true + bind.clone.frozen?.should == true + end end diff --git a/spec/ruby/core/binding/dup_spec.rb b/spec/ruby/core/binding/dup_spec.rb index 43968213c8..f5f0c72d5d 100644 --- a/spec/ruby/core/binding/dup_spec.rb +++ b/spec/ruby/core/binding/dup_spec.rb @@ -4,4 +4,27 @@ require_relative 'shared/clone' describe "Binding#dup" do it_behaves_like :binding_clone, :dup + + it "resets frozen status" do + bind = binding.freeze + bind.frozen?.should == true + bind.dup.frozen?.should == false + end + + it "retains original binding variables but the list is distinct" do + bind1 = binding + eval "a = 1", bind1 + + bind2 = bind1.dup + eval("a = 2", bind2) + eval("a", bind1).should == 2 + eval("a", bind2).should == 2 + + eval("b = 2", bind2) + -> { eval("b", bind1) }.should.raise(NameError) + eval("b", bind2).should == 2 + + bind1.local_variables.sort.should == [:a, :bind1, :bind2] + bind2.local_variables.sort.should == [:a, :b, :bind1, :bind2] + end end diff --git a/spec/ruby/core/binding/eval_spec.rb b/spec/ruby/core/binding/eval_spec.rb index 9a397757e9..f1d8591320 100644 --- a/spec/ruby/core/binding/eval_spec.rb +++ b/spec/ruby/core/binding/eval_spec.rb @@ -7,7 +7,7 @@ describe "Binding#eval" do bind = obj.get_binding bind.eval("@secret += square(3)").should == 10 - bind.eval("a").should be_true + bind.eval("a").should == true bind.eval("class Inside; end") bind.eval("Inside.name").should == "BindingSpecs::Demo::Inside" @@ -23,15 +23,83 @@ describe "Binding#eval" do bind2.local_variables.should == [] end + it "starts with line 1 if single argument is given" do + obj = BindingSpecs::Demo.new(1) + bind = obj.get_binding + bind.eval("__LINE__").should == 1 + end + + it "preserves __LINE__ across multiple calls to eval" do + obj = BindingSpecs::Demo.new(1) + bind = obj.get_binding + bind.eval("__LINE__").should == 1 + bind.eval("__LINE__").should == 1 + end + + it "increments __LINE__ on each line of a multiline eval" do + obj = BindingSpecs::Demo.new(1) + bind = obj.get_binding + bind.eval("#foo\n__LINE__").should == 2 + end + + it "starts with line 1 if the Binding is created with #send" do + obj = BindingSpecs::Demo.new(1) + bind, line = obj.get_binding_with_send_and_line + bind.eval("__LINE__").should == 1 + end + + it "starts with a __LINE__ of 1 if a filename is passed" do + bind = BindingSpecs::Demo.new(1).get_binding + bind.eval("__LINE__", "(test)").should == 1 + bind.eval("#foo\n__LINE__", "(test)").should == 2 + end + + it "starts with a __LINE__ from the third argument if passed" do + bind = BindingSpecs::Demo.new(1).get_binding + bind.eval("__LINE__", "(test)", 88).should == 88 + bind.eval("#foo\n__LINE__", "(test)", 88).should == 89 + end + + it "uses 1 as __LINE__" do + obj = BindingSpecs::Demo.new(1) + bind = obj.get_binding + suppress_warning { bind.eval("__LINE__") }.should == 1 + end + + it "uses the __FILE__ that is passed in" do + bind = BindingSpecs::Demo.new(1).get_binding + bind.eval("__FILE__", "(test)").should == "(test)" + end + describe "with a file given" do it "does not store the filename permanently" do obj = BindingSpecs::Demo.new(1) bind = obj.get_binding bind.eval("__FILE__", "test.rb").should == "test.rb" - bind.eval("__FILE__").should_not == "test.rb" + suppress_warning {bind.eval("__FILE__")}.should_not == "test.rb" end end - it "needs to be reviewed for spec completeness" + it "with __method__ returns the method where the Binding was created" do + obj = BindingSpecs::Demo.new(1) + bind, meth = obj.get_binding_and_method + bind.eval("__method__").should == meth + end + + it "with __method__ returns the method where the Binding was created, ignoring #send" do + obj = BindingSpecs::Demo.new(1) + bind, meth = obj.get_binding_with_send_and_method + bind.eval("__method__").should == meth + end + + it "reflects refinements activated in the binding scope" do + bind = BindingSpecs::Refined.refined_binding + + bind.eval("'bar'.foo").should == "foo" + end + + it "uses the caller location as default filename" do + binding.eval("[__FILE__, __LINE__]").should == ["(eval at #{__FILE__}:#{__LINE__})", 1] + end end diff --git a/spec/ruby/core/binding/fixtures/classes.rb b/spec/ruby/core/binding/fixtures/classes.rb index 05ca2479ba..b5f3ce9008 100644 --- a/spec/ruby/core/binding/fixtures/classes.rb +++ b/spec/ruby/core/binding/fixtures/classes.rb @@ -25,6 +25,18 @@ module BindingSpecs __FILE__ end + def get_binding_with_send_and_line + [send(:binding), __LINE__] + end + + def get_binding_and_method + [binding, :get_binding_and_method] + end + + def get_binding_with_send_and_method + [send(:binding), :get_binding_with_send_and_method] + end + def get_empty_binding binding end @@ -37,4 +49,18 @@ module BindingSpecs end end end + + module AddFooToString + refine(String) do + def foo + "foo" + end + end + end + class Refined + using AddFooToString + def self.refined_binding + binding + end + end end diff --git a/spec/ruby/core/binding/fixtures/location.rb b/spec/ruby/core/binding/fixtures/location.rb new file mode 100644 index 0000000000..a78ae75731 --- /dev/null +++ b/spec/ruby/core/binding/fixtures/location.rb @@ -0,0 +1,6 @@ +module BindingSpecs + module LocationMethod + FILE_PATH = __FILE__ + TEST_BINDING = binding + end +end diff --git a/spec/ruby/core/binding/local_variable_defined_spec.rb b/spec/ruby/core/binding/local_variable_defined_spec.rb index 7b48257294..2fc6504ee5 100644 --- a/spec/ruby/core/binding/local_variable_defined_spec.rb +++ b/spec/ruby/core/binding/local_variable_defined_spec.rb @@ -26,7 +26,7 @@ describe 'Binding#local_variable_defined?' do it 'returns true when a local variable is defined in a parent scope' do foo = 10 - lambda { + -> { binding.local_variable_defined?(:foo) }.call.should == true end diff --git a/spec/ruby/core/binding/local_variable_get_spec.rb b/spec/ruby/core/binding/local_variable_get_spec.rb index eeb3ae44ed..d97100deda 100644 --- a/spec/ruby/core/binding/local_variable_get_spec.rb +++ b/spec/ruby/core/binding/local_variable_get_spec.rb @@ -11,17 +11,17 @@ describe "Binding#local_variable_get" do it "raises a NameError for missing variables" do bind = BindingSpecs::Demo.new(1).get_empty_binding - lambda { + -> { bind.local_variable_get(:no_such_variable) - }.should raise_error(NameError) + }.should.raise(NameError) end it "reads variables added later to the binding" do bind = BindingSpecs::Demo.new(1).get_empty_binding - lambda { + -> { bind.local_variable_get(:a) - }.should raise_error(NameError) + }.should.raise(NameError) bind.local_variable_set(:a, 42) @@ -31,7 +31,7 @@ describe "Binding#local_variable_get" do it 'gets a local variable defined in a parent scope' do number = 10 - lambda { + -> { binding.local_variable_get(:number) }.call.should == 10 end @@ -45,12 +45,12 @@ describe "Binding#local_variable_get" do it "raises a NameError on global access" do bind = binding - lambda { bind.local_variable_get(:$0) }.should raise_error(NameError) + -> { bind.local_variable_get(:$0) }.should.raise(NameError) end it "raises a NameError on special variable access" do bind = binding - lambda { bind.local_variable_get(:$~) }.should raise_error(NameError) - lambda { bind.local_variable_get(:$_) }.should raise_error(NameError) + -> { bind.local_variable_get(:$~) }.should.raise(NameError) + -> { bind.local_variable_get(:$_) }.should.raise(NameError) end end diff --git a/spec/ruby/core/binding/local_variable_set_spec.rb b/spec/ruby/core/binding/local_variable_set_spec.rb index 035e9a3c2e..3e4f407fc3 100644 --- a/spec/ruby/core/binding/local_variable_set_spec.rb +++ b/spec/ruby/core/binding/local_variable_set_spec.rb @@ -38,7 +38,7 @@ describe "Binding#local_variable_set" do bind = binding bind.local_variable_set(:number, 10) - lambda { number }.should raise_error(NameError) + -> { number }.should.raise(NameError) end it 'overwrites an existing local variable defined before a Binding' do @@ -59,13 +59,13 @@ describe "Binding#local_variable_set" do it "raises a NameError on global access" do bind = binding - lambda { bind.local_variable_set(:$0, "") }.should raise_error(NameError) + -> { bind.local_variable_set(:$0, "") }.should.raise(NameError) end it "raises a NameError on special variable access" do bind = binding - lambda { bind.local_variable_set(:$~, "") }.should raise_error(NameError) - lambda { bind.local_variable_set(:$_, "") }.should raise_error(NameError) + -> { bind.local_variable_set(:$~, "") }.should.raise(NameError) + -> { bind.local_variable_set(:$_, "") }.should.raise(NameError) end end diff --git a/spec/ruby/core/binding/local_variables_spec.rb b/spec/ruby/core/binding/local_variables_spec.rb index 92c817b9a8..0f59681342 100644 --- a/spec/ruby/core/binding/local_variables_spec.rb +++ b/spec/ruby/core/binding/local_variables_spec.rb @@ -2,7 +2,7 @@ require_relative '../../spec_helper' describe "Binding#local_variables" do it "returns an Array" do - binding.local_variables.should be_kind_of(Array) + binding.local_variables.should.is_a?(Array) end it "includes local variables in the current scope" do diff --git a/spec/ruby/core/binding/location_spec.rb b/spec/ruby/core/binding/location_spec.rb deleted file mode 100644 index 2ae0c5e9f1..0000000000 --- a/spec/ruby/core/binding/location_spec.rb +++ /dev/null @@ -1,46 +0,0 @@ -require_relative '../../spec_helper' -require_relative 'fixtures/classes' - -describe "Binding#eval" do - it "inherits __LINE__ from the enclosing scope" do - obj = BindingSpecs::Demo.new(1) - bind = obj.get_binding - bind.eval("__LINE__").should == obj.get_line_of_binding - end - - it "preserves __LINE__ across multiple calls to eval" do - obj = BindingSpecs::Demo.new(1) - bind = obj.get_binding - bind.eval("__LINE__").should == obj.get_line_of_binding - bind.eval("__LINE__").should == obj.get_line_of_binding - end - - it "increments __LINE__ on each line of a multiline eval" do - obj = BindingSpecs::Demo.new(1) - bind = obj.get_binding - bind.eval("#foo\n__LINE__").should == obj.get_line_of_binding + 1 - end - - it "starts with a __LINE__ of 1 if a filename is passed" do - bind = BindingSpecs::Demo.new(1).get_binding - bind.eval("__LINE__", "(test)").should == 1 - bind.eval("#foo\n__LINE__", "(test)").should == 2 - end - - it "starts with a __LINE__ from the third argument if passed" do - bind = BindingSpecs::Demo.new(1).get_binding - bind.eval("__LINE__", "(test)", 88).should == 88 - bind.eval("#foo\n__LINE__", "(test)", 88).should == 89 - end - - it "inherits __FILE__ from the enclosing scope" do - obj = BindingSpecs::Demo.new(1) - bind = obj.get_binding - bind.eval("__FILE__").should == obj.get_file_of_binding - end - - it "uses the __FILE__ that is passed in" do - bind = BindingSpecs::Demo.new(1).get_binding - bind.eval("__FILE__", "(test)").should == "(test)" - end -end diff --git a/spec/ruby/core/binding/shared/clone.rb b/spec/ruby/core/binding/shared/clone.rb index 0e934ac1b5..2d854fce96 100644 --- a/spec/ruby/core/binding/shared/clone.rb +++ b/spec/ruby/core/binding/shared/clone.rb @@ -31,4 +31,26 @@ describe :binding_clone, shared: true do b2.local_variable_defined?(:x).should == false end end + + ruby_version_is "3.4" do + it "copies instance variables" do + @b1.instance_variable_set(:@ivar, 1) + cl = @b1.send(@method) + cl.instance_variables.should == [:@ivar] + end + + it "copies the finalizer" do + code = <<-'RUBY' + obj = binding + + ObjectSpace.define_finalizer(obj, Proc.new { STDOUT.write "finalized\n" }) + + obj.clone + + exit 0 + RUBY + + ruby_exe(code).lines.sort.should == ["finalized\n", "finalized\n"] + end + end end diff --git a/spec/ruby/core/binding/source_location_spec.rb b/spec/ruby/core/binding/source_location_spec.rb new file mode 100644 index 0000000000..d1c8191ea8 --- /dev/null +++ b/spec/ruby/core/binding/source_location_spec.rb @@ -0,0 +1,14 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/location' + +describe "Binding#source_location" do + it "returns an [file, line] pair" do + b = BindingSpecs::LocationMethod::TEST_BINDING + b.source_location.should == [BindingSpecs::LocationMethod::FILE_PATH, 4] + end + + it "works for eval with a given line" do + b = eval('binding', nil, "foo", 100) + b.source_location.should == ["foo", 100] + end +end |
