File: test_binding_of_caller.rb

package info (click to toggle)
ruby-binding-of-caller 0.7.2%2Bdebian1-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, stretch
  • size: 176 kB
  • ctags: 65
  • sloc: ruby: 308; ansic: 173; makefile: 9
file content (161 lines) | stat: -rwxr-xr-x 3,601 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
unless Object.const_defined? :BindingOfCaller
  $:.unshift File.expand_path '../../lib', __FILE__
  require 'binding_of_caller'
  require 'binding_of_caller/version'
end

class Module
  public :remove_const
end

puts "Testing binding_of_caller version #{BindingOfCaller::VERSION}..."
puts "Ruby version: #{RUBY_VERSION}"

describe BindingOfCaller do
  describe "of_caller" do
    it "should fetch immediate caller's binding when 0 is passed" do
      o = Object.new
      def o.a
        var = 1
        binding.of_caller(0).eval('var')
      end

      o. a.should == 1
    end

    it "should fetch parent of caller's binding when 1 is passed" do
      o = Object.new
      def o.a
        var = 1
        b
      end

      def o.b
        binding.of_caller(1).eval('var')
      end

      o.a.should == 1
    end

    it "should modify locals in parent of caller's binding" do
      o = Object.new
      def o.a
        var = 1
        b
        var
      end

      def o.b
        binding.of_caller(1).eval('var = 20')
      end

      o.a.should == 20
    end

    it "should raise an exception when retrieving an out of band binding" do
      o = Object.new
      def o.a
        binding.of_caller(100)
      end

      lambda { o.a }.should.raise RuntimeError
    end
  end

  describe "callers" do
    before do
      @o = Object.new
    end

    it 'should return the first non-internal binding when using callers.first' do
      def @o.meth
        x = :a_local
        [binding.callers.first, binding.of_caller(0)]
      end

      b1, b2 = @o.meth
      b1.eval("x").should == :a_local
      b2.eval("x").should == :a_local
    end
  end

  describe "frame_count" do
    it 'frame_count should equal callers.count' do
      binding.frame_count.should == binding.callers.count
    end
  end

  describe "frame_descripton" do
    it 'can be called on ordinary binding without raising' do
      lambda { binding.frame_description }.should.not.raise 
    end

    it 'describes a block frame' do
      binding.of_caller(0).frame_description.should =~ /block/
    end

    it 'describes a method frame' do
      o = Object.new
      def o.horsey_malone
        binding.of_caller(0).frame_description.should =~ /horsey_malone/
      end
      o.horsey_malone
    end

    it 'describes a class frame' do
      class HorseyMalone
        binding.of_caller(0).frame_description.should =~ /class/i
      end
      Object.remove_const(:HorseyMalone)
    end
  end

  describe "frame_type" do
    it 'can be called on ordinary binding without raising' do
      lambda { binding.frame_type }.should.not.raise 
    end

    describe "when inside a class definition" do
      before do
        class HorseyMalone
          @binding = binding.of_caller(0)
          def self.binding; @binding; end
        end
        @binding = HorseyMalone.binding
      end

      it 'returns :class' do
        @binding.frame_type.should == :class
      end
    end

    describe "when evaluated" do
      before { @binding = eval("binding.of_caller(0)") }

      it 'returns :eval' do
        @binding.frame_type.should == :eval
      end
    end

    describe "when inside a block" do
      before { @binding = proc { binding.of_caller(0) }.call }

      it 'returns :block' do
        @binding.frame_type.should == :block
      end
    end

    describe "when inside an instance method" do
      before do
        o = Object.new
        def o.a; binding.of_caller(0); end
        @binding = o.a;
      end

      it 'returns :method' do
        @binding.frame_type.should == :method
      end
    end
  end
end