easy_callbacks 0.1.2 → 1.0.0
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.
- checksums.yaml +4 -4
- data/README.rdoc +97 -68
- data/easy_callbacks.gemspec +2 -1
- data/lib/easy_callbacks/all.rb +8 -0
- data/lib/easy_callbacks/dsls/target_classes_dsl.rb +77 -0
- data/lib/easy_callbacks/models/callback.rb +18 -0
- data/lib/easy_callbacks/models/target_class.rb +35 -0
- data/lib/easy_callbacks/repositories/base_repository.rb +37 -0
- data/lib/easy_callbacks/repositories/callbacks_repository.rb +44 -0
- data/lib/easy_callbacks/repositories/target_classes_repository.rb +15 -0
- data/lib/easy_callbacks/utils/serializer.rb +20 -0
- data/lib/easy_callbacks/utils/validator.rb +17 -0
- data/lib/easy_callbacks/version.rb +1 -1
- data/lib/easy_callbacks.rb +59 -7
- data/spec/lib/easy_callbacks_spec.rb +187 -0
- data/spec/lib/repositories/base_repository_spec.rb +15 -0
- data/spec/support/dummy_class.rb +160 -0
- metadata +33 -10
- data/changelog.txt +0 -13
- data/lib/easy_callbacks/base.rb +0 -117
- data/spec/lib/easy_callbacks/base_spec.rb +0 -28
- data/spec/support/some_class.rb +0 -36
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9ce7df274e4dff1affe27fa7d7b1bf71b6411c4
|
4
|
+
data.tar.gz: a55360bfebf3f88130a858cb48bfea028a5d5107
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6a48def8a8b217b9425dd879766619b74214df262a9d70db9b802ebc1a6ea43574229fb28f8fb441419eed5a7739aa63200566ebe0367214f3327a0cd93acac
|
7
|
+
data.tar.gz: 6ff374249befe64bfb279dc2c0d18134ba3f2b55de961c25cdd2c992cc39807743bcd30e12255486c0d409cb37e4e0a003b25134653fbda4a15571d34fd2f1c9
|
data/README.rdoc
CHANGED
@@ -1,115 +1,144 @@
|
|
1
1
|
= Easy Callbacks
|
2
2
|
|
3
|
-
|
3
|
+
Provides callback support for Ruby classes.
|
4
4
|
|
5
5
|
== Example
|
6
6
|
|
7
|
+
For a given class:
|
8
|
+
|
7
9
|
class SomeClass
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
11
|
+
def some_method(some_arg)
|
12
|
+
puts "some_method: #{some_arg}"
|
13
|
+
end
|
12
14
|
|
13
|
-
|
15
|
+
def before_some_method(some_arg)
|
16
|
+
puts "before_some_method: #{some_arg}"
|
17
|
+
end
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
after :some_method, :do_it_after
|
19
|
+
def around_some_method(some_arg)
|
20
|
+
puts "around_some_method: #{some_arg}"
|
21
|
+
end
|
19
22
|
|
20
|
-
|
21
|
-
before :some_method do |some_arg, callback_details|
|
22
|
-
# ...
|
23
|
-
end
|
23
|
+
end
|
24
24
|
|
25
|
-
|
26
|
-
# ...
|
27
|
-
end
|
25
|
+
EasyCallbacks.configure(SomeClass) do
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
end
|
27
|
+
# named callback
|
28
|
+
before :some_method, :before_some_method
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
# named callback
|
31
|
+
around :some_method, :around_some_method
|
32
|
+
|
33
|
+
# anonymous callback
|
34
|
+
after :some_method do
|
35
|
+
puts "after_some_method: #{call_args[0]}"
|
36
|
+
end
|
36
37
|
|
37
38
|
end
|
38
39
|
|
39
|
-
|
40
|
+
This call:
|
40
41
|
|
41
|
-
|
42
|
+
SomeClass.new.some_method :some_arg
|
42
43
|
|
43
|
-
|
44
|
+
Produces this output:
|
44
45
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
callback_name: :do_it_before,
|
50
|
-
proc: nil
|
51
|
-
}
|
46
|
+
before_some_method: hue
|
47
|
+
some_method: hue
|
48
|
+
around_some_method: hue
|
49
|
+
after_some_method: hue
|
52
50
|
|
53
|
-
|
51
|
+
== Helper Methods
|
54
52
|
|
55
|
-
|
56
|
-
class: SomeClass,
|
57
|
-
object: #<SomeClass:0x00000002b65ab0>,
|
58
|
-
target: :some_method,
|
59
|
-
type: :before,
|
60
|
-
callback_name: nil,
|
61
|
-
proc: #<Proc:0x00000002655a20@...>
|
62
|
-
}
|
53
|
+
Inside a callback block/method, you can call three helper methods:
|
63
54
|
|
64
|
-
|
55
|
+
call_args # returns original arguments given to the call
|
56
|
+
call_block # returns original block given to the call
|
57
|
+
callback_details # returns details of callback execution
|
65
58
|
|
66
|
-
|
67
|
-
class: SomeClass,
|
68
|
-
target: :some_method,
|
69
|
-
type: :around,
|
70
|
-
callback_name: :do_it_around,
|
71
|
-
proc: nil,
|
72
|
-
return_type: :success,
|
73
|
-
return_object: nil
|
74
|
-
}
|
59
|
+
=== Callback Details
|
75
60
|
|
76
|
-
|
61
|
+
The `callback_details` helper method will return:
|
77
62
|
|
78
63
|
{
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
return_type: :
|
85
|
-
return_object:
|
64
|
+
target_class: SomeClass,
|
65
|
+
callback_type: :around,
|
66
|
+
target_method_name: :some_method,
|
67
|
+
callback_method_name: :around_some_method,
|
68
|
+
callback_block: nil,
|
69
|
+
return_type: :success, # exclusive for `around` callbacks
|
70
|
+
return_object: nil # exclusive for `around` callbacks
|
86
71
|
}
|
87
72
|
|
73
|
+
== Module inclusion
|
74
|
+
|
75
|
+
You can call `before`, `around` and `after` methods directly instead of calling them inside of `EasyCallbacks.configure` block. Just include `EasyCallbacks` module:
|
76
|
+
|
77
|
+
class SomeClass
|
78
|
+
|
79
|
+
def some_method(some_arg)
|
80
|
+
puts "some_method: #{some_arg}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def before_some_method(some_arg)
|
84
|
+
puts "before_some_method: #{some_arg}"
|
85
|
+
end
|
86
|
+
|
87
|
+
def around_some_method(some_arg)
|
88
|
+
puts "around_some_method: #{some_arg}"
|
89
|
+
end
|
90
|
+
|
91
|
+
include EasyCallbacks
|
92
|
+
|
93
|
+
before :some_method, :before_some_method
|
94
|
+
|
95
|
+
around :some_method, :around_some_method
|
96
|
+
|
97
|
+
after :some_method do
|
98
|
+
puts "after_some_method: #{call_args[0]}"
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
88
103
|
== Singleton Classes Support
|
89
104
|
|
90
105
|
It works too:
|
91
106
|
|
92
107
|
class SomeClass
|
93
108
|
|
94
|
-
|
109
|
+
class << self
|
95
110
|
|
96
|
-
|
97
|
-
|
98
|
-
|
111
|
+
def some_method(some_arg)
|
112
|
+
puts "some_method: #{some_arg}"
|
113
|
+
end
|
99
114
|
|
100
|
-
|
115
|
+
def before_some_method(some_arg)
|
116
|
+
puts "before_some_method: #{some_arg}"
|
117
|
+
end
|
101
118
|
|
102
|
-
|
119
|
+
def around_some_method(some_arg)
|
120
|
+
puts "around_some_method: #{some_arg}"
|
121
|
+
end
|
103
122
|
|
123
|
+
include EasyCallbacks
|
124
|
+
|
125
|
+
before :some_method, :before_some_method
|
126
|
+
|
127
|
+
around :some_method, :around_some_method
|
128
|
+
|
129
|
+
after :some_method do
|
130
|
+
puts "after_some_method: #{call_args[0]}"
|
104
131
|
end
|
105
132
|
|
133
|
+
end
|
134
|
+
|
106
135
|
end
|
107
136
|
|
108
|
-
SomeClass.some_method
|
137
|
+
SomeClass.some_method :hue
|
109
138
|
|
110
|
-
==
|
139
|
+
== More
|
111
140
|
|
112
|
-
|
141
|
+
To see more of `EasyCallbacks` usages, please take a look at DummyClass[https://github.com/r4z3c/easy_callbacks/blob/master/spec/support/dummy_class.rb].
|
113
142
|
|
114
143
|
===
|
115
144
|
|
data/easy_callbacks.gemspec
CHANGED
@@ -19,9 +19,10 @@ Gem::Specification.new do |s|
|
|
19
19
|
|
20
20
|
s.add_dependency 'bundler', '~>1'
|
21
21
|
s.add_dependency 'activesupport', '~>4'
|
22
|
-
s.add_dependency 'method_decorator', '~>1'
|
22
|
+
s.add_dependency 'method_decorator', '~>3.0.1'
|
23
23
|
|
24
24
|
s.add_development_dependency 'rspec', '~>3'
|
25
25
|
s.add_development_dependency 'simplecov', '~>0'
|
26
26
|
s.add_development_dependency 'model-builder', '~>2'
|
27
|
+
s.add_development_dependency 'rake'
|
27
28
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'easy_callbacks/models/target_class'
|
2
|
+
require 'easy_callbacks/models/callback'
|
3
|
+
require 'easy_callbacks/repositories/base_repository'
|
4
|
+
require 'easy_callbacks/repositories/target_classes_repository'
|
5
|
+
require 'easy_callbacks/repositories/callbacks_repository'
|
6
|
+
require 'easy_callbacks/dsls/target_classes_dsl'
|
7
|
+
require 'easy_callbacks/utils/validator'
|
8
|
+
require 'easy_callbacks/utils/serializer'
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'method_decorator'
|
2
|
+
|
3
|
+
module EasyCallbacks
|
4
|
+
module Dsls
|
5
|
+
|
6
|
+
class TargetClassesDsl
|
7
|
+
|
8
|
+
attr_accessor :target_class_instance
|
9
|
+
|
10
|
+
def initialize(target_class_instance)
|
11
|
+
self.target_class_instance = target_class_instance
|
12
|
+
end
|
13
|
+
|
14
|
+
def before(target_method_name, callback_method_name=nil, &callback_block)
|
15
|
+
handle_callback_definition :before, target_method_name, callback_method_name, &callback_block
|
16
|
+
end
|
17
|
+
|
18
|
+
def around(target_method_name, callback_method_name=nil, &callback_block)
|
19
|
+
handle_callback_definition :around, target_method_name, callback_method_name, &callback_block
|
20
|
+
end
|
21
|
+
|
22
|
+
def after(target_method_name, callback_method_name=nil, &callback_block)
|
23
|
+
handle_callback_definition :after, target_method_name, callback_method_name, &callback_block
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
|
28
|
+
def handle_callback_definition(callback_type, target_method_name, callback_method_name, &callback_block)
|
29
|
+
push_callback callback_type, target_method_name, callback_method_name, &callback_block
|
30
|
+
decorate_method target_method_name
|
31
|
+
end
|
32
|
+
|
33
|
+
def push_callback(callback_type, target_method_name, callback_method_name, &callback_block)
|
34
|
+
target_class_instance.add_callback callback_type, target_method_name, callback_method_name, &callback_block
|
35
|
+
end
|
36
|
+
|
37
|
+
def decorate_method(target_method_name)
|
38
|
+
tci = target_class_instance
|
39
|
+
MethodDecorator.decorate target_class_instance.target_class, target_method_name do
|
40
|
+
EasyCallbacks.execute_callbacks self, tci, :before, target_method_name, nil, call_args, &call_block
|
41
|
+
|
42
|
+
result = error = nil
|
43
|
+
begin
|
44
|
+
result = call_original
|
45
|
+
rescue => e
|
46
|
+
error = e
|
47
|
+
end
|
48
|
+
|
49
|
+
additional_options = error ?
|
50
|
+
{ return_type: :error, return_object: error } :
|
51
|
+
{ return_type: :success, return_object: result }
|
52
|
+
|
53
|
+
EasyCallbacks.execute_callbacks self, tci, :around, target_method_name, additional_options, call_args, &call_block
|
54
|
+
|
55
|
+
raise error if error
|
56
|
+
|
57
|
+
EasyCallbacks.execute_callbacks self, tci, :after, target_method_name, nil, call_args, &call_block
|
58
|
+
|
59
|
+
result
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def target_class_instance=(target_class_instance)
|
64
|
+
validate_target_class_instance target_class_instance
|
65
|
+
@target_class_instance = target_class_instance
|
66
|
+
end
|
67
|
+
|
68
|
+
def validate_target_class_instance(target_class_instance)
|
69
|
+
Utils::Validator.validate_instance_type! :target_class_instance,
|
70
|
+
target_class_instance,
|
71
|
+
Models::TargetClass
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module EasyCallbacks
|
2
|
+
module Models
|
3
|
+
|
4
|
+
class Callback
|
5
|
+
|
6
|
+
attr_accessor :callback_type, :target_method_name, :callback_method_name, :callback_block
|
7
|
+
|
8
|
+
def initialize(callback_type, target_method_name, callback_method_name)
|
9
|
+
self.callback_type = callback_type
|
10
|
+
self.target_method_name = target_method_name
|
11
|
+
self.callback_method_name = callback_method_name
|
12
|
+
self.callback_block = block_given? ? Proc.new : nil
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module EasyCallbacks
|
2
|
+
module Models
|
3
|
+
|
4
|
+
class TargetClass
|
5
|
+
|
6
|
+
attr_accessor :target_class, :callbacks_repository
|
7
|
+
|
8
|
+
def initialize(target_class)
|
9
|
+
self.target_class = target_class
|
10
|
+
self.callbacks_repository = ::EasyCallbacks::Repositories::CallbacksRepository.new self
|
11
|
+
end
|
12
|
+
|
13
|
+
def add_callback(callback_type, target_method_name, callback_method_name, &callback_block)
|
14
|
+
callbacks_repository.find_or_add callback_type, target_method_name, callback_method_name, &callback_block
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_callbacks_for(callback_type, target_method_name)
|
18
|
+
callbacks_repository.get_callbacks_for callback_type, target_method_name
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def target_class=(target_class)
|
24
|
+
validate_target_class target_class
|
25
|
+
@target_class = target_class
|
26
|
+
end
|
27
|
+
|
28
|
+
def validate_target_class(target_class)
|
29
|
+
Utils::Validator.validate_instance_type! :target_class, target_class, Class
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module EasyCallbacks
|
2
|
+
module Repositories
|
3
|
+
|
4
|
+
class BaseRepository
|
5
|
+
|
6
|
+
attr_accessor :list
|
7
|
+
|
8
|
+
def initialize(*args); self.list = [] end
|
9
|
+
|
10
|
+
def find_or_add(*args, &block); find(*args) || add(*args, &block) end
|
11
|
+
|
12
|
+
def add(*args, &block)
|
13
|
+
unless exists? *args
|
14
|
+
model_instance = block_given? ? model.new(*args, &block) : model.new(*args)
|
15
|
+
self.list.push(model_instance)
|
16
|
+
model_instance
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def exists?(*args); not find(*args).nil? end
|
21
|
+
|
22
|
+
def find(*args); list.find &find_block(*args) end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def find_block(*args)
|
27
|
+
raise NotImplementedError.new("find_block@#{self.class} must overwrite find_block@#{self.class.superclass}")
|
28
|
+
end
|
29
|
+
|
30
|
+
def model
|
31
|
+
raise NotImplementedError.new("model@#{self.class} must overwrite model@#{self.class.superclass}")
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module EasyCallbacks
|
2
|
+
module Repositories
|
3
|
+
|
4
|
+
class CallbacksRepository < BaseRepository
|
5
|
+
|
6
|
+
attr_accessor :target_class_instance
|
7
|
+
|
8
|
+
def initialize(target_class_instance)
|
9
|
+
super
|
10
|
+
self.target_class_instance = target_class_instance
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_callbacks_for(callback_type, target_method_name)
|
14
|
+
list.select do |c|
|
15
|
+
c.callback_type.eql?(callback_type) and
|
16
|
+
c.target_method_name.eql?(target_method_name)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def find_block(callback_type, target_method_name, callback_method_name)
|
23
|
+
Proc.new do |item|
|
24
|
+
item.callback_type.eql? callback_type and
|
25
|
+
item.target_method_name.eql? target_method_name and
|
26
|
+
item.callback_method_name.eql? callback_method_name
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def model; Models::Callback end
|
31
|
+
|
32
|
+
def target_class_instance=(target_class_instance)
|
33
|
+
validate_target_class_instance target_class_instance
|
34
|
+
@target_class_instance = target_class_instance
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_target_class_instance(target_class_instance)
|
38
|
+
Utils::Validator.validate_instance_type! :target_class_instance, target_class_instance, Models::TargetClass
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module EasyCallbacks
|
2
|
+
module Repositories
|
3
|
+
|
4
|
+
class TargetClassesRepository < BaseRepository
|
5
|
+
|
6
|
+
protected
|
7
|
+
|
8
|
+
def find_block(target_class); Proc.new { |item| item.target_class.eql? target_class } end
|
9
|
+
|
10
|
+
def model; Models::TargetClass end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module EasyCallbacks
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
class Serializer
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def to_h(object, attrs=[])
|
9
|
+
attrs = [attrs] unless attrs.is_a? Array
|
10
|
+
hash = {}
|
11
|
+
attrs.each { |k| hash[k.to_sym] = object.send k }
|
12
|
+
hash
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module EasyCallbacks
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
class Validator
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def validate_instance_type!(attribute_name, instance, desired_type)
|
9
|
+
raise TypeError.new("#{attribute_name} must be a #{desired_type}") unless instance.is_a? desired_type
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/easy_callbacks.rb
CHANGED
@@ -1,17 +1,69 @@
|
|
1
|
-
|
1
|
+
require 'easy_callbacks/all'
|
2
|
+
require 'active_support/concern'
|
2
3
|
|
3
|
-
|
4
|
+
module EasyCallbacks extend ActiveSupport::Concern
|
4
5
|
|
5
|
-
|
6
|
+
included do
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def before(target_method_name, callback_method_name=nil, &callback_block)
|
11
|
+
handle_callback_definition :before, target_method_name, callback_method_name, &callback_block
|
12
|
+
end
|
6
13
|
|
7
|
-
|
8
|
-
|
9
|
-
require file
|
14
|
+
def around(target_method_name, callback_method_name=nil, &callback_block)
|
15
|
+
handle_callback_definition :around, target_method_name, callback_method_name, &callback_block
|
10
16
|
end
|
17
|
+
|
18
|
+
def after(target_method_name, callback_method_name=nil, &callback_block)
|
19
|
+
handle_callback_definition :after, target_method_name, callback_method_name, &callback_block
|
20
|
+
end
|
21
|
+
|
22
|
+
def handle_callback_definition(callback_type, target_method_name, callback_method_name, &callback_block)
|
23
|
+
EasyCallbacks.configure(self) { send callback_type, target_method_name, callback_method_name, &callback_block }
|
24
|
+
end
|
25
|
+
|
11
26
|
end
|
12
27
|
|
13
28
|
end
|
14
29
|
|
15
|
-
|
30
|
+
class << self
|
31
|
+
|
32
|
+
attr_writer :target_classes_repository
|
33
|
+
|
34
|
+
def configure(target_class, &cfg_block)
|
35
|
+
target_class_instance = target_classes_repository.find_or_add target_class
|
36
|
+
Dsls::TargetClassesDsl.new(target_class_instance).instance_eval &cfg_block
|
37
|
+
end
|
38
|
+
|
39
|
+
def execute_callbacks(context, target_class_instance, callback_type, target_method_name, additional_options, call_args, &call_block)
|
40
|
+
validate_target_class_instance target_class_instance
|
41
|
+
target_class_instance.get_callbacks_for(callback_type, target_method_name).each do |callback|
|
42
|
+
define_callback_details_method additional_options, callback, target_class_instance
|
43
|
+
proc = callback.callback_block
|
44
|
+
proc.nil? ? context.send(callback.callback_method_name, *call_args, &call_block) : context.instance_eval(&proc)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def define_callback_details_method(additional_options, callback, target_class_instance)
|
49
|
+
target_class_instance.target_class.send :define_method, :callback_details do
|
50
|
+
callback_details = Utils::Serializer.to_h(
|
51
|
+
callback, %w(callback_type target_method_name callback_method_name callback_block)
|
52
|
+
).merge(target_class: target_class_instance.target_class)
|
53
|
+
additional_options ? callback_details.merge(additional_options) : callback_details
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def validate_target_class_instance(target_class_instance)
|
60
|
+
Utils::Validator.validate_instance_type! :target_class_instance, target_class_instance, Models::TargetClass
|
61
|
+
end
|
62
|
+
|
63
|
+
def target_classes_repository
|
64
|
+
@target_classes_repository ||= Repositories::TargetClassesRepository.new
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
16
68
|
|
17
69
|
end
|
@@ -0,0 +1,187 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/dummy_class'
|
3
|
+
|
4
|
+
describe EasyCallbacks do
|
5
|
+
|
6
|
+
let(:dummy_arg) { :dummy_arg }
|
7
|
+
|
8
|
+
context 'when common class as target' do
|
9
|
+
|
10
|
+
let(:target) { DummyClass }
|
11
|
+
let(:target_instance) { target.new }
|
12
|
+
|
13
|
+
context 'when public method' do
|
14
|
+
|
15
|
+
context 'when through module singleton method' do
|
16
|
+
|
17
|
+
before do
|
18
|
+
expect(target_instance).to receive(:puts).with("before_a_public_instance_method_with: #{[dummy_arg]}").ordered
|
19
|
+
expect(target_instance).to receive(:puts).with("a_public_instance_method_arg: #{dummy_arg}").ordered
|
20
|
+
expect(target_instance).to receive(:puts).with("around_a_public_instance_method_with: #{[dummy_arg]}").ordered
|
21
|
+
expect(target_instance).to receive(:puts).with("after_a_public_instance_method_with: #{[dummy_arg]}").ordered
|
22
|
+
end
|
23
|
+
|
24
|
+
it { target_instance.a_public_instance_method dummy_arg }
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'when through module inclusion' do
|
29
|
+
|
30
|
+
before do
|
31
|
+
expect(target_instance).to receive(:puts).with("before_another_public_instance_method_with: #{[dummy_arg]}").ordered
|
32
|
+
expect(target_instance).to receive(:puts).with("another_public_instance_method_arg: #{dummy_arg}").ordered
|
33
|
+
expect(target_instance).to receive(:puts).with("around_another_public_instance_method_with: #{[dummy_arg]}").ordered
|
34
|
+
expect(target_instance).to receive(:puts).with("after_another_public_instance_method_with: #{[dummy_arg]}").ordered
|
35
|
+
end
|
36
|
+
|
37
|
+
it { target_instance.another_public_instance_method dummy_arg }
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'when protected method' do
|
44
|
+
|
45
|
+
context 'when calling protected method deliberately' do
|
46
|
+
|
47
|
+
it { expect{target_instance.a_protected_instance_method dummy_arg}.to raise_error NoMethodError }
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'when calling protected method through `send`' do
|
52
|
+
|
53
|
+
before do
|
54
|
+
expect(target_instance).to receive(:puts).with("before_a_protected_instance_method_with: #{[dummy_arg]}").ordered
|
55
|
+
expect(target_instance).to receive(:puts).with("a_protected_instance_method_arg: #{dummy_arg}").ordered
|
56
|
+
expect(target_instance).to receive(:puts).with("around_a_protected_instance_method_with: #{[dummy_arg]}").ordered
|
57
|
+
expect(target_instance).to receive(:puts).with("after_a_protected_instance_method_with: #{[dummy_arg]}").ordered
|
58
|
+
end
|
59
|
+
|
60
|
+
it { target_instance.send :a_protected_instance_method, dummy_arg }
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'when private method' do
|
67
|
+
|
68
|
+
context 'when calling private method deliberately' do
|
69
|
+
|
70
|
+
it { expect{target_instance.a_private_instance_method dummy_arg}.to raise_error NoMethodError }
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'when calling private method through `send`' do
|
75
|
+
|
76
|
+
before do
|
77
|
+
expect(target_instance).to receive(:puts).with("before_a_private_instance_method_with: #{[dummy_arg]}").ordered
|
78
|
+
expect(target_instance).to receive(:puts).with("a_private_instance_method_arg: #{dummy_arg}").ordered
|
79
|
+
expect(target_instance).to receive(:puts).with("around_a_private_instance_method_with: #{[dummy_arg]}").ordered
|
80
|
+
expect(target_instance).to receive(:puts).with("after_a_private_instance_method_with: #{[dummy_arg]}").ordered
|
81
|
+
end
|
82
|
+
|
83
|
+
it { target_instance.send :a_private_instance_method, dummy_arg }
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'when dealing with around callback error' do
|
90
|
+
|
91
|
+
let(:error_msg) { 'some runtime error' }
|
92
|
+
|
93
|
+
before do
|
94
|
+
expect(target_instance).to receive(:puts).with("a_public_instance_method_with_error_arg: #{dummy_arg}").ordered
|
95
|
+
expect(target_instance).to receive(:puts).with("around_a_public_instance_method_with_error: #{error_msg}").ordered
|
96
|
+
end
|
97
|
+
|
98
|
+
it { expect{target_instance.a_public_instance_method_with_error dummy_arg}.to raise_error(RuntimeError, error_msg) }
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'when singleton class as target' do
|
105
|
+
|
106
|
+
let(:target) { DummyClass.singleton_class }
|
107
|
+
let(:target_instance) { DummyClass }
|
108
|
+
|
109
|
+
context 'when public method' do
|
110
|
+
|
111
|
+
context 'when through module singleton method' do
|
112
|
+
|
113
|
+
before do
|
114
|
+
expect(target_instance).to receive(:puts).with("before_a_public_singleton_method_with: #{[dummy_arg]}").ordered
|
115
|
+
expect(target_instance).to receive(:puts).with("a_public_singleton_method_arg: #{dummy_arg}").ordered
|
116
|
+
expect(target_instance).to receive(:puts).with("around_a_public_singleton_method_with: #{[dummy_arg]}").ordered
|
117
|
+
expect(target_instance).to receive(:puts).with("after_a_public_singleton_method_with: #{[dummy_arg]}").ordered
|
118
|
+
end
|
119
|
+
|
120
|
+
it { target_instance.a_public_singleton_method dummy_arg }
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'when through module inclusion' do
|
125
|
+
|
126
|
+
before do
|
127
|
+
expect(target_instance).to receive(:puts).with("before_another_public_singleton_method_with: #{[dummy_arg]}").ordered
|
128
|
+
expect(target_instance).to receive(:puts).with("another_public_singleton_method_arg: #{dummy_arg}").ordered
|
129
|
+
expect(target_instance).to receive(:puts).with("around_another_public_singleton_method_with: #{[dummy_arg]}").ordered
|
130
|
+
expect(target_instance).to receive(:puts).with("after_another_public_singleton_method_with: #{[dummy_arg]}").ordered
|
131
|
+
end
|
132
|
+
|
133
|
+
it { target_instance.another_public_singleton_method dummy_arg }
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
context 'when protected method' do
|
140
|
+
|
141
|
+
context 'when calling protected method deliberately' do
|
142
|
+
|
143
|
+
it { expect{target_instance.a_protected_singleton_method dummy_arg}.to raise_error NoMethodError }
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
context 'when calling protected method through `send`' do
|
148
|
+
|
149
|
+
before do
|
150
|
+
expect(target_instance).to receive(:puts).with("before_a_protected_singleton_method_with: #{[dummy_arg]}").ordered
|
151
|
+
expect(target_instance).to receive(:puts).with("a_protected_singleton_method_arg: #{dummy_arg}").ordered
|
152
|
+
expect(target_instance).to receive(:puts).with("around_a_protected_singleton_method_with: #{[dummy_arg]}").ordered
|
153
|
+
expect(target_instance).to receive(:puts).with("after_a_protected_singleton_method_with: #{[dummy_arg]}").ordered
|
154
|
+
end
|
155
|
+
|
156
|
+
it { target_instance.send :a_protected_singleton_method, dummy_arg }
|
157
|
+
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
context 'when private method' do
|
163
|
+
|
164
|
+
context 'when calling private method deliberately' do
|
165
|
+
|
166
|
+
it { expect{target_instance.a_private_singleton_method dummy_arg}.to raise_error NoMethodError }
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'when calling private method through `send`' do
|
171
|
+
|
172
|
+
before do
|
173
|
+
expect(target_instance).to receive(:puts).with("before_a_private_singleton_method_with: #{[dummy_arg]}").ordered
|
174
|
+
expect(target_instance).to receive(:puts).with("a_private_singleton_method_arg: #{dummy_arg}").ordered
|
175
|
+
expect(target_instance).to receive(:puts).with("around_a_private_singleton_method_with: #{[dummy_arg]}").ordered
|
176
|
+
expect(target_instance).to receive(:puts).with("after_a_private_singleton_method_with: #{[dummy_arg]}").ordered
|
177
|
+
end
|
178
|
+
|
179
|
+
it { target_instance.send :a_private_singleton_method, dummy_arg }
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
base_repository = EasyCallbacks::Repositories::BaseRepository
|
4
|
+
|
5
|
+
describe base_repository do
|
6
|
+
|
7
|
+
it 'must override base repository `find_block` method' do
|
8
|
+
expect{base_repository.new.send :find_block }.to raise_error(NotImplementedError)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'must override base repository `model` method' do
|
12
|
+
expect{base_repository.new.send :model }.to raise_error(NotImplementedError)
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
class DummyClass
|
2
|
+
|
3
|
+
def a_public_instance_method(arg)
|
4
|
+
puts "a_public_instance_method_arg: #{arg}"
|
5
|
+
end
|
6
|
+
|
7
|
+
def another_public_instance_method(arg)
|
8
|
+
puts "another_public_instance_method_arg: #{arg}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def a_public_instance_method_with_error(arg)
|
12
|
+
puts "a_public_instance_method_with_error_arg: #{arg}"
|
13
|
+
raise 'some runtime error'
|
14
|
+
end
|
15
|
+
|
16
|
+
protected
|
17
|
+
|
18
|
+
def a_protected_instance_method(arg)
|
19
|
+
puts "a_protected_instance_method_arg: #{arg}"
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def a_private_instance_method(arg)
|
25
|
+
puts "a_private_instance_method_arg: #{arg}"
|
26
|
+
end
|
27
|
+
|
28
|
+
class << self
|
29
|
+
|
30
|
+
def a_public_singleton_method(arg)
|
31
|
+
puts "a_public_singleton_method_arg: #{arg}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def another_public_singleton_method(arg)
|
35
|
+
puts "another_public_singleton_method_arg: #{arg}"
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def a_protected_singleton_method(arg)
|
41
|
+
puts "a_protected_singleton_method_arg: #{arg}"
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def a_private_singleton_method(arg)
|
47
|
+
puts "a_private_singleton_method_arg: #{arg}"
|
48
|
+
end
|
49
|
+
|
50
|
+
include EasyCallbacks
|
51
|
+
|
52
|
+
before :another_public_singleton_method do
|
53
|
+
puts "before_another_public_singleton_method_with: #{call_args}"
|
54
|
+
end
|
55
|
+
|
56
|
+
around :another_public_singleton_method do
|
57
|
+
puts "around_another_public_singleton_method_with: #{call_args}"
|
58
|
+
end
|
59
|
+
|
60
|
+
after :another_public_singleton_method do
|
61
|
+
puts "after_another_public_singleton_method_with: #{call_args}"
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
include EasyCallbacks
|
67
|
+
|
68
|
+
before :another_public_instance_method do
|
69
|
+
puts "before_another_public_instance_method_with: #{call_args}"
|
70
|
+
end
|
71
|
+
|
72
|
+
around :another_public_instance_method do
|
73
|
+
puts "around_another_public_instance_method_with: #{call_args}"
|
74
|
+
end
|
75
|
+
|
76
|
+
after :another_public_instance_method do
|
77
|
+
puts "after_another_public_instance_method_with: #{call_args}"
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
EasyCallbacks.configure(DummyClass) do
|
83
|
+
before :a_public_instance_method do
|
84
|
+
puts "before_a_public_instance_method_with: #{call_args}"
|
85
|
+
end
|
86
|
+
|
87
|
+
around :a_public_instance_method do
|
88
|
+
puts "around_a_public_instance_method_with: #{call_args}"
|
89
|
+
end
|
90
|
+
|
91
|
+
after :a_public_instance_method do
|
92
|
+
puts "after_a_public_instance_method_with: #{call_args}"
|
93
|
+
end
|
94
|
+
|
95
|
+
before :a_protected_instance_method do
|
96
|
+
puts "before_a_protected_instance_method_with: #{call_args}"
|
97
|
+
end
|
98
|
+
|
99
|
+
around :a_protected_instance_method do
|
100
|
+
puts "around_a_protected_instance_method_with: #{call_args}"
|
101
|
+
end
|
102
|
+
|
103
|
+
after :a_protected_instance_method do
|
104
|
+
puts "after_a_protected_instance_method_with: #{call_args}"
|
105
|
+
end
|
106
|
+
|
107
|
+
before :a_private_instance_method do
|
108
|
+
puts "before_a_private_instance_method_with: #{call_args}"
|
109
|
+
end
|
110
|
+
|
111
|
+
around :a_private_instance_method do
|
112
|
+
puts "around_a_private_instance_method_with: #{call_args}"
|
113
|
+
end
|
114
|
+
|
115
|
+
after :a_private_instance_method do
|
116
|
+
puts "after_a_private_instance_method_with: #{call_args}"
|
117
|
+
end
|
118
|
+
|
119
|
+
around :a_public_instance_method_with_error do
|
120
|
+
puts "around_a_public_instance_method_with_error: #{callback_details[:return_object]}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
EasyCallbacks.configure(DummyClass.singleton_class) do
|
125
|
+
before :a_public_singleton_method do
|
126
|
+
puts "before_a_public_singleton_method_with: #{call_args}"
|
127
|
+
end
|
128
|
+
|
129
|
+
around :a_public_singleton_method do
|
130
|
+
puts "around_a_public_singleton_method_with: #{call_args}"
|
131
|
+
end
|
132
|
+
|
133
|
+
after :a_public_singleton_method do
|
134
|
+
puts "after_a_public_singleton_method_with: #{call_args}"
|
135
|
+
end
|
136
|
+
|
137
|
+
before :a_protected_singleton_method do
|
138
|
+
puts "before_a_protected_singleton_method_with: #{call_args}"
|
139
|
+
end
|
140
|
+
|
141
|
+
around :a_protected_singleton_method do
|
142
|
+
puts "around_a_protected_singleton_method_with: #{call_args}"
|
143
|
+
end
|
144
|
+
|
145
|
+
after :a_protected_singleton_method do
|
146
|
+
puts "after_a_protected_singleton_method_with: #{call_args}"
|
147
|
+
end
|
148
|
+
|
149
|
+
before :a_private_singleton_method do
|
150
|
+
puts "before_a_private_singleton_method_with: #{call_args}"
|
151
|
+
end
|
152
|
+
|
153
|
+
around :a_private_singleton_method do
|
154
|
+
puts "around_a_private_singleton_method_with: #{call_args}"
|
155
|
+
end
|
156
|
+
|
157
|
+
after :a_private_singleton_method do
|
158
|
+
puts "after_a_private_singleton_method_with: #{call_args}"
|
159
|
+
end
|
160
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: easy_callbacks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- r4z3c
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 3.0.1
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 3.0.1
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '2'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
description: Provide callbacks support for Ruby classes
|
98
112
|
email:
|
99
113
|
- r4z3c.43@gmail.com
|
@@ -107,14 +121,22 @@ files:
|
|
107
121
|
- MIT-LICENSE
|
108
122
|
- README.rdoc
|
109
123
|
- Rakefile
|
110
|
-
- changelog.txt
|
111
124
|
- easy_callbacks.gemspec
|
112
125
|
- lib/easy_callbacks.rb
|
113
|
-
- lib/easy_callbacks/
|
126
|
+
- lib/easy_callbacks/all.rb
|
127
|
+
- lib/easy_callbacks/dsls/target_classes_dsl.rb
|
128
|
+
- lib/easy_callbacks/models/callback.rb
|
129
|
+
- lib/easy_callbacks/models/target_class.rb
|
130
|
+
- lib/easy_callbacks/repositories/base_repository.rb
|
131
|
+
- lib/easy_callbacks/repositories/callbacks_repository.rb
|
132
|
+
- lib/easy_callbacks/repositories/target_classes_repository.rb
|
133
|
+
- lib/easy_callbacks/utils/serializer.rb
|
134
|
+
- lib/easy_callbacks/utils/validator.rb
|
114
135
|
- lib/easy_callbacks/version.rb
|
115
|
-
- spec/lib/
|
136
|
+
- spec/lib/easy_callbacks_spec.rb
|
137
|
+
- spec/lib/repositories/base_repository_spec.rb
|
116
138
|
- spec/spec_helper.rb
|
117
|
-
- spec/support/
|
139
|
+
- spec/support/dummy_class.rb
|
118
140
|
homepage: https://github.com/r4z3c/easy_callbacks.git
|
119
141
|
licenses:
|
120
142
|
- MIT
|
@@ -140,6 +162,7 @@ signing_key:
|
|
140
162
|
specification_version: 4
|
141
163
|
summary: Set callbacks for Ruby class methods
|
142
164
|
test_files:
|
143
|
-
- spec/lib/
|
165
|
+
- spec/lib/easy_callbacks_spec.rb
|
166
|
+
- spec/lib/repositories/base_repository_spec.rb
|
144
167
|
- spec/spec_helper.rb
|
145
|
-
- spec/support/
|
168
|
+
- spec/support/dummy_class.rb
|
data/changelog.txt
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# 0.1.2
|
2
|
-
|
3
|
-
- setting 'execute_callbacks_for' (and related methods) as private
|
4
|
-
|
5
|
-
# 0.1.1
|
6
|
-
|
7
|
-
- fixing callbacks initialization bug: when trying to 'execute_callbacks_for' for a type (e.g. 'before') that doesn't
|
8
|
-
received pushes, it crashes by trying call 'select' to a nil object
|
9
|
-
|
10
|
-
# 0.1.0
|
11
|
-
|
12
|
-
- adding 'object' key to 'callback_details' providing context to anonymous callbacks
|
13
|
-
- removing 'method_missing' strategy from base module, this isn't strictly necessary
|
data/lib/easy_callbacks/base.rb
DELETED
@@ -1,117 +0,0 @@
|
|
1
|
-
require 'method_decorator'
|
2
|
-
|
3
|
-
module EasyCallbacks
|
4
|
-
module Base extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
included do
|
7
|
-
|
8
|
-
include MethodDecorator
|
9
|
-
|
10
|
-
class << self
|
11
|
-
|
12
|
-
attr_accessor :callbacks
|
13
|
-
|
14
|
-
def before(target, callback_name=nil, &block)
|
15
|
-
handle_callback_definition :before, target, callback_name, &block
|
16
|
-
end
|
17
|
-
|
18
|
-
def around(target, callback_name=nil, &block)
|
19
|
-
handle_callback_definition :around, target, callback_name, &block
|
20
|
-
end
|
21
|
-
|
22
|
-
def after(target, callback_name=nil, &block)
|
23
|
-
handle_callback_definition :after, target, callback_name, &block
|
24
|
-
end
|
25
|
-
|
26
|
-
private
|
27
|
-
|
28
|
-
def handle_callback_definition(type, target, callback_name, &block)
|
29
|
-
push_callback type, target, callback_name, &block
|
30
|
-
decorate_target target
|
31
|
-
end
|
32
|
-
|
33
|
-
def push_callback(type, target, callback_name)
|
34
|
-
initialize_callbacks
|
35
|
-
self.callbacks[type].push target: target,
|
36
|
-
callback_name: callback_name,
|
37
|
-
proc: (block_given? ? Proc.new : nil)
|
38
|
-
end
|
39
|
-
|
40
|
-
def initialize_callbacks
|
41
|
-
self.callbacks ||= {}
|
42
|
-
self.callbacks[:before] ||= []
|
43
|
-
self.callbacks[:around] ||= []
|
44
|
-
self.callbacks[:after] ||= []
|
45
|
-
end
|
46
|
-
|
47
|
-
def decorate_target(target)
|
48
|
-
decorate_method target do |*args, &block|
|
49
|
-
execute_callbacks_for :before, target, nil, *args, &block
|
50
|
-
result, error = execute_original_method target, *args, &block
|
51
|
-
|
52
|
-
additional_options = error ?
|
53
|
-
{ return_type: :error, return_object: error } :
|
54
|
-
{ return_type: :success, return_object: result }
|
55
|
-
|
56
|
-
execute_callbacks_for :around, target, additional_options, *args, &block
|
57
|
-
|
58
|
-
raise error if error
|
59
|
-
|
60
|
-
execute_callbacks_for :after, target, nil, *args, &block
|
61
|
-
|
62
|
-
result
|
63
|
-
end unless method_defined? original_method_name_for(target)
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
private
|
69
|
-
|
70
|
-
def execute_callbacks_for(type, target, additional_options, *args, &block)
|
71
|
-
get_callbacks_for(type).select { |c| c[:target].eql? target }.each do |callback|
|
72
|
-
cn = callback[:callback_name]
|
73
|
-
proc = callback[:proc]
|
74
|
-
t = callback[:target]
|
75
|
-
arguments = args + [
|
76
|
-
class: callbacks_holder,
|
77
|
-
target: t,
|
78
|
-
type: type,
|
79
|
-
callback_name: cn,
|
80
|
-
proc: proc
|
81
|
-
];
|
82
|
-
|
83
|
-
arguments.last.merge! additional_options if additional_options
|
84
|
-
|
85
|
-
if proc.nil?
|
86
|
-
send(cn, *arguments, &block)
|
87
|
-
else
|
88
|
-
arguments.last.merge! object: self
|
89
|
-
proc.call(*arguments, &block)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
def get_callbacks_for(type)
|
95
|
-
callbacks_holder.callbacks[type]
|
96
|
-
end
|
97
|
-
|
98
|
-
def callbacks_holder
|
99
|
-
self.class.eql?(Class) ? self.singleton_class : self.class
|
100
|
-
end
|
101
|
-
|
102
|
-
def execute_original_method(target, *args, &block)
|
103
|
-
result = error = nil
|
104
|
-
|
105
|
-
begin
|
106
|
-
result = call_original_method target, *args, &block
|
107
|
-
rescue => e
|
108
|
-
error = e
|
109
|
-
end
|
110
|
-
|
111
|
-
return result, error
|
112
|
-
end
|
113
|
-
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'support/some_class'
|
3
|
-
|
4
|
-
describe EasyCallbacks::Base do
|
5
|
-
|
6
|
-
let(:instance) { SomeClass.new }
|
7
|
-
|
8
|
-
it do
|
9
|
-
expect_instance_for_puts_with('before_1: some_arg')
|
10
|
-
expect_class_for_puts_with('before_2: some_arg')
|
11
|
-
expect_instance_for_puts_with('some_method: some_arg')
|
12
|
-
expect_instance_for_puts_with('around_1: some_arg')
|
13
|
-
expect_class_for_puts_with('around_2: some_arg')
|
14
|
-
expect_instance_for_puts_with('after_1: some_arg')
|
15
|
-
expect_class_for_puts_with('after_2: some_arg')
|
16
|
-
|
17
|
-
instance.some_method(:some_arg)
|
18
|
-
end
|
19
|
-
|
20
|
-
def expect_instance_for_puts_with(expected)
|
21
|
-
expect(instance).to receive(:puts).with(expected).ordered
|
22
|
-
end
|
23
|
-
|
24
|
-
def expect_class_for_puts_with(expected)
|
25
|
-
expect(SomeClass).to receive(:puts).with(expected).ordered
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
data/spec/support/some_class.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
class SomeClass
|
2
|
-
|
3
|
-
def some_method(some_arg)
|
4
|
-
puts "some_method: #{some_arg}"
|
5
|
-
end
|
6
|
-
|
7
|
-
include EasyCallbacks::Base
|
8
|
-
|
9
|
-
before :some_method, :before_1
|
10
|
-
before :some_method do |some_arg, callback_details|
|
11
|
-
puts "before_2: #{some_arg}"
|
12
|
-
end
|
13
|
-
|
14
|
-
around :some_method, :around_1
|
15
|
-
around :some_method do |some_arg, callback_details|
|
16
|
-
puts "around_2: #{some_arg}"
|
17
|
-
end
|
18
|
-
|
19
|
-
after :some_method, :after_1
|
20
|
-
after :some_method do |some_arg, callback_details|
|
21
|
-
puts "after_2: #{some_arg}"
|
22
|
-
end
|
23
|
-
|
24
|
-
def before_1(some_arg, callback_details)
|
25
|
-
puts "before_1: #{some_arg}"
|
26
|
-
end
|
27
|
-
|
28
|
-
def around_1(some_arg, callback_details)
|
29
|
-
puts "around_1: #{some_arg}"
|
30
|
-
end
|
31
|
-
|
32
|
-
def after_1(some_arg, callback_details)
|
33
|
-
puts "after_1: #{some_arg}"
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|