peeek 1.0.3 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +12 -0
- data/TODO.md +2 -0
- data/lib/peeek.rb +19 -0
- data/lib/peeek/call.rb +12 -1
- data/lib/peeek/hook.rb +9 -5
- data/lib/peeek/hook/instance.rb +1 -1
- data/lib/peeek/hook/singleton.rb +1 -1
- data/lib/peeek/version.rb +1 -1
- data/spec/peeek/call_spec.rb +77 -33
- data/spec/peeek/hook/instance_spec.rb +1 -1
- data/spec/peeek/hook/singleton_spec.rb +1 -1
- data/spec/peeek/hook_spec.rb +20 -2
- metadata +18 -11
- checksums.yaml +0 -7
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
data/lib/peeek.rb
CHANGED
@@ -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)
|
data/lib/peeek/call.rb
CHANGED
@@ -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?
|
data/lib/peeek/hook.rb
CHANGED
@@ -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
|
-
|
186
|
-
|
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
|
data/lib/peeek/hook/instance.rb
CHANGED
@@ -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.
|
data/lib/peeek/hook/singleton.rb
CHANGED
@@ -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.
|
data/lib/peeek/version.rb
CHANGED
data/spec/peeek/call_spec.rb
CHANGED
@@ -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
|
-
|
24
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
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, '#
|
53
|
-
it '
|
54
|
-
|
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
|
data/spec/peeek/hook_spec.rb
CHANGED
@@ -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 ==
|
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
|
-
|
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.
|
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-
|
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:
|
111
|
+
rubygems_version: 1.8.23
|
105
112
|
signing_key:
|
106
|
-
specification_version:
|
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
|