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.
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