aquarium 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|