peeek 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ class Peeek
2
+ VERSION = '1.0.1'
3
+ end
data/peeek.gemspec ADDED
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'peeek/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'peeek'
8
+ spec.version = Peeek::VERSION
9
+ spec.authors = ['Takahiro Kondo']
10
+ spec.email = ['heartery@gmail.com']
11
+ spec.description = %q{Peek at calls of a method}
12
+ spec.summary = spec.description
13
+ spec.homepage = 'https://github.com/takkkun/peeek'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 1.8.7'
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.3'
23
+ spec.add_development_dependency 'rake'
24
+ spec.add_development_dependency 'rspec'
25
+ end
@@ -0,0 +1,226 @@
1
+ require 'peeek/call'
2
+
3
+ def sample_call(attrs = {})
4
+ hook = attrs[:hook] || stub('Peeek::Hook', :to_s => 'String#%')
5
+ args = attrs[:args] || ['Koyomi', 18]
6
+ result = attrs[:result] || Peeek::Call::ReturnValue.new('Koyomi (18)')
7
+ Peeek::Call.new(hook, sample_backtrace, '%s (%d)', args, result)
8
+ end
9
+
10
+ def sample_backtrace
11
+ ["koyomi.rb:7:in `print'", "koyomi.rb:21:in `<main>'"]
12
+ end
13
+
14
+ def sample_return_value
15
+ Peeek::Call::ReturnValue.new(:return_value)
16
+ end
17
+
18
+ def sample_exception
19
+ Peeek::Call::Exception.new(:exception)
20
+ end
21
+
22
+ describe Peeek::Call, '#initialize' do
23
+ it 'raises ArgumentError if the result is invalid' do
24
+ lambda { sample_call(:result => :result) }.should raise_error(ArgumentError, 'invalid as result')
25
+ end
26
+ end
27
+
28
+ describe Peeek::Call, '#hook' do
29
+ it 'returns the value when constructed the call' do
30
+ hook = :hook
31
+ call = sample_call(:hook => hook)
32
+ call.hook.should == hook
33
+ end
34
+ end
35
+
36
+ describe Peeek::Call, '#backtrace' do
37
+ it 'returns the value when constructed the call' do
38
+ call = sample_call
39
+ call.backtrace.should == sample_backtrace
40
+ end
41
+ end
42
+
43
+ describe Peeek::Call, '#file' do
44
+ it 'returns name of top file on the backtrace' do
45
+ call = sample_call
46
+ call.file.should == 'koyomi.rb'
47
+ end
48
+ end
49
+
50
+ describe Peeek::Call, '#line' do
51
+ it 'returns top line number on the backtrace' do
52
+ call = sample_call
53
+ call.line.should == 7
54
+ end
55
+ end
56
+
57
+ describe Peeek::Call, '#receiver' do
58
+ it 'returns the value when constructed the call' do
59
+ call = sample_call
60
+ call.receiver.should == '%s (%d)'
61
+ end
62
+ end
63
+
64
+ describe Peeek::Call, '#arguments' do
65
+ it 'returns the value when constructed the call' do
66
+ call = sample_call
67
+ call.arguments.should == ['Koyomi', 18]
68
+ end
69
+ end
70
+
71
+ describe Peeek::Call, '#result' do
72
+ it 'returns the value when constructed the call' do
73
+ result = sample_return_value
74
+ call = sample_call(:result => result)
75
+ call.result.should == result
76
+ end
77
+ end
78
+
79
+ describe Peeek::Call, '#return_value' do
80
+ it 'returns value of the result' do
81
+ call = sample_call(:result => sample_return_value)
82
+ call.return_value.should == :return_value
83
+ end
84
+
85
+ it 'raises TypeError if the call is raised an exception' do
86
+ call = sample_call(:result => sample_exception)
87
+ lambda { call.return_value }.should raise_error(TypeError, "the call didn't return a value")
88
+ end
89
+ end
90
+
91
+ describe Peeek::Call, '#exception' do
92
+ it 'returns value of the result' do
93
+ call = sample_call(:result => sample_exception)
94
+ call.exception.should == :exception
95
+ end
96
+
97
+ it 'raises TypeError if the call returned a value' do
98
+ call = sample_call(:result => sample_return_value)
99
+ lambda { call.exception }.should raise_error(TypeError, "the call didn't raised an exception")
100
+ end
101
+ end
102
+
103
+ describe Peeek::Call, '#returned?' do
104
+ it 'is true if the call returned a value' do
105
+ call = sample_call(:result => sample_return_value)
106
+ call.should be_returned
107
+ end
108
+
109
+ it 'is false if the call is raised an exception' do
110
+ call = sample_call(:result => sample_exception)
111
+ call.should_not be_returned
112
+ end
113
+ end
114
+
115
+ describe Peeek::Call, '#raised?' do
116
+ it 'is true if the call is raised an exception' do
117
+ call = sample_call(:result => sample_exception)
118
+ call.should be_raised
119
+ end
120
+
121
+ it 'is false if the call returned a value' do
122
+ call = sample_call(:result => sample_return_value)
123
+ call.should_not be_raised
124
+ end
125
+ end
126
+
127
+ describe Peeek::Call, '#to_s' do
128
+ context 'with no arguments' do
129
+ it 'returns the stringified call' do
130
+ call = sample_call(:args => [])
131
+ call.to_s.should == 'String#% from "%s (%d)" returned "Koyomi (18)" in koyomi.rb at 7'
132
+ end
133
+ end
134
+
135
+ context 'with an argument' do
136
+ it 'returns the stringified call' do
137
+ call = sample_call(:args => [:arg])
138
+ call.to_s.should == 'String#% from "%s (%d)" with :arg returned "Koyomi (18)" in koyomi.rb at 7'
139
+ end
140
+ end
141
+
142
+ context 'with multiple arguments' do
143
+ it 'returns the stringified call' do
144
+ call = sample_call(:args => [:arg1, :arg2])
145
+ call.to_s.should == 'String#% from "%s (%d)" with (:arg1, :arg2) returned "Koyomi (18)" in koyomi.rb at 7'
146
+ end
147
+ end
148
+
149
+ context 'with a return value result' do
150
+ it 'returns the stringified call' do
151
+ call = sample_call(:result => sample_return_value)
152
+ call.to_s.should == 'String#% from "%s (%d)" with ("Koyomi", 18) returned :return_value in koyomi.rb at 7'
153
+ end
154
+ end
155
+
156
+ context 'with an exception result' do
157
+ it 'returns the stringified call' do
158
+ call = sample_call(:result => sample_exception)
159
+ call.to_s.should == 'String#% from "%s (%d)" with ("Koyomi", 18) raised :exception in koyomi.rb at 7'
160
+ end
161
+ end
162
+ end
163
+
164
+ describe Peeek::Call::ReturnValue do
165
+ it 'inhertis Peeek::Call::Result' do
166
+ result = described_class.allocate
167
+ result.should be_a(Peeek::Call::Result)
168
+ end
169
+
170
+ it 'identifies as key in a hash' do
171
+ hash = {sample_return_value => :return_value}
172
+ hash.should be_key(sample_return_value)
173
+ hash.should_not be_key(sample_exception)
174
+ hash.should_not be_key(described_class.new(:other_return_value))
175
+ hash.should_not be_key(Peeek::Call::Exception.new(:return_value))
176
+ end
177
+ end
178
+
179
+ describe Peeek::Call::ReturnValue, '#value' do
180
+ it 'returns the value when constructed the result' do
181
+ result = sample_return_value
182
+ result.value.should == :return_value
183
+ end
184
+ end
185
+
186
+ describe Peeek::Call::ReturnValue, '#==' do
187
+ it 'verifies equivalency' do
188
+ result = sample_return_value
189
+ result.should == sample_return_value
190
+ result.should_not == sample_exception
191
+ result.should_not == described_class.new(:other_return_value)
192
+ result.should_not == Peeek::Call::Exception.new(:return_value)
193
+ end
194
+ end
195
+
196
+ describe Peeek::Call::Exception do
197
+ it 'inhertis Peeek::Call::Result' do
198
+ result = described_class.allocate
199
+ result.should be_a(Peeek::Call::Result)
200
+ end
201
+
202
+ it 'identifies as key in a hash' do
203
+ hash = {sample_exception => :exception}
204
+ hash.should be_key(sample_exception)
205
+ hash.should_not be_key(sample_return_value)
206
+ hash.should_not be_key(described_class.new(:other_exception))
207
+ hash.should_not be_key(Peeek::Call::ReturnValue.new(:exception))
208
+ end
209
+ end
210
+
211
+ describe Peeek::Call::Exception, '#value' do
212
+ it 'returns the value when constructed the result' do
213
+ result = sample_exception
214
+ result.value.should == :exception
215
+ end
216
+ end
217
+
218
+ describe Peeek::Call::Exception, '#==' do
219
+ it 'verifies equivalency' do
220
+ result = sample_exception
221
+ result.should == sample_exception
222
+ result.should_not == sample_return_value
223
+ result.should_not == described_class.new(:other_exception)
224
+ result.should_not == Peeek::Call::ReturnValue.new(:exception)
225
+ end
226
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+ require 'peeek/calls'
3
+
4
+ def sample_calls
5
+ Peeek::Calls.new([
6
+ call_stub(:return_value, :file => 'koyomi.rb', :line => 5, :receiver => String),
7
+ call_stub(:exception, :file => 'koyomi.rb', :line => 7, :receiver => String),
8
+ call_stub(:return_value, :file => 'koyomi.rb', :line => 11, :receiver => Numeric),
9
+ call_stub(:return_value, :file => 'karen.rb', :line => 4, :receiver => String),
10
+ call_stub(:return_value, :file => 'karen.rb', :line => 7, :receiver => Numeric),
11
+ call_stub(:return_value, :file => 'karen.rb', :line => 12, :receiver => Numeric),
12
+ call_stub(:return_value, :file => 'tsukihi.rb', :line => 2, :receiver => Numeric),
13
+ call_stub(:return_value, :file => 'tsukihi.rb', :line => 3, :receiver => String),
14
+ call_stub(:return_value, :file => 'tsukihi.rb', :line => 12, :receiver => String)
15
+ ])
16
+ end
17
+
18
+ describe Peeek::Calls, '#in' do
19
+ it "returns an instance of #{described_class}" do
20
+ filtered_calls = sample_calls.in('koyomi.rb')
21
+ filtered_calls.should be_a(described_class)
22
+ end
23
+
24
+ it 'returns calls that corresponds to the name of the file' do
25
+ filtered_calls = sample_calls.in('koyomi.rb')
26
+ filtered_calls.should have(3).items
27
+ end
28
+
29
+ it 'supports Regexp' do
30
+ filtered_calls = sample_calls.in(/^k/)
31
+ filtered_calls.should have(6).items
32
+ end
33
+ end
34
+
35
+ describe Peeek::Calls, '#at' do
36
+ it "returns an instance of #{described_class}" do
37
+ filtered_calls = sample_calls.at(7)
38
+ filtered_calls.should be_a(described_class)
39
+ end
40
+
41
+ it 'returns calls that corresponds to the line number' do
42
+ filtered_calls = sample_calls.at(7)
43
+ filtered_calls.should have(2).items
44
+ end
45
+
46
+ it 'supports Range' do
47
+ filtered_calls = sample_calls.at(1..10)
48
+ filtered_calls.should have(6).items
49
+ end
50
+ end
51
+
52
+ describe Peeek::Calls, '#from' do
53
+ it "returns an instance of #{described_class}" do
54
+ filtered_calls = sample_calls.from(String)
55
+ filtered_calls.should be_a(described_class)
56
+ end
57
+
58
+ it 'returns calls that corresponds to the receiver' do
59
+ filtered_calls = sample_calls.from(String)
60
+ filtered_calls.should have(5).items
61
+ end
62
+ end
63
+
64
+ describe Peeek::Calls, '#return_values' do
65
+ it "returns an instance of #{described_class}" do
66
+ filtered_calls = sample_calls.return_values
67
+ filtered_calls.should be_a(described_class)
68
+ end
69
+
70
+ it 'returns calls that a value returned' do
71
+ filtered_calls = sample_calls.return_values
72
+ filtered_calls.should have(8).items
73
+ end
74
+ end
75
+
76
+ describe Peeek::Calls, '#exceptions' do
77
+ it "returns an instance of #{described_class}" do
78
+ filtered_calls = sample_calls.exceptions
79
+ filtered_calls.should be_a(described_class)
80
+ end
81
+
82
+ it 'returns calls that an exception raised' do
83
+ filtered_calls = sample_calls.exceptions
84
+ filtered_calls.should have(1).items
85
+ end
86
+ end
@@ -0,0 +1,87 @@
1
+ require 'peeek/hook/instance'
2
+
3
+ def sample_instance_linker(method_name = :%)
4
+ Peeek::Hook::Instance.new(String, method_name)
5
+ end
6
+
7
+ describe Peeek::Hook::Instance, '#method_prefix' do
8
+ it 'returns "#"' do
9
+ linker = sample_instance_linker
10
+ linker.method_prefix.should == '#'
11
+ end
12
+ end
13
+
14
+ describe Peeek::Hook::Instance, '#defined?' do
15
+ it 'is true if the method is defined in the object' do
16
+ linker = sample_instance_linker
17
+ linker.should be_defined
18
+ end
19
+
20
+ it 'is true if the method is defined privately in the object' do
21
+ linker = sample_instance_linker(:binding)
22
+ linker.should be_defined
23
+ end
24
+
25
+ it 'is false if the method is not defined in the object' do
26
+ linker = sample_instance_linker(:undefined_method)
27
+ linker.should_not be_defined
28
+ end
29
+ end
30
+
31
+ describe Peeek::Hook::Instance, '#link' do
32
+ before do
33
+ @original_method = String.instance_method(:%)
34
+ @linker = sample_instance_linker
35
+ end
36
+
37
+ after do
38
+ @linker.unlink(@original_method)
39
+ end
40
+
41
+ it 'gives appropriate arguments to the block when calling the method' do
42
+ block_args = nil
43
+ @linker.link { |*args| block_args = args }
44
+ '%s (%d)' % ['Koyomi', 18]
45
+ block_args[0][0].should =~ %r(spec/peeek/hook/instance_spec\.rb)
46
+ block_args[1].should == '%s (%d)'
47
+ block_args[2].should == [['Koyomi', 18]]
48
+ end
49
+
50
+ it 'is return value from the block as return value from the method' do
51
+ return_value = 'return_value'
52
+ @linker.link { |*args| return_value }
53
+ ('%s (%d)' % ['Koyomi', 18]).should equal(return_value)
54
+ end
55
+
56
+ it 'is exception from the block as exception from the method' do
57
+ @linker.link { |*args| raise 'exception' }
58
+ lambda { '%s (%d)' % ['Koyomi', 18] }.should raise_error('exception')
59
+ end
60
+
61
+ it 'returns the original method' do
62
+ @linker.link { }.should == @original_method
63
+ end
64
+
65
+ it 'raises ArgumentError if a block not given' do
66
+ lambda { @linker.link }.should raise_error(ArgumentError, 'block not supplied')
67
+ end
68
+ end
69
+
70
+ describe Peeek::Hook::Instance, '#unlink' do
71
+ before do
72
+ @original_method = String.instance_method(:%)
73
+ @linker = sample_instance_linker
74
+ @linker.link { fail }
75
+ end
76
+
77
+ it 'defines method with the original method' do
78
+ call = lambda { '%s (%d)' % ['Koyomi', 18] }
79
+
80
+ # assert
81
+ call.should raise_error
82
+
83
+ @linker.unlink(@original_method)
84
+ call.should_not raise_error
85
+ call[].should == 'Koyomi (18)'
86
+ end
87
+ end
@@ -0,0 +1,15 @@
1
+ require 'peeek/hook/linker'
2
+
3
+ describe Peeek::Hook::Linker, '.classes' do
4
+ before do
5
+ @class = Class.new(described_class)
6
+ end
7
+
8
+ after do
9
+ described_class.classes.delete(@class)
10
+ end
11
+
12
+ it "returns classes that inherited #{described_class}" do
13
+ described_class.classes.should be_include(@class)
14
+ end
15
+ end