peeek 1.0.3 → 1.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -3,6 +3,18 @@ Peeek
3
3
 
4
4
  Peeek peeks at calls of a method
5
5
 
6
+ Get started quickly
7
+ -------------------
8
+
9
+ Peeek has command line interface, you can get started quickly after installed.
10
+
11
+ $ gem install peeek
12
+ $ peeek -H'String#%' -e 'puts "%s (%d)" % ["Koyomi", 18]'
13
+ Koyomi (18)
14
+ String#% from "%s (%d)" with ["Koyomi", 18] returned "Koyomi (18)" in -e at 1
15
+
16
+ See at the details on using by `peeek -h`.
17
+
6
18
  Installation
7
19
  ------------
8
20
 
data/TODO.md ADDED
@@ -0,0 +1,2 @@
1
+ * Implement Peeek::Readily#peeek_lazily
2
+ * Can hook methods that is using in Peeek::Hook#call (e.g. UnboundMethod#bind)
@@ -3,6 +3,7 @@ require 'peeek/hook'
3
3
  require 'peeek/hooks'
4
4
  require 'peeek/supervisor'
5
5
  require 'peeek/calls'
6
+ require 'peeek/lazy'
6
7
 
7
8
  class Peeek
8
9
 
@@ -89,6 +90,8 @@ class Peeek
89
90
  #
90
91
  # @see Peeek::Hook.create
91
92
  def hook(object, *method_specs, &process)
93
+ object = object.take if object.is_a?(Lazy) and object.defined?
94
+
92
95
  hooks = method_specs.map do |method_spec|
93
96
  Hook.create(object, method_spec, &process).tap do |hook|
94
97
  if hook.defined?
@@ -137,10 +140,26 @@ class Peeek
137
140
  # @yieldparam [Peeek::Call] call a call to the methods
138
141
  #
139
142
  # @see Peeek#hook
143
+ # @see Peeek::Readily#peeek_lazily
140
144
  def peeek(*method_specs, &process)
141
145
  Peeek.current.hook(self, *method_specs, &process)
142
146
  end
143
147
 
148
+ # Register a hook to methods of an object to the current Peeek object. The
149
+ # object is that is pointed by self, work well even if the object isn't
150
+ # defined when called this method.
151
+ #
152
+ # @param [Array<String, Array<Symbol>] method_specs method specifiers of
153
+ # the object. see also examples of {Peeek::Hook.create}
154
+ # @yield [call] process a call to the methods. give optionally
155
+ # @yieldparam [Peeek::Call] call a call to the methods
156
+ #
157
+ # @see Peeek#hook
158
+ # @see Peeek::Readily#peeek
159
+ def peeek_lazily(*method_specs, &process)
160
+ Lazy.new(self).peeek(*method_specs, &process)
161
+ end
162
+
144
163
  end
145
164
 
146
165
  Object.__send__(:include, Readily)
@@ -7,14 +7,16 @@ class Peeek
7
7
  # @param [Array<String>] backtrace backtrace the call occurred
8
8
  # @param [Module, Class, Object] receiver object that received the call
9
9
  # @param [Array] arguments arguments at the call
10
+ # @param [Proc] block block at the call
10
11
  # @param [Peeek::Call::Result] result result of the call
11
- def initialize(hook, backtrace, receiver, arguments, result)
12
+ def initialize(hook, backtrace, receiver, arguments, block, result)
12
13
  raise ArgumentError, 'invalid as result' unless result.is_a?(Result)
13
14
  @hook = hook
14
15
  @backtrace = backtrace
15
16
  @file, @line = extract_file_and_line(backtrace.first)
16
17
  @receiver = receiver
17
18
  @arguments = arguments
19
+ @block = block
18
20
  @result = result
19
21
  end
20
22
 
@@ -42,6 +44,10 @@ class Peeek
42
44
  # @return [Array] arguments at the call
43
45
  attr_reader :arguments
44
46
 
47
+ # @attribute [r] block
48
+ # @return [Proc] block at the call
49
+ attr_reader :block
50
+
45
51
  # @attribute [r] result
46
52
  # @return [Peeek::Call::Result] result of the call
47
53
  attr_reader :result
@@ -84,6 +90,11 @@ class Peeek
84
90
  parts << "with (#{@arguments.map(&:inspect) * ', '})"
85
91
  end
86
92
 
93
+ if @block
94
+ conjunction = @arguments.empty? ? 'with' : 'and'
95
+ parts << "#{conjunction} a block"
96
+ end
97
+
87
98
  if returned?
88
99
  parts << "returned #{return_value.inspect}"
89
100
  elsif raised?
@@ -171,19 +171,23 @@ class Peeek
171
171
  private :parse
172
172
  end
173
173
 
174
- def call(backtrace, receiver, args)
174
+ def call(backtrace, receiver, args, block)
175
175
  method = @original_method.is_a?(UnboundMethod) ? @original_method.bind(receiver) : @original_method
176
176
 
177
177
  result = begin
178
178
  Call::ReturnValue.new(method[*args])
179
- rescue => e
179
+ rescue Exception => e
180
180
  e.set_backtrace(backtrace)
181
181
  Call::Exception.new(e)
182
182
  end
183
183
 
184
- call = Call.new(self, backtrace, receiver, args, result)
185
- @calls << call
186
- @process[call] if @process
184
+ call = Call.new(self, backtrace, receiver, args, block, result)
185
+
186
+ unless call.file =~ %r(lib/peeek(?:\.rb|/))
187
+ @calls << call
188
+ @process[call] if @process
189
+ end
190
+
187
191
  raise call.exception if call.raised?
188
192
  call.return_value
189
193
  end
@@ -33,7 +33,7 @@ class Peeek
33
33
  # @yieldreturn [Object] return value of the original method
34
34
  def link
35
35
  raise ArgumentError, 'block not supplied' unless block_given?
36
- define_method { |*args| yield caller, self, args }
36
+ define_method { |*args, &block| yield caller, self, args, block }
37
37
  end
38
38
 
39
39
  # Unlink the hook from the instance method.
@@ -33,7 +33,7 @@ class Peeek
33
33
  # @yieldreturn [Object] return value of the original method
34
34
  def link
35
35
  raise ArgumentError, 'block not supplied' unless block_given?
36
- define_method { |*args| yield caller, self, args }
36
+ define_method { |*args, &block| yield caller, self, args, block }
37
37
  end
38
38
 
39
39
  # Unlink the hook from the method.
@@ -1,3 +1,3 @@
1
1
  class Peeek
2
- VERSION = '1.0.3'
2
+ VERSION = '1.0.4'
3
3
  end
@@ -3,8 +3,9 @@ require 'peeek/call'
3
3
  def sample_call(attrs = {})
4
4
  hook = attrs[:hook] || stub('Peeek::Hook', :to_s => 'String#%')
5
5
  args = attrs[:args] || ['Koyomi', 18]
6
+ block = attrs.key?(:block) ? attrs[:block] : lambda { }
6
7
  result = attrs[:result] || Peeek::Call::ReturnValue.new('Koyomi (18)')
7
- Peeek::Call.new(hook, sample_backtrace, '%s (%d)', args, result)
8
+ Peeek::Call.new(hook, sample_backtrace, '%s (%d)', args, block, result)
8
9
  end
9
10
 
10
11
  def sample_backtrace
@@ -19,39 +20,68 @@ def sample_exception
19
20
  Peeek::Call::Exception.new(:exception)
20
21
  end
21
22
 
22
- describe Peeek::Call do
23
- describe '#initialize' do
24
- it do
25
- expect {
26
- described_class.new(:hook, ["koyomi.rb:7:in `print'"], '%s (%d)', ['Koyomi', 18], :result)
27
- }.to raise_error(ArgumentError, 'invalid as result')
28
- end
23
+ describe Peeek::Call, '#initialize' do
24
+ it 'raises ArgumentError if the result is invalid' do
25
+ lambda { sample_call(:result => :result) }.should raise_error(ArgumentError, 'invalid as result')
29
26
  end
27
+ end
30
28
 
31
- context 'basic instance attributes' do
32
- subject {
33
- described_class.new(
34
- :hook,
35
- ["koyomi.rb:7:in `print'", "koyomi.rb:21:in `<main>'"],
36
- '%s (%d)',
37
- ['Koyomi', 18],
38
- Peeek::Call::ReturnValue.new('Koyomi (18)')
39
- )
40
- }
29
+ describe Peeek::Call, '#hook' do
30
+ it 'returns the value when constructed the call' do
31
+ hook = :hook
32
+ call = sample_call(:hook => hook)
33
+ call.hook.should == hook
34
+ end
35
+ end
41
36
 
42
- its(:hook) { should == :hook }
43
- its(:backtrace) { should == ["koyomi.rb:7:in `print'", "koyomi.rb:21:in `<main>'"] }
44
- its(:file) { should == 'koyomi.rb' }
45
- its(:line) { should == 7 }
46
- its(:receiver) { should == '%s (%d)' }
47
- its(:arguments) { should == ['Koyomi', 18] }
48
- its(:result) { should == Peeek::Call::ReturnValue.new('Koyomi (18)') }
37
+ describe Peeek::Call, '#backtrace' do
38
+ it 'returns the value when constructed the call' do
39
+ call = sample_call
40
+ call.backtrace.should == sample_backtrace
49
41
  end
50
42
  end
51
43
 
52
- describe Peeek::Call, '#initialize' do
53
- it 'raises ArgumentError if the result is invalid' do
54
- lambda { sample_call(:result => :result) }.should raise_error(ArgumentError, 'invalid as result')
44
+ describe Peeek::Call, '#file' do
45
+ it 'returns name of top file on the backtrace' do
46
+ call = sample_call
47
+ call.file.should == 'koyomi.rb'
48
+ end
49
+ end
50
+
51
+ describe Peeek::Call, '#line' do
52
+ it 'returns top line number on the backtrace' do
53
+ call = sample_call
54
+ call.line.should == 7
55
+ end
56
+ end
57
+
58
+ describe Peeek::Call, '#receiver' do
59
+ it 'returns the value when constructed the call' do
60
+ call = sample_call
61
+ call.receiver.should == '%s (%d)'
62
+ end
63
+ end
64
+
65
+ describe Peeek::Call, '#arguments' do
66
+ it 'returns the value when constructed the call' do
67
+ call = sample_call
68
+ call.arguments.should == ['Koyomi', 18]
69
+ end
70
+ end
71
+
72
+ describe Peeek::Call, '#block' do
73
+ it 'returns the value when constructed the call' do
74
+ block = lambda { }
75
+ call = sample_call(:block => block)
76
+ call.block.should == block
77
+ end
78
+ end
79
+
80
+ describe Peeek::Call, '#result' do
81
+ it 'returns the value when constructed the call' do
82
+ result = sample_return_value
83
+ call = sample_call(:result => result)
84
+ call.result.should == result
55
85
  end
56
86
  end
57
87
 
@@ -107,35 +137,49 @@ describe Peeek::Call, '#to_s' do
107
137
  context 'with no arguments' do
108
138
  it 'returns the stringified call' do
109
139
  call = sample_call(:args => [])
110
- call.to_s.should == 'String#% from "%s (%d)" returned "Koyomi (18)" in koyomi.rb at 7'
140
+ call.to_s.should == 'String#% from "%s (%d)" with a block returned "Koyomi (18)" in koyomi.rb at 7'
111
141
  end
112
142
  end
113
143
 
114
144
  context 'with an argument' do
115
145
  it 'returns the stringified call' do
116
146
  call = sample_call(:args => [:arg])
117
- call.to_s.should == 'String#% from "%s (%d)" with :arg returned "Koyomi (18)" in koyomi.rb at 7'
147
+ call.to_s.should == 'String#% from "%s (%d)" with :arg and a block returned "Koyomi (18)" in koyomi.rb at 7'
118
148
  end
119
149
  end
120
150
 
121
151
  context 'with multiple arguments' do
122
152
  it 'returns the stringified call' do
123
153
  call = sample_call(:args => [:arg1, :arg2])
124
- call.to_s.should == 'String#% from "%s (%d)" with (:arg1, :arg2) returned "Koyomi (18)" in koyomi.rb at 7'
154
+ call.to_s.should == 'String#% from "%s (%d)" with (:arg1, :arg2) and a block returned "Koyomi (18)" in koyomi.rb at 7'
155
+ end
156
+ end
157
+
158
+ context 'with no block' do
159
+ it 'returns the stringified call' do
160
+ call = sample_call(:block => nil)
161
+ call.to_s.should == 'String#% from "%s (%d)" with ("Koyomi", 18) returned "Koyomi (18)" in koyomi.rb at 7'
162
+ end
163
+ end
164
+
165
+ context 'with a block' do
166
+ it 'returns the stringified call' do
167
+ call = sample_call(:block => lambda { })
168
+ call.to_s.should == 'String#% from "%s (%d)" with ("Koyomi", 18) and a block returned "Koyomi (18)" in koyomi.rb at 7'
125
169
  end
126
170
  end
127
171
 
128
172
  context 'with a return value result' do
129
173
  it 'returns the stringified call' do
130
174
  call = sample_call(:result => sample_return_value)
131
- call.to_s.should == 'String#% from "%s (%d)" with ("Koyomi", 18) returned :return_value in koyomi.rb at 7'
175
+ call.to_s.should == 'String#% from "%s (%d)" with ("Koyomi", 18) and a block returned :return_value in koyomi.rb at 7'
132
176
  end
133
177
  end
134
178
 
135
179
  context 'with an exception result' do
136
180
  it 'returns the stringified call' do
137
181
  call = sample_call(:result => sample_exception)
138
- call.to_s.should == 'String#% from "%s (%d)" with ("Koyomi", 18) raised :exception in koyomi.rb at 7'
182
+ call.to_s.should == 'String#% from "%s (%d)" with ("Koyomi", 18) and a block raised :exception in koyomi.rb at 7'
139
183
  end
140
184
  end
141
185
  end
@@ -16,7 +16,7 @@ describe Peeek::Hook::Instance, '#target_method' do
16
16
  linker = sample_instance_linker
17
17
  method = linker.target_method
18
18
  method.owner.should == String
19
- method.name.should == :%
19
+ method.name.to_sym.should == :%
20
20
  end
21
21
  end
22
22
 
@@ -16,7 +16,7 @@ describe Peeek::Hook::Singleton, '#target_method' do
16
16
  linker = sample_singleton_linker
17
17
  method = linker.target_method
18
18
  method.receiver.should == Regexp
19
- method.name.should == :quote
19
+ method.name.to_sym.should == :quote
20
20
  end
21
21
  end
22
22
 
@@ -175,7 +175,7 @@ describe Peeek::Hook, '#link' do
175
175
 
176
176
  it "calls #{described_class}::Linker#link with the block" do
177
177
  @linker.should_receive(:link).with { }.and_return do |&block|
178
- block.arity.should == 3
178
+ block.arity.should == 4
179
179
  @original_method
180
180
  end
181
181
 
@@ -319,12 +319,14 @@ describe 'recording of a call by', Peeek::Hook do
319
319
  end
320
320
 
321
321
  it 'sets attributes to the call' do
322
- line = __LINE__; '%s (%d)' % ['Koyomi', 18]
322
+ block = lambda { }
323
+ line = __LINE__; '%s (%d)'.%(['Koyomi', 18], &block)
323
324
  call = @hook.calls.first
324
325
  call.file.should == __FILE__
325
326
  call.line.should == line
326
327
  call.receiver.should == '%s (%d)'
327
328
  call.arguments.should == [['Koyomi', 18]]
329
+ call.block.should eq(block)
328
330
  end
329
331
 
330
332
  context 'if a value returned' do
@@ -357,6 +359,22 @@ describe 'recording of a call by', Peeek::Hook do
357
359
  exception.should equal(call.exception)
358
360
  end
359
361
 
362
+ it 'handles critical exception (inherited Exception)' do
363
+ hook = Peeek::Hook.create(Kernel, :require)
364
+ hook.link
365
+
366
+ exception = begin
367
+ require 'undefined_library'
368
+ rescue LoadError => e
369
+ e
370
+ end
371
+
372
+ call = hook.calls.first
373
+ exception.should equal(call.exception)
374
+
375
+ hook.unlink
376
+ end
377
+
360
378
  it 'raises the exception with valid backtrace' do
361
379
  line = __LINE__; exception = '%s (%d)' % ['Koyomi'] rescue $!
362
380
  exception.backtrace.first.should be_start_with("#{__FILE__}:#{line}")
metadata CHANGED
@@ -1,41 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: peeek
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.0.4
5
+ prerelease:
5
6
  platform: ruby
6
7
  authors:
7
8
  - Takahiro Kondo
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2013-04-16 00:00:00.000000000 Z
12
+ date: 2013-04-17 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rake
15
16
  requirement: !ruby/object:Gem::Requirement
17
+ none: false
16
18
  requirements:
17
- - - '>='
19
+ - - ! '>='
18
20
  - !ruby/object:Gem::Version
19
21
  version: '0'
20
22
  type: :development
21
23
  prerelease: false
22
24
  version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
23
26
  requirements:
24
- - - '>='
27
+ - - ! '>='
25
28
  - !ruby/object:Gem::Version
26
29
  version: '0'
27
30
  - !ruby/object:Gem::Dependency
28
31
  name: rspec
29
32
  requirement: !ruby/object:Gem::Requirement
33
+ none: false
30
34
  requirements:
31
- - - '>='
35
+ - - ! '>='
32
36
  - !ruby/object:Gem::Version
33
37
  version: '0'
34
38
  type: :development
35
39
  prerelease: false
36
40
  version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
37
42
  requirements:
38
- - - '>='
43
+ - - ! '>='
39
44
  - !ruby/object:Gem::Version
40
45
  version: '0'
41
46
  description: Peek at calls of a method
@@ -52,6 +57,7 @@ files:
52
57
  - LICENSE.txt
53
58
  - README.md
54
59
  - Rakefile
60
+ - TODO.md
55
61
  - bin/peeek
56
62
  - lib/peeek.rb
57
63
  - lib/peeek/call.rb
@@ -84,26 +90,27 @@ files:
84
90
  homepage: https://github.com/takkkun/peeek
85
91
  licenses:
86
92
  - MIT
87
- metadata: {}
88
93
  post_install_message:
89
94
  rdoc_options: []
90
95
  require_paths:
91
96
  - lib
92
97
  required_ruby_version: !ruby/object:Gem::Requirement
98
+ none: false
93
99
  requirements:
94
- - - '>='
100
+ - - ! '>='
95
101
  - !ruby/object:Gem::Version
96
102
  version: 1.8.7
97
103
  required_rubygems_version: !ruby/object:Gem::Requirement
104
+ none: false
98
105
  requirements:
99
- - - '>='
106
+ - - ! '>='
100
107
  - !ruby/object:Gem::Version
101
108
  version: '0'
102
109
  requirements: []
103
110
  rubyforge_project:
104
- rubygems_version: 2.0.3
111
+ rubygems_version: 1.8.23
105
112
  signing_key:
106
- specification_version: 4
113
+ specification_version: 3
107
114
  summary: Peek at calls of a method
108
115
  test_files:
109
116
  - spec/peeek/call_spec.rb
checksums.yaml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- SHA1:
3
- metadata.gz: 4cf3690abfc7e18ba772e5813bd248c6e8f77e31
4
- data.tar.gz: 97b35ef5d8c535fc08db01336fbc0ee319be02f9
5
- SHA512:
6
- metadata.gz: 19ddd27a103fe0c1c52484f1525e73743ed7755bdfbc323a3de52263bc4ba2aee2694280ac50ccdeb0d5fbac44d412812c3d745c44c560c81a594c1ed2fd767d
7
- data.tar.gz: 31f272cd92df1acf44b5e16877a30c1c7975e0fec030322c7cb8308449b69ef421153af4b0cf8048eff5c9f4fa967b2e2eebc18f0c5793ce9be78d06bcf45b5a