aquarium 0.1.7 → 0.1.8
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/CHANGES +20 -0
- data/README +17 -0
- data/UPGRADE +5 -0
- data/lib/aquarium/aspects/advice.rb +10 -9
- data/lib/aquarium/aspects/aspect.rb +274 -199
- data/lib/aquarium/aspects/default_object_handler.rb +22 -10
- data/lib/aquarium/aspects/exclusion_handler.rb +61 -0
- data/lib/aquarium/aspects/join_point.rb +18 -17
- data/lib/aquarium/aspects/pointcut.rb +44 -49
- data/lib/aquarium/finders/method_finder.rb +1 -1
- data/lib/aquarium/finders/object_finder.rb +1 -0
- data/lib/aquarium/utils/method_utils.rb +49 -8
- data/lib/aquarium/version.rb +1 -1
- data/spec/aquarium/aspects/advice_chain_node_spec.rb +5 -3
- data/spec/aquarium/aspects/aspect_invocation_spec.rb +1334 -31
- data/spec/aquarium/aspects/aspect_spec.rb +164 -426
- data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +18 -2
- data/spec/aquarium/aspects/join_point_spec.rb +46 -4
- data/spec/aquarium/aspects/pointcut_spec.rb +80 -39
- data/spec/aquarium/finders/method_finder_spec.rb +25 -2
- data/spec/aquarium/finders/type_finder_spec.rb +1 -1
- data/spec/aquarium/spec_example_classes.rb +17 -0
- data/spec/aquarium/utils/method_utils_spec.rb +270 -46
- metadata +4 -3
data/lib/aquarium/version.rb
CHANGED
@@ -2,12 +2,14 @@ require File.dirname(__FILE__) + '/../spec_helper.rb'
|
|
2
2
|
require File.dirname(__FILE__) + '/../spec_example_classes'
|
3
3
|
require 'aquarium'
|
4
4
|
|
5
|
+
include Aquarium::Aspects::Advice
|
6
|
+
|
5
7
|
# Some of AdviceChainNode and related classes are tested through advice_spec.rb. We rely on rcov to
|
6
8
|
# tell us otherwise...
|
7
9
|
describe Aquarium::Aspects::AdviceChainNode, "#each" do
|
8
10
|
it "should return each node in succession" do
|
9
11
|
static_join_point = :static_join_point
|
10
|
-
advice = lambda {|jp, *args| p "none advice"}
|
12
|
+
advice = lambda {|jp, *args| p ":none advice"}
|
11
13
|
options = {
|
12
14
|
:advice_kind => :none,
|
13
15
|
:advice => advice,
|
@@ -15,7 +17,7 @@ describe Aquarium::Aspects::AdviceChainNode, "#each" do
|
|
15
17
|
:static_join_point => static_join_point}
|
16
18
|
advice_chain = Aquarium::Aspects::AdviceChainNodeFactory.make_node options
|
17
19
|
|
18
|
-
|
20
|
+
KINDS_IN_PRIORITY_ORDER.each do |advice_kind|
|
19
21
|
advice = lambda {|jp, *args| p "#{advice_kind} advice"}
|
20
22
|
options[:advice_kind] = advice_kind
|
21
23
|
options[:advice] = advice,
|
@@ -24,7 +26,7 @@ describe Aquarium::Aspects::AdviceChainNode, "#each" do
|
|
24
26
|
end
|
25
27
|
|
26
28
|
advice_chain.size.should == 6
|
27
|
-
expected_advice_kinds =
|
29
|
+
expected_advice_kinds = KINDS_IN_PRIORITY_ORDER.reverse + [:none]
|
28
30
|
count = 0
|
29
31
|
advice_chain.each do |node|
|
30
32
|
node.advice_kind.should == expected_advice_kinds[count]
|
@@ -2,11 +2,36 @@ require File.dirname(__FILE__) + '/../spec_helper.rb'
|
|
2
2
|
require File.dirname(__FILE__) + '/../spec_example_classes'
|
3
3
|
require 'aquarium/aspects/aspect'
|
4
4
|
require 'aquarium/aspects/dsl'
|
5
|
+
require 'aquarium/utils/array_utils'
|
6
|
+
|
7
|
+
require 'profiler'
|
5
8
|
|
6
9
|
include Aquarium::Aspects
|
10
|
+
include Aquarium::Utils::ArrayUtils
|
11
|
+
|
12
|
+
|
13
|
+
def aspects_should_be_equal num_jps, aspect1, aspect2
|
14
|
+
# We don't use @aspect1.should eql(@aspect2) because the "specifications" are different.
|
15
|
+
aspect1.pointcuts.size.should == 1
|
16
|
+
aspect2.pointcuts.size.should == 1
|
17
|
+
aspect1.pointcuts.should eql(aspect2.pointcuts)
|
18
|
+
aspect1.advice.should eql(@advice)
|
19
|
+
aspect2.advice.should eql(@advice)
|
20
|
+
join_points_should_be_equal num_jps, aspect1, aspect2
|
21
|
+
end
|
7
22
|
|
8
|
-
|
9
|
-
|
23
|
+
def join_points_should_be_equal num_jps, aspect1, aspect2
|
24
|
+
aspect1.join_points_matched.size.should == num_jps
|
25
|
+
aspect2.join_points_matched.size.should == num_jps
|
26
|
+
aspect1.join_points_matched.each {|jp| @expected_methods.should include(jp.method_name)}
|
27
|
+
aspect2.join_points_matched.each {|jp| @expected_methods.should include(jp.method_name)}
|
28
|
+
aspect1.join_points_matched.should eql(aspect2.join_points_matched)
|
29
|
+
aspect1.join_points_not_matched.should eql(aspect2.join_points_not_matched)
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
describe Aspect, "#new parameters that specify the kind of advice" do
|
34
|
+
it "should require the kind of advice as the first parameter." do
|
10
35
|
lambda { Aspect.new :pointcut => {:type => Watchful} }.should raise_error(Aquarium::Utils::InvalidOptions)
|
11
36
|
end
|
12
37
|
|
@@ -22,9 +47,7 @@ describe Aspect, "#new with invalid invocation parameter list" do
|
|
22
47
|
lambda { Aspect.new :after, :after_raising, :pointcut => {:type => Watchful} }.should raise_error(Aquarium::Utils::InvalidOptions)
|
23
48
|
lambda { Aspect.new :after_returning, :after_raising, :pointcut => {:type => Watchful} }.should raise_error(Aquarium::Utils::InvalidOptions)
|
24
49
|
end
|
25
|
-
end
|
26
50
|
|
27
|
-
describe Aspect, "#new, when the arguments contain more than one advice type," do
|
28
51
|
it "should allow :before to be specified with :after." do
|
29
52
|
lambda { Aspect.new :before, :after, :pointcut => {:type => Watchful}, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
30
53
|
end
|
@@ -38,26 +61,753 @@ describe Aspect, "#new, when the arguments contain more than one advice type," d
|
|
38
61
|
end
|
39
62
|
end
|
40
63
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
64
|
+
describe Aspect, "#new parameters that specify join points" do
|
65
|
+
it "should contain at least one of :method(s), :pointcut(s), :type(s), or :object(s)." do
|
66
|
+
lambda {Aspect.new(:after) {|jp, *args| true}}.should raise_error(Aquarium::Utils::InvalidOptions)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should contain at least one of :pointcut(s), :type(s), or :object(s) unless :default_object => object is given." do
|
70
|
+
aspect = Aspect.new(:after, :default_object => Watchful.new, :methods => :public_watchful_method) {|jp, *args| true}
|
71
|
+
aspect.unadvise
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should not contain :pointcut(s) and either :type(s) or :object(s)." do
|
75
|
+
lambda {Aspect.new(:after, :pointcuts => {:type => Watchful, :methods => :public_watchful_method}, :type => Watchful, :methods => :public_watchful_method) {|jp, *args| true}}.should raise_error(Aquarium::Utils::InvalidOptions)
|
76
|
+
lambda {Aspect.new(:after, :pointcuts => {:type => Watchful, :methods => :public_watchful_method}, :object => Watchful.new, :methods => :public_watchful_method) {|jp, *args| true}}.should raise_error(Aquarium::Utils::InvalidOptions)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should include an advice block or :advice => advice parameter." do
|
80
|
+
lambda {Aspect.new(:after, :type => Watchful, :methods => :public_watchful_method)}.should raise_error(Aquarium::Utils::InvalidOptions)
|
81
|
+
end
|
49
82
|
end
|
50
83
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
84
|
+
|
85
|
+
describe Aspect, "#new :type parameter" do
|
86
|
+
it "should be accepted as a synonym for :types" do
|
87
|
+
@advice = Proc.new {}
|
88
|
+
@expected_methods = [:public_watchful_method]
|
89
|
+
aspect1 = Aspect.new :before, :type => Watchful, :method => @expected_methods, :advice => @advice
|
90
|
+
aspect2 = Aspect.new :before, :types => Watchful, :method => @expected_methods, :advice => @advice
|
91
|
+
aspects_should_be_equal 1, aspect1, aspect2
|
92
|
+
aspect1.unadvise
|
93
|
+
aspect2.unadvise
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe Aspect, "#new :pointcut parameter" do
|
98
|
+
it "should be accepted as a synonym for :pointcuts" do
|
99
|
+
@advice = Proc.new {}
|
100
|
+
@expected_methods = [:public_watchful_method]
|
101
|
+
aspect1 = Aspect.new :before, :pointcut => {:type => Watchful, :method => @expected_methods}, :advice => @advice
|
102
|
+
aspect2 = Aspect.new :before, :pointcuts => {:type => Watchful, :method => @expected_methods}, :advice => @advice
|
103
|
+
aspects_should_be_equal 1, aspect1, aspect2
|
104
|
+
aspect1.unadvise
|
105
|
+
aspect2.unadvise
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe Aspect, "#new :object parameter" do
|
110
|
+
it "should be accepted as a synonym for :objects" do
|
111
|
+
@advice = Proc.new {}
|
112
|
+
@expected_methods = [:public_watchful_method]
|
113
|
+
watchful = Watchful.new
|
114
|
+
aspect1 = Aspect.new :before, :object => watchful, :method => @expected_methods, :advice => @advice
|
115
|
+
aspect2 = Aspect.new :before, :objects => watchful, :method => @expected_methods, :advice => @advice
|
116
|
+
aspects_should_be_equal 1, aspect1, aspect2
|
117
|
+
aspect1.unadvise
|
118
|
+
aspect2.unadvise
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
describe Aspect, "#new :method parameter" do
|
123
|
+
it "should be accepted as a synonym for :methods" do
|
124
|
+
@advice = Proc.new {}
|
125
|
+
@expected_methods = [:public_watchful_method]
|
126
|
+
aspect1 = Aspect.new :before, :type => Watchful, :method => @expected_methods, :advice => @advice
|
127
|
+
aspect2 = Aspect.new :before, :type => Watchful, :methods => @expected_methods, :advice => @advice
|
128
|
+
aspects_should_be_equal 1, aspect1, aspect2
|
129
|
+
aspect1.unadvise
|
130
|
+
aspect2.unadvise
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe Aspect, "#new :attribute parameter" do
|
135
|
+
it "should be accepted as a synonym for :attributes" do
|
136
|
+
@advice = Proc.new {}
|
137
|
+
@expected_methods = [:public_watchful_method_args, :public_watchful_method_args=]
|
138
|
+
aspect1 = Aspect.new :before, :type => Watchful, :attribute => @expected_methods, :advice => @advice
|
139
|
+
aspect2 = Aspect.new :before, :type => Watchful, :attributes => @expected_methods, :advice => @advice
|
140
|
+
aspects_should_be_equal 2, aspect1, aspect2
|
141
|
+
aspect1.unadvise
|
142
|
+
aspect2.unadvise
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
describe Aspect, "#new with a :type(s) parameter and a :method(s) parameter" do
|
148
|
+
before :each do
|
149
|
+
@protection = 'public'
|
150
|
+
@are_class_methods = false
|
151
|
+
@method_options = []
|
152
|
+
end
|
153
|
+
|
154
|
+
def do_type_spec
|
155
|
+
aspect = nil
|
156
|
+
advice_called = false
|
157
|
+
aspect = Aspect.new :before, :types => @type_spec, :methods => @method_spec, :method_options => @method_options do |jp, *args|
|
158
|
+
advice_called = true
|
159
|
+
jp.should_not be_nil
|
160
|
+
args.size.should == 4
|
161
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
162
|
+
end
|
163
|
+
if @are_class_methods
|
164
|
+
Watchful.method("#{@protection}_class_watchful_method").call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
165
|
+
else
|
166
|
+
Watchful.new.method("#{@protection}_watchful_method").call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
167
|
+
end
|
168
|
+
advice_called.should be_true
|
169
|
+
aspect.unadvise
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should accept :type(s) => [T1, ...], :methods => [m, ...]" do
|
173
|
+
@type_spec = [Watchful]
|
174
|
+
@method_spec = [:public_watchful_method]
|
175
|
+
do_type_spec
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should accept :type(s) => [T1, ...], :methods => m" do
|
179
|
+
@type_spec = [Watchful]
|
180
|
+
@method_spec = :public_watchful_method
|
181
|
+
do_type_spec
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should accept :type(s) => [T1, ...], :methods => /m/" do
|
185
|
+
@type_spec = [Watchful]
|
186
|
+
@method_spec = /watchful_method/
|
187
|
+
do_type_spec
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should accept :type(s) => T1, :methods => [m, ...]" do
|
191
|
+
@type_spec = Watchful
|
192
|
+
@method_spec = [:public_watchful_method]
|
193
|
+
do_type_spec
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should accept :type(s) => T1, :methods => m" do
|
197
|
+
@type_spec = Watchful
|
198
|
+
@method_spec = :public_watchful_method
|
199
|
+
do_type_spec
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should accept :type(s) => T1, :methods => /m/" do
|
203
|
+
@type_spec = Watchful
|
204
|
+
@method_spec = /watchful_method/
|
205
|
+
do_type_spec
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should accept :type(s) => /T1/, :methods => [m, ...]" do
|
209
|
+
@type_spec = /Watchful/
|
210
|
+
@method_spec = [:public_watchful_method]
|
211
|
+
do_type_spec
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should accept :type(s) => /T1/, :methods => m" do
|
215
|
+
@type_spec = /Watchful/
|
216
|
+
@method_spec = :public_watchful_method
|
217
|
+
do_type_spec
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should accept :type(s) => /T1/, :methods => /m/" do
|
221
|
+
@type_spec = /Watchful/
|
222
|
+
@method_spec = /watchful_method/
|
223
|
+
do_type_spec
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should accept :type(s) => ..., :methods => ..., :method_options => [:exclude_ancestor_methods] to exclude methods defined in ancestors" do
|
227
|
+
@type_spec = /Watchful/
|
228
|
+
@method_spec = /watchful_method/
|
229
|
+
@method_options = [:exclude_ancestor_methods]
|
230
|
+
do_type_spec
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should accept :type(s) => ..., :methods => ..., :method_options => [:instance, :public] to match only instance and public (both are the defaults) methods" do
|
234
|
+
@type_spec = /Watchful/
|
235
|
+
@method_spec = /watchful_method/
|
236
|
+
@method_options = [:instance, :public]
|
237
|
+
do_type_spec
|
238
|
+
end
|
239
|
+
|
240
|
+
%w[public protected private].each do |protection|
|
241
|
+
it "should accept :type(s) => ..., :methods => ..., :method_options => [#{protection.intern}] to match only instance (default) #{protection} methods" do
|
242
|
+
@type_spec = /Watchful/
|
243
|
+
@method_spec = /watchful_method/
|
244
|
+
@method_options = [protection.intern]
|
245
|
+
@protection = protection
|
246
|
+
do_type_spec
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should accept :type(s) => ..., :methods => ..., :method_options => [:class] to match only public (default) class methods" do
|
251
|
+
@type_spec = /Watchful/
|
252
|
+
@method_spec = /watchful_method/
|
253
|
+
@method_options = [:class]
|
254
|
+
@are_class_methods = true
|
255
|
+
do_type_spec
|
256
|
+
end
|
257
|
+
|
258
|
+
%w[public private].each do |protection|
|
259
|
+
it "should accept :type(s) => ..., :methods => ..., :method_options => [:class, :#{protection.intern}] to match only class #{protection} methods" do
|
260
|
+
@type_spec = /Watchful/
|
261
|
+
@method_spec = /watchful_method/
|
262
|
+
@method_options = [:class, protection.intern]
|
263
|
+
@protection = protection
|
264
|
+
@are_class_methods = true
|
265
|
+
do_type_spec
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
|
271
|
+
describe Aspect, "#new with a :type(s) parameter and a :attribute(s) parameter" do
|
272
|
+
before :each do
|
273
|
+
@protection = 'public'
|
274
|
+
@attribute_options = []
|
275
|
+
@are_class_methods = false
|
276
|
+
end
|
277
|
+
|
278
|
+
def do_type_attribute_spec
|
279
|
+
aspect = nil
|
280
|
+
advice_called = false
|
281
|
+
aspect = Aspect.new :before, :types => @type_spec, :attributes => @attribute_spec, :attribute_options => @attribute_options do |jp, *args|
|
282
|
+
advice_called = true
|
283
|
+
jp.should_not be_nil
|
284
|
+
expected_args = make_array(@expected_args)
|
285
|
+
args.should == expected_args
|
286
|
+
args.size.should == expected_args.size
|
287
|
+
end
|
288
|
+
watchful = Watchful.new
|
289
|
+
@expected_args = nil
|
290
|
+
watchful.method("#{@protection}_watchful_method_args".intern).call
|
291
|
+
@expected_args = :a1
|
292
|
+
watchful.method("#{@protection}_watchful_method_args=".intern).call @expected_args
|
293
|
+
advice_called.should be_true
|
294
|
+
aspect.unadvise
|
295
|
+
end
|
296
|
+
|
297
|
+
it "should accept :type(s) => [T1, ...], :attribute(s) => [a, ...]" do
|
298
|
+
@type_spec = [Watchful]
|
299
|
+
@attribute_spec = [:public_watchful_method_args]
|
300
|
+
do_type_attribute_spec
|
301
|
+
end
|
302
|
+
|
303
|
+
it "should accept :type(s) => [T1, ...], :attribute(s) => a" do
|
304
|
+
@type_spec = [Watchful]
|
305
|
+
@attribute_spec = :public_watchful_method_args
|
306
|
+
do_type_attribute_spec
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should accept :type(s) => [T1, ...], :attribute(s) => /a/" do
|
310
|
+
@type_spec = [Watchful]
|
311
|
+
@attribute_spec = /watchful_method_args/
|
312
|
+
do_type_attribute_spec
|
313
|
+
end
|
314
|
+
|
315
|
+
it "should accept :type(s) => T1, :attribute(s) => [a]" do
|
316
|
+
@type_spec = Watchful
|
317
|
+
@attribute_spec = [:public_watchful_method_args]
|
318
|
+
do_type_attribute_spec
|
319
|
+
end
|
320
|
+
|
321
|
+
it "should accept :type(s) => T1, :attribute(s) => a" do
|
322
|
+
@type_spec = Watchful
|
323
|
+
@attribute_spec = :public_watchful_method_args
|
324
|
+
do_type_attribute_spec
|
325
|
+
end
|
326
|
+
|
327
|
+
it "should accept :type(s) => T1, :attribute(s) => /a/" do
|
328
|
+
@type_spec = Watchful
|
329
|
+
@attribute_spec = /watchful_method_args/
|
330
|
+
do_type_attribute_spec
|
331
|
+
end
|
332
|
+
|
333
|
+
it "should accept :type(s) => /T1/, :attribute(s) => [a, ...]" do
|
334
|
+
@type_spec = /Watchful/
|
335
|
+
@attribute_spec = [:public_watchful_method_args]
|
336
|
+
do_type_attribute_spec
|
337
|
+
end
|
338
|
+
|
339
|
+
it "should accept :type(s) => /T1/, :attribute(s) => a" do
|
340
|
+
@type_spec = /Watchful/
|
341
|
+
@attribute_spec = :public_watchful_method_args
|
342
|
+
do_type_attribute_spec
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should accept :type(s) => /T1/, :attribute(s) => a" do
|
346
|
+
@type_spec = /Watchful/
|
347
|
+
@attribute_spec = /watchful_method_args/
|
348
|
+
do_type_attribute_spec
|
349
|
+
end
|
350
|
+
|
351
|
+
it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:readers, :writers] to include both attribute reader and writer methods (default)" do
|
352
|
+
@type_spec = /Watchful/
|
353
|
+
@attribute_spec = /watchful_method_args/
|
354
|
+
@attribute_options = [:readers, :writers]
|
355
|
+
do_type_attribute_spec
|
356
|
+
end
|
357
|
+
|
358
|
+
it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:readers] to include only attribute reader methods" do
|
359
|
+
@type_spec = /Watchful/
|
360
|
+
@attribute_spec = /watchful_method_args/
|
361
|
+
@attribute_options = [:readers]
|
362
|
+
do_type_attribute_spec
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should accept attribute option :reader as a synonym for :readers" do
|
366
|
+
@type_spec = /Watchful/
|
367
|
+
@attribute_spec = /watchful_method_args/
|
368
|
+
@attribute_options = [:reader]
|
369
|
+
do_type_attribute_spec
|
370
|
+
end
|
371
|
+
|
372
|
+
it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:writers] to include only attribute writer methods" do
|
373
|
+
@type_spec = /Watchful/
|
374
|
+
@attribute_spec = /watchful_method_args/
|
375
|
+
@attribute_options = [:writers]
|
376
|
+
do_type_attribute_spec
|
377
|
+
end
|
378
|
+
|
379
|
+
it "should accept attribute option :writer as a synonym for :writers" do
|
380
|
+
@type_spec = /Watchful/
|
381
|
+
@attribute_spec = /watchful_method_args/
|
382
|
+
@attribute_options = [:writer]
|
383
|
+
do_type_attribute_spec
|
384
|
+
end
|
385
|
+
|
386
|
+
it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:class, :readers, :writers] to include both attribute reader and writer methods (default) for class methods" do
|
387
|
+
@type_spec = /Watchful/
|
388
|
+
@attribute_spec = /watchful_method_args/
|
389
|
+
@attribute_options = [:class, :readers, :writers]
|
390
|
+
do_type_attribute_spec
|
391
|
+
end
|
392
|
+
|
393
|
+
it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:class, :readers] to include only attribute reader class methods" do
|
394
|
+
@type_spec = /Watchful/
|
395
|
+
@attribute_spec = /watchful_method_args/
|
396
|
+
@attribute_options = [:class, :readers]
|
397
|
+
do_type_attribute_spec
|
398
|
+
end
|
399
|
+
|
400
|
+
it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:class, :writers] to include only attribute writer class methods" do
|
401
|
+
@type_spec = /Watchful/
|
402
|
+
@attribute_spec = /watchful_method_args/
|
403
|
+
@attribute_options = [:class, :writers]
|
404
|
+
do_type_attribute_spec
|
405
|
+
end
|
58
406
|
end
|
59
407
|
|
60
|
-
describe Aspect, "#new
|
408
|
+
describe Aspect, "#new with a :object(s) parameter and a :method(s) parameter" do
|
409
|
+
before :each do
|
410
|
+
@watchful1 = Watchful.new
|
411
|
+
@watchful2 = Watchful.new
|
412
|
+
@protection = 'public'
|
413
|
+
@method_options = []
|
414
|
+
end
|
415
|
+
|
416
|
+
def do_object_spec
|
417
|
+
aspect = nil
|
418
|
+
advice_called = false
|
419
|
+
aspect = Aspect.new :before, :objects => @object_spec, :methods => @method_spec, :method_options => @method_options do |jp, *args|
|
420
|
+
advice_called = true
|
421
|
+
jp.should_not be_nil
|
422
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
423
|
+
end
|
424
|
+
make_array(@object_spec).each do |object|
|
425
|
+
object.method("#{@protection}_watchful_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
426
|
+
end
|
427
|
+
advice_called.should be_true
|
428
|
+
aspect.unadvise
|
429
|
+
end
|
430
|
+
|
431
|
+
it "should accept :object(s) => [o1, ...], :methods => [m, ...]" do
|
432
|
+
@object_spec = [@watchful1, @watchful2]
|
433
|
+
@method_spec = [:public_watchful_method]
|
434
|
+
do_object_spec
|
435
|
+
end
|
436
|
+
|
437
|
+
it "should accept :object(s) => [o1, ...], :methods => m" do
|
438
|
+
@object_spec = [@watchful1, @watchful2]
|
439
|
+
@method_spec = :public_watchful_method
|
440
|
+
do_object_spec
|
441
|
+
end
|
442
|
+
|
443
|
+
it "should accept :object(s) => [o1, ...], :methods => /m/" do
|
444
|
+
@object_spec = [@watchful1, @watchful2]
|
445
|
+
@method_spec = /watchful_method/
|
446
|
+
do_object_spec
|
447
|
+
end
|
448
|
+
|
449
|
+
it "should accept :object(s) => o1, :methods => [m, ...]" do
|
450
|
+
@object_spec = @watchful1
|
451
|
+
@method_spec = [:public_watchful_method]
|
452
|
+
do_object_spec
|
453
|
+
end
|
454
|
+
|
455
|
+
it "should accept :object(s) => o1, :methods => m" do
|
456
|
+
@object_spec = @watchful1
|
457
|
+
@method_spec = :public_watchful_method
|
458
|
+
do_object_spec
|
459
|
+
end
|
460
|
+
|
461
|
+
it "should accept :object(s) => o1, :methods => /m/" do
|
462
|
+
@object_spec = @watchful1
|
463
|
+
@method_spec = /watchful_method/
|
464
|
+
do_object_spec
|
465
|
+
end
|
466
|
+
|
467
|
+
it "should accept :object(s) => ..., :methods => ..., :method_options => [:exclude_ancestor_methods] to exclude methods defined in ancestors" do
|
468
|
+
@object_spec = @watchful1
|
469
|
+
@method_spec = /watchful_method/
|
470
|
+
@method_options = [:exclude_ancestor_methods]
|
471
|
+
do_object_spec
|
472
|
+
end
|
473
|
+
|
474
|
+
it "should accept :object(s) => ..., :methods => ..., :method_options => [:instance, :public] to match only instance and public (both are the defaults) methods" do
|
475
|
+
@object_spec = @watchful1
|
476
|
+
@method_spec = /watchful_method/
|
477
|
+
@method_options = [:instance, :public]
|
478
|
+
do_object_spec
|
479
|
+
end
|
480
|
+
|
481
|
+
%w[public protected private].each do |protection|
|
482
|
+
it "should accept :object(s) => ..., :methods => ..., :method_options => [#{protection.intern}] to match only instance (default) #{protection} methods" do
|
483
|
+
@object_spec = @watchful1
|
484
|
+
@method_spec = /watchful_method/
|
485
|
+
@method_options = [protection.intern]
|
486
|
+
@protection = protection
|
487
|
+
do_object_spec
|
488
|
+
end
|
489
|
+
|
490
|
+
it "should accept :object(s) => ..., :methods => ..., :method_options => [:instance, #{protection.intern}] to match only instance #{protection} methods" do
|
491
|
+
@object_spec = @watchful1
|
492
|
+
@method_spec = /watchful_method/
|
493
|
+
@method_options = [:instance, protection.intern]
|
494
|
+
@protection = protection
|
495
|
+
do_object_spec
|
496
|
+
end
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
describe Aspect, "#new with a :object(s) parameter and a :attribute(s) parameter" do
|
501
|
+
before :each do
|
502
|
+
@watchful1 = Watchful.new
|
503
|
+
@watchful2 = Watchful.new
|
504
|
+
@protection = 'public'
|
505
|
+
@attribute_options = []
|
506
|
+
end
|
507
|
+
|
508
|
+
def do_object_attribute_spec
|
509
|
+
aspect = nil
|
510
|
+
advice_called = false
|
511
|
+
aspect = Aspect.new :before, :objects => @object_spec, :attributes => @attribute_spec, :attribute_options => @attribute_options do |jp, *args|
|
512
|
+
advice_called = true
|
513
|
+
jp.should_not be_nil
|
514
|
+
expected_args = make_array(@expected_args)
|
515
|
+
args.should == expected_args
|
516
|
+
args.size.should == expected_args.size
|
517
|
+
end
|
518
|
+
make_array(@object_spec).each do |object|
|
519
|
+
@expected_args = nil
|
520
|
+
object.method("#{@protection}_watchful_method_args".intern).call
|
521
|
+
@expected_args = :a1
|
522
|
+
object.method("#{@protection}_watchful_method_args=".intern).call @expected_args
|
523
|
+
advice_called.should be_true
|
524
|
+
end
|
525
|
+
aspect.unadvise
|
526
|
+
end
|
527
|
+
|
528
|
+
it "should accept :object(s) => [T1, ...], :attribute(s) => [a, ...]" do
|
529
|
+
@object_spec = [@watchful1, @watchful2]
|
530
|
+
@attribute_spec = [:public_watchful_method_args]
|
531
|
+
do_object_attribute_spec
|
532
|
+
end
|
533
|
+
|
534
|
+
it "should accept :object(s) => [T1, ...], :attribute(s) => a" do
|
535
|
+
@object_spec = [@watchful1, @watchful2]
|
536
|
+
@attribute_spec = :public_watchful_method_args
|
537
|
+
do_object_attribute_spec
|
538
|
+
end
|
539
|
+
|
540
|
+
it "should accept :object(s) => [T1, ...], :attribute(s) => /a/" do
|
541
|
+
@object_spec = [@watchful1, @watchful2]
|
542
|
+
@attribute_spec = /watchful_method_args/
|
543
|
+
do_object_attribute_spec
|
544
|
+
end
|
545
|
+
|
546
|
+
it "should accept :object(s) => T1, :attribute(s) => [a]" do
|
547
|
+
@object_spec = @watchful1
|
548
|
+
@attribute_spec = [:public_watchful_method_args]
|
549
|
+
do_object_attribute_spec
|
550
|
+
end
|
551
|
+
|
552
|
+
it "should accept :object(s) => T1, :attribute(s) => a" do
|
553
|
+
@object_spec = @watchful1
|
554
|
+
@attribute_spec = :public_watchful_method_args
|
555
|
+
do_object_attribute_spec
|
556
|
+
end
|
557
|
+
|
558
|
+
it "should accept :object(s) => T1, :attribute(s) => /a/" do
|
559
|
+
@object_spec = @watchful1
|
560
|
+
@attribute_spec = /watchful_method_args/
|
561
|
+
do_object_attribute_spec
|
562
|
+
end
|
563
|
+
|
564
|
+
it "should accept :object(s) => ..., :attributes => ..., :attribute_options => [:readers, :writers] to include both attribute reader and writer methods (default)" do
|
565
|
+
@object_spec = @watchful1
|
566
|
+
@attribute_spec = /watchful_method_args/
|
567
|
+
@attribute_options = [:readers, :writers]
|
568
|
+
do_object_attribute_spec
|
569
|
+
end
|
570
|
+
|
571
|
+
it "should accept :object(s) => ..., :attributes => ..., :attribute_options => [:readers] to include only attribute reader methods" do
|
572
|
+
@object_spec = @watchful1
|
573
|
+
@attribute_spec = /watchful_method_args/
|
574
|
+
@attribute_options = [:readers]
|
575
|
+
do_object_attribute_spec
|
576
|
+
end
|
577
|
+
|
578
|
+
it "should accept attribute option :reader as a synonym for :readers" do
|
579
|
+
@object_spec = @watchful1
|
580
|
+
@attribute_spec = /watchful_method_args/
|
581
|
+
@attribute_options = [:reader]
|
582
|
+
do_object_attribute_spec
|
583
|
+
end
|
584
|
+
|
585
|
+
it "should accept :object(s) => ..., :attributes => ..., :attribute_options => [:writers] to include only attribute writer methods" do
|
586
|
+
@object_spec = @watchful1
|
587
|
+
@attribute_spec = /watchful_method_args/
|
588
|
+
@attribute_options = [:writers]
|
589
|
+
do_object_attribute_spec
|
590
|
+
end
|
591
|
+
|
592
|
+
it "should accept attribute option :writer as a synonym for :writers" do
|
593
|
+
@object_spec = @watchful1
|
594
|
+
@attribute_spec = /watchful_method_args/
|
595
|
+
@attribute_options = [:writer]
|
596
|
+
do_object_attribute_spec
|
597
|
+
end
|
598
|
+
end
|
599
|
+
|
600
|
+
describe Aspect, "#new with a :pointcut parameter taking a hash with type specifications" do
|
601
|
+
before :each do
|
602
|
+
@protection = 'public'
|
603
|
+
@are_class_methods = false
|
604
|
+
end
|
605
|
+
|
606
|
+
def do_type_pointcut_spec
|
607
|
+
aspect = nil
|
608
|
+
advice_called = false
|
609
|
+
aspect = Aspect.new :before, :pointcut => @pointcut_hash do |jp, *args|
|
610
|
+
advice_called = true
|
611
|
+
jp.should_not be_nil
|
612
|
+
args.size.should == 4
|
613
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
614
|
+
end
|
615
|
+
if @are_class_methods
|
616
|
+
Watchful.method("#{@protection}_class_watchful_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
617
|
+
else
|
618
|
+
Watchful.new.method("#{@protection}_watchful_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
619
|
+
end
|
620
|
+
advice_called.should be_true
|
621
|
+
aspect.unadvise
|
622
|
+
end
|
623
|
+
|
624
|
+
it "should accept {:type(s) => [T1, ...], :methods => [m, ...]} " do
|
625
|
+
@pointcut_hash = {:type => [Watchful], :methods => [:public_watchful_method]}
|
626
|
+
do_type_pointcut_spec
|
627
|
+
end
|
628
|
+
|
629
|
+
it "should accept {:type(s) => [T1, ...], :methods => m} " do
|
630
|
+
@pointcut_hash = {:type => [Watchful], :methods => :public_watchful_method}
|
631
|
+
do_type_pointcut_spec
|
632
|
+
end
|
633
|
+
|
634
|
+
it "should accept {:type(s) => [T1, ...], :methods => /m/} " do
|
635
|
+
@pointcut_hash = {:type => [Watchful], :methods => /watchful_method/}
|
636
|
+
do_type_pointcut_spec
|
637
|
+
end
|
638
|
+
|
639
|
+
it "should accept {:type(s) => T1, :methods => [m, ...]} " do
|
640
|
+
@pointcut_hash = {:type => Watchful, :methods => [:public_watchful_method]}
|
641
|
+
do_type_pointcut_spec
|
642
|
+
end
|
643
|
+
|
644
|
+
it "should accept {:type(s) => T1, :methods => m} " do
|
645
|
+
@pointcut_hash = {:type => Watchful, :methods => :public_watchful_method}
|
646
|
+
do_type_pointcut_spec
|
647
|
+
end
|
648
|
+
|
649
|
+
it "should accept {:type(s) => T1, :methods => /m/} " do
|
650
|
+
@pointcut_hash = {:type => Watchful, :methods => /watchful_method/}
|
651
|
+
do_type_pointcut_spec
|
652
|
+
end
|
653
|
+
|
654
|
+
it "should accept {:type(s) => /T1/, :methods => [m, ...]} " do
|
655
|
+
@pointcut_hash = {:type => /Watchful/, :methods => [:public_watchful_method]}
|
656
|
+
do_type_pointcut_spec
|
657
|
+
end
|
658
|
+
|
659
|
+
it "should accept {:type(s) => /T1/, :methods => m} " do
|
660
|
+
@pointcut_hash = {:type => /Watchful/, :methods => :public_watchful_method}
|
661
|
+
do_type_pointcut_spec
|
662
|
+
end
|
663
|
+
|
664
|
+
it "should accept {:type(s) => /T1/, :methods => /m/} " do
|
665
|
+
@pointcut_hash = {:type => /Watchful/, :methods => /watchful_method/}
|
666
|
+
do_type_pointcut_spec
|
667
|
+
end
|
668
|
+
|
669
|
+
%w[public protected private].each do |protection|
|
670
|
+
it "should accept {:type(s) => T1, :methods => /m/, :method_options =>[:instance, #{protection}]} " do
|
671
|
+
@protection = protection
|
672
|
+
@pointcut_hash = {:type => Watchful, :methods => /watchful_method/, :method_options =>[:instance, protection.intern]}
|
673
|
+
do_type_pointcut_spec
|
674
|
+
end
|
675
|
+
end
|
676
|
+
|
677
|
+
%w[public private].each do |protection|
|
678
|
+
it "should accept {:type(s) => T1, :methods => /m/, :method_options =>[:class, #{protection}]} " do
|
679
|
+
@pointcut_hash = {:type => Watchful, :methods => /class_watchful_method/, :method_options =>[:class, protection.intern]}
|
680
|
+
@protection = protection
|
681
|
+
@are_class_methods = true
|
682
|
+
do_type_pointcut_spec
|
683
|
+
end
|
684
|
+
end
|
685
|
+
|
686
|
+
it "should accept {:type(s) => T1, :methods => /m/, :method_options =>[:instance]} defaults to public methods" do
|
687
|
+
@pointcut_hash = {:type => Watchful, :methods => /watchful_method/, :method_options =>[:instance]}
|
688
|
+
do_type_pointcut_spec
|
689
|
+
end
|
690
|
+
|
691
|
+
it "should accept {:type(s) => T1, :methods => /m/, :method_options =>[:class]} defaults to public class methods" do
|
692
|
+
@pointcut_hash = {:type => Watchful, :methods => /watchful_method/, :method_options =>[:class]}
|
693
|
+
@are_class_methods = true
|
694
|
+
do_type_pointcut_spec
|
695
|
+
end
|
696
|
+
end
|
697
|
+
|
698
|
+
describe Aspect, "#new with a :pointcut parameter taking a hash with object specifications" do
|
699
|
+
before :each do
|
700
|
+
@protection = 'public'
|
701
|
+
@expected_advice_count = 2
|
702
|
+
@watchful1 = Watchful.new
|
703
|
+
@watchful2 = Watchful.new
|
704
|
+
end
|
705
|
+
|
706
|
+
def do_object_pointcut_spec
|
707
|
+
aspect = nil
|
708
|
+
advice_count = 0
|
709
|
+
aspect = Aspect.new :before, :pointcut => @pointcut_hash do |jp, *args|
|
710
|
+
advice_count += 1
|
711
|
+
jp.should_not be_nil
|
712
|
+
args.size.should == 4
|
713
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
714
|
+
end
|
715
|
+
@watchful1.method("#{@protection}_watchful_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
716
|
+
@watchful2.method("#{@protection}_watchful_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
717
|
+
advice_count.should == @expected_advice_count
|
718
|
+
aspect.unadvise
|
719
|
+
end
|
720
|
+
|
721
|
+
it "should accept {:objects => [o1, ...], :methods => [m, ...]} " do
|
722
|
+
@pointcut_hash = {:objects => [@watchful1, @watchful2], :methods => [:public_watchful_method]}
|
723
|
+
do_object_pointcut_spec
|
724
|
+
end
|
725
|
+
|
726
|
+
it "should accept {:objects => [o1, ...], :methods => m} " do
|
727
|
+
@pointcut_hash = {:objects => [@watchful1, @watchful2], :methods => :public_watchful_method}
|
728
|
+
do_object_pointcut_spec
|
729
|
+
end
|
730
|
+
|
731
|
+
it "should accept {:objects => [o1, ...], :methods => /m/} " do
|
732
|
+
@pointcut_hash = {:objects => [@watchful1, @watchful2], :methods => /watchful_method/}
|
733
|
+
do_object_pointcut_spec
|
734
|
+
end
|
735
|
+
|
736
|
+
it "should accept {:object => o1, :methods => [m, ...]} " do
|
737
|
+
@expected_advice_count = 1
|
738
|
+
@pointcut_hash = {:object => @watchful1, :methods => [:public_watchful_method]}
|
739
|
+
do_object_pointcut_spec
|
740
|
+
end
|
741
|
+
|
742
|
+
it "should accept {:objects => o1, :methods => m} " do
|
743
|
+
@expected_advice_count = 1
|
744
|
+
@pointcut_hash = {:objects => @watchful1, :methods => :public_watchful_method}
|
745
|
+
do_object_pointcut_spec
|
746
|
+
end
|
747
|
+
|
748
|
+
it "should accept {:objects => o1, :methods => /m/} " do
|
749
|
+
@expected_advice_count = 1
|
750
|
+
@pointcut_hash = {:objects => @watchful1, :methods => /watchful_method/}
|
751
|
+
do_object_pointcut_spec
|
752
|
+
end
|
753
|
+
end
|
754
|
+
|
755
|
+
describe Aspect, "#new with a :pointcut parameter and a Pointcut object or an array of Pointcuts" do
|
756
|
+
def do_pointcut_pointcut_spec
|
757
|
+
aspect = nil
|
758
|
+
advice_called = false
|
759
|
+
aspect = Aspect.new :before, :pointcut => @pointcuts do |jp, *args|
|
760
|
+
advice_called = true
|
761
|
+
jp.should_not be_nil
|
762
|
+
args.size.should == 4
|
763
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
764
|
+
end
|
765
|
+
Watchful.new.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
766
|
+
advice_called.should be_true
|
767
|
+
aspect.unadvise
|
768
|
+
end
|
769
|
+
|
770
|
+
it "should accept a single Pointcut object." do
|
771
|
+
@pointcuts = Pointcut.new :type => [Watchful], :methods => :public_watchful_method
|
772
|
+
do_pointcut_pointcut_spec
|
773
|
+
end
|
774
|
+
|
775
|
+
it "should accept an array of Pointcut objects." do
|
776
|
+
pointcut1 = Pointcut.new :type => [Watchful], :methods => :public_watchful_method
|
777
|
+
pointcut2 = Pointcut.new :type => [Watchful], :methods => :public_class_watchful_method, :method_options => [:class]
|
778
|
+
@pointcuts = [pointcut1, pointcut2]
|
779
|
+
do_pointcut_pointcut_spec
|
780
|
+
end
|
781
|
+
end
|
782
|
+
|
783
|
+
describe Aspect, "#new with a :pointcut parameter and an array of Pointcuts" do
|
784
|
+
it "should treat the array as if it is one Pointcut \"or'ed\" together." do
|
785
|
+
advice_called = 0
|
786
|
+
advice = Proc.new {|jp, *args|
|
787
|
+
advice_called += 1
|
788
|
+
jp.should_not be_nil
|
789
|
+
args.size.should == 4
|
790
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
791
|
+
}
|
792
|
+
pointcut1 = Pointcut.new :type => [Watchful], :methods => :public_watchful_method
|
793
|
+
pointcut2 = Pointcut.new :type => [Watchful], :methods => :public_class_watchful_method, :method_options => [:class]
|
794
|
+
pointcut12 = pointcut1.or pointcut2
|
795
|
+
aspect1 = Aspect.new :before, :pointcut => [pointcut1, pointcut2], :advice => advice
|
796
|
+
Watchful.new.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
797
|
+
Watchful.public_class_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
798
|
+
advice_called.should == 2
|
799
|
+
aspect1.unadvise
|
800
|
+
advice_called = 0
|
801
|
+
aspect2 = Aspect.new :before, :pointcut => pointcut12, :advice => advice
|
802
|
+
Watchful.new.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
803
|
+
Watchful.public_class_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
804
|
+
advice_called.should == 2
|
805
|
+
aspect2.unadvise
|
806
|
+
aspect1.join_points_matched.should eql(aspect2.join_points_matched)
|
807
|
+
end
|
808
|
+
end
|
809
|
+
|
810
|
+
describe Aspect, "#new with a :type(s) parameter and a :method(s) parameter or one of several equivalent :pointcut parameters" do
|
61
811
|
before :each do
|
62
812
|
@advice = proc {|jp,*args| "advice"}
|
63
813
|
@expected_methods = [:public_watchful_method]
|
@@ -79,7 +829,7 @@ describe Aspect, "#new arguments for specifying the types and methods" do
|
|
79
829
|
@aspect2 = Aspect.new :after, :pointcut => pointcut, &@advice
|
80
830
|
aspects_should_be_equal 1, @aspect1, @aspect2
|
81
831
|
end
|
82
|
-
|
832
|
+
|
83
833
|
it "should advise equivalent join points when :pointcut =>{:type => T, :method => m} is used or :pointcut => pointcut is used, where pointcut matches :type => T and :method => m." do
|
84
834
|
@aspect1 = Aspect.new :after, :pointcut => {:type => Watchful, :method => :public_watchful_method}, &@advice
|
85
835
|
pointcut = Aquarium::Aspects::Pointcut.new :type => Watchful, :method => :public_watchful_method
|
@@ -95,11 +845,8 @@ describe Aspect, "#new arguments for specifying the types and methods" do
|
|
95
845
|
end
|
96
846
|
end
|
97
847
|
|
98
|
-
describe Aspect, "#new
|
848
|
+
describe Aspect, "#new with a :type(s) parameter and an :attributes(s) parameter or one of several equivalent :pointcut parameters" do
|
99
849
|
class ClassWithAttrib1
|
100
|
-
def initialize *args
|
101
|
-
@state = args
|
102
|
-
end
|
103
850
|
def dummy; end
|
104
851
|
attr_accessor :state
|
105
852
|
end
|
@@ -140,7 +887,6 @@ describe Aspect, "#new arguments for specifying the types and attributes" do
|
|
140
887
|
end
|
141
888
|
|
142
889
|
it "should advise equivalent join points when :type => T and :attribute => a (the attribute's reader and writer) is used or :pointcut => [join_points] is used, where the join_points match :type => T and :method => :a and :method => :a=." do
|
143
|
-
# pending "working on Pointcut.new first."
|
144
890
|
@aspect1 = Aspect.new :after, :type => ClassWithAttrib1, :attribute => :state, &@advice
|
145
891
|
join_point1 = Aquarium::Aspects::JoinPoint.new :type => ClassWithAttrib1, :method => :state
|
146
892
|
join_point2 = Aquarium::Aspects::JoinPoint.new :type => ClassWithAttrib1, :method => :state=
|
@@ -149,7 +895,6 @@ describe Aspect, "#new arguments for specifying the types and attributes" do
|
|
149
895
|
end
|
150
896
|
|
151
897
|
it "should advise an equivalent join point when :type => T and :method => :a= (the attribute's writer) is used or :pointcut => join_point is used, where join_point matches :type => T and :method => a=." do
|
152
|
-
# pending "working on Pointcut.new first."
|
153
898
|
@aspect1 = Aspect.new :after, :type => ClassWithAttrib1, :attribute => :state, :attribute_options => [:writer], &@advice
|
154
899
|
join_point = Aquarium::Aspects::JoinPoint.new :type => ClassWithAttrib1, :method => :state=
|
155
900
|
@aspect2 = Aspect.new :after, :pointcut => join_point, &@advice
|
@@ -157,7 +902,7 @@ describe Aspect, "#new arguments for specifying the types and attributes" do
|
|
157
902
|
end
|
158
903
|
end
|
159
904
|
|
160
|
-
describe Aspect, "#new
|
905
|
+
describe Aspect, "#new with a :object(s) parameter and a :method(s) parameter or one of several equivalent :pointcut parameters" do
|
161
906
|
before :each do
|
162
907
|
@advice = proc {|jp,*args| "advice"}
|
163
908
|
@expected_methods = [:public_watchful_method]
|
@@ -191,7 +936,7 @@ describe Aspect, "#new arguments for specifying the objects and methods" do
|
|
191
936
|
end
|
192
937
|
end
|
193
938
|
|
194
|
-
describe Aspect, "#new
|
939
|
+
describe Aspect, "#new with a :object(s) parameter and an :attributes(s) parameter or one of several equivalent :pointcut parameters" do
|
195
940
|
class ClassWithAttrib2
|
196
941
|
def initialize *args
|
197
942
|
@state = args
|
@@ -237,7 +982,6 @@ describe Aspect, "#new arguments for specifying the objects and attributes" do
|
|
237
982
|
end
|
238
983
|
|
239
984
|
it "should advise equivalent join points when :type => T and :attribute => a (the attribute's reader and writer) is used or :pointcut => [join_points] is used, where the join_points match :type => T and :method => :a and :method => :a=." do
|
240
|
-
# pending "working on Pointcut.new first."
|
241
985
|
@aspect1 = Aspect.new :after, :object => @object, :attribute => :state, &@advice
|
242
986
|
join_point1 = Aquarium::Aspects::JoinPoint.new :object => @object, :method => :state
|
243
987
|
join_point2 = Aquarium::Aspects::JoinPoint.new :object => @object, :method => :state=
|
@@ -246,7 +990,6 @@ describe Aspect, "#new arguments for specifying the objects and attributes" do
|
|
246
990
|
end
|
247
991
|
|
248
992
|
it "should advise an equivalent join point when :type => T and :method => :a= (the attribute's writer) is used or :pointcut => join_point is used, where join_point matches :type => T and :method => a=." do
|
249
|
-
# pending "working on Pointcut.new first."
|
250
993
|
@aspect1 = Aspect.new :after, :object => @object, :attribute => :state, :attribute_options => [:writer], &@advice
|
251
994
|
join_point = Aquarium::Aspects::JoinPoint.new :object => @object, :method => :state=
|
252
995
|
@aspect2 = Aspect.new :after, :pointcut => join_point, &@advice
|
@@ -254,3 +997,563 @@ describe Aspect, "#new arguments for specifying the objects and attributes" do
|
|
254
997
|
end
|
255
998
|
end
|
256
999
|
|
1000
|
+
describe Aspect, "#new block for advice" do
|
1001
|
+
it "should accept a block as the advice to use." do
|
1002
|
+
watchful = Watchful.new
|
1003
|
+
advice_called = false
|
1004
|
+
aspect = Aspect.new :before, :object => watchful, :methods => :public_watchful_method do |jp, *args|
|
1005
|
+
advice_called = true
|
1006
|
+
jp.should_not be_nil
|
1007
|
+
args.size.should == 4
|
1008
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
1009
|
+
end
|
1010
|
+
watchful.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
1011
|
+
advice_called.should be_true
|
1012
|
+
aspect.unadvise
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
it "should accept an :advice => Proc parameter indicating the advice to use." do
|
1016
|
+
watchful = Watchful.new
|
1017
|
+
advice_called = false
|
1018
|
+
advice = Proc.new {|jp, *args|
|
1019
|
+
advice_called = true
|
1020
|
+
jp.should_not be_nil
|
1021
|
+
args.size.should == 4
|
1022
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
1023
|
+
}
|
1024
|
+
aspect = Aspect.new :before, :object => watchful, :methods => :public_watchful_method, :advice => advice
|
1025
|
+
watchful.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
1026
|
+
advice_called.should be_true
|
1027
|
+
aspect.unadvise
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
it "should accept a :call => Proc parameter as a synonym for :advice." do
|
1031
|
+
watchful = Watchful.new
|
1032
|
+
advice_called = false
|
1033
|
+
advice = Proc.new {|jp, *args|
|
1034
|
+
advice_called = true
|
1035
|
+
jp.should_not be_nil
|
1036
|
+
args.size.should == 4
|
1037
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
1038
|
+
}
|
1039
|
+
aspect = Aspect.new :before, :object => watchful, :methods => :public_watchful_method, :call => advice
|
1040
|
+
watchful.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
1041
|
+
advice_called.should be_true
|
1042
|
+
aspect.unadvise
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
it "should accept a :invoke => Proc parameter as a synonym for :advice." do
|
1046
|
+
watchful = Watchful.new
|
1047
|
+
advice_called = false
|
1048
|
+
advice = Proc.new {|jp, *args|
|
1049
|
+
advice_called = true
|
1050
|
+
jp.should_not be_nil
|
1051
|
+
args.size.should == 4
|
1052
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
1053
|
+
}
|
1054
|
+
aspect = Aspect.new :before, :object => watchful, :methods => :public_watchful_method, :invoke => advice
|
1055
|
+
watchful.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
1056
|
+
advice_called.should be_true
|
1057
|
+
aspect.unadvise
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
it "should accept a :advise_with => Proc parameter as a synonym for :advice." do
|
1061
|
+
watchful = Watchful.new
|
1062
|
+
advice_called = false
|
1063
|
+
advice = Proc.new {|jp, *args|
|
1064
|
+
advice_called = true
|
1065
|
+
jp.should_not be_nil
|
1066
|
+
args.size.should == 4
|
1067
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
1068
|
+
}
|
1069
|
+
aspect = Aspect.new :before, :object => watchful, :methods => :public_watchful_method, :advise_with => advice
|
1070
|
+
watchful.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
1071
|
+
advice_called.should be_true
|
1072
|
+
aspect.unadvise
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
it "should ignore all other advice parameters if a block is given." do
|
1076
|
+
watchful = Watchful.new
|
1077
|
+
advice_called = false
|
1078
|
+
advice1 = Proc.new {|jp, *args| fail "advice1"}
|
1079
|
+
advice2 = Proc.new {|jp, *args| fail "advice2"}
|
1080
|
+
aspect = Aspect.new :before, :object => watchful, :methods => :public_watchful_method, :advice => advice1, :invoke => advice2 do |jp, *args|
|
1081
|
+
advice_called = true
|
1082
|
+
end
|
1083
|
+
watchful.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
1084
|
+
advice_called.should be_true
|
1085
|
+
aspect.unadvise
|
1086
|
+
end
|
1087
|
+
|
1088
|
+
it "should ignore all but the last advice parameter, using any synonym, if there is no advice block." do
|
1089
|
+
watchful = Watchful.new
|
1090
|
+
advice_called = false
|
1091
|
+
advice1 = Proc.new {|jp, *args|
|
1092
|
+
advice_called = true
|
1093
|
+
jp.should_not be_nil
|
1094
|
+
args.size.should == 4
|
1095
|
+
args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
1096
|
+
}
|
1097
|
+
advice2 = Proc.new {|jp, *args| raise "should not be called"}
|
1098
|
+
aspect = Aspect.new :before, :object => watchful, :methods => :public_watchful_method, :advice => advice2, :advice => advice1
|
1099
|
+
watchful.public_watchful_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
|
1100
|
+
advice_called.should be_true
|
1101
|
+
aspect.unadvise
|
1102
|
+
end
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
|
1106
|
+
class ExcludeBase
|
1107
|
+
def doit; end
|
1108
|
+
def initialize arg; @value = arg; end
|
1109
|
+
attr_accessor :value
|
1110
|
+
def inspect; "(#{self.class}: #{@value})"; end
|
1111
|
+
def eql? other
|
1112
|
+
return false unless other.kind_of?(self.class)
|
1113
|
+
@value == other.value
|
1114
|
+
end
|
1115
|
+
alias_method :==, :eql?
|
1116
|
+
end
|
1117
|
+
class DontExclude1 < ExcludeBase; end
|
1118
|
+
class DontExclude2 < ExcludeBase; end
|
1119
|
+
class Exclude1 < ExcludeBase; end
|
1120
|
+
class Exclude2 < ExcludeBase; end
|
1121
|
+
|
1122
|
+
class Exclude1b < Exclude1
|
1123
|
+
def initialize arg; super(arg); end
|
1124
|
+
def doit2; end
|
1125
|
+
end
|
1126
|
+
class Exclude1c < Exclude1
|
1127
|
+
def initialize arg; super(arg); end
|
1128
|
+
def doit3; end
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
describe Aspect, "#new with a :type(s) parameter and an :exclude_type(s) parameter" do
|
1132
|
+
def do_exclude_types exclude_type_sym
|
1133
|
+
included_types = [DontExclude1, DontExclude2]
|
1134
|
+
excluded_types = [Exclude1, Exclude2]
|
1135
|
+
aspect = nil
|
1136
|
+
advice_called = false
|
1137
|
+
aspect = Aspect.new :before, :types => (included_types + excluded_types), exclude_type_sym => excluded_types, :methods => :doit do |jp, *args|
|
1138
|
+
advice_called = true
|
1139
|
+
excluded_types.should_not include(jp.target_type)
|
1140
|
+
end
|
1141
|
+
included_types.each do |type|
|
1142
|
+
advice_called = false
|
1143
|
+
type.new(1).doit
|
1144
|
+
advice_called.should be_true
|
1145
|
+
end
|
1146
|
+
excluded_types.each do |type|
|
1147
|
+
advice_called = false
|
1148
|
+
type.new(1).doit
|
1149
|
+
advice_called.should_not be_true
|
1150
|
+
end
|
1151
|
+
aspect.unadvise
|
1152
|
+
end
|
1153
|
+
|
1154
|
+
it "should accept :type(s) => [T1, ...], :exclude_type(s) => [T2, ...] and exclude join points in the excluded types" do
|
1155
|
+
do_exclude_types :exclude_types
|
1156
|
+
end
|
1157
|
+
|
1158
|
+
it "should accept :exclude_type as a synonym for :exclude_types" do
|
1159
|
+
do_exclude_types :exclude_type
|
1160
|
+
end
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
|
1164
|
+
describe Aspect, "#new with a :object(s) parameter and an :exclude_object(s) parameter" do
|
1165
|
+
def do_exclude_objects exclude_object_sym
|
1166
|
+
dontExclude1 = DontExclude1.new(1)
|
1167
|
+
dontExclude2 = DontExclude1.new(2)
|
1168
|
+
exclude1 = DontExclude1.new(3)
|
1169
|
+
exclude2 = DontExclude1.new(4)
|
1170
|
+
included_objects = [dontExclude1, dontExclude2]
|
1171
|
+
excluded_objects = [exclude1, exclude2]
|
1172
|
+
aspect = nil
|
1173
|
+
advice_called = false
|
1174
|
+
aspect = Aspect.new :before, :objects => (included_objects + excluded_objects), exclude_object_sym => excluded_objects, :methods => :doit do |jp, *args|
|
1175
|
+
advice_called = true
|
1176
|
+
excluded_objects.should_not include(jp.context.advised_object)
|
1177
|
+
end
|
1178
|
+
included_objects.each do |object|
|
1179
|
+
advice_called = false
|
1180
|
+
object.doit
|
1181
|
+
advice_called.should be_true
|
1182
|
+
end
|
1183
|
+
excluded_objects.each do |object|
|
1184
|
+
advice_called = false
|
1185
|
+
object.doit
|
1186
|
+
advice_called.should_not be_true
|
1187
|
+
end
|
1188
|
+
aspect.unadvise
|
1189
|
+
end
|
1190
|
+
|
1191
|
+
it "should accept :object(s) => [o1, ...], :exclude_object(s) => [o2, ...] and exclude join points in the excluded objects" do
|
1192
|
+
do_exclude_objects :exclude_objects
|
1193
|
+
end
|
1194
|
+
|
1195
|
+
it "should accept :exclude_object as a synonym for :exclude_objects" do
|
1196
|
+
do_exclude_objects :exclude_object
|
1197
|
+
end
|
1198
|
+
end
|
1199
|
+
|
1200
|
+
|
1201
|
+
describe Aspect, "#new with a :pointcut(s), :type(s), :object(s), and :method(s) parameter and an :exclude_join_point(s) parameter" do
|
1202
|
+
def do_exclude_join_points exclude_join_points_sym
|
1203
|
+
dontExclude1 = DontExclude1.new(1)
|
1204
|
+
dontExclude2 = DontExclude1.new(2)
|
1205
|
+
exclude1 = DontExclude1.new(3)
|
1206
|
+
exclude2 = DontExclude1.new(4)
|
1207
|
+
included_objects = [dontExclude1, dontExclude2]
|
1208
|
+
excluded_objects = [exclude1, exclude2]
|
1209
|
+
excluded_join_point1 = JoinPoint.new :object => exclude1, :method => :doit
|
1210
|
+
excluded_join_point2 = JoinPoint.new :object => exclude2, :method => :doit
|
1211
|
+
excluded_join_points = [excluded_join_point1, excluded_join_point2]
|
1212
|
+
aspect = nil
|
1213
|
+
advice_called = false
|
1214
|
+
aspect = Aspect.new :before, :objects => (included_objects + excluded_objects), exclude_join_points_sym => excluded_join_points, :methods => :doit do |jp, *args|
|
1215
|
+
advice_called = true
|
1216
|
+
excluded_objects.should_not include(jp.context.advised_object)
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
included_objects.each do |object|
|
1220
|
+
advice_called = false
|
1221
|
+
object.doit
|
1222
|
+
advice_called.should be_true
|
1223
|
+
end
|
1224
|
+
excluded_objects.each do |object|
|
1225
|
+
advice_called = false
|
1226
|
+
object.doit
|
1227
|
+
advice_called.should_not be_true
|
1228
|
+
end
|
1229
|
+
aspect.unadvise
|
1230
|
+
end
|
1231
|
+
|
1232
|
+
it "should accept :exclude_join_point as a synonym for :exclude_join_points" do
|
1233
|
+
do_exclude_join_points :exclude_join_point
|
1234
|
+
end
|
1235
|
+
|
1236
|
+
it "should accept :object(s) => [o1, ...], :exclude_join_point(s) => [jps], where [jps] are the list of join points for the objects and methods to exclude" do
|
1237
|
+
do_exclude_join_points :exclude_join_points
|
1238
|
+
end
|
1239
|
+
|
1240
|
+
it "should accept :type(s) => [T1, ...], :exclude_join_point(s) => [jps], where [jps] are the list of join points for the types and methods to exclude" do
|
1241
|
+
included_types = [DontExclude1, DontExclude2]
|
1242
|
+
excluded_types = [Exclude1, Exclude2]
|
1243
|
+
excluded_join_point1 = JoinPoint.new :type => Exclude1, :method => :doit
|
1244
|
+
excluded_join_point2 = JoinPoint.new :type => Exclude2, :method => :doit
|
1245
|
+
excluded_join_points = [excluded_join_point1, excluded_join_point2]
|
1246
|
+
aspect = nil
|
1247
|
+
advice_called = false
|
1248
|
+
aspect = Aspect.new :before, :types => (included_types + excluded_types), :exclude_join_points => excluded_join_points, :methods => :doit do |jp, *args|
|
1249
|
+
advice_called = true
|
1250
|
+
excluded_types.should_not include(jp.target_type)
|
1251
|
+
end
|
1252
|
+
|
1253
|
+
included_types.each do |type|
|
1254
|
+
advice_called = false
|
1255
|
+
type.new(1).doit
|
1256
|
+
advice_called.should be_true
|
1257
|
+
end
|
1258
|
+
excluded_types.each do |type|
|
1259
|
+
advice_called = false
|
1260
|
+
type.new(1).doit
|
1261
|
+
advice_called.should_not be_true
|
1262
|
+
end
|
1263
|
+
aspect.unadvise
|
1264
|
+
end
|
1265
|
+
|
1266
|
+
it "should accept :pointcut(s) => [P1, ...], :exclude_join_point(s) => [jps], where [jps] are the list of join points for the types and methods to exclude" do
|
1267
|
+
included_types = [DontExclude1, DontExclude2]
|
1268
|
+
excluded_types = [Exclude1, Exclude2]
|
1269
|
+
excluded_join_point1 = JoinPoint.new :type => Exclude1, :method => :doit
|
1270
|
+
excluded_join_point2 = JoinPoint.new :type => Exclude2, :method => :doit
|
1271
|
+
excluded_join_points = [excluded_join_point1, excluded_join_point2]
|
1272
|
+
pointcut1 = Pointcut.new :types => included_types, :method => :doit
|
1273
|
+
pointcut2 = Pointcut.new :types => excluded_types, :method => :doit
|
1274
|
+
aspect = nil
|
1275
|
+
advice_called = false
|
1276
|
+
aspect = Aspect.new :before, :pointcuts => [pointcut1, pointcut2], :exclude_join_points => excluded_join_points do |jp, *args|
|
1277
|
+
advice_called = true
|
1278
|
+
excluded_types.should_not include(jp.target_type)
|
1279
|
+
end
|
1280
|
+
included_types.each do |type|
|
1281
|
+
advice_called = false
|
1282
|
+
type.new(1).doit
|
1283
|
+
advice_called.should be_true
|
1284
|
+
end
|
1285
|
+
excluded_types.each do |type|
|
1286
|
+
advice_called = false
|
1287
|
+
type.new(1).doit
|
1288
|
+
advice_called.should_not be_true
|
1289
|
+
end
|
1290
|
+
aspect.unadvise
|
1291
|
+
end
|
1292
|
+
end
|
1293
|
+
|
1294
|
+
describe Aspect, "#new with a :pointcut(s), :type(s), :object(s), and :method(s) parameter and an :exclude_pointcut(s) parameter" do
|
1295
|
+
def do_exclude_pointcuts exclude_pointcuts_sym
|
1296
|
+
dontExclude1 = DontExclude1.new(1)
|
1297
|
+
dontExclude2 = DontExclude1.new(2)
|
1298
|
+
exclude1 = DontExclude1.new(3)
|
1299
|
+
exclude2 = DontExclude1.new(4)
|
1300
|
+
included_objects = [dontExclude1, dontExclude2]
|
1301
|
+
excluded_objects = [exclude1, exclude2]
|
1302
|
+
excluded_pointcut1 = Pointcut.new :object => exclude1, :method => :doit
|
1303
|
+
excluded_pointcut2 = Pointcut.new :object => exclude2, :method => :doit
|
1304
|
+
excluded_pointcuts = [excluded_pointcut1, excluded_pointcut2]
|
1305
|
+
aspect = nil
|
1306
|
+
advice_called = false
|
1307
|
+
aspect = Aspect.new :before, :objects => (included_objects + excluded_objects), exclude_pointcuts_sym => excluded_pointcuts, :methods => :doit do |jp, *args|
|
1308
|
+
advice_called = true
|
1309
|
+
excluded_objects.should_not include(jp.context.advised_object)
|
1310
|
+
end
|
1311
|
+
|
1312
|
+
included_objects.each do |object|
|
1313
|
+
advice_called = false
|
1314
|
+
object.doit
|
1315
|
+
advice_called.should be_true
|
1316
|
+
end
|
1317
|
+
excluded_objects.each do |object|
|
1318
|
+
advice_called = false
|
1319
|
+
object.doit
|
1320
|
+
advice_called.should_not be_true
|
1321
|
+
end
|
1322
|
+
aspect.unadvise
|
1323
|
+
end
|
1324
|
+
|
1325
|
+
it "should accept :exclude_pointcut as a synonym for :exclude_pointcuts" do
|
1326
|
+
do_exclude_pointcuts :exclude_pointcut
|
1327
|
+
end
|
1328
|
+
|
1329
|
+
it "should accept :object(s) => [o1, ...], :exclude_pointcut(s) => [pcs], where [pcs] are the list of pointcuts for the objects and methods to exclude" do
|
1330
|
+
do_exclude_pointcuts :exclude_pointcuts
|
1331
|
+
end
|
1332
|
+
|
1333
|
+
it "should accept :type(s) => [T1, ...], :exclude_pointcut(s) => [pcs], where [pcs] are the list of pointcuts for the types and methods to exclude" do
|
1334
|
+
included_types = [DontExclude1, DontExclude2]
|
1335
|
+
excluded_types = [Exclude1, Exclude2]
|
1336
|
+
excluded_pointcut1 = Pointcut.new :type => Exclude1, :method => :doit
|
1337
|
+
excluded_pointcut2 = Pointcut.new :type => Exclude2, :method => :doit
|
1338
|
+
excluded_pointcuts = [excluded_pointcut1, excluded_pointcut2]
|
1339
|
+
aspect = nil
|
1340
|
+
advice_called = false
|
1341
|
+
aspect = Aspect.new :before, :types => (included_types + excluded_types), :exclude_pointcuts => excluded_pointcuts, :methods => :doit do |jp, *args|
|
1342
|
+
advice_called = true
|
1343
|
+
excluded_types.should_not include(jp.target_type)
|
1344
|
+
end
|
1345
|
+
|
1346
|
+
included_types.each do |type|
|
1347
|
+
advice_called = false
|
1348
|
+
type.new(1).doit
|
1349
|
+
advice_called.should be_true
|
1350
|
+
end
|
1351
|
+
excluded_types.each do |type|
|
1352
|
+
advice_called = false
|
1353
|
+
type.new(1).doit
|
1354
|
+
advice_called.should_not be_true
|
1355
|
+
end
|
1356
|
+
aspect.unadvise
|
1357
|
+
end
|
1358
|
+
|
1359
|
+
it "should accept :pointcut(s) => [P1, ...], :exclude_pointcut(s) => [pcs], where [pcs] are the list of pointcuts for the types and methods to exclude" do
|
1360
|
+
included_types = [DontExclude1, DontExclude2]
|
1361
|
+
excluded_types = [Exclude1, Exclude2]
|
1362
|
+
excluded_pointcut1 = Pointcut.new :type => Exclude1, :method => :doit
|
1363
|
+
excluded_pointcut2 = Pointcut.new :type => Exclude2, :method => :doit
|
1364
|
+
excluded_pointcuts = [excluded_pointcut1, excluded_pointcut2]
|
1365
|
+
pointcut1 = Pointcut.new :types => included_types, :method => :doit
|
1366
|
+
pointcut2 = Pointcut.new :types => excluded_types, :method => :doit
|
1367
|
+
aspect = nil
|
1368
|
+
advice_called = false
|
1369
|
+
aspect = Aspect.new :before, :pointcuts => [pointcut1, pointcut2], :exclude_pointcuts => excluded_pointcuts do |jp, *args|
|
1370
|
+
advice_called = true
|
1371
|
+
excluded_types.should_not include(jp.target_type)
|
1372
|
+
end
|
1373
|
+
included_types.each do |type|
|
1374
|
+
advice_called = false
|
1375
|
+
type.new(1).doit
|
1376
|
+
advice_called.should be_true
|
1377
|
+
end
|
1378
|
+
excluded_types.each do |type|
|
1379
|
+
advice_called = false
|
1380
|
+
type.new(1).doit
|
1381
|
+
advice_called.should_not be_true
|
1382
|
+
end
|
1383
|
+
aspect.unadvise
|
1384
|
+
end
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
describe Aspect, "#new with type-based :pointcut(s) and :exclude_type(s) parameter" do
|
1388
|
+
|
1389
|
+
it "should accept :pointcut(s) => [P1, ...], :exclude_type(s) => [types], where join points with [types] are excluded" do
|
1390
|
+
included_types = [DontExclude1, DontExclude2]
|
1391
|
+
excluded_types = [Exclude1, Exclude2]
|
1392
|
+
pointcut1 = Pointcut.new :types => included_types, :method => :doit
|
1393
|
+
pointcut2 = Pointcut.new :types => excluded_types, :method => :doit
|
1394
|
+
aspect = nil
|
1395
|
+
advice_called = false
|
1396
|
+
aspect = Aspect.new :before, :pointcuts => [pointcut1, pointcut2], :exclude_types => excluded_types do |jp, *args|
|
1397
|
+
advice_called = true
|
1398
|
+
excluded_types.should_not include(jp.target_type)
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
included_types.each do |type|
|
1402
|
+
advice_called = false
|
1403
|
+
type.new(1).doit
|
1404
|
+
advice_called.should be_true
|
1405
|
+
end
|
1406
|
+
excluded_types.each do |type|
|
1407
|
+
advice_called = false
|
1408
|
+
type.new(1).doit
|
1409
|
+
advice_called.should_not be_true
|
1410
|
+
end
|
1411
|
+
aspect.unadvise
|
1412
|
+
end
|
1413
|
+
end
|
1414
|
+
|
1415
|
+
|
1416
|
+
describe Aspect, "#new with object-based :pointcut(s) and :exclude_object(s) or :exclude_method(s) parameter" do
|
1417
|
+
|
1418
|
+
it "should accept :pointcut(s) => [P1, ...], :exclude_object(s) => [objects], where join points with [objects] are excluded" do
|
1419
|
+
dontExclude1 = DontExclude1.new(1)
|
1420
|
+
dontExclude2 = DontExclude1.new(2)
|
1421
|
+
exclude1 = DontExclude1.new(3)
|
1422
|
+
exclude2 = DontExclude1.new(4)
|
1423
|
+
included_objects = [dontExclude1, dontExclude2]
|
1424
|
+
excluded_objects = [exclude1, exclude2]
|
1425
|
+
pointcut1 = Pointcut.new :objects => included_objects, :method => :doit
|
1426
|
+
pointcut2 = Pointcut.new :objects => excluded_objects, :method => :doit
|
1427
|
+
aspect = nil
|
1428
|
+
advice_called = false
|
1429
|
+
aspect = Aspect.new :before, :pointcuts => [pointcut1, pointcut2], :exclude_objects => excluded_objects do |jp, *args|
|
1430
|
+
advice_called = true
|
1431
|
+
excluded_objects.should_not include(jp.context.advised_object)
|
1432
|
+
end
|
1433
|
+
included_objects.each do |object|
|
1434
|
+
advice_called = false
|
1435
|
+
object.doit
|
1436
|
+
advice_called.should be_true
|
1437
|
+
end
|
1438
|
+
excluded_objects.each do |object|
|
1439
|
+
advice_called = false
|
1440
|
+
object.doit
|
1441
|
+
advice_called.should_not be_true
|
1442
|
+
end
|
1443
|
+
aspect.unadvise
|
1444
|
+
end
|
1445
|
+
end
|
1446
|
+
|
1447
|
+
describe Aspect, "#new with :method(s) and :exclude_method(s) parameter" do
|
1448
|
+
before :each do
|
1449
|
+
@dontExclude1 = DontExclude1.new(1)
|
1450
|
+
@dontExclude2 = DontExclude1.new(2)
|
1451
|
+
@exclude1 = DontExclude1.new(3)
|
1452
|
+
@exclude2 = DontExclude1.new(4)
|
1453
|
+
@exclude1c = Exclude1c.new(5)
|
1454
|
+
@included_objects = [@dontExclude1, @dontExclude2, @exclude1, @exclude2]
|
1455
|
+
@excluded_objects = [@exclude1c]
|
1456
|
+
@included_types = [DontExclude1, DontExclude2, Exclude1, Exclude2]
|
1457
|
+
@excluded_types = [Exclude1c]
|
1458
|
+
@excluded_methods = [:doit3]
|
1459
|
+
@pointcut1 = Pointcut.new :objects => @included_objects, :method => /doit/
|
1460
|
+
@pointcut2 = Pointcut.new :objects => @excluded_objects, :method => /doit/
|
1461
|
+
@pointcut3 = Pointcut.new :types => @included_types, :method => /doit/
|
1462
|
+
@pointcut4 = Pointcut.new :types => @excluded_types, :method => /doit/
|
1463
|
+
end
|
1464
|
+
|
1465
|
+
def do_method_exclusion parameter_hash, types_were_specified
|
1466
|
+
parameter_hash[:before] = ''
|
1467
|
+
parameter_hash[:exclude_method] = :doit3
|
1468
|
+
aspect = nil
|
1469
|
+
advice_called = false
|
1470
|
+
aspect = Aspect.new parameter_hash do |jp, *args|
|
1471
|
+
advice_called = true
|
1472
|
+
@excluded_methods.should_not include(jp.method_name)
|
1473
|
+
end
|
1474
|
+
if types_were_specified
|
1475
|
+
(@included_types + @excluded_types).each do |type|
|
1476
|
+
advice_called = false
|
1477
|
+
type.new(1).doit
|
1478
|
+
advice_called.should be_true
|
1479
|
+
end
|
1480
|
+
@excluded_types.each do |type|
|
1481
|
+
advice_called = false
|
1482
|
+
type.new(1).doit3
|
1483
|
+
advice_called.should_not be_true
|
1484
|
+
end
|
1485
|
+
end
|
1486
|
+
(@included_objects + @excluded_objects).each do |object|
|
1487
|
+
advice_called = false
|
1488
|
+
object.doit
|
1489
|
+
advice_called.should be_true
|
1490
|
+
end
|
1491
|
+
@excluded_objects.each do |object|
|
1492
|
+
advice_called = false
|
1493
|
+
object.doit3
|
1494
|
+
advice_called.should_not be_true
|
1495
|
+
end
|
1496
|
+
aspect.unadvise
|
1497
|
+
end
|
1498
|
+
|
1499
|
+
it "should accept :exclude_method as a synonym for exclude_methods" do
|
1500
|
+
parameter_hash = { :pointcuts => [@pointcut1, @pointcut2, @pointcut3, @pointcut4] }
|
1501
|
+
do_method_exclusion parameter_hash, true
|
1502
|
+
end
|
1503
|
+
|
1504
|
+
it "should accept :pointcut(s) => [P1, ...], :exclude_method(s) => [methods], where join points with [methods] are excluded" do
|
1505
|
+
parameter_hash = { :pointcuts => [@pointcut1, @pointcut2, @pointcut3, @pointcut4] }
|
1506
|
+
do_method_exclusion parameter_hash, true
|
1507
|
+
end
|
1508
|
+
|
1509
|
+
it "should accept :type(s) => ..., :method(s) => ..., :exclude_method(s) => [methods], where join points with [methods] are excluded" do
|
1510
|
+
parameter_hash = { :types => (@included_types + @excluded_types), :methods => /doit/ }
|
1511
|
+
do_method_exclusion parameter_hash, true
|
1512
|
+
end
|
1513
|
+
|
1514
|
+
# it "should accept :object(s) => ..., :method(s) => ..., :exclude_method(s) => [methods], where join points with [methods] are excluded" do
|
1515
|
+
# pending "bug fix"
|
1516
|
+
# Aspect.echo = true
|
1517
|
+
# parameter_hash = { :objects => (@included_objects + @excluded_objects), :methods => /doit/ }
|
1518
|
+
# do_method_exclusion parameter_hash, false
|
1519
|
+
# Aspect.echo = false
|
1520
|
+
# end
|
1521
|
+
#
|
1522
|
+
# def do_method_exclusion2 parameter_hash, types_were_specified
|
1523
|
+
# parameter_hash[:before] = ''
|
1524
|
+
# parameter_hash[:exclude_method] = :doit3
|
1525
|
+
# parameter_hash[:method] = /doit/
|
1526
|
+
# aspect = nil
|
1527
|
+
# advice_called = false
|
1528
|
+
# aspect = Aspect.new parameter_hash do |jp, *args|
|
1529
|
+
# advice_called = true
|
1530
|
+
# @excluded_methods.should_not include(jp.method_name)
|
1531
|
+
# end
|
1532
|
+
# (@excluded_objects).each do |object|
|
1533
|
+
# advice_called = false
|
1534
|
+
# object.doit
|
1535
|
+
# advice_called.should be_true
|
1536
|
+
# end
|
1537
|
+
# aspect.unadvise
|
1538
|
+
# end
|
1539
|
+
#
|
1540
|
+
# def buggy parameter_hash
|
1541
|
+
# parameter_hash[:before] = ''
|
1542
|
+
# parameter_hash[:exclude_method] = :doit3
|
1543
|
+
# aspect = Aspect.new parameter_hash do |jp, *args|
|
1544
|
+
# end
|
1545
|
+
# @excluded_objects.each do |object|
|
1546
|
+
# object.doit
|
1547
|
+
# end
|
1548
|
+
# aspect.unadvise
|
1549
|
+
# end
|
1550
|
+
#
|
1551
|
+
# it "#15202 bug..." do
|
1552
|
+
# pending "bug fix"
|
1553
|
+
# @pointcut5 = Pointcut.new :types => [Exclude1, Exclude1c], :method => /doit/
|
1554
|
+
# parameter_hash = { :pointcuts => [@pointcut5] } #[@pointcut1, @pointcut2, @pointcut3, @pointcut4] }
|
1555
|
+
# buggy parameter_hash
|
1556
|
+
# parameter_hash = { :objects => (@excluded_objects), :method => /doit/ }
|
1557
|
+
# buggy parameter_hash
|
1558
|
+
# end
|
1559
|
+
end
|