aspector 0.13.1 → 0.14.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 +7 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +26 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +8 -11
- data/Changelog.md +59 -0
- data/Gemfile +9 -14
- data/Gemfile.lock +84 -50
- data/README.md +118 -0
- data/Rakefile +6 -22
- data/aspector.gemspec +15 -127
- data/benchmarks/after_benchmark.rb +28 -0
- data/benchmarks/around_advice_benchmark.rb +35 -0
- data/benchmarks/around_benchmark.rb +32 -0
- data/benchmarks/before_benchmark.rb +28 -0
- data/benchmarks/benchmark_helper.rb +17 -0
- data/benchmarks/combined_benchmark.rb +36 -0
- data/benchmarks/method_invocation_benchmark.rb +30 -0
- data/benchmarks/raw_benchmark.rb +39 -0
- data/examples/activerecord_hooks.rb +10 -15
- data/examples/around_example.rb +20 -31
- data/examples/aspector_apply_example.rb +10 -17
- data/examples/aspector_example.rb +7 -16
- data/examples/cache_aspect.rb +20 -30
- data/examples/design_by_contract.rb +20 -44
- data/examples/exception_handler.rb +12 -20
- data/examples/exception_handler2.rb +16 -24
- data/examples/implicit_method_option_test.rb +8 -16
- data/examples/interception_options_example.rb +71 -0
- data/examples/logging_aspect.rb +16 -24
- data/examples/process_aspector.rb +13 -0
- data/examples/retry_aspect.rb +20 -20
- data/lib/aspector.rb +17 -15
- data/lib/aspector/advice.rb +44 -57
- data/lib/aspector/advice_metadata.rb +10 -11
- data/lib/aspector/aspect_instances.rb +2 -3
- data/lib/aspector/base.rb +6 -368
- data/lib/aspector/base_class_methods.rb +24 -55
- data/lib/aspector/deferred_logic.rb +3 -4
- data/lib/aspector/deferred_option.rb +5 -10
- data/lib/aspector/interception.rb +356 -0
- data/lib/aspector/logger.rb +18 -45
- data/lib/aspector/logging.rb +10 -29
- data/lib/aspector/method_matcher.rb +5 -6
- data/lib/aspector/object_extension.rb +4 -12
- data/lib/aspector/version.rb +3 -0
- data/spec/examples_spec.rb +59 -0
- data/spec/functionals/aspect_for_multiple_targets_spec.rb +54 -0
- data/spec/functionals/aspect_interception_options_accessing_spec.rb +112 -0
- data/spec/functionals/aspect_on_a_class_spec.rb +159 -0
- data/spec/functionals/aspect_on_an_instance_spec.rb +66 -0
- data/spec/functionals/aspector_spec.rb +138 -0
- data/spec/functionals/aspects_combined_spec.rb +37 -0
- data/spec/functionals/aspects_execution_order_spec.rb +61 -0
- data/spec/functionals/aspects_on_private_methods_spec.rb +82 -0
- data/spec/spec_helper.rb +20 -21
- data/spec/support/class_builder.rb +44 -0
- data/spec/units/advice_spec.rb +49 -0
- data/spec/units/advices/after_spec.rb +328 -0
- data/spec/units/advices/around_spec.rb +336 -0
- data/spec/units/advices/before_filter_spec.rb +287 -0
- data/spec/units/advices/before_spec.rb +237 -0
- data/spec/units/advices/raw_spec.rb +67 -0
- data/spec/units/base_class_methods_spec.rb +262 -0
- data/spec/units/base_spec.rb +133 -0
- data/spec/units/deferred_logic_spec.rb +35 -0
- data/spec/units/logger_spec.rb +20 -0
- data/spec/units/logging_spec.rb +85 -0
- data/spec/units/method_matcher_spec.rb +95 -0
- data/spec/units/object_extension_spec.rb +11 -0
- data/spec/units/special_chars_spec.rb +128 -0
- metadata +98 -246
- data/.document +0 -5
- data/.rvmrc +0 -8
- data/README.rdoc +0 -80
- data/VERSION +0 -1
- data/performance-tests/after_test.rb +0 -25
- data/performance-tests/around_advice_benchmark.rb +0 -66
- data/performance-tests/around_test.rb +0 -27
- data/performance-tests/before_test.rb +0 -25
- data/performance-tests/combined_test.rb +0 -33
- data/performance-tests/method_invocation_test.rb +0 -25
- data/performance-tests/raw_test.rb +0 -37
- data/performance-tests/test_helper.rb +0 -9
- data/run_all_examples.sh +0 -12
- data/spec/functional/advices_on_private_methods_spec.rb +0 -21
- data/spec/functional/aspect_on_eigen_class_spec.rb +0 -72
- data/spec/functional/aspect_on_object_spec.rb +0 -20
- data/spec/functional/aspector_spec.rb +0 -140
- data/spec/functional/aspects_combined_spec.rb +0 -48
- data/spec/functional/execution_order_spec.rb +0 -42
- data/spec/unit/advice_spec.rb +0 -4
- data/spec/unit/after_spec.rb +0 -88
- data/spec/unit/around_spec.rb +0 -76
- data/spec/unit/base_class_methods_spec.rb +0 -28
- data/spec/unit/base_spec.rb +0 -112
- data/spec/unit/before_spec.rb +0 -125
- data/spec/unit/deferred_logic_spec.rb +0 -23
- data/spec/unit/method_matcher_spec.rb +0 -43
- data/spec/unit/raw_spec.rb +0 -53
- data/spec/unit/special_chars_spec.rb +0 -122
@@ -0,0 +1,287 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'Before filter advices' do
|
4
|
+
subject { klass.new }
|
5
|
+
|
6
|
+
context 'standard cases' do
|
7
|
+
before do
|
8
|
+
aspector(klass) do
|
9
|
+
before_filter :exec, :before_exec
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when code returns false' do
|
14
|
+
let(:klass) do
|
15
|
+
ClassBuilder.build do
|
16
|
+
def before_exec
|
17
|
+
values << 'before_exec'
|
18
|
+
false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should execute before_exec' do
|
24
|
+
expect(subject)
|
25
|
+
.to receive(:before_exec)
|
26
|
+
.once
|
27
|
+
|
28
|
+
subject.exec
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should not execute original code' do
|
32
|
+
subject.exec
|
33
|
+
expect(subject.values).to eq %w( before_exec )
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'when code returns nil' do
|
38
|
+
let(:klass) do
|
39
|
+
ClassBuilder.build do
|
40
|
+
def before_exec
|
41
|
+
values << 'before_exec'
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should execute before_exec' do
|
48
|
+
expect(subject)
|
49
|
+
.to receive(:before_exec)
|
50
|
+
.once
|
51
|
+
|
52
|
+
subject.exec
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not execute original code' do
|
56
|
+
subject.exec
|
57
|
+
expect(subject.values).to eq %w( before_exec )
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when code doesnt return false or nil' do
|
62
|
+
let(:klass) do
|
63
|
+
ClassBuilder.build do
|
64
|
+
def before_exec
|
65
|
+
values << 'before_exec'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should execute before_exec' do
|
71
|
+
expect(subject)
|
72
|
+
.to receive(:before_exec)
|
73
|
+
.once
|
74
|
+
|
75
|
+
subject.exec
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should work' do
|
79
|
+
subject.exec
|
80
|
+
expect(subject.values).to eq %w( before_exec exec-result )
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'logic in string' do
|
86
|
+
let(:klass) { ClassBuilder.build }
|
87
|
+
|
88
|
+
before do
|
89
|
+
aspector(klass) do
|
90
|
+
before_filter :exec, <<-CODE
|
91
|
+
values << 'before-exec'
|
92
|
+
CODE
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should work' do
|
97
|
+
subject.exec
|
98
|
+
expect(subject.values).to eq %w( before-exec exec-result )
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'logic in block' do
|
103
|
+
let(:klass) { ClassBuilder.build }
|
104
|
+
|
105
|
+
before do
|
106
|
+
aspector(klass) do
|
107
|
+
before_filter :exec do
|
108
|
+
values << 'before-exec'
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should work' do
|
114
|
+
subject.exec
|
115
|
+
expect(subject.values).to eq %w( before-exec exec-result )
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context 'when we want to use method that is defined after aspector binding' do
|
120
|
+
let(:klass) do
|
121
|
+
ClassBuilder.build do
|
122
|
+
aspector do
|
123
|
+
before_filter :exec, :before_exec
|
124
|
+
end
|
125
|
+
|
126
|
+
def before_exec
|
127
|
+
values << 'before-exec'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'should be able to use it' do
|
133
|
+
subject.exec
|
134
|
+
expect(subject.values).to eq %w( before-exec exec-result )
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'method with method_arg' do
|
139
|
+
let(:klass) do
|
140
|
+
ClassBuilder.build do
|
141
|
+
def before_exec(method)
|
142
|
+
values << "before_exec(#{method})"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
before do
|
148
|
+
aspector(klass) do
|
149
|
+
before_filter :exec, :before_exec, method_arg: true
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should execute before_exec with method args' do
|
154
|
+
expect(subject)
|
155
|
+
.to receive(:before_exec)
|
156
|
+
.with('exec')
|
157
|
+
.once
|
158
|
+
|
159
|
+
subject.exec
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should work' do
|
163
|
+
subject.exec
|
164
|
+
expect(subject.values).to eq %w( before_exec(exec) exec-result )
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe 'implicit method option' do
|
169
|
+
context 'when we want to bind to a single method' do
|
170
|
+
let(:klass) do
|
171
|
+
ClassBuilder.build do
|
172
|
+
def before_method
|
173
|
+
values << 'before-method'
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
before do
|
179
|
+
aspector klass, method: %i( exec ) do
|
180
|
+
before_filter :before_method
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should work' do
|
185
|
+
subject.exec
|
186
|
+
expect(subject.values).to eq %w( before-method exec-result )
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'when we want to bind to multiple methods' do
|
191
|
+
let(:klass) do
|
192
|
+
ClassBuilder.build do
|
193
|
+
def before_method
|
194
|
+
values << 'before-method'
|
195
|
+
end
|
196
|
+
|
197
|
+
def exec_new
|
198
|
+
values << 'exec-new'
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
before do
|
204
|
+
aspector klass, methods: %i( exec exec_new ) do
|
205
|
+
before_filter :before_method
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
it 'should work for method 1' do
|
210
|
+
subject.exec
|
211
|
+
expect(subject.values).to eq %w( before-method exec-result )
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should work for method 2' do
|
215
|
+
subject.exec_new
|
216
|
+
expect(subject.values).to eq %w( before-method exec-new )
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context 'disabling aspect' do
|
222
|
+
let(:klass) do
|
223
|
+
ClassBuilder.build do
|
224
|
+
def before_exec
|
225
|
+
values << 'before-exec'
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
let(:aspect) do
|
231
|
+
aspector(klass) do
|
232
|
+
before_filter :exec, :before_exec
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
before do
|
237
|
+
aspect.disable
|
238
|
+
end
|
239
|
+
|
240
|
+
context 'when we define an aspect and we disable it' do
|
241
|
+
it 'should not work' do
|
242
|
+
subject.exec
|
243
|
+
expect(subject.values).to eq %w( exec-result )
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'and we enable it back' do
|
248
|
+
it 'should not work' do
|
249
|
+
subject.exec
|
250
|
+
expect(subject.values).to eq %w( exec-result )
|
251
|
+
aspect.enable
|
252
|
+
subject.exec
|
253
|
+
expect(subject.values).to eq %w( exec-result before-exec exec-result )
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context 'all methods except' do
|
259
|
+
let(:klass) do
|
260
|
+
ClassBuilder.build do
|
261
|
+
def before_exec
|
262
|
+
values << 'before-exec'
|
263
|
+
end
|
264
|
+
|
265
|
+
def except_exec
|
266
|
+
values << 'except-exec'
|
267
|
+
end
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
before do
|
272
|
+
aspector(klass) do
|
273
|
+
before_filter(/^ex.*/, :before_exec, except: :except_exec)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
it 'should work with exec' do
|
278
|
+
subject.exec
|
279
|
+
expect(subject.values).to eq %w( before-exec exec-result )
|
280
|
+
end
|
281
|
+
|
282
|
+
it 'should not work with except_exec' do
|
283
|
+
subject.except_exec
|
284
|
+
expect(subject.values).to eq %w( except-exec )
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe 'Before advices' do
|
4
|
+
subject { klass.new }
|
5
|
+
|
6
|
+
context 'standard case' do
|
7
|
+
let(:klass) do
|
8
|
+
ClassBuilder.build do
|
9
|
+
def before_exec
|
10
|
+
values << 'before_exec'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
before do
|
16
|
+
aspector(klass) do
|
17
|
+
before :exec, :before_exec
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should execute before_exec' do
|
22
|
+
expect(subject)
|
23
|
+
.to receive(:before_exec)
|
24
|
+
.once
|
25
|
+
|
26
|
+
subject.exec
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should work' do
|
30
|
+
subject.exec
|
31
|
+
expect(subject.values).to eq %w( before_exec exec-result )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'logic in string' do
|
36
|
+
let(:klass) { ClassBuilder.build }
|
37
|
+
|
38
|
+
before do
|
39
|
+
aspector(klass) do
|
40
|
+
before :exec, <<-CODE
|
41
|
+
values << 'before-exec'
|
42
|
+
CODE
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should work' do
|
47
|
+
subject.exec
|
48
|
+
expect(subject.values).to eq %w( before-exec exec-result )
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'logic in block' do
|
53
|
+
let(:klass) { ClassBuilder.build }
|
54
|
+
|
55
|
+
before do
|
56
|
+
aspector(klass) do
|
57
|
+
before :exec do
|
58
|
+
values << 'before-exec'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should work' do
|
64
|
+
subject.exec
|
65
|
+
expect(subject.values).to eq %w( before-exec exec-result )
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'when we want to use method that is defined after aspector binding' do
|
70
|
+
let(:klass) do
|
71
|
+
ClassBuilder.build do
|
72
|
+
aspector do
|
73
|
+
before :exec, :before_exec
|
74
|
+
end
|
75
|
+
|
76
|
+
def before_exec
|
77
|
+
values << 'before-exec'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should be able to use it' do
|
83
|
+
subject.exec
|
84
|
+
expect(subject.values).to eq %w( before-exec exec-result )
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'method with method_arg' do
|
89
|
+
let(:klass) do
|
90
|
+
ClassBuilder.build do
|
91
|
+
def before_exec(method)
|
92
|
+
values << "before_exec(#{method})"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
before do
|
98
|
+
aspector(klass) do
|
99
|
+
before :exec, :before_exec, method_arg: true
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should execute before_exec with method args' do
|
104
|
+
expect(subject)
|
105
|
+
.to receive(:before_exec)
|
106
|
+
.with('exec')
|
107
|
+
.once
|
108
|
+
|
109
|
+
subject.exec
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should work' do
|
113
|
+
subject.exec
|
114
|
+
expect(subject.values).to eq %w( before_exec(exec) exec-result )
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'implicit method option' do
|
119
|
+
context 'when we want to bind to a single method' do
|
120
|
+
let(:klass) do
|
121
|
+
ClassBuilder.build do
|
122
|
+
def before_method
|
123
|
+
values << 'before-method'
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
before do
|
129
|
+
aspector klass, method: %i( exec ) do
|
130
|
+
before :before_method
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should work' do
|
135
|
+
subject.exec
|
136
|
+
expect(subject.values).to eq %w( before-method exec-result )
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'when we want to bind to multiple methods' do
|
141
|
+
let(:klass) do
|
142
|
+
ClassBuilder.build do
|
143
|
+
def before_method
|
144
|
+
values << 'before-method'
|
145
|
+
end
|
146
|
+
|
147
|
+
def exec_new
|
148
|
+
values << 'exec-new'
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
before do
|
154
|
+
aspector klass, methods: %i( exec exec_new ) do
|
155
|
+
before :before_method
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should work for method 1' do
|
160
|
+
subject.exec
|
161
|
+
expect(subject.values).to eq %w( before-method exec-result )
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'should work for method 2' do
|
165
|
+
subject.exec_new
|
166
|
+
expect(subject.values).to eq %w( before-method exec-new )
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
context 'disabling aspect' do
|
172
|
+
let(:klass) do
|
173
|
+
ClassBuilder.build do
|
174
|
+
def before_exec
|
175
|
+
values << 'before-exec'
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
let(:aspect) do
|
181
|
+
aspector(klass) do
|
182
|
+
before :exec, :before_exec
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
before do
|
187
|
+
aspect.disable
|
188
|
+
end
|
189
|
+
|
190
|
+
context 'when we define an aspect and we disable it' do
|
191
|
+
it 'should not work' do
|
192
|
+
subject.exec
|
193
|
+
expect(subject.values).to eq %w( exec-result )
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context 'and we enable it back' do
|
198
|
+
it 'should not work' do
|
199
|
+
subject.exec
|
200
|
+
expect(subject.values).to eq %w( exec-result )
|
201
|
+
aspect.enable
|
202
|
+
subject.exec
|
203
|
+
expect(subject.values).to eq %w( exec-result before-exec exec-result )
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context 'all methods except' do
|
209
|
+
let(:klass) do
|
210
|
+
ClassBuilder.build do
|
211
|
+
def before_exec
|
212
|
+
values << 'before-exec'
|
213
|
+
end
|
214
|
+
|
215
|
+
def except_exec
|
216
|
+
values << 'except-exec'
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
before do
|
222
|
+
aspector(klass) do
|
223
|
+
before(/^ex.*/, :before_exec, except: :except_exec)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should work with exec' do
|
228
|
+
subject.exec
|
229
|
+
expect(subject.values).to eq %w( before-exec exec-result )
|
230
|
+
end
|
231
|
+
|
232
|
+
it 'should not work with except_exec' do
|
233
|
+
subject.except_exec
|
234
|
+
expect(subject.values).to eq %w( except-exec )
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|