aquarium 0.4.1 → 0.4.2
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.
- data/Aquarium-IDEA.ipr +252 -0
- data/Aquarium-IDEA.iws +493 -0
- data/Aquarium.ipr +1 -1
- data/Aquarium.iws +133 -138
- data/CHANGES +63 -0
- data/ParseTreePlay.rb +25 -0
- data/README +55 -3
- data/RELEASE-PLAN +9 -1
- data/TODO.rb +175 -15
- data/examples/aspect_design_example.rb +13 -1
- data/examples/aspect_design_example_spec.rb +20 -2
- data/examples/introductions_example.rb +35 -0
- data/examples/introductions_example_spec.rb +37 -0
- data/examples/method_missing_example.rb +2 -1
- data/lib/aquarium/aspects/advice.rb +127 -74
- data/lib/aquarium/aspects/aspect.rb +139 -72
- data/lib/aquarium/aspects/default_objects_handler.rb +6 -4
- data/lib/aquarium/aspects/exclusion_handler.rb +15 -3
- data/lib/aquarium/aspects/join_point.rb +60 -55
- data/lib/aquarium/aspects/pointcut.rb +153 -124
- data/lib/aquarium/aspects/pointcut_composition.rb +1 -1
- data/lib/aquarium/dsl/aspect_dsl.rb +13 -5
- data/lib/aquarium/dsl/object_dsl.rb +4 -2
- data/lib/aquarium/extras/design_by_contract.rb +9 -5
- data/lib/aquarium/finders.rb +1 -0
- data/lib/aquarium/finders/finder_result.rb +13 -5
- data/lib/aquarium/finders/method_finder.rb +75 -70
- data/lib/aquarium/finders/pointcut_finder.rb +166 -0
- data/lib/aquarium/finders/type_finder.rb +104 -62
- data/lib/aquarium/utils/array_utils.rb +1 -1
- data/lib/aquarium/utils/invalid_options.rb +2 -0
- data/lib/aquarium/utils/name_utils.rb +3 -2
- data/lib/aquarium/utils/nil_object.rb +7 -3
- data/lib/aquarium/utils/options_utils.rb +38 -27
- data/lib/aquarium/utils/set_utils.rb +2 -2
- data/lib/aquarium/utils/type_utils.rb +11 -0
- data/lib/aquarium/version.rb +1 -1
- data/spec/aquarium/aspects/advice_spec.rb +147 -32
- data/spec/aquarium/aspects/aspect_invocation_spec.rb +252 -43
- data/spec/aquarium/aspects/aspect_spec.rb +148 -88
- data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +40 -34
- data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +39 -3
- data/spec/aquarium/aspects/join_point_spec.rb +190 -227
- data/spec/aquarium/aspects/pointcut_spec.rb +24 -1
- data/spec/aquarium/dsl/aspect_dsl_spec.rb +17 -17
- data/spec/aquarium/finders/method_finder_spec.rb +8 -2
- data/spec/aquarium/finders/pointcut_finder_spec.rb +193 -0
- data/spec/aquarium/finders/pointcut_finder_spec_test_classes.rb +90 -0
- data/spec/aquarium/finders/type_finder_spec.rb +17 -0
- data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +4 -4
- data/spec/aquarium/finders/type_finder_with_nested_types.rb +47 -0
- data/spec/aquarium/utils/nil_object_spec.rb +21 -0
- data/spec/aquarium/utils/type_utils_sample_nested_types.rb +51 -0
- data/spec/aquarium/utils/type_utils_spec.rb +18 -1
- metadata +13 -3
@@ -6,6 +6,22 @@ require 'logger'
|
|
6
6
|
|
7
7
|
include Aquarium::Aspects
|
8
8
|
|
9
|
+
class MyError1 < StandardError; end
|
10
|
+
class MyError2 < StandardError; end
|
11
|
+
class MyError3 < StandardError; end
|
12
|
+
class ClassThatRaises
|
13
|
+
class CTRException < StandardError; end
|
14
|
+
def raises
|
15
|
+
raise CTRException
|
16
|
+
end
|
17
|
+
end
|
18
|
+
class ClassThatRaisesString
|
19
|
+
class CTRException < StandardError; end
|
20
|
+
def raises
|
21
|
+
raise "A string exception."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
9
25
|
|
10
26
|
describe Aspect, " cannot advise the private implementation methods inserted by other aspects" do
|
11
27
|
it "should have no affect." do
|
@@ -69,18 +85,19 @@ describe Aspect, " with :before advice" do
|
|
69
85
|
|
70
86
|
it "should pass the context information to the advice, including self and the method parameters." do
|
71
87
|
watchful = Watchful.new
|
72
|
-
|
88
|
+
advice_called = false
|
73
89
|
@aspect = Aspect.new :before, :pointcut => {:type => Watchful, :methods => :public_watchful_method} do |jp, obj, *args|
|
74
|
-
|
90
|
+
advice_called = true
|
91
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
92
|
+
jp.context.advice_kind.should == :before
|
93
|
+
jp.context.advised_object.should == watchful
|
94
|
+
jp.context.returned_value.should == nil
|
95
|
+
jp.context.raised_exception.should == nil
|
75
96
|
end
|
76
97
|
block_called = 0
|
77
98
|
watchful.public_watchful_method(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
78
99
|
block_called.should == 1
|
79
|
-
|
80
|
-
context.advised_object.should == watchful
|
81
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
82
|
-
context.returned_value.should == nil
|
83
|
-
context.raised_exception.should == nil
|
100
|
+
advice_called.should be_true
|
84
101
|
end
|
85
102
|
|
86
103
|
it "should evaluate the advice before the method body and its block (if any)." do
|
@@ -98,18 +115,19 @@ describe Aspect, " with :after advice" do
|
|
98
115
|
|
99
116
|
it "should pass the context information to the advice, including self, the method parameters, and the return value when the method returns normally." do
|
100
117
|
watchful = Watchful.new
|
101
|
-
|
118
|
+
advice_called = false
|
102
119
|
@aspect = Aspect.new :after, :pointcut => {:type => Watchful, :methods => :public_watchful_method} do |jp, obj, *args|
|
103
|
-
|
120
|
+
advice_called = true
|
121
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
122
|
+
jp.context.advice_kind.should == :after
|
123
|
+
jp.context.advised_object.should == watchful
|
124
|
+
jp.context.returned_value.should == 1
|
125
|
+
jp.context.raised_exception.should == nil
|
104
126
|
end
|
105
127
|
block_called = 0
|
106
128
|
watchful.public_watchful_method(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
107
129
|
block_called.should == 1
|
108
|
-
|
109
|
-
context.advised_object.should == watchful
|
110
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
111
|
-
context.returned_value.should == block_called
|
112
|
-
context.raised_exception.should == nil
|
130
|
+
advice_called.should be_true
|
113
131
|
end
|
114
132
|
|
115
133
|
it "should pass the context information to the advice, including self, the method parameters, and the rescued exception when an exception is raised." do
|
@@ -119,10 +137,12 @@ describe Aspect, " with :after advice" do
|
|
119
137
|
context = jp.context
|
120
138
|
end
|
121
139
|
block_called = 0
|
122
|
-
lambda {watchful.public_watchful_method_that_raises(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2')
|
140
|
+
lambda {watchful.public_watchful_method_that_raises(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') do |*args|
|
141
|
+
block_called += 1
|
142
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
143
|
+
end }.should raise_error(Watchful::WatchfulError)
|
123
144
|
block_called.should == 1
|
124
145
|
context.advised_object.should == watchful
|
125
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
126
146
|
context.returned_value.should == nil
|
127
147
|
context.raised_exception.kind_of?(Watchful::WatchfulError).should be_true
|
128
148
|
end
|
@@ -161,6 +181,18 @@ describe Aspect, " with :after advice" do
|
|
161
181
|
end
|
162
182
|
ReturningValue.new.doit(ary).should == %w[aa a b c d e]
|
163
183
|
end
|
184
|
+
|
185
|
+
it "should allow advice to change the exception raised" do
|
186
|
+
aspect_advice_invoked = false
|
187
|
+
@aspect = Aspect.new :after, :pointcut => {:type => ClassThatRaises, :methods => :raises} do |jp, obj, *args|
|
188
|
+
aspect_advice_invoked = true
|
189
|
+
jp.context.raised_exception = MyError1
|
190
|
+
end
|
191
|
+
aspect_advice_invoked.should be_false
|
192
|
+
ctr = ClassThatRaises.new
|
193
|
+
lambda {ctr.raises}.should raise_error(MyError1)
|
194
|
+
aspect_advice_invoked.should be_true
|
195
|
+
end
|
164
196
|
end
|
165
197
|
|
166
198
|
describe Aspect, " with :after_returning advice" do
|
@@ -170,18 +202,19 @@ describe Aspect, " with :after_returning advice" do
|
|
170
202
|
|
171
203
|
it "should pass the context information to the advice, including self, the method parameters, and the return value." do
|
172
204
|
watchful = Watchful.new
|
173
|
-
|
205
|
+
advice_called = false
|
174
206
|
@aspect = Aspect.new :after_returning, :pointcut => {:type => Watchful, :methods => :public_watchful_method} do |jp, obj, *args|
|
175
|
-
|
207
|
+
advice_called = true
|
208
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
209
|
+
jp.context.advice_kind.should == :after_returning
|
210
|
+
jp.context.advised_object.should == watchful
|
211
|
+
jp.context.returned_value.should == 1
|
212
|
+
jp.context.raised_exception.should == nil
|
176
213
|
end
|
177
214
|
block_called = 0
|
178
215
|
watchful.public_watchful_method(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
179
216
|
block_called.should == 1
|
180
|
-
|
181
|
-
context.advised_object.should == watchful
|
182
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
183
|
-
context.returned_value.should == block_called
|
184
|
-
context.raised_exception.should == nil
|
217
|
+
advice_called.should be_true
|
185
218
|
end
|
186
219
|
|
187
220
|
it "should evaluate the advice after the method body and its block (if any)." do
|
@@ -205,7 +238,7 @@ describe Aspect, " with :after_returning advice" do
|
|
205
238
|
ReturningValue.new.doit(ary).should == %w[a b c d]
|
206
239
|
end
|
207
240
|
|
208
|
-
it "should
|
241
|
+
it "should allow the advice to change the returned value" do
|
209
242
|
class ReturningValue
|
210
243
|
def doit args
|
211
244
|
args + ["d"]
|
@@ -220,10 +253,6 @@ describe Aspect, " with :after_returning advice" do
|
|
220
253
|
end
|
221
254
|
end
|
222
255
|
|
223
|
-
class MyError1 < StandardError; end
|
224
|
-
class MyError2 < StandardError; end
|
225
|
-
class MyError3 < StandardError; end
|
226
|
-
|
227
256
|
describe Aspect, " with :after_raising advice" do
|
228
257
|
after(:each) do
|
229
258
|
@aspect.unadvise if @aspect
|
@@ -231,18 +260,19 @@ describe Aspect, " with :after_raising advice" do
|
|
231
260
|
|
232
261
|
it "should pass the context information to the advice, including self, the method parameters, and the rescued exception." do
|
233
262
|
watchful = Watchful.new
|
234
|
-
|
263
|
+
advice_called = false
|
235
264
|
@aspect = Aspect.new :after_raising, :pointcut => {:type => Watchful, :methods => /public_watchful_method/} do |jp, obj, *args|
|
236
|
-
|
265
|
+
advice_called = true
|
266
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
267
|
+
jp.context.advised_object.should == watchful
|
268
|
+
jp.context.advice_kind.should == :after_raising
|
269
|
+
jp.context.returned_value.should == nil
|
270
|
+
jp.context.raised_exception.kind_of?(Watchful::WatchfulError).should be_true
|
237
271
|
end
|
238
272
|
block_called = 0
|
239
273
|
lambda {watchful.public_watchful_method_that_raises(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }}.should raise_error(Watchful::WatchfulError)
|
240
274
|
block_called.should == 1
|
241
|
-
|
242
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
243
|
-
context.advice_kind.should == :after_raising
|
244
|
-
context.returned_value.should == nil
|
245
|
-
context.raised_exception.kind_of?(Watchful::WatchfulError).should be_true
|
275
|
+
advice_called.should be_true
|
246
276
|
end
|
247
277
|
|
248
278
|
it "should evaluate the advice after the method body and its block (if any)." do
|
@@ -302,6 +332,14 @@ describe Aspect, " with :after_raising advice" do
|
|
302
332
|
block_invoked.should be_true
|
303
333
|
end
|
304
334
|
|
335
|
+
it "should invoke advice when an exception that subclasses a specified exception type is raised" do
|
336
|
+
aspect_advice_invoked = false
|
337
|
+
@aspect = Aspect.new(:after_raising => StandardError, :pointcut => {:type => ClassThatRaises, :methods => :raises}) {|jp, obj, *args| aspect_advice_invoked = true}
|
338
|
+
ctr = ClassThatRaises.new
|
339
|
+
lambda {ctr.raises}.should raise_error(ClassThatRaises::CTRException)
|
340
|
+
aspect_advice_invoked.should be_true
|
341
|
+
end
|
342
|
+
|
305
343
|
it "should not invoke advice when exceptions of types that don't match the specified list of exception types are raised" do
|
306
344
|
aspect_advice_invoked = false
|
307
345
|
@aspect = Aspect.new(:after_raising => [MyError1, MyError2], :pointcut => {:type => Watchful, :methods => /public_watchful_method/}) {|jp, obj, *args| aspect_advice_invoked = true}
|
@@ -339,12 +377,6 @@ describe Aspect, " with :after_raising advice" do
|
|
339
377
|
end
|
340
378
|
|
341
379
|
it "should advise all methods that raise exceptions when no specific exceptions are specified" do
|
342
|
-
class ClassThatRaises
|
343
|
-
class CTRException < Exception; end
|
344
|
-
def raises
|
345
|
-
raise CTRException
|
346
|
-
end
|
347
|
-
end
|
348
380
|
aspect_advice_invoked = false
|
349
381
|
@aspect = Aspect.new :after_raising, :pointcut => {:type => ClassThatRaises, :methods => :raises} do |jp, obj, *args|
|
350
382
|
aspect_advice_invoked = true
|
@@ -356,12 +388,6 @@ describe Aspect, " with :after_raising advice" do
|
|
356
388
|
end
|
357
389
|
|
358
390
|
it "should advise all methods that raise strings (which are converted to RuntimeError) when no specific exceptions are specified" do
|
359
|
-
class ClassThatRaisesString
|
360
|
-
class CTRException < Exception; end
|
361
|
-
def raises
|
362
|
-
raise "A string exception."
|
363
|
-
end
|
364
|
-
end
|
365
391
|
aspect_advice_invoked = false
|
366
392
|
@aspect = Aspect.new :after_raising, :pointcut => {:type => ClassThatRaisesString, :methods => :raises} do |jp, obj, *args|
|
367
393
|
aspect_advice_invoked = true
|
@@ -371,6 +397,18 @@ describe Aspect, " with :after_raising advice" do
|
|
371
397
|
lambda {ctr.raises}.should raise_error(RuntimeError)
|
372
398
|
aspect_advice_invoked.should be_true
|
373
399
|
end
|
400
|
+
|
401
|
+
it "should allow advice to change the exception raised" do
|
402
|
+
aspect_advice_invoked = false
|
403
|
+
@aspect = Aspect.new :after_raising, :pointcut => {:type => ClassThatRaises, :methods => :raises} do |jp, obj, *args|
|
404
|
+
aspect_advice_invoked = true
|
405
|
+
jp.context.raised_exception = MyError1
|
406
|
+
end
|
407
|
+
aspect_advice_invoked.should be_false
|
408
|
+
ctr = ClassThatRaises.new
|
409
|
+
lambda {ctr.raises}.should raise_error(MyError1)
|
410
|
+
aspect_advice_invoked.should be_true
|
411
|
+
end
|
374
412
|
end
|
375
413
|
|
376
414
|
describe Aspect, " with :before and :after advice" do
|
@@ -379,22 +417,30 @@ describe Aspect, " with :before and :after advice" do
|
|
379
417
|
end
|
380
418
|
|
381
419
|
it "should pass the context information to the advice, including self and the method parameters, plus the return value for the after-advice case." do
|
420
|
+
# We record the contexts seen and the volatile advice kinds and returned values separately, as those values will have been
|
421
|
+
# reset in the contexts by the time we return from the advised method.
|
382
422
|
contexts = []
|
423
|
+
advice_kinds = []
|
424
|
+
returned_values = []
|
383
425
|
@aspect = Aspect.new :before, :after, :pointcut => {:type => Watchful, :methods => [:public_watchful_method]} do |jp, obj, *args|
|
384
426
|
contexts << jp.context
|
427
|
+
advice_kinds << jp.context.advice_kind
|
428
|
+
returned_values << jp.context.returned_value
|
429
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
385
430
|
end
|
386
431
|
watchful = Watchful.new
|
387
432
|
public_block_called = 0
|
388
|
-
watchful.public_watchful_method(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2')
|
433
|
+
watchful.public_watchful_method(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') do |*args|
|
434
|
+
public_block_called += 1
|
435
|
+
end
|
389
436
|
public_block_called.should == 1
|
390
437
|
contexts.size.should == 2
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
438
|
+
advice_kinds[0].should == :before
|
439
|
+
advice_kinds[1].should == :after
|
440
|
+
returned_values[0].should == nil
|
441
|
+
returned_values[1].should == 1
|
395
442
|
contexts.each do |context|
|
396
443
|
context.advised_object.should == watchful
|
397
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
398
444
|
context.raised_exception.should == nil
|
399
445
|
end
|
400
446
|
|
@@ -421,21 +467,27 @@ describe Aspect, " with :before and :after_returning advice" do
|
|
421
467
|
|
422
468
|
it "should pass the context information to the advice, including self and the method parameters, plus the return value for the after-advice case." do
|
423
469
|
watchful = Watchful.new
|
470
|
+
# We record the contexts seen and the volatile advice kinds and returned values separately, as those values will have been
|
471
|
+
# reset in the contexts by the time we return from the advised method.
|
424
472
|
contexts = []
|
473
|
+
advice_kinds = []
|
474
|
+
returned_values = []
|
425
475
|
@aspect = Aspect.new :before, :after_returning, :pointcut => {:type => Watchful, :methods => :public_watchful_method} do |jp, obj, *args|
|
426
476
|
contexts << jp.context
|
477
|
+
advice_kinds << jp.context.advice_kind
|
478
|
+
returned_values << jp.context.returned_value
|
479
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
427
480
|
end
|
428
481
|
block_called = 0
|
429
482
|
watchful.public_watchful_method(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
430
483
|
block_called.should == 1
|
431
484
|
contexts.size.should == 2
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
485
|
+
advice_kinds[0].should == :before
|
486
|
+
advice_kinds[1].should == :after_returning
|
487
|
+
returned_values[0].should == nil
|
488
|
+
returned_values[1].should == 1
|
436
489
|
contexts.each do |context|
|
437
490
|
context.advised_object.should == watchful
|
438
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
439
491
|
context.raised_exception.should == nil
|
440
492
|
end
|
441
493
|
end
|
@@ -455,21 +507,27 @@ describe Aspect, " with :before and :after_raising advice" do
|
|
455
507
|
|
456
508
|
it "should pass the context information to the advice, including self and the method parameters, plus the raised exception for the after-advice case." do
|
457
509
|
watchful = Watchful.new
|
510
|
+
# We record the contexts seen and the volatile advice kinds and raised exceptions separately, as those values will have been
|
511
|
+
# reset in the contexts by the time we return from the advised method.
|
458
512
|
contexts = []
|
513
|
+
advice_kinds = []
|
514
|
+
raised_exceptions = []
|
459
515
|
@aspect = Aspect.new :before, :after_raising, :pointcut => {:type => Watchful, :methods => :public_watchful_method_that_raises} do |jp, obj, *args|
|
460
516
|
contexts << jp.context
|
517
|
+
advice_kinds << jp.context.advice_kind
|
518
|
+
raised_exceptions << jp.context.raised_exception
|
519
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
461
520
|
end
|
462
521
|
block_called = 0
|
463
522
|
lambda {watchful.public_watchful_method_that_raises(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }}.should raise_error(Watchful::WatchfulError)
|
464
523
|
block_called.should == 1
|
465
524
|
contexts.size.should == 2
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
525
|
+
advice_kinds[0].should == :before
|
526
|
+
advice_kinds[1].should == :after_raising
|
527
|
+
raised_exceptions[0].should == nil
|
528
|
+
raised_exceptions[1].kind_of?(Watchful::WatchfulError).should be_true
|
470
529
|
contexts.each do |context|
|
471
530
|
context.advised_object.should == watchful
|
472
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
473
531
|
context.returned_value.should == nil
|
474
532
|
end
|
475
533
|
end
|
@@ -488,11 +546,16 @@ describe Aspect, " with :around advice" do
|
|
488
546
|
end
|
489
547
|
|
490
548
|
it "should pass the context information to the advice, including the object, advice kind, the method invocation parameters, etc." do
|
491
|
-
|
549
|
+
watchful = Watchful.new
|
550
|
+
advice_called = false
|
492
551
|
@aspect = Aspect.new :around, :pointcut => {:type => Watchful, :methods => [:public_watchful_method]} do |jp, obj, *args|
|
493
|
-
|
552
|
+
advice_called = true
|
553
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
554
|
+
jp.context.advised_object.should == watchful
|
555
|
+
jp.context.advice_kind.should == :around
|
556
|
+
jp.context.returned_value.should == nil
|
557
|
+
jp.context.raised_exception.should == nil
|
494
558
|
end
|
495
|
-
watchful = Watchful.new
|
496
559
|
public_block_called = false
|
497
560
|
protected_block_called = false
|
498
561
|
private_block_called = false
|
@@ -502,12 +565,7 @@ describe Aspect, " with :around advice" do
|
|
502
565
|
public_block_called.should be_false # proceed is never called!
|
503
566
|
protected_block_called.should be_true
|
504
567
|
private_block_called.should be_true
|
505
|
-
|
506
|
-
contexts[0].advised_object.should == watchful
|
507
|
-
contexts[0].advice_kind.should == :around
|
508
|
-
contexts[0].returned_value.should == nil
|
509
|
-
contexts[0].parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
510
|
-
contexts[0].raised_exception.should == nil
|
568
|
+
advice_called.should be_true
|
511
569
|
end
|
512
570
|
|
513
571
|
it "should advise subclass invocations of methods advised in the superclass." do
|
@@ -529,11 +587,16 @@ describe Aspect, " with :around advice" do
|
|
529
587
|
end
|
530
588
|
end
|
531
589
|
|
532
|
-
|
590
|
+
child = AdvisingSuperClass::SubClass.new
|
591
|
+
advice_called = false
|
533
592
|
@aspect = Aspect.new :around, :pointcut => {:type => AdvisingSuperClass::SuperClass, :methods => [:public_method]} do |jp, obj, *args|
|
534
|
-
|
593
|
+
advice_called = true
|
594
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
595
|
+
jp.context.advised_object.should == child
|
596
|
+
jp.context.advice_kind.should == :around
|
597
|
+
jp.context.returned_value.should == nil
|
598
|
+
jp.context.raised_exception.should == nil
|
535
599
|
end
|
536
|
-
child = AdvisingSuperClass::SubClass.new
|
537
600
|
public_block_called = false
|
538
601
|
protected_block_called = false
|
539
602
|
private_block_called = false
|
@@ -543,11 +606,7 @@ describe Aspect, " with :around advice" do
|
|
543
606
|
public_block_called.should be_false # proceed is never called!
|
544
607
|
protected_block_called.should be_true
|
545
608
|
private_block_called.should be_true
|
546
|
-
|
547
|
-
context.advice_kind.should == :around
|
548
|
-
context.returned_value.should == nil
|
549
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
550
|
-
context.raised_exception.should == nil
|
609
|
+
advice_called.should be_true
|
551
610
|
end
|
552
611
|
|
553
612
|
it "should advise subclass invocations of methods advised in the subclass that are defined in the superclass." do
|
@@ -569,11 +628,16 @@ describe Aspect, " with :around advice" do
|
|
569
628
|
end
|
570
629
|
end
|
571
630
|
|
572
|
-
|
631
|
+
child = AdvisingSubClass::SubClass.new
|
632
|
+
advice_called = false
|
573
633
|
@aspect = Aspect.new :around, :pointcut => {:type => AdvisingSubClass::SuperClass, :methods => [:public_method]} do |jp, obj, *args|
|
574
|
-
|
634
|
+
advice_called = true
|
635
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
636
|
+
jp.context.advised_object.should == child
|
637
|
+
jp.context.advice_kind.should == :around
|
638
|
+
jp.context.returned_value.should == nil
|
639
|
+
jp.context.raised_exception.should == nil
|
575
640
|
end
|
576
|
-
child = AdvisingSubClass::SubClass.new
|
577
641
|
public_block_called = false
|
578
642
|
protected_block_called = false
|
579
643
|
private_block_called = false
|
@@ -583,11 +647,7 @@ describe Aspect, " with :around advice" do
|
|
583
647
|
public_block_called.should be_false # proceed is never called!
|
584
648
|
protected_block_called.should be_true
|
585
649
|
private_block_called.should be_true
|
586
|
-
|
587
|
-
context.advice_kind.should == :around
|
588
|
-
context.returned_value.should == nil
|
589
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
590
|
-
context.raised_exception.should == nil
|
650
|
+
advice_called.should be_true
|
591
651
|
end
|
592
652
|
|
593
653
|
it "should not advise subclass overrides of superclass methods, when advising superclasses (but calls to superclass methods are advised)." do
|
@@ -30,34 +30,36 @@ describe Aspect, ".new when advising methods in a nested class" do
|
|
30
30
|
|
31
31
|
it "should correctly advise methods in a nested class." do
|
32
32
|
myclass = Nested1::Nested2::MyClass.new
|
33
|
-
|
33
|
+
advice_called = false
|
34
34
|
@aspect = Aspect.new :before, :pointcut => {:type => Nested1::Nested2::MyClass, :methods => :do1} do |jp, obj, *args|
|
35
|
-
|
35
|
+
advice_called = true
|
36
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
37
|
+
jp.context.advice_kind.should == :before
|
38
|
+
jp.context.advised_object.should == myclass
|
39
|
+
jp.context.returned_value.should == nil
|
40
|
+
jp.context.raised_exception.should == nil
|
36
41
|
end
|
37
42
|
block_called = 0
|
38
43
|
myclass.do1(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
39
44
|
block_called.should == 1
|
40
|
-
|
41
|
-
context.advised_object.should == myclass
|
42
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
43
|
-
context.returned_value.should == nil
|
44
|
-
context.raised_exception.should == nil
|
45
|
+
advice_called.should be_true
|
45
46
|
end
|
46
47
|
|
47
48
|
it "should correctly advise methods in an instance of the nested class." do
|
48
49
|
myclass = Nested1::Nested2::MyClass.new
|
49
|
-
|
50
|
+
advice_called = false
|
50
51
|
@aspect = Aspect.new :before, :pointcut => {:object => myclass, :methods => :do1} do |jp, obj, *args|
|
51
|
-
|
52
|
+
advice_called = true
|
53
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
54
|
+
jp.context.advice_kind.should == :before
|
55
|
+
jp.context.advised_object.should == myclass
|
56
|
+
jp.context.returned_value.should == nil
|
57
|
+
jp.context.raised_exception.should == nil
|
52
58
|
end
|
53
59
|
block_called = 0
|
54
60
|
myclass.do1(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
55
61
|
block_called.should == 1
|
56
|
-
|
57
|
-
context.advised_object.should == myclass
|
58
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
59
|
-
context.returned_value.should == nil
|
60
|
-
context.raised_exception.should == nil
|
62
|
+
advice_called.should be_true
|
61
63
|
end
|
62
64
|
end
|
63
65
|
|
@@ -72,18 +74,19 @@ describe Aspect, ".new when advising methods in a nested module included by a cl
|
|
72
74
|
end
|
73
75
|
|
74
76
|
myclass = MyClassWithModule1.new
|
75
|
-
|
77
|
+
advice_called = false
|
76
78
|
@aspect = Aspect.new :before, :pointcut => {:type => Nested1::Nested2::MyModule, :methods => :do2} do |jp, obj, *args|
|
77
|
-
|
79
|
+
advice_called = true
|
80
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
81
|
+
jp.context.advice_kind.should == :before
|
82
|
+
jp.context.advised_object.should == myclass
|
83
|
+
jp.context.returned_value.should == nil
|
84
|
+
jp.context.raised_exception.should == nil
|
78
85
|
end
|
79
86
|
block_called = 0
|
80
87
|
myclass.do2(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
81
88
|
block_called.should == 1
|
82
|
-
|
83
|
-
context.advised_object.should == myclass
|
84
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
85
|
-
context.returned_value.should == nil
|
86
|
-
context.raised_exception.should == nil
|
89
|
+
advice_called.should be_true
|
87
90
|
end
|
88
91
|
|
89
92
|
it "should correctly advise the module's methods when the class is specified." do
|
@@ -92,18 +95,19 @@ describe Aspect, ".new when advising methods in a nested module included by a cl
|
|
92
95
|
end
|
93
96
|
|
94
97
|
myclass = MyClassWithModule2.new
|
95
|
-
|
98
|
+
advice_called = false
|
96
99
|
@aspect = Aspect.new :before, :pointcut => {:type => MyClassWithModule2, :methods => :do2} do |jp, obj, *args|
|
97
|
-
|
100
|
+
advice_called = true
|
101
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
102
|
+
jp.context.advice_kind.should == :before
|
103
|
+
jp.context.advised_object.should == myclass
|
104
|
+
jp.context.returned_value.should == nil
|
105
|
+
jp.context.raised_exception.should == nil
|
98
106
|
end
|
99
107
|
block_called = 0
|
100
108
|
myclass.do2(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
101
109
|
block_called.should == 1
|
102
|
-
|
103
|
-
context.advised_object.should == myclass
|
104
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
105
|
-
context.returned_value.should == nil
|
106
|
-
context.raised_exception.should == nil
|
110
|
+
advice_called.should be_true
|
107
111
|
end
|
108
112
|
|
109
113
|
it "should correctly advise the module's methods when an instance of the class is specified." do
|
@@ -113,17 +117,19 @@ describe Aspect, ".new when advising methods in a nested module included by a cl
|
|
113
117
|
|
114
118
|
myclass = MyClassWithModule3.new
|
115
119
|
context = nil
|
120
|
+
advice_called = false
|
116
121
|
@aspect = Aspect.new :before, :pointcut => {:object => myclass, :methods => :do2} do |jp, obj, *args|
|
117
|
-
|
122
|
+
advice_called = true
|
123
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
124
|
+
jp.context.advice_kind.should == :before
|
125
|
+
jp.context.advised_object.should == myclass
|
126
|
+
jp.context.returned_value.should == nil
|
127
|
+
jp.context.raised_exception.should == nil
|
118
128
|
end
|
119
129
|
block_called = 0
|
120
130
|
myclass.do2(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
121
131
|
block_called.should == 1
|
122
|
-
|
123
|
-
context.advised_object.should == myclass
|
124
|
-
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
125
|
-
context.returned_value.should == nil
|
126
|
-
context.raised_exception.should == nil
|
132
|
+
advice_called.should be_true
|
127
133
|
end
|
128
134
|
end
|
129
135
|
|