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,92 @@
1
+ require 'spec_helper'
2
+ require 'peeek/hooks'
3
+
4
+ def sample_hooks
5
+ Peeek::Hooks.new([
6
+ hook_stub(:object => String, :method_name => :%, :calls => 1, :linked => true),
7
+ hook_stub(:object => Numeric, :method_name => :abs, :calls => 0, :linked => false),
8
+ hook_stub(:object => String, :method_name => :index, :calls => 3, :linked => true)
9
+ ])
10
+ end
11
+
12
+ describe Peeek::Hooks, '#get' do
13
+ it 'returns a hook that corresponds to the object' do
14
+ hooks = sample_hooks
15
+ hooks.get(String).should == hooks[0]
16
+ hooks.get(Numeric).should == hooks[1]
17
+ end
18
+
19
+ it "returns nil if a hook that corresponds to the object doesn't exist" do
20
+ hooks = sample_hooks
21
+ hooks.get(Regexp).should be_nil
22
+ end
23
+
24
+ context 'with a method name' do
25
+ it 'returns a hook that corresponds to the object and the method name' do
26
+ hooks = sample_hooks
27
+ hooks.get(String, :%).should == hooks[0]
28
+ hooks.get(Numeric, :abs).should == hooks[1]
29
+ hooks.get(String, :index).should == hooks[2]
30
+ end
31
+
32
+ it "returns nil if a hook that corresponds to the object and the method name doesn't exist" do
33
+ hooks = sample_hooks
34
+ hooks.get(String, :rindex).should be_nil
35
+ end
36
+ end
37
+ end
38
+
39
+ describe Peeek::Hooks, '#clear' do
40
+ it 'unlinks the hooks from the methods' do
41
+ hooks = sample_hooks
42
+ original_hooks = hooks.dup
43
+ one_or_more(original_hooks).should be_any { |hook| hook.linked? } # assert
44
+ hooks.clear
45
+ one_or_more(original_hooks).should be_all { |hook| !hook.linked? }
46
+ end
47
+
48
+ it 'clears calls of the hooks' do
49
+ hooks = sample_hooks
50
+ original_hooks = hooks.dup
51
+ one_or_more(original_hooks).should be_any { |hook| !hook.calls.empty? } # assert
52
+ hooks.clear
53
+ one_or_more(original_hooks).should be_all { |hook| hook.calls.empty? }
54
+ end
55
+
56
+ it 'clears the hooks' do
57
+ hooks = sample_hooks
58
+ hooks.clear
59
+ hooks.should be_empty
60
+ end
61
+
62
+ it 'returns self' do
63
+ hooks = sample_hooks
64
+ hooks.clear.should equal(hooks)
65
+ end
66
+ end
67
+
68
+ describe Peeek::Hooks, '#circumvent' do
69
+ it 'unlinks the hooks from the methods in the block' do
70
+ hooks = sample_hooks
71
+
72
+ hooks.circumvent do
73
+ one_or_more(hooks).should be_all { |hook| !hook.linked? }
74
+ end
75
+ end
76
+
77
+ it 'reverts state of the hooks after calling' do
78
+ hooks = sample_hooks
79
+ linked_hooks = hooks.select(&:linked?)
80
+ unlinked_hooks = hooks.reject(&:linked?)
81
+ one_or_more(linked_hooks).should be_all { |hook| hook.linked? } # assert
82
+ one_or_more(unlinked_hooks).should be_all { |hook| !hook.linked? } # assert
83
+ hooks.circumvent { }
84
+ one_or_more(linked_hooks).should be_all { |hook| hook.linked? }
85
+ one_or_more(unlinked_hooks).should be_all { |hook| !hook.linked? }
86
+ end
87
+
88
+ it 'raises ArgumentError if a block not given' do
89
+ hooks = sample_hooks
90
+ lambda { hooks.circumvent }.should raise_error(ArgumentError, 'block not supplied')
91
+ end
92
+ end
@@ -0,0 +1,129 @@
1
+ require 'spec_helper'
2
+ require 'peeek/supervisor'
3
+
4
+ def sample_supervisor
5
+ Peeek::Supervisor.create_for_instance.tap do |supervisor|
6
+ supervisor << hook_stub(:object => String, :method_name => :capitalize)
7
+ supervisor << hook_stub(:object => Numeric, :method_name => :days)
8
+ supervisor << hook_stub(:object => String, :method_name => :singularize)
9
+ end
10
+ end
11
+
12
+ describe Peeek::Supervisor, '.create_for_instance' do
13
+ it "calls #{described_class}.new with :method_added" do
14
+ described_class.should_receive(:new).with(:method_added)
15
+ described_class.create_for_instance
16
+ end
17
+
18
+ it "returns an instance of #{described_class}" do
19
+ supervisor = described_class.create_for_instance
20
+ supervisor.should be_a(described_class)
21
+ end
22
+ end
23
+
24
+ describe Peeek::Supervisor, '.create_for_singleton' do
25
+ it "calls #{described_class}.new with :singleton_method_added" do
26
+ described_class.should_receive(:new).with(:singleton_method_added)
27
+ described_class.create_for_singleton
28
+ end
29
+
30
+ it "returns an instance of #{described_class}" do
31
+ supervisor = described_class.create_for_singleton
32
+ supervisor.should be_a(described_class)
33
+ end
34
+ end
35
+
36
+ describe Peeek::Supervisor, '#add' do
37
+ before do
38
+ @supervisor = sample_supervisor
39
+ end
40
+
41
+ after do
42
+ @supervisor.clear
43
+ end
44
+
45
+ it 'adds the hook to the supervisor' do
46
+ hook = hook_stub(:object => String)
47
+ @supervisor.add(hook)
48
+ @supervisor.hooks.should be_include(hook)
49
+ end
50
+
51
+ it 'starts supervision to the object of the hook' do
52
+ Regexp.should_not be_supervised_for_instance # assert
53
+ hook = hook_stub(:object => Regexp)
54
+ @supervisor.add(hook)
55
+ @supervisor.original_callbacks.should be_include(Regexp)
56
+ Regexp.should be_supervised_for_instance
57
+ end
58
+
59
+ it "doesn't start supervision to object that is supervising already" do
60
+ hook = hook_stub(:object => String)
61
+ original_callback = @supervisor.original_callbacks[String]
62
+ @supervisor.add(hook)
63
+ @supervisor.original_callbacks[String].should equal(original_callback)
64
+ end
65
+
66
+ it 'returns self' do
67
+ hook = hook_stub(:object => String)
68
+ @supervisor.add(hook).should equal(@supervisor)
69
+ end
70
+ end
71
+
72
+ describe Peeek::Supervisor, '#clear' do
73
+ it 'clears the hooks in the supervisor' do
74
+ supervisor = sample_supervisor
75
+ supervisor.hooks.should_not be_empty # assert
76
+ supervisor.clear
77
+ supervisor.hooks.should be_empty
78
+ end
79
+
80
+ it 'clears the original callbacks in the supervisor' do
81
+ supervisor = sample_supervisor
82
+ supervisor.original_callbacks.should_not be_empty # assert
83
+ supervisor.clear
84
+ supervisor.original_callbacks.should be_empty
85
+ end
86
+
87
+ it 'revokes supervision to the objects' do
88
+ supervisor = sample_supervisor
89
+ String.should be_supervised_for_instance # assert
90
+ Numeric.should be_supervised_for_instance # assert
91
+ supervisor.clear
92
+ String.should_not be_supervised_for_instance
93
+ Numeric.should_not be_supervised_for_instance
94
+ end
95
+
96
+ it 'returns self' do
97
+ supervisor = sample_supervisor
98
+ supervisor.clear.should equal(supervisor)
99
+ end
100
+ end
101
+
102
+ describe Peeek::Supervisor, '#circumvent' do
103
+ before do
104
+ @supervisor = sample_supervisor
105
+ end
106
+
107
+ after do
108
+ @supervisor.clear
109
+ end
110
+
111
+ it 'revokes supervision to the objects in the block' do
112
+ @supervisor.circumvent do
113
+ String.should_not be_supervised_for_instance
114
+ Numeric.should_not be_supervised_for_instance
115
+ end
116
+ end
117
+
118
+ it 'restarts supervision to the objects after calling' do
119
+ String.should be_supervised_for_instance # assert
120
+ Numeric.should be_supervised_for_instance # assert
121
+ @supervisor.circumvent { }
122
+ String.should be_supervised_for_instance
123
+ Numeric.should be_supervised_for_instance
124
+ end
125
+
126
+ it 'raises ArgumentError if a block not given' do
127
+ lambda { @supervisor.circumvent }.should raise_error(ArgumentError, 'block not supplied')
128
+ end
129
+ end
@@ -0,0 +1,335 @@
1
+ require 'spec_helper'
2
+ require 'peeek'
3
+
4
+ describe Peeek, '.global' do
5
+ it 'returns the Peeek object' do
6
+ described_class.global.should be_a(described_class)
7
+ end
8
+
9
+ it 'returns same object' do
10
+ peeek = described_class.global
11
+ described_class.global.should equal(peeek)
12
+ end
13
+ end
14
+
15
+ describe Peeek, '.current' do
16
+ it 'returns the Peeek object' do
17
+ described_class.current.should be_a(described_class)
18
+ end
19
+
20
+ it 'returns same object' do
21
+ peeek = described_class.current
22
+ described_class.current.should equal(peeek)
23
+ end
24
+ end
25
+
26
+ describe Peeek, '.local' do
27
+ it 'returns return value from the block' do
28
+ result = described_class.local { 'local' }
29
+ result.should == 'local'
30
+ end
31
+
32
+ it 'switches the current Peeek object in the block' do
33
+ peeek = described_class.current
34
+
35
+ described_class.local do
36
+ described_class.current.should_not equal(peeek)
37
+ end
38
+ end
39
+
40
+ it 'gets back the current Peeek object after calling' do
41
+ peeek = described_class.current
42
+ described_class.local { }
43
+ described_class.current.should equal(peeek)
44
+ end
45
+
46
+ it 'supports nested calling' do
47
+ peeek1 = described_class.current
48
+
49
+ described_class.local do
50
+ peeek2 = described_class.current
51
+
52
+ described_class.local do
53
+ peeek3 = described_class.current
54
+ described_class.local { }
55
+ described_class.current.should equal(peeek3)
56
+ end
57
+
58
+ described_class.current.should equal(peeek2)
59
+ end
60
+
61
+ described_class.current.should equal(peeek1)
62
+ end
63
+
64
+ it 'unlinks the hooks of the current Peeek object over the block in the block, and revokes supervision' do
65
+ described_class.local do
66
+ peeek = described_class.current
67
+ peeek.hook(String, :to_s, :undefined_method)
68
+ peeek.hooks.get(String, :to_s).should be_linked # assert
69
+ peeek.hooks.get(String, :undefined_method).should_not be_linked # assert
70
+ String.should be_supervised_for_instance # assert
71
+
72
+ described_class.local do
73
+ peeek.hooks.should have(2).items
74
+ peeek.hooks.get(String, :to_s).should_not be_linked
75
+ peeek.hooks.get(String, :undefined_method).should_not be_linked
76
+ String.should_not be_supervised_for_instance
77
+ end
78
+ end
79
+ end
80
+
81
+ it 'links the hooks of the current Peeek object over the block after calling, and starts supervision' do
82
+ described_class.local do
83
+ peeek = described_class.current
84
+ peeek.hook(String, :to_s, :undefined_method)
85
+ described_class.local { }
86
+ peeek.hooks.should have(2).items
87
+ peeek.hooks.get(String, :to_s).should be_linked
88
+ peeek.hooks.get(String, :undefined_method).should_not be_linked
89
+ String.should be_supervised_for_instance
90
+ end
91
+ end
92
+
93
+ it 'releases the current Peeek object in the block after calling' do
94
+ hook = described_class.local do
95
+ described_class.current.hook(String, :%, :undefined_method)
96
+ '%s (%d)' % ['Koyomi', 18]
97
+ String.should be_supervised_for_instance # assert
98
+
99
+ described_class.current.hooks.get(String, :%).tap do |hook|
100
+ hook.should be_linked
101
+ hook.calls.should have(1).items
102
+ end
103
+ end
104
+
105
+ hook.should_not be_linked
106
+ hook.calls.should be_empty
107
+ String.should_not be_supervised_for_instance
108
+ end
109
+
110
+ it 'raises ArgumentError if a block not given' do
111
+ lambda { described_class.local }.should raise_error(ArgumentError, 'block not supplied')
112
+ end
113
+ end
114
+
115
+ describe Peeek, '.capture' do
116
+ it "calls #{described_class}.local with a block" do
117
+ described_class.should_receive(:local).with { }
118
+ described_class.capture(String => :%) { }
119
+ end
120
+
121
+ it 'links hooks to the objects and the methods in the block' do
122
+ described_class.capture(String => [:%, :index], $stdout => :write) do
123
+ hooks = described_class.current.hooks
124
+ hooks.get(String, :%).should be_linked
125
+ hooks.get(String, :index).should be_linked
126
+ hooks.get($stdout, :write).should be_linked
127
+ end
128
+ end
129
+
130
+ it "returns an instance of #{described_class}::Calls" do
131
+ calls = described_class.capture(String => :%) { }
132
+ calls.should be_a(Peeek::Calls)
133
+ end
134
+
135
+ it 'returns result that captured calls in the block' do
136
+ calls = described_class.capture(String => :%) do
137
+ format = '%s (%d)'
138
+ format % ['Koyomi', 18]
139
+ format % ['Karen', 14]
140
+ format % ['Tsukihi', 14]
141
+ end
142
+
143
+ calls.should have(3).items
144
+ end
145
+
146
+ it 'raises ArgumentError if a block not given' do
147
+ lambda { described_class.capture(String => :%) }.should raise_error(ArgumentError, 'block not supplied')
148
+ end
149
+ end
150
+
151
+ describe Peeek, '#calls' do
152
+ it "returns an instance of #{described_class}::Calls" do
153
+ peeek = described_class.new
154
+ peeek.calls.should be_a(Peeek::Calls)
155
+ end
156
+
157
+ it "returns an empty calls if hooks aren't registered" do
158
+ peeek = described_class.new
159
+ peeek.calls.should be_empty
160
+ end
161
+
162
+ it 'returns calls of the registered hooks' do
163
+ peeek = described_class.new
164
+ peeek.hook(String, :%, :index)
165
+ peeek.calls.should be_empty # assert
166
+ '%s (%d)' % ['Koyomi', 18]
167
+ 'abc'.index('x')
168
+ peeek.hooks.get(String, :%).calls.should have(1).items
169
+ peeek.hooks.get(String, :index).calls.should have(1).items
170
+ peeek.calls.should have(2).items
171
+ end
172
+ end
173
+
174
+ describe Peeek, '#hook' do
175
+ before do
176
+ @peeek = described_class.new
177
+ @peeek.hook(String, :%, :index)
178
+ end
179
+
180
+ after do
181
+ @peeek.release
182
+ end
183
+
184
+ it "calls #{described_class}::Hook.create with the object, the method specification and the block" do
185
+ block = lambda { }
186
+ Peeek::Hook.should_receive(:create).with($stdout, :write, &block).and_return(hook_stub)
187
+ Peeek::Hook.should_receive(:create).with(Numeric, :abs, &block).and_return(hook_stub)
188
+ @peeek.hook($stdout, :write, &block)
189
+ @peeek.hook(Numeric, :abs, &block)
190
+ end
191
+
192
+ it "returns an instance of #{described_class}::Calls" do
193
+ hooks = @peeek.hook($stdout, :write)
194
+ hooks.should be_a(Peeek::Hooks)
195
+ end
196
+
197
+ it "returns registered hooks at calling" do
198
+ hooks = @peeek.hook($stdout, :write)
199
+ hooks.should have(1).items
200
+ hooks.get($stdout, :write).should_not be_nil
201
+ end
202
+
203
+ it 'links a hook to the method' do
204
+ hook = @peeek.hook($stdout, :write).get($stdout, :write)
205
+ hook.should be_linked
206
+ end
207
+
208
+ it "starts supervision for instance method if the method isn't defined yet" do
209
+ String.should_not be_supervised_for_instance # assert
210
+ @peeek.hook(String, :undefined_method)
211
+ String.should be_supervised_for_instance
212
+
213
+ Numeric.should_not be_supervised_for_instance # assert
214
+ @peeek.hook(Numeric, :abs)
215
+ Numeric.should_not be_supervised_for_instance
216
+ end
217
+
218
+ it "starts supervision for singleton method if the method isn't defined yet" do
219
+ $stdout.should_not be_supervised_for_singleton # assert
220
+ @peeek.hook($stdout, :undefined_method)
221
+ $stdout.should be_supervised_for_singleton
222
+
223
+ Regexp.should_not be_supervised_for_singleton # assert
224
+ @peeek.hook(Regexp, '.quote')
225
+ Regexp.should_not be_supervised_for_singleton
226
+ end
227
+
228
+ it "adds hooks to the registered hooks" do
229
+ hook = @peeek.hook($stdout, :write).get($stdout, :write)
230
+ @peeek.hooks.should be_include(hook)
231
+ end
232
+ end
233
+
234
+ describe Peeek, '#release' do
235
+ before do
236
+ @peeek = described_class.new
237
+ @peeek.hook(String, :%, :undefined_method)
238
+ @peeek.hook($stdout, :undefined_method)
239
+ end
240
+
241
+ it 'cleras the hooks' do
242
+ @peeek.hooks.should_not be_empty # assert
243
+ @peeek.release
244
+ @peeek.hooks.should be_empty
245
+ end
246
+
247
+ it 'unlinks the hooks' do
248
+ original_hooks = @peeek.hooks.dup
249
+ one_or_more(original_hooks).should be_any { |hook| hook.linked? } # assert
250
+ @peeek.release
251
+ one_or_more(original_hooks).should be_all { |hook| !hook.linked? }
252
+ end
253
+
254
+ it 'clears calls of the hooks' do
255
+ '%s (%d)' % ['Koyomi', 18]
256
+ original_hooks = @peeek.hooks.dup
257
+ one_or_more(original_hooks).should be_any { |hook| !hook.calls.empty? } # assert
258
+ @peeek.release
259
+ one_or_more(original_hooks).should be_all { |hook| hook.calls.empty? }
260
+ end
261
+
262
+ it 'revokes supervision for instance method' do
263
+ String.should be_supervised_for_instance # assert
264
+ @peeek.release
265
+ String.should_not be_supervised_for_instance
266
+ end
267
+
268
+ it 'revokes supervision for singleton method' do
269
+ $stdout.should be_supervised_for_singleton # assert
270
+ @peeek.release
271
+ $stdout.should_not be_supervised_for_singleton
272
+ end
273
+
274
+ it 'returns self' do
275
+ @peeek.release.should equal(@peeek)
276
+ end
277
+ end
278
+
279
+ describe Peeek, '#circumvent' do
280
+ before do
281
+ @peeek = described_class.new
282
+ end
283
+
284
+ after do
285
+ @peeek.release
286
+ end
287
+
288
+ it 'unlinks the hooks only in the block' do
289
+ @peeek.hook(String, :%)
290
+ @peeek.hooks.get(String, :%).should be_linked # assert
291
+
292
+ @peeek.circumvent do
293
+ @peeek.hooks.get(String, :%).should_not be_linked
294
+ end
295
+
296
+ @peeek.hooks.get(String, :%).should be_linked
297
+ end
298
+
299
+ it 'revokes supervision for instance method only in the block' do
300
+ @peeek.hook(String, :undefined_method)
301
+ String.should be_supervised_for_instance # assert
302
+
303
+ @peeek.circumvent do
304
+ String.should_not be_supervised_for_instance
305
+ end
306
+
307
+ String.should be_supervised_for_instance
308
+ end
309
+
310
+ it 'revokes supervision for singleton method only in the block' do
311
+ @peeek.hook($stdout, :undefined_method)
312
+ $stdout.should be_supervised_for_singleton # assert
313
+
314
+ @peeek.circumvent do
315
+ $stdout.should_not be_supervised_for_singleton
316
+ end
317
+
318
+ $stdout.should be_supervised_for_singleton
319
+ end
320
+
321
+ it 'raises ArgumentError if a block not given' do
322
+ lambda { @peeek.circumvent }.should raise_error(ArgumentError, 'block not supplied')
323
+ end
324
+ end
325
+
326
+ describe Peeek::Readily, '#peeek' do
327
+ it 'registers hooks to the current Peeek object' do
328
+ Peeek.local do
329
+ Peeek.current.should_receive(:hook).with(String, :%, :index)
330
+ Peeek.current.should_receive(:hook).with(Numeric, :abs)
331
+ String.peeek(:%, :index)
332
+ Numeric.peeek(:abs)
333
+ end
334
+ end
335
+ end