peeek 1.0.1

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.
@@ -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