hookable 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,11 @@
1
+ = Hookable
2
+
3
+ Patch any method with before, after and around hooks.
4
+
5
+ == Installation
6
+
7
+ $ sudo gem install hookable --source http://gemcutter.org
8
+
9
+ == Usage
10
+
11
+ Still very alpha, documentation will come later.
@@ -0,0 +1,20 @@
1
+ require "rake/testtask"
2
+
3
+ begin
4
+ require "hanna/rdoctask"
5
+ rescue LoadError
6
+ require "rake/rdoctask"
7
+ end
8
+
9
+ task :default => [:test]
10
+
11
+ Rake::TestTask.new do |t|
12
+ t.test_files = Dir["test/*_test.rb"]
13
+ end
14
+
15
+ Rake::RDocTask.new do |t|
16
+ t.title = "Hookable Documentation"
17
+ t.main = "README.rdoc"
18
+ t.rdoc_files.include("README.rdoc", "lib/**/*.rb")
19
+ t.rdoc_dir = "doc"
20
+ end
@@ -0,0 +1,141 @@
1
+ require 'rubygems'
2
+ require 'kinda-core'
3
+
4
+ module Kinda
5
+ module Hookable
6
+ include Core
7
+
8
+ ClassMethods = inheritable_extend do
9
+ [:before, :after, :around].each do |kind|
10
+ define_method(kind) do |method_name, &block|
11
+ add_hook(kind, method_name, &block)
12
+ end
13
+ end
14
+
15
+ alias_method :on, :after
16
+
17
+ def method_hooked?(method_name)
18
+ self_and_ancestors.each do |ancestor|
19
+ ancestor.is_a?(Module) ? next : break unless ancestor.respond_to?(:hooked_methods)
20
+ return true if ancestor.hooked_methods.include?(method_name)
21
+ end
22
+ false
23
+ end
24
+
25
+ protected
26
+
27
+ def hooked_methods
28
+ @hooked_methods ||= Hash.new do |hash, method_name|
29
+ hash[method_name] = Hookable::HookedMethod.new(self, method_name)
30
+ end
31
+ end
32
+
33
+ def patch_method(method_name)
34
+ return if Thread.current[:__adding_method__]
35
+ # puts "Patching method ##{method_name} in #{self.inspect}"
36
+ original_method = instance_method(method_name)
37
+ Thread.current[:__adding_method__] = true
38
+ define_method(method_name) do |*args, &block|
39
+ singleton_class_send(:exec_method, method_name, original_method, self, *args, &block)
40
+ end
41
+ Thread.current[:__adding_method__] = false
42
+ hooked_methods[method_name].method_patched = true
43
+ end
44
+
45
+ private
46
+
47
+ def add_hook(kind, method_name, &block)
48
+ hooked_methods[method_name.to_sym].hooks[kind] << block
49
+ patch_method_if_necessary(method_name.to_sym)
50
+ end
51
+
52
+ def exec_method(method_name, original_method, original_self, *args, &block)
53
+ result = nil
54
+
55
+ chained_hooks = [] << lambda do |*args, &block|
56
+ find_hooks(method_name, :before).each do |hook|
57
+ original_self.call_with_this(hook, *args, &block)
58
+ end
59
+ result = original_method.bind(original_self).call(*args, &block) if original_method
60
+ find_hooks(method_name, :after).each do |hook|
61
+ original_self.call_with_this(hook, *args, &block)
62
+ end
63
+ end
64
+
65
+ hooks = find_hooks(method_name, :around)
66
+ hooks.each_index do |index|
67
+ chained_hooks << lambda do |*args, &block|
68
+ original_self.call_with_this(hooks[index], chained_hooks[index], *args, &block)
69
+ end
70
+ end
71
+ chained_hooks.last.call(*args, &block)
72
+
73
+ result
74
+ end
75
+
76
+ def find_hooks(method_name, kind)
77
+ hooks = []
78
+ self_and_ancestors.each do |ancestor|
79
+ ancestor.is_a?(Module) ? next : break unless ancestor.respond_to?(:hooked_methods)
80
+ next unless ancestor.hooked_methods.include?(method_name)
81
+ next unless ancestor.hooked_methods[method_name].hooks.include?(kind)
82
+ hooks.concat(ancestor.hooked_methods[method_name].hooks[kind])
83
+ end
84
+ hooks
85
+ end
86
+
87
+ def method_added(method_name)
88
+ super
89
+ if method_hooked?(method_name)
90
+ patch_method(method_name)
91
+ end
92
+ end
93
+
94
+ def patch_method_if_necessary(method_name)
95
+ self_and_ancestors.each do |ancestor|
96
+ ancestor.is_a?(Module) ? next : break unless ancestor.respond_to?(:patch_method)
97
+ method_defined_in_this_class = ancestor.instance_method(method_name).owner == ancestor rescue false
98
+ if method_defined_in_this_class
99
+ ancestor.patch_method(method_name) unless ancestor.hooked_methods[method_name].method_patched
100
+ break
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ ###
107
+
108
+ delegate_to_class ClassMethods.public_instance_methods
109
+ delegate_to_class :singleton_method_added => :method_added
110
+
111
+ def respond_to?(method_name, include_private=false)
112
+ super || method_hooked?(method_name)
113
+ end
114
+
115
+ private
116
+
117
+ def method_missing(method_name, *args, &block)
118
+ if method_hooked?(method_name)
119
+ singleton_class_send(:exec_method, method_name, nil, self, *args, &block)
120
+ else
121
+ super
122
+ end
123
+ end
124
+
125
+ ###
126
+
127
+ class HookedMethod
128
+ attr_reader :klass, :name
129
+ attr_accessor :method_patched
130
+
131
+ def initialize(klass, name)
132
+ @klass = klass
133
+ @name = name
134
+ end
135
+
136
+ def hooks
137
+ @hooks ||= Hash.new { |hash, kind| hash[kind] = [] }
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), 'hookable')
@@ -0,0 +1,567 @@
1
+ #!/usr/bin/ruby19
2
+ # encoding: utf-8
3
+
4
+ require 'test/unit'
5
+
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')).uniq!
7
+ require 'kinda-hookable'
8
+
9
+ class HookableClassTest < Test::Unit::TestCase
10
+ def setup
11
+ @simple_class = Class.new do
12
+ include Kinda::Hookable
13
+ end
14
+
15
+ @simple = @simple_class.new
16
+ end
17
+
18
+ def test_no_method_error
19
+ assert_raise NoMethodError do
20
+ @simple.hello
21
+ end
22
+ end
23
+
24
+ def test_before
25
+ result = []
26
+ @simple.before(:hello) { result << 'before' }
27
+ @simple.hello
28
+ assert_equal ['before'], result
29
+ end
30
+
31
+ def test_before_and_after
32
+ result = []
33
+ @simple.before(:hello) { result << 'before' }
34
+ @simple.after(:hello) { result << 'after' }
35
+ @simple.hello
36
+ assert_equal ['before', 'after'], result
37
+ end
38
+
39
+ def test_before_after_and_around
40
+ result = []
41
+ @simple.before(:hello) { result << 'before' }
42
+ @simple.after(:hello) { result << 'after' }
43
+ @simple.around(:hello) do |original_method|
44
+ result << 'around begin'
45
+ original_method.call
46
+ result << 'around end'
47
+ end
48
+ @simple.hello
49
+ assert_equal ['around begin', 'before', 'after', 'around end'], result
50
+ end
51
+
52
+ def test_respond_to
53
+ assert @simple.respond_to?(:before)
54
+ @simple.before(:hello) { result << 'before' }
55
+ assert @simple.respond_to?(:hello)
56
+ assert !@simple.respond_to?(:undefined_method)
57
+ end
58
+ end
59
+
60
+ ###
61
+
62
+ class HookableClassWithAMethodTest < Test::Unit::TestCase
63
+ def setup
64
+ @simple_class = Class.new do
65
+ include Kinda::Hookable
66
+
67
+ attr_accessor :result
68
+
69
+ def initialize
70
+ @result = []
71
+ end
72
+
73
+ def hello
74
+ @result << 'hello'
75
+ end
76
+ end
77
+
78
+ @simple = @simple_class.new
79
+ end
80
+
81
+ def test_hello
82
+ @simple.hello
83
+ assert_equal ['hello'], @simple.result
84
+ end
85
+
86
+ def test_before
87
+ @simple.before(:hello) { this.result << 'before' }
88
+ @simple.hello
89
+ assert_equal ['before', 'hello'], @simple.result
90
+ end
91
+
92
+ def test_two_befores
93
+ @simple.before(:hello) { this.result << 'before 1' }
94
+ @simple.before(:hello) { this.result << 'before 2' }
95
+ @simple.hello
96
+ assert_equal ['before 1', 'before 2', 'hello'], @simple.result
97
+ end
98
+
99
+ def test_before_after_and_around
100
+ @simple.before(:hello) { this.result << 'before' }
101
+ @simple.after(:hello) { this.result << 'after' }
102
+ @simple.around(:hello) do |original_method|
103
+ this.result << 'around begin'
104
+ original_method.call
105
+ this.result << 'around end'
106
+ end
107
+ @simple.hello
108
+ assert_equal ['around begin', 'before', 'hello', 'after', 'around end'], @simple.result
109
+ end
110
+
111
+ def test_two_arounds
112
+ @simple.around(:hello) do |original_method|
113
+ this.result << 'around 1 begin'
114
+ original_method.call
115
+ this.result << 'around 1 end'
116
+ end
117
+ @simple.around(:hello) do |original_method|
118
+ this.result << 'around 2 begin'
119
+ original_method.call
120
+ this.result << 'around 2 end'
121
+ end
122
+ @simple.hello
123
+ assert_equal ['around 2 begin', 'around 1 begin', 'hello',
124
+ 'around 1 end', 'around 2 end'], @simple.result
125
+ end
126
+
127
+ def test_respond_to
128
+ assert @simple.respond_to?(:hello)
129
+ end
130
+ end
131
+
132
+ ###
133
+
134
+ class HookableClassWithAMethodWithParametersAndResultTest < Test::Unit::TestCase
135
+ def setup
136
+ @simple_class = Class.new do
137
+ include Kinda::Hookable
138
+
139
+ attr_accessor :result
140
+
141
+ def initialize
142
+ @result = []
143
+ end
144
+
145
+ def hello(first_name, last_name)
146
+ greeting = "hello #{first_name} #{last_name}"
147
+ @result << greeting
148
+ greeting
149
+ end
150
+ end
151
+
152
+ @simple = @simple_class.new
153
+ end
154
+
155
+ def test_hello
156
+ greeting = @simple.hello('Manuel', 'Vila')
157
+ assert_equal 'hello Manuel Vila', greeting
158
+ assert_equal ['hello Manuel Vila'], @simple.result
159
+ end
160
+
161
+ def test_before
162
+ @simple.before(:hello) { |first, last| this.result << "before hello #{first} #{last}" }
163
+ greeting = @simple.hello('Manuel', 'Vila')
164
+ assert_equal 'hello Manuel Vila', greeting
165
+ assert_equal ['before hello Manuel Vila', 'hello Manuel Vila'], @simple.result
166
+ end
167
+
168
+ def test_after
169
+ @simple.after(:hello) { |first, last| this.result << "after hello #{first} #{last}" }
170
+ greeting = @simple.hello('Manuel', 'Vila')
171
+ assert_equal 'hello Manuel Vila', greeting
172
+ assert_equal ['hello Manuel Vila', 'after hello Manuel Vila'], @simple.result
173
+ end
174
+
175
+ def test_before_and_around
176
+ @simple.before(:hello) { |first, last| this.result << "before hello #{first} #{last}" }
177
+ @simple.around(:hello) do |original_method, first, last|
178
+ this.result << "around hello #{first} #{last} begin"
179
+ original_method.call(first, last)
180
+ this.result << "around hello #{first} #{last} end"
181
+ end
182
+ greeting = @simple.hello('Manuel', 'Vila')
183
+ assert_equal 'hello Manuel Vila', greeting
184
+ assert_equal ['around hello Manuel Vila begin', 'before hello Manuel Vila',
185
+ 'hello Manuel Vila', 'around hello Manuel Vila end'], @simple.result
186
+ end
187
+ end
188
+
189
+ ###
190
+
191
+ class HookableSuperClassTest < Test::Unit::TestCase
192
+ def setup
193
+ @super_simple_class = Class.new do
194
+ include Kinda::Hookable
195
+
196
+ attr_accessor :result
197
+
198
+ def initialize
199
+ @result = []
200
+ end
201
+ end
202
+
203
+ @simple_class = Class.new(@super_simple_class)
204
+
205
+ @simple = @simple_class.new
206
+ end
207
+
208
+ def test_before_in_superclass
209
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
210
+ @simple.hello
211
+ assert_equal [@simple.class.superclass], @simple.result
212
+ end
213
+
214
+ def test_respond_to_with_before_in_superclass
215
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
216
+ assert @simple.respond_to?(:hello)
217
+ end
218
+
219
+ def test_before_in_class
220
+ @simple_class.class_eval { before(:hello) { this.result << self } }
221
+ @simple.hello
222
+ assert_equal [@simple.class], @simple.result
223
+ end
224
+
225
+ def test_respond_to_with_before_in_class
226
+ @simple_class.class_eval { before(:hello) { this.result << self } }
227
+ assert @simple.respond_to?(:hello)
228
+ end
229
+
230
+ def test_before_in_singleton_class
231
+ @simple.before(:hello) { this.result << self }
232
+ @simple.hello
233
+ assert_equal [self], @simple.result
234
+ end
235
+
236
+ def test_before_in_superclass_class_and_singleton_class
237
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
238
+ @simple_class.class_eval { before(:hello) { this.result << self } }
239
+ @simple.before(:hello) { this.result << self }
240
+ @simple.hello
241
+ assert_equal [self, @simple.class, @simple.class.superclass], @simple.result
242
+ end
243
+ end
244
+
245
+ ###
246
+
247
+ class HookableSuperClassWithAMethodTest < Test::Unit::TestCase
248
+ def setup
249
+ @super_simple_class = Class.new do
250
+ include Kinda::Hookable
251
+
252
+ attr_accessor :result
253
+
254
+ def initialize
255
+ @result = []
256
+ end
257
+
258
+ def hello
259
+ @result << 'hello'
260
+ end
261
+ end
262
+
263
+ @simple_class = Class.new(@super_simple_class)
264
+
265
+ @simple = @simple_class.new
266
+ end
267
+
268
+ def test_respond_to
269
+ assert @simple.respond_to?(:hello)
270
+ end
271
+
272
+ def test_before_in_superclass
273
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
274
+ @simple.hello
275
+ assert_equal [@simple.class.superclass, 'hello'], @simple.result
276
+ end
277
+
278
+ def test_respond_to_with_before_in_superclass
279
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
280
+ assert @simple.respond_to?(:hello)
281
+ end
282
+
283
+ def test_before_in_class
284
+ @simple_class.class_eval { before(:hello) { this.result << self } }
285
+ @simple.hello
286
+ assert_equal [@simple.class, 'hello'], @simple.result
287
+ end
288
+
289
+ def test_respond_to_with_before_in_class
290
+ @simple_class.class_eval { before(:hello) { this.result << self } }
291
+ assert @simple.respond_to?(:hello)
292
+ end
293
+
294
+ def test_before_in_singleton_class
295
+ @simple.before(:hello) { this.result << self }
296
+ @simple.hello
297
+ assert_equal [self, 'hello'], @simple.result
298
+ end
299
+
300
+ def test_before_in_superclass_class_and_singleton_class
301
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
302
+ @simple_class.class_eval { before(:hello) { this.result << self } }
303
+ @simple.before(:hello) { this.result << self }
304
+ @simple.hello
305
+ assert_equal [self, @simple.class, @simple.class.superclass, 'hello'], @simple.result
306
+ end
307
+ end
308
+
309
+ ###
310
+
311
+ class HookableSuperClassWithAMethodInClassTest < Test::Unit::TestCase
312
+ def setup
313
+ @super_simple_class = Class.new do
314
+ include Kinda::Hookable
315
+
316
+ attr_accessor :result
317
+
318
+ def initialize
319
+ @result = []
320
+ end
321
+ end
322
+
323
+ @simple_class = Class.new(@super_simple_class) do
324
+ def hello
325
+ @result << 'hello'
326
+ end
327
+ end
328
+
329
+ @simple = @simple_class.new
330
+ end
331
+
332
+ def test_respond_to
333
+ assert @simple.respond_to?(:hello)
334
+ end
335
+
336
+ def test_before_in_superclass
337
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
338
+ @simple.hello
339
+ assert_equal ['hello'], @simple.result
340
+ end
341
+
342
+ def test_before_in_class
343
+ @simple_class.class_eval { before(:hello) { this.result << self } }
344
+ @simple.hello
345
+ assert_equal [@simple.class, 'hello'], @simple.result
346
+ end
347
+
348
+ def test_before_in_singleton_class
349
+ @simple.before(:hello) { this.result << self }
350
+ @simple.hello
351
+ assert_equal [self, 'hello'], @simple.result
352
+ end
353
+
354
+ def test_before_in_superclass_class_and_singleton_class
355
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
356
+ @simple_class.class_eval { before(:hello) { this.result << self } }
357
+ @simple.before(:hello) { this.result << self }
358
+ @simple.hello
359
+ assert_equal [self, @simple.class, @simple.class.superclass, 'hello'], @simple.result
360
+ end
361
+ end
362
+
363
+ ###
364
+
365
+ class HookableSuperClassWithAMethodInSingletonClassTest < Test::Unit::TestCase
366
+ def setup
367
+ @super_simple_class = Class.new do
368
+ include Kinda::Hookable
369
+
370
+ attr_accessor :result
371
+
372
+ def initialize
373
+ @result = []
374
+ end
375
+ end
376
+
377
+ @simple_class = Class.new(@super_simple_class)
378
+
379
+ @simple = @simple_class.new
380
+
381
+ def @simple.hello
382
+ @result << 'hello'
383
+ end
384
+ end
385
+
386
+ def test_respond_to
387
+ assert @simple.respond_to?(:hello)
388
+ end
389
+
390
+ def test_before_in_superclass
391
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
392
+ @simple.hello
393
+ assert_equal ['hello'], @simple.result
394
+ end
395
+
396
+ def test_before_in_class
397
+ @simple_class.class_eval { before(:hello) { this.result << self } }
398
+ @simple.hello
399
+ assert_equal ['hello'], @simple.result
400
+ end
401
+
402
+ def test_before_in_singleton_class
403
+ @simple.before(:hello) { this.result << self }
404
+ @simple.hello
405
+ assert_equal [self, 'hello'], @simple.result
406
+ end
407
+
408
+ def test_before_in_superclass_class_and_singleton_class
409
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
410
+ @simple_class.class_eval { before(:hello) { this.result << self } }
411
+ @simple.before(:hello) { this.result << self }
412
+ @simple.hello
413
+ assert_equal [self, @simple.class, @simple.class.superclass, 'hello'], @simple.result
414
+ end
415
+ end
416
+
417
+ ###
418
+
419
+ class HookableModuleTest < Test::Unit::TestCase
420
+ def setup
421
+ @super_simple_class = Class.new do
422
+ include Kinda::Hookable
423
+
424
+ attr_accessor :result
425
+
426
+ def initialize
427
+ @result = []
428
+ end
429
+ end
430
+
431
+ @simple_module = Module.new do
432
+ include Kinda::Hookable
433
+ end
434
+
435
+ @simple_class = Class.new(@super_simple_class)
436
+ @simple_class.send(:include, @simple_module)
437
+
438
+ @simple = @simple_class.new
439
+ end
440
+
441
+ def test_before_in_superclass
442
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
443
+ @simple.hello
444
+ assert_equal [@simple.class.superclass], @simple.result
445
+ end
446
+
447
+ def test_respond_to_with_before_in_superclass
448
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
449
+ assert @simple.respond_to?(:hello)
450
+ end
451
+
452
+ def test_before_in_module
453
+ @simple_module.module_eval { before(:hello) { this.result << self } }
454
+ @simple.hello
455
+ assert_equal [@simple_module], @simple.result
456
+ end
457
+
458
+ def test_respond_to_with_before_in_module
459
+ @simple_module.module_eval { before(:hello) { this.result << self } }
460
+ assert @simple.respond_to?(:hello)
461
+ end
462
+
463
+ def test_before_in_class
464
+ @simple_class.class_eval { before(:hello) { this.result << self } }
465
+ @simple.hello
466
+ assert_equal [@simple.class], @simple.result
467
+ end
468
+
469
+ def test_respond_to_with_before_in_class
470
+ @simple_class.class_eval { before(:hello) { this.result << self } }
471
+ assert @simple.respond_to?(:hello)
472
+ end
473
+
474
+ def test_before_in_singleton_class
475
+ @simple.before(:hello) { this.result << self }
476
+ @simple.hello
477
+ assert_equal [self], @simple.result
478
+ end
479
+
480
+ def test_before_in_superclass_class_and_singleton_class
481
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
482
+ @simple_class.class_eval { before(:hello) { this.result << self } }
483
+ @simple.before(:hello) { this.result << self }
484
+ @simple.hello
485
+ assert_equal [self, @simple.class, @simple.class.superclass], @simple.result
486
+ end
487
+ end
488
+
489
+ ###
490
+
491
+ class HookableModuleWithAMethodTest < Test::Unit::TestCase
492
+ def setup
493
+ @super_simple_class = Class.new do
494
+ include Kinda::Hookable
495
+
496
+ attr_accessor :result
497
+
498
+ def initialize
499
+ @result = []
500
+ end
501
+ end
502
+
503
+ @simple_module = Module.new do
504
+ include Kinda::Hookable
505
+
506
+ def hello
507
+ @result << 'hello'
508
+ end
509
+ end
510
+
511
+ @simple_class = Class.new(@super_simple_class)
512
+ @simple_class.send(:include, @simple_module)
513
+
514
+ @simple = @simple_class.new
515
+ end
516
+
517
+ def test_respond_to
518
+ assert @simple.respond_to?(:hello)
519
+ end
520
+
521
+ def test_before_in_superclass
522
+ @super_simple_class.class_eval { before(:hello) { this.result << self } } # not executed
523
+ @simple.hello
524
+ assert_equal ['hello'], @simple.result
525
+ end
526
+
527
+ def test_respond_to_with_before_in_superclass
528
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
529
+ assert @simple.respond_to?(:hello)
530
+ end
531
+
532
+ def test_before_in_module
533
+ @simple_module.module_eval { before(:hello) { this.result << self } }
534
+ @simple.hello
535
+ assert_equal [@simple_module, 'hello'], @simple.result
536
+ end
537
+
538
+ def test_respond_to_with_before_in_module
539
+ @simple_module.module_eval { before(:hello) { this.result << self } }
540
+ assert @simple.respond_to?(:hello)
541
+ end
542
+
543
+ def test_before_in_class
544
+ @simple_class.class_eval { before(:hello) { this.result << self } }
545
+ @simple.hello
546
+ assert_equal [@simple.class, 'hello'], @simple.result
547
+ end
548
+
549
+ def test_respond_to_with_before_in_class
550
+ @simple_class.class_eval { before(:hello) { this.result << self } }
551
+ assert @simple.respond_to?(:hello)
552
+ end
553
+
554
+ def test_before_in_singleton_class
555
+ @simple.before(:hello) { this.result << self }
556
+ @simple.hello
557
+ assert_equal [self, 'hello'], @simple.result
558
+ end
559
+
560
+ def test_before_in_superclass_class_and_singleton_class
561
+ @super_simple_class.class_eval { before(:hello) { this.result << self } }
562
+ @simple_class.class_eval { before(:hello) { this.result << self } }
563
+ @simple.before(:hello) { this.result << self }
564
+ @simple.hello
565
+ assert_equal [self, @simple.class, @simple.class.superclass, 'hello'], @simple.result
566
+ end
567
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hookable
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ platform: ruby
6
+ authors:
7
+ - Manuel Vila
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-12 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: kinda-core
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.1
24
+ version:
25
+ description: Patch any method with before, after and around hooks
26
+ email: mvila@3base.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README.rdoc
33
+ files:
34
+ - Rakefile
35
+ - lib/hookable.rb
36
+ - lib/kinda-hookable.rb
37
+ - README.rdoc
38
+ has_rdoc: true
39
+ homepage: http://github.com/kinda/hookable
40
+ licenses: []
41
+
42
+ post_install_message:
43
+ rdoc_options: []
44
+
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: 1.9.1
52
+ version:
53
+ required_rubygems_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ version:
59
+ requirements: []
60
+
61
+ rubyforge_project: kinda-hookable
62
+ rubygems_version: 1.3.5
63
+ signing_key:
64
+ specification_version: 3
65
+ summary: Patch any method with before, after and around hooks
66
+ test_files:
67
+ - test/hookable_test.rb