aspector 0.13.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rubocop.yml +26 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +8 -11
  7. data/Changelog.md +59 -0
  8. data/Gemfile +9 -14
  9. data/Gemfile.lock +84 -50
  10. data/README.md +118 -0
  11. data/Rakefile +6 -22
  12. data/aspector.gemspec +15 -127
  13. data/benchmarks/after_benchmark.rb +28 -0
  14. data/benchmarks/around_advice_benchmark.rb +35 -0
  15. data/benchmarks/around_benchmark.rb +32 -0
  16. data/benchmarks/before_benchmark.rb +28 -0
  17. data/benchmarks/benchmark_helper.rb +17 -0
  18. data/benchmarks/combined_benchmark.rb +36 -0
  19. data/benchmarks/method_invocation_benchmark.rb +30 -0
  20. data/benchmarks/raw_benchmark.rb +39 -0
  21. data/examples/activerecord_hooks.rb +10 -15
  22. data/examples/around_example.rb +20 -31
  23. data/examples/aspector_apply_example.rb +10 -17
  24. data/examples/aspector_example.rb +7 -16
  25. data/examples/cache_aspect.rb +20 -30
  26. data/examples/design_by_contract.rb +20 -44
  27. data/examples/exception_handler.rb +12 -20
  28. data/examples/exception_handler2.rb +16 -24
  29. data/examples/implicit_method_option_test.rb +8 -16
  30. data/examples/interception_options_example.rb +71 -0
  31. data/examples/logging_aspect.rb +16 -24
  32. data/examples/process_aspector.rb +13 -0
  33. data/examples/retry_aspect.rb +20 -20
  34. data/lib/aspector.rb +17 -15
  35. data/lib/aspector/advice.rb +44 -57
  36. data/lib/aspector/advice_metadata.rb +10 -11
  37. data/lib/aspector/aspect_instances.rb +2 -3
  38. data/lib/aspector/base.rb +6 -368
  39. data/lib/aspector/base_class_methods.rb +24 -55
  40. data/lib/aspector/deferred_logic.rb +3 -4
  41. data/lib/aspector/deferred_option.rb +5 -10
  42. data/lib/aspector/interception.rb +356 -0
  43. data/lib/aspector/logger.rb +18 -45
  44. data/lib/aspector/logging.rb +10 -29
  45. data/lib/aspector/method_matcher.rb +5 -6
  46. data/lib/aspector/object_extension.rb +4 -12
  47. data/lib/aspector/version.rb +3 -0
  48. data/spec/examples_spec.rb +59 -0
  49. data/spec/functionals/aspect_for_multiple_targets_spec.rb +54 -0
  50. data/spec/functionals/aspect_interception_options_accessing_spec.rb +112 -0
  51. data/spec/functionals/aspect_on_a_class_spec.rb +159 -0
  52. data/spec/functionals/aspect_on_an_instance_spec.rb +66 -0
  53. data/spec/functionals/aspector_spec.rb +138 -0
  54. data/spec/functionals/aspects_combined_spec.rb +37 -0
  55. data/spec/functionals/aspects_execution_order_spec.rb +61 -0
  56. data/spec/functionals/aspects_on_private_methods_spec.rb +82 -0
  57. data/spec/spec_helper.rb +20 -21
  58. data/spec/support/class_builder.rb +44 -0
  59. data/spec/units/advice_spec.rb +49 -0
  60. data/spec/units/advices/after_spec.rb +328 -0
  61. data/spec/units/advices/around_spec.rb +336 -0
  62. data/spec/units/advices/before_filter_spec.rb +287 -0
  63. data/spec/units/advices/before_spec.rb +237 -0
  64. data/spec/units/advices/raw_spec.rb +67 -0
  65. data/spec/units/base_class_methods_spec.rb +262 -0
  66. data/spec/units/base_spec.rb +133 -0
  67. data/spec/units/deferred_logic_spec.rb +35 -0
  68. data/spec/units/logger_spec.rb +20 -0
  69. data/spec/units/logging_spec.rb +85 -0
  70. data/spec/units/method_matcher_spec.rb +95 -0
  71. data/spec/units/object_extension_spec.rb +11 -0
  72. data/spec/units/special_chars_spec.rb +128 -0
  73. metadata +98 -246
  74. data/.document +0 -5
  75. data/.rvmrc +0 -8
  76. data/README.rdoc +0 -80
  77. data/VERSION +0 -1
  78. data/performance-tests/after_test.rb +0 -25
  79. data/performance-tests/around_advice_benchmark.rb +0 -66
  80. data/performance-tests/around_test.rb +0 -27
  81. data/performance-tests/before_test.rb +0 -25
  82. data/performance-tests/combined_test.rb +0 -33
  83. data/performance-tests/method_invocation_test.rb +0 -25
  84. data/performance-tests/raw_test.rb +0 -37
  85. data/performance-tests/test_helper.rb +0 -9
  86. data/run_all_examples.sh +0 -12
  87. data/spec/functional/advices_on_private_methods_spec.rb +0 -21
  88. data/spec/functional/aspect_on_eigen_class_spec.rb +0 -72
  89. data/spec/functional/aspect_on_object_spec.rb +0 -20
  90. data/spec/functional/aspector_spec.rb +0 -140
  91. data/spec/functional/aspects_combined_spec.rb +0 -48
  92. data/spec/functional/execution_order_spec.rb +0 -42
  93. data/spec/unit/advice_spec.rb +0 -4
  94. data/spec/unit/after_spec.rb +0 -88
  95. data/spec/unit/around_spec.rb +0 -76
  96. data/spec/unit/base_class_methods_spec.rb +0 -28
  97. data/spec/unit/base_spec.rb +0 -112
  98. data/spec/unit/before_spec.rb +0 -125
  99. data/spec/unit/deferred_logic_spec.rb +0 -23
  100. data/spec/unit/method_matcher_spec.rb +0 -43
  101. data/spec/unit/raw_spec.rb +0 -53
  102. 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