C0 code coverage information
Generated on Sun Oct 26 11:18:04 -0500 2008 with rcov 0.8.1.2
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 require File.dirname(__FILE__) + '/../spec_helper'
2 require 'aquarium/spec_example_types'
3 require 'aquarium/utils/type_utils_sample_nested_types'
4 require 'aquarium/aspects/aspect'
5 require 'aquarium/dsl'
6 require 'aquarium/utils/array_utils'
7 require 'aquarium/finders/pointcut_finder_spec_test_classes'
8
9 require 'profiler'
10
11 include Aquarium::Aspects
12 include Aquarium::Utils::ArrayUtils
13 include Aquarium::PointcutFinderTestClasses
14
15
16 def aspects_should_be_equal num_jps, aspect1, aspect2
17 # We don't use @aspect1.should eql(@aspect2) because the "specifications" are different.
18 aspect1.pointcuts.size.should == 1
19 aspect2.pointcuts.size.should == 1
20 aspect1.pointcuts.should eql(aspect2.pointcuts)
21 aspect1.advice.should eql(@advice)
22 aspect2.advice.should eql(@advice)
23 join_points_should_be_equal num_jps, aspect1, aspect2
24 end
25
26 def join_points_should_be_equal num_jps, aspect1, aspect2
27 aspect1.join_points_matched.size.should == num_jps
28 aspect2.join_points_matched.size.should == num_jps
29 aspect1.join_points_matched.each {|jp| @expected_methods.should include(jp.method_name)}
30 aspect2.join_points_matched.each {|jp| @expected_methods.should include(jp.method_name)}
31 aspect1.join_points_matched.should eql(aspect2.join_points_matched)
32 aspect1.join_points_not_matched.should eql(aspect2.join_points_not_matched)
33 end
34
35 module Aquarium
36 class AspectInvocationTestClass
37 include Aquarium::DSL
38 attr_accessor :public_test_method_args
39 def public_test_method *args; @args=args; end
40 protected
41 def protected_test_method *args; @args=args; end
42 private
43 def private_test_method *args; @args=args; end
44 def self.public_class_test_method *args; end
45 def self.private_class_test_method *args; end
46 private_class_method :private_class_test_method
47 end
48 class AspectInvocationTestClass2
49 include Aquarium::DSL
50 attr_accessor :public_test_method_args
51 def public_test_method *args; @args=args; end
52 end
53 class AspectInvocationTestClass3
54 attr_accessor :public_test_method_args
55 attr_accessor :public_test_method_args2
56 def public_test_method *args; @args=args; end
57 end
58 end
59
60 describe Aspect, "methods" do
61 include Aquarium::TypeUtilsStub
62
63 before :all do
64 stub_type_utils_descendents
65 end
66 after :all do
67 unstub_type_utils_descendents
68 end
69
70 describe Aspect, ".new (the :ignore_no_matching_join_points parameter that specifies whether or not to warn about no join point matches)" do
71 before :each do
72 @log_stream = StringIO.new
73 end
74
75 it "should warn about no join point matches if the :ignore_no_matching_join_points is not specified." do
76 lambda {Aspect.new(:after, :logger_stream => @log_stream) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
77 @log_stream.string.should_not be_empty
78 end
79 it "should warn about no join point matches if :ignore_no_matching_join_points => false is specified." do
80 lambda {Aspect.new(:after, :logger_stream => @log_stream, :ignore_no_matching_join_points => false) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
81 @log_stream.string.should_not be_empty
82 end
83 it "should not warn about no join point matches if :ignore_no_matching_join_points => true is specified." do
84 lambda {Aspect.new(:after, :logger_stream => @log_stream, :ignore_no_matching_join_points => true) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
85 @log_stream.string.should be_empty
86 end
87 end
88
89 describe Aspect, ".new (parameters that specify the kind of advice)" do
90 before :all do
91 @pointcut_opts = {:type => Aquarium::AspectInvocationTestClass}
92 end
93
94 it "should require the kind of advice as the first parameter." do
95 lambda { Aspect.new :pointcut => @pointcut_opts }.should raise_error(Aquarium::Utils::InvalidOptions)
96 end
97
98 it "should contain no other advice types if :around advice specified." do
99 lambda { Aspect.new :around, :before, :pointcut => @pointcut_opts }.should raise_error(Aquarium::Utils::InvalidOptions)
100 lambda { Aspect.new :around, :after, :pointcut => @pointcut_opts }.should raise_error(Aquarium::Utils::InvalidOptions)
101 lambda { Aspect.new :around, :after_returning, :pointcut => @pointcut_opts }.should raise_error(Aquarium::Utils::InvalidOptions)
102 lambda { Aspect.new :around, :after_raising, :pointcut => @pointcut_opts }.should raise_error(Aquarium::Utils::InvalidOptions)
103 end
104
105 it "should allow only one of :after, :after_returning, or :after_raising advice to be specified." do
106 lambda { Aspect.new :after, :after_returning, :pointcut => @pointcut_opts }.should raise_error(Aquarium::Utils::InvalidOptions)
107 lambda { Aspect.new :after, :after_raising, :pointcut => @pointcut_opts }.should raise_error(Aquarium::Utils::InvalidOptions)
108 lambda { Aspect.new :after_returning, :after_raising, :pointcut => @pointcut_opts }.should raise_error(Aquarium::Utils::InvalidOptions)
109 end
110
111 it "should allow :before to be specified with :after." do
112 lambda { Aspect.new :before, :after, :pointcut => @pointcut_opts, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
113 end
114
115 it "should allow :before to be specified with :after_returning." do
116 lambda { Aspect.new :before, :after_returning, :pointcut => @pointcut_opts, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
117 end
118
119 it "should allow :before to be specified with :after_raising." do
120 lambda { Aspect.new :before, :after_raising, :pointcut => @pointcut_opts, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
121 end
122
123 it "should accept a single exception specified with :after_raising." do
124 lambda { Aspect.new :before, :after_raising => Exception, :pointcut => @pointcut_opts, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
125 end
126
127 it "should accept a list of exceptions specified with :after_raising." do
128 lambda { Aspect.new :before, :after_raising => [Exception, String], :pointcut => @pointcut_opts, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
129 end
130
131 it "should accept a separate :exceptions => list of exceptions specified with :after_raising." do
132 lambda { Aspect.new :before, :after_raising, :exceptions => [Exception, String], :pointcut => @pointcut_opts, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
133 end
134
135 it "should reject the :exceptions argument unless specified with :after_raising." do
136 lambda { Aspect.new :before, :after, :exceptions => [Exception, String], :pointcut => @pointcut_opts, :noop => true }.should raise_error(Aquarium::Utils::InvalidOptions)
137 end
138 end
139
140 describe Aspect, ".new (parameters that specify pointcuts)" do
141 before :all do
142 @pointcut_opts = {:type => Aquarium::AspectInvocationTestClass}
143 end
144
145 it "should contain at least one of :method(s), :pointcut(s), :named_pointcut(s), :type(s), or :object(s)." do
146 lambda {Aspect.new(:after, :ignore_no_matching_join_points => true) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
147 end
148
149 it "should contain at least one of :pointcut(s), :named_pointcut(s), :type(s), or :object(s) unless :default_objects => object is given." do
150 aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass.new, :method => :public_test_method, :noop => true) {true}
151 end
152
153 it "should ignore the :default_objects if at least one other :object is given and the :default_objects are objects." do
154 object1 = Aquarium::AspectInvocationTestClass.new
155 object2 = Aquarium::AspectInvocationTestClass2.new
156 aspect = Aspect.new(:after, :default_objects => object1, :object => object2, :method => :public_test_method) {true}
157 aspect.join_points_matched.size.should == 1
158 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == object1}
159 end
160
161 it "should ignore the :default_objects if at least one other :object is given and the :default_objects are types." do
162 object = Aquarium::AspectInvocationTestClass2.new
163 aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass,
164 :object => object, :method => :public_test_method) {true}
165 aspect.join_points_matched.size.should == 1
166 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == Aquarium::AspectInvocationTestClass}
167 end
168
169 it "should ignore the :default_objects if at least one :pointcut is given even if the :default_objects => object are given." do
170 object = Aquarium::AspectInvocationTestClass.new
171 aspect = Aspect.new(:after, :default_objects => object,
172 :pointcut => {:type => Aquarium::AspectInvocationTestClass2, :method => :public_test_method}, :method => :public_test_method) {true}
173 aspect.join_points_matched.size.should == 1
174 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == object}
175 end
176
177 it "should ignore the :default_objects if at least one :pointcut is given even if the :default_objects => type are given." do
178 aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass,
179 :pointcut => {:type => Aquarium::AspectInvocationTestClass2, :method => :public_test_method}, :method => :public_test_method) {true}
180 aspect.join_points_matched.size.should == 1
181 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == Aquarium::AspectInvocationTestClass}
182 end
183
184 it "should ignore the :default_objects if at least one :join_point is given and the :default_objects are objects." do
185 join_point = JoinPoint.new :type => Aquarium::AspectInvocationTestClass2, :method => :public_test_method
186 object = Aquarium::AspectInvocationTestClass.new
187 aspect = Aspect.new(:after, :default_objects => object, :join_point => join_point, :method => :public_test_method) {true}
188 aspect.join_points_matched.size.should == 1
189 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == object}
190 end
191
192 it "should ignore the :default_objects if at least one :join_point is given and the :default_objects are types." do
193 join_point = JoinPoint.new :type => Aquarium::AspectInvocationTestClass2, :method => :public_test_method
194 aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass, :join_point => join_point, :method => :public_test_method) {true}
195 aspect.join_points_matched.size.should == 1
196 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == Aquarium::AspectInvocationTestClass}
197 end
198
199 [:type, :type_and_descendents, :type_and_ancestors, :type_and_nested_types].each do |type_key|
200 it "should ignore the :default_objects if at least one :#{type_key} is given and the :default_objects are objects." do
201 object = Aquarium::AspectInvocationTestClass.new
202 aspect = Aspect.new(:after, :default_objects => object, type_key => Aquarium::AspectInvocationTestClass2, :method => :public_test_method, :method => :public_test_method) {true}
203 aspect.join_points_matched.size.should == 1
204 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == object}
205 end
206
207 it "should ignore the :default_objects if at least one :#{type_key} is given and the :default_objects are types." do
208 aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass, type_key => Aquarium::AspectInvocationTestClass2, :method => :public_test_method, :method => :public_test_method) {true}
209 aspect.join_points_matched.size.should == 1
210 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == Aquarium::AspectInvocationTestClass}
211 end
212 end
213
214 Aspect::CANONICAL_OPTIONS["default_objects"].each do |key|
215 it "should accept :#{key} as a synonym for :default_objects." do
216 aspect = Aspect.new(:after, key.intern => Aquarium::AspectInvocationTestClass.new, :method => :public_test_method, :noop => true) {true}
217 end
218 end
219
220 it "should not contain :pointcut(s) and either :type(s) or :object(s)." do
221 lambda {Aspect.new(:after, :pointcuts => @pointcut_opts, :type => Aquarium::AspectInvocationTestClass, :method => :public_test_method) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
222 lambda {Aspect.new(:after, :pointcuts => @pointcut_opts, :object => Aquarium::AspectInvocationTestClass.new, :method => :public_test_method) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
223 end
224 end
225
226 describe Aspect, ".new (parameters that specify named constant and/or class variable pointcuts)" do
227 it "should contain at least one :types or TypeFinder synonym for :types." do
228 lambda {Aspect.new(:after, :named_pointcuts => {}, :noop => true) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
229 lambda {Aspect.new(:after, :named_pointcuts => {:types => all_pointcut_classes}, :noop => true) {true}}.should_not raise_error(Aquarium::Utils::InvalidOptions)
230 end
231
232 it "should ignore the :default_objects if at least one :named_pointcut is given even if the :default_objects => object are given." do
233 object = Aquarium::AspectInvocationTestClass.new
234 aspect = Aspect.new(:after, :default_objects => object, :named_pointcut => {:types => Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1}) {true}
235 aspect.join_points_matched.size.should == 1
236 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == object}
237 end
238
239 it "should ignore the :default_objects if at least one :named_pointcut is given even if the :default_objects => type are given." do
240 aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass, :named_pointcut => {:types => Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1}) {true}
241 aspect.join_points_matched.size.should == 1
242 aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == Aquarium::AspectInvocationTestClass}
243 end
244
245 Aspect::CANONICAL_OPTIONS["named_pointcuts"].each do |key|
246 it "should accept :#{key} as a synonym for :named_pointcuts." do
247 lambda { Aspect.new :before, key.intern => {:types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes}, :noop => true do; end }.should_not raise_error
248 end
249 end
250
251 it "should not contain :named_pointcut(s) and either :type(s) or :object(s)." do
252 lambda {Aspect.new(:after, :named_pointcuts => {:types => Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1}, :type => Aquarium::AspectInvocationTestClass, :method => :public_test_method) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
253 lambda {Aspect.new(:after, :named_pointcuts => {:types => Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1}, :object => Aquarium::AspectInvocationTestClass.new, :method => :public_test_method) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
254 end
255 end
256
257 describe Aspect, ".new with :types parameter" do
258 it "should advise the specified types." do
259 @advice_called = false
260 aspect = Aspect.new :before, :types => Aquarium::AspectInvocationTestClass, :method => :public_test_method do; @advice_called = true; end
261 Aquarium::AspectInvocationTestClass.new.public_test_method
262 aspect.unadvise
263 @advice_called.should be_true
264 end
265
266 Aspect::CANONICAL_OPTIONS["types"].each do |key|
267 it "should accept :#{key} as a synonym for :types." do
268 lambda { Aspect.new :before, key.intern => Aquarium::AspectInvocationTestClass, :method => :public_test_method, :noop => true do; end }.should_not raise_error
269 end
270 end
271 end
272
273 describe Aspect, ".new with :pointcuts parameter" do
274 it "should advise the specified pointcuts." do
275 @advice_called = false
276 aspect = Aspect.new :before, :pointcuts => {:types => Aquarium::AspectInvocationTestClass, :method => :public_test_method} do; @advice_called = true; end
277 Aquarium::AspectInvocationTestClass.new.public_test_method
278 aspect.unadvise
279 @advice_called.should be_true
280 end
281
282 Aspect::CANONICAL_OPTIONS["pointcuts"].each do |key|
283 it "should accept :#{key} as a synonym for :pointcuts." do
284 lambda { Aspect.new :before, key.intern => {:type => Aquarium::AspectInvocationTestClass, :method => :public_test_method}, :noop => true do; end }.should_not raise_error
285 end
286 end
287 end
288
289 describe Aspect, ".new with :objects parameter" do
290 it "should advise the specified objects." do
291 @advice_called = false
292 object = Aquarium::AspectInvocationTestClass.new
293 aspect = Aspect.new :before, :objects => object, :method => :public_test_method do; @advice_called = true; end
294 object.public_test_method
295 aspect.unadvise
296 @advice_called.should be_true
297 end
298
299 Aspect::CANONICAL_OPTIONS["objects"].each do |key|
300 it "should accept :#{key} as a synonym for :objects." do
301 object = Aquarium::AspectInvocationTestClass.new
302 lambda { Aspect.new :before, key.intern => object, :method => :public_test_method, :noop => true do; end }.should_not raise_error
303 end
304 end
305 end
306
307 describe Aspect, ".new with :methods parameter" do
308 it "should advise the specified methods." do
309 @advice_called = false
310 aspect = Aspect.new :before, :types => Aquarium::AspectInvocationTestClass, :methods => :public_test_method do; @advice_called = true; end
311 Aquarium::AspectInvocationTestClass.new.public_test_method
312 aspect.unadvise
313 @advice_called.should be_true
314 end
315
316 Aspect::CANONICAL_OPTIONS["methods"].each do |key|
317 it "should accept :#{key} as a synonym for :methods." do
318 lambda { Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, key.intern => :public_test_method, :noop => true do; end }.should_not raise_error
319 end
320 end
321 end
322
323 describe Aspect, ".new (:attributes parameter)" do
324 Aspect::CANONICAL_OPTIONS["attributes"].each do |key|
325 it "should accept :#{key} as a synonym for :attributes." do
326 @advice_called = false
327 aspect = Aspect.new :before, :types => Aquarium::AspectInvocationTestClass, :attributes => :public_test_method_args do; @advice_called = true; end
328 Aquarium::AspectInvocationTestClass.new.public_test_method_args
329 aspect.unadvise
330 end
331 end
332
333 it "should require the values for :reading => ... and :writing => ... to be equal if both are specified." do
334 @advice = Proc.new {}
335 lambda {Aspect.new :before, :type => Aquarium::AspectInvocationTestClass3,
336 :reading => :public_test_method_args, :writing => :public_test_method_args2, :advice => @advice}.should raise_error(Aquarium::Utils::InvalidOptions)
337 end
338
339 it "should require the values for :reading => ... and :changing => ... to be equal if both are specified." do
340 @advice = Proc.new {}
341 lambda {Aspect.new :before, :type => Aquarium::AspectInvocationTestClass3,
342 :reading => :public_test_method_args, :changing => :public_test_method_args2, :advice => @advice}.should raise_error(Aquarium::Utils::InvalidOptions)
343 end
344
345 it "should accept :reading => ... as a synonym for :attributes => ..., :attribute_options => [:readers]." do
346 @advice = Proc.new {}
347 @expected_methods = [:public_test_method_args]
348 aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :reading => :public_test_method_args, :advice => @advice
349 aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :attributes => :public_test_method_args, :attribute_options => [:readers], :advice => @advice
350 aspects_should_be_equal 1, aspect1, aspect2
351 aspect1.unadvise
352 aspect2.unadvise
353 end
354
355 it "should accept :writing => ... as a synonym for :attributes => ..., :attribute_options => [:writer]." do
356 @advice = Proc.new {}
357 @expected_methods = [:public_test_method_args=]
358 aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :writing => :public_test_method_args, :advice => @advice
359 aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :attributes => :public_test_method_args, :attribute_options => [:writers], :advice => @advice
360 aspects_should_be_equal 1, aspect1, aspect2
361 aspect1.unadvise
362 aspect2.unadvise
363 end
364
365 it "should accept :changing => ... as a synonym for :attributes => ..., :attribute_options => [:writer]." do
366 @advice = Proc.new {}
367 @expected_methods = [:public_test_method_args=]
368 aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :changing => :public_test_method_args, :advice => @advice
369 aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :attributes => :public_test_method_args, :attribute_options => [:writers], :advice => @advice
370 aspects_should_be_equal 1, aspect1, aspect2
371 aspect1.unadvise
372 aspect2.unadvise
373 end
374 end
375
376 describe Aspect, ".new (with a :type(s) parameter and a :method(s) parameter)" do
377 before :each do
378 @protection = 'public'
379 @are_class_methods = false
380 @types_option = :types
381 @method_options = []
382 end
383
384 def do_type_spec
385 aspect = nil
386 advice_called = false
387 aspect = Aspect.new :before, @types_option => @type_spec, :methods => @method_spec, :method_options => @method_options do |jp, obj, *args|
388 advice_called = true
389 jp.should_not be_nil
390 args.size.should == 4
391 args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
392 end
393 if @are_class_methods
394 Aquarium::AspectInvocationTestClass.method("#{@protection}_class_test_method").call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
395 else
396 Aquarium::AspectInvocationTestClass.new.method("#{@protection}_test_method").call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
397 end
398 advice_called.should be_true
399 aspect.unadvise
400 end
401
402 it "should accept :type(s) => T1, :methods => m" do
403 @type_spec = Aquarium::AspectInvocationTestClass
404 @method_spec = :public_test_method
405 do_type_spec
406 end
407
408 it "should accept :type(s) => T1, :methods => [m, ...]" do
409 @type_spec = Aquarium::AspectInvocationTestClass
410 @method_spec = [:public_test_method]
411 do_type_spec
412 end
413
414 it "should accept :type(s) => T1, :methods => /m/" do
415 @type_spec = Aquarium::AspectInvocationTestClass
416 @method_spec = /test_method/
417 do_type_spec
418 end
419
420 it "should accept :type(s) => [T1, ...], :methods => m" do
421 @type_spec = [Aquarium::AspectInvocationTestClass]
422 @method_spec = :public_test_method
423 do_type_spec
424 end
425
426 it "should accept :type(s) => [T1, ...], :methods => [m, ...]" do
427 @type_spec = [Aquarium::AspectInvocationTestClass]
428 @method_spec = [:public_test_method]
429 do_type_spec
430 end
431
432 it "should accept :type(s) => [T1, ...], :methods => /m/" do
433 @type_spec = [Aquarium::AspectInvocationTestClass]
434 @method_spec = /test_method/
435 do_type_spec
436 end
437
438 it "should accept :type(s) => /T1/, :methods => m" do
439 @type_spec = /Aquarium::AspectInvocationTestClass/
440 @method_spec = :public_test_method
441 do_type_spec
442 end
443
444 it "should accept :type(s) => /T1/, :methods => [m, ...]" do
445 @type_spec = /Aquarium::AspectInvocationTestClass/
446 @method_spec = [:public_test_method]
447 do_type_spec
448 end
449
450 it "should accept :type(s) => /T1/, :methods => /m/" do
451 @type_spec = /Aquarium::AspectInvocationTestClass/
452 @method_spec = /test_method/
453 do_type_spec
454 end
455
456 it "should accept :type(s)_and_ancestors => T1, :methods => [m, ...]" do
457 @types_option = :types_and_ancestors
458 @type_spec = Aquarium::AspectInvocationTestClass
459 @method_spec = [:public_test_method]
460 do_type_spec
461 end
462
463 it "should accept :type(s)_and_ancestors => [T1, ...], :methods => [m, ...]" do
464 @types_option = :types_and_ancestors
465 @type_spec = [Aquarium::AspectInvocationTestClass]
466 @method_spec = [:public_test_method]
467 do_type_spec
468 end
469
470 it "should accept :type(s)_and_ancestors => /T1/, :methods => [m, ...]" do
471 @types_option = :types_and_ancestors
472 @type_spec = /Aquarium::AspectInvocationTestClass/
473 @method_spec = [:public_test_method]
474 do_type_spec
475 end
476
477 it "should accept :type(s)_and_descendents => T1, :methods => [m, ...]" do
478 @types_option = :types_and_descendents
479 @type_spec = Aquarium::AspectInvocationTestClass
480 @method_spec = [:public_test_method]
481 do_type_spec
482 end
483
484 it "should accept :type(s)_and_descendents => [T1, ...], :methods => [m, ...]" do
485 @types_option = :types_and_descendents
486 @type_spec = [Aquarium::AspectInvocationTestClass]
487 @method_spec = [:public_test_method]
488 do_type_spec
489 end
490
491 it "should accept :type(s)_and_descendents => /T1/, :methods => [m, ...]" do
492 @types_option = :types_and_descendents
493 @type_spec = /Aquarium::AspectInvocationTestClass/
494 @method_spec = [:public_test_method]
495 do_type_spec
496 end
497
498 it "should accept :type(s)_and_nested_types => T1, :methods => [m, ...]" do
499 @types_option = :types_and_nested_types
500 @type_spec = Aquarium::AspectInvocationTestClass
501 @method_spec = [:public_test_method]
502 do_type_spec
503 end
504
505 it "should accept :type(s)_and_nested_types => [T1, ...], :methods => [m, ...]" do
506 @types_option = :types_and_nested_types
507 @type_spec = [Aquarium::AspectInvocationTestClass]
508 @method_spec = [:public_test_method]
509 do_type_spec
510 end
511
512 it "should accept :type(s)_and_nested_types => /T1/, :methods => [m, ...]" do
513 @types_option = :types_and_nested_types
514 @type_spec = /Aquarium::AspectInvocationTestClass/
515 @method_spec = [:public_test_method]
516 do_type_spec
517 end
518
519 it "should accept :type(s) => ..., :methods => ..., :method_options => [:exclude_ancestor_methods] to exclude methods defined in ancestors" do
520 @type_spec = /Aquarium::AspectInvocationTestClass/
521 @method_spec = /test_method/
522 @method_options = [:exclude_ancestor_methods]
523 do_type_spec
524 end
525
526 it "should accept :type(s) => ..., :methods => ..., :method_options => [:instance, :public] to match only instance and public (both are the defaults) methods" do
527 @type_spec = /Aquarium::AspectInvocationTestClass/
528 @method_spec = /test_method/
529 @method_options = [:instance, :public]
530 do_type_spec
531 end
532
533 %w[public protected private].each do |protection|
534 it "should accept :type(s) => ..., :methods => ..., :method_options => [#{protection.intern}] to match only instance (default) #{protection} methods" do
535 @type_spec = /Aquarium::AspectInvocationTestClass/
536 @method_spec = /test_method/
537 @method_options = [protection.intern]
538 @protection = protection
539 do_type_spec
540 end
541 end
542
543 it "should accept :type(s) => ..., :methods => ..., :method_options => [:class] to match only public (default) class methods" do
544 @type_spec = /Aquarium::AspectInvocationTestClass/
545 @method_spec = /test_method/
546 @method_options = [:class]
547 @are_class_methods = true
548 do_type_spec
549 end
550
551 %w[public private].each do |protection|
552 it "should accept :type(s) => ..., :methods => ..., :method_options => [:class, :#{protection.intern}] to match only class #{protection} methods" do
553 @type_spec = /Aquarium::AspectInvocationTestClass/
554 @method_spec = /test_method/
555 @method_options = [:class, protection.intern]
556 @protection = protection
557 @are_class_methods = true
558 do_type_spec
559 end
560 end
561 end
562
563
564 describe Aspect, ".new (with a :type(s) parameter and a :attribute(s) parameter)" do
565 before :each do
566 @protection = 'public'
567 @attribute_options = []
568 @are_class_methods = false
569 end
570
571 def do_type_attribute_spec
572 aspect = nil
573 advice_called = false
574 aspect = Aspect.new :before, :types => @type_spec, :attributes => @attribute_spec, :attribute_options => @attribute_options do |jp, obj, *args|
575 advice_called = true
576 jp.should_not be_nil
577 expected_args = make_array(@expected_args)
578 args.should == expected_args
579 args.size.should == expected_args.size
580 end
581 object = Aquarium::AspectInvocationTestClass.new
582 @expected_args = nil
583 object.method("#{@protection}_test_method_args".intern).call
584 @expected_args = :a1
585 object.method("#{@protection}_test_method_args=".intern).call @expected_args
586 advice_called.should be_true
587 aspect.unadvise
588 end
589
590 it "should accept :type(s) => [T1, ...], :attribute(s) => [a, ...]" do
591 @type_spec = [Aquarium::AspectInvocationTestClass]
592 @attribute_spec = [:public_test_method_args]
593 do_type_attribute_spec
594 end
595
596 it "should accept :type(s) => [T1, ...], :attribute(s) => a" do
597 @type_spec = [Aquarium::AspectInvocationTestClass]
598 @attribute_spec = :public_test_method_args
599 do_type_attribute_spec
600 end
601
602 it "should accept :type(s) => [T1, ...], :attribute(s) => /a/" do
603 @type_spec = [Aquarium::AspectInvocationTestClass]
604 @attribute_spec = /test_method_args/
605 do_type_attribute_spec
606 end
607
608 it "should accept :type(s) => T1, :attribute(s) => [a]" do
609 @type_spec = Aquarium::AspectInvocationTestClass
610 @attribute_spec = [:public_test_method_args]
611 do_type_attribute_spec
612 end
613
614 it "should accept :type(s) => T1, :attribute(s) => a" do
615 @type_spec = Aquarium::AspectInvocationTestClass
616 @attribute_spec = :public_test_method_args
617 do_type_attribute_spec
618 end
619
620 it "should accept :type(s) => T1, :attribute(s) => /a/" do
621 @type_spec = Aquarium::AspectInvocationTestClass
622 @attribute_spec = /test_method_args/
623 do_type_attribute_spec
624 end
625
626 it "should accept :type(s) => /T1/, :attribute(s) => [a, ...]" do
627 @type_spec = /Aquarium::AspectInvocationTestClass/
628 @attribute_spec = [:public_test_method_args]
629 do_type_attribute_spec
630 end
631
632 it "should accept :type(s) => /T1/, :attribute(s) => a" do
633 @type_spec = /Aquarium::AspectInvocationTestClass/
634 @attribute_spec = :public_test_method_args
635 do_type_attribute_spec
636 end
637
638 it "should accept :type(s) => /T1/, :attribute(s) => a" do
639 @type_spec = /Aquarium::AspectInvocationTestClass/
640 @attribute_spec = /test_method_args/
641 do_type_attribute_spec
642 end
643
644 it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:readers, :writers] to include both attribute reader and writer methods (default)" do
645 @type_spec = /Aquarium::AspectInvocationTestClass/
646 @attribute_spec = /test_method_args/
647 @attribute_options = [:readers, :writers]
648 do_type_attribute_spec
649 end
650
651 it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:readers] to include only attribute reader methods" do
652 @type_spec = /Aquarium::AspectInvocationTestClass/
653 @attribute_spec = /test_method_args/
654 @attribute_options = [:readers]
655 do_type_attribute_spec
656 end
657
658 it "should accept attribute option :reader as a synonym for :readers" do
659 @type_spec = /Aquarium::AspectInvocationTestClass/
660 @attribute_spec = /test_method_args/
661 @attribute_options = [:reader]
662 do_type_attribute_spec
663 end
664
665 it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:writers] to include only attribute writer methods" do
666 @type_spec = /Aquarium::AspectInvocationTestClass/
667 @attribute_spec = /test_method_args/
668 @attribute_options = [:writers]
669 do_type_attribute_spec
670 end
671
672 it "should accept attribute option :writer as a synonym for :writers" do
673 @type_spec = /Aquarium::AspectInvocationTestClass/
674 @attribute_spec = /test_method_args/
675 @attribute_options = [:writer]
676 do_type_attribute_spec
677 end
678
679 it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:class, :readers, :writers] to include both attribute reader and writer methods (default) for class methods" do
680 @type_spec = /Aquarium::AspectInvocationTestClass/
681 @attribute_spec = /test_method_args/
682 @attribute_options = [:class, :readers, :writers]
683 do_type_attribute_spec
684 end
685
686 it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:class, :readers] to include only attribute reader class methods" do
687 @type_spec = /Aquarium::AspectInvocationTestClass/
688 @attribute_spec = /test_method_args/
689 @attribute_options = [:class, :readers]
690 do_type_attribute_spec
691 end
692
693 it "should accept :type(s) => ..., :attributes => ..., :attribute_options => [:class, :writers] to include only attribute writer class methods" do
694 @type_spec = /Aquarium::AspectInvocationTestClass/
695 @attribute_spec = /test_method_args/
696 @attribute_options = [:class, :writers]
697 do_type_attribute_spec
698 end
699 end
700
701 describe Aspect, ".new (with a :object(s) parameter and a :method(s) parameter)" do
702 before :each do
703 @object1 = Aquarium::AspectInvocationTestClass.new
704 @object2 = Aquarium::AspectInvocationTestClass.new
705 @protection = 'public'
706 @method_options = []
707 end
708
709 def do_object_spec
710 aspect = nil
711 advice_called = false
712 aspect = Aspect.new :before, :objects => @object_spec, :methods => @method_spec, :method_options => @method_options do |jp, obj, *args|
713 advice_called = true
714 jp.should_not be_nil
715 args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
716 end
717 make_array(@object_spec).each do |object|
718 object.method("#{@protection}_test_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
719 end
720 advice_called.should be_true
721 aspect.unadvise
722 end
723
724 it "should accept :object(s) => [o1, ...], :methods => [m, ...]" do
725 @object_spec = [@object1, @object2]
726 @method_spec = [:public_test_method]
727 do_object_spec
728 end
729
730 it "should accept :object(s) => [o1, ...], :methods => m" do
731 @object_spec = [@object1, @object2]
732 @method_spec = :public_test_method
733 do_object_spec
734 end
735
736 it "should accept :object(s) => [o1, ...], :methods => /m/" do
737 @object_spec = [@object1, @object2]
738 @method_spec = /test_method/
739 do_object_spec
740 end
741
742 it "should accept :object(s) => o1, :methods => [m, ...]" do
743 @object_spec = @object1
744 @method_spec = [:public_test_method]
745 do_object_spec
746 end
747
748 it "should accept :object(s) => o1, :methods => m" do
749 @object_spec = @object1
750 @method_spec = :public_test_method
751 do_object_spec
752 end
753
754 it "should accept :object(s) => o1, :methods => /m/" do
755 @object_spec = @object1
756 @method_spec = /test_method/
757 do_object_spec
758 end
759
760 it "should accept :object(s) => ..., :methods => ..., :method_options => [:exclude_ancestor_methods] to exclude methods defined in ancestors" do
761 @object_spec = @object1
762 @method_spec = /test_method/
763 @method_options = [:exclude_ancestor_methods]
764 do_object_spec
765 end
766
767 it "should accept :object(s) => ..., :methods => ..., :method_options => [:instance, :public] to match only instance and public (both are the defaults) methods" do
768 @object_spec = @object1
769 @method_spec = /test_method/
770 @method_options = [:instance, :public]
771 do_object_spec
772 end
773
774 %w[public protected private].each do |protection|
775 it "should accept :object(s) => ..., :methods => ..., :method_options => [#{protection.intern}] to match only instance (default) #{protection} methods" do
776 @object_spec = @object1
777 @method_spec = /test_method/
778 @method_options = [protection.intern]
779 @protection = protection
780 do_object_spec
781 end
782
783 it "should accept :object(s) => ..., :methods => ..., :method_options => [:instance, #{protection.intern}] to match only instance #{protection} methods" do
784 @object_spec = @object1
785 @method_spec = /test_method/
786 @method_options = [:instance, protection.intern]
787 @protection = protection
788 do_object_spec
789 end
790 end
791 end
792
793 describe Aspect, ".new (with a :object(s) parameter and a :attribute(s) parameter)" do
794 before :each do
795 @object1 = Aquarium::AspectInvocationTestClass.new
796 @object2 = Aquarium::AspectInvocationTestClass.new
797 @protection = 'public'
798 @attribute_options = []
799 end
800
801 def do_object_attribute_spec
802 aspect = nil
803 advice_called = false
804 aspect = Aspect.new :before, :objects => @object_spec, :attributes => @attribute_spec, :attribute_options => @attribute_options do |jp, obj, *args|
805 advice_called = true
806 jp.should_not be_nil
807 expected_args = make_array(@expected_args)
808 args.should == expected_args
809 args.size.should == expected_args.size
810 end
811 make_array(@object_spec).each do |object|
812 @expected_args = nil
813 object.method("#{@protection}_test_method_args".intern).call
814 @expected_args = :a1
815 object.method("#{@protection}_test_method_args=".intern).call @expected_args
816 advice_called.should be_true
817 end
818 aspect.unadvise
819 end
820
821 it "should accept :object(s) => [T1, ...], :attribute(s) => [a, ...]" do
822 @object_spec = [@object1, @object2]
823 @attribute_spec = [:public_test_method_args]
824 do_object_attribute_spec
825 end
826
827 it "should accept :object(s) => [T1, ...], :attribute(s) => a" do
828 @object_spec = [@object1, @object2]
829 @attribute_spec = :public_test_method_args
830 do_object_attribute_spec
831 end
832
833 it "should accept :object(s) => [T1, ...], :attribute(s) => /a/" do
834 @object_spec = [@object1, @object2]
835 @attribute_spec = /test_method_args/
836 do_object_attribute_spec
837 end
838
839 it "should accept :object(s) => T1, :attribute(s) => [a]" do
840 @object_spec = @object1
841 @attribute_spec = [:public_test_method_args]
842 do_object_attribute_spec
843 end
844
845 it "should accept :object(s) => T1, :attribute(s) => a" do
846 @object_spec = @object1
847 @attribute_spec = :public_test_method_args
848 do_object_attribute_spec
849 end
850
851 it "should accept :object(s) => T1, :attribute(s) => /a/" do
852 @object_spec = @object1
853 @attribute_spec = /test_method_args/
854 do_object_attribute_spec
855 end
856
857 it "should accept :object(s) => ..., :attributes => ..., :attribute_options => [:readers, :writers] to include both attribute reader and writer methods (default)" do
858 @object_spec = @object1
859 @attribute_spec = /test_method_args/
860 @attribute_options = [:readers, :writers]
861 do_object_attribute_spec
862 end
863
864 it "should accept :object(s) => ..., :attributes => ..., :attribute_options => [:readers] to include only attribute reader methods" do
865 @object_spec = @object1
866 @attribute_spec = /test_method_args/
867 @attribute_options = [:readers]
868 do_object_attribute_spec
869 end
870
871 it "should accept attribute option :reader as a synonym for :readers" do
872 @object_spec = @object1
873 @attribute_spec = /test_method_args/
874 @attribute_options = [:reader]
875 do_object_attribute_spec
876 end
877
878 it "should accept :object(s) => ..., :attributes => ..., :attribute_options => [:writers] to include only attribute writer methods" do
879 @object_spec = @object1
880 @attribute_spec = /test_method_args/
881 @attribute_options = [:writers]
882 do_object_attribute_spec
883 end
884
885 it "should accept attribute option :writer as a synonym for :writers" do
886 @object_spec = @object1
887 @attribute_spec = /test_method_args/
888 @attribute_options = [:writer]
889 do_object_attribute_spec
890 end
891 end
892
893 describe Aspect, ".new (with a :pointcut parameter taking a hash with type specifications)" do
894 before :each do
895 @protection = 'public'
896 @are_class_methods = false
897 end
898
899 def do_type_pointcut_spec
900 aspect = nil
901 advice_called = false
902 aspect = Aspect.new :before, :pointcut => @pointcut_hash do |jp, obj, *args|
903 advice_called = true
904 jp.should_not be_nil
905 args.size.should == 4
906 args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
907 end
908 if @are_class_methods
909 Aquarium::AspectInvocationTestClass.method("#{@protection}_class_test_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
910 else
911 Aquarium::AspectInvocationTestClass.new.method("#{@protection}_test_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
912 end
913 advice_called.should be_true
914 aspect.unadvise
915 end
916
917 it "should accept {:type(s) => [T1, ...], :methods => [m, ...]} " do
918 @pointcut_hash = {:type => [Aquarium::AspectInvocationTestClass], :methods => [:public_test_method]}
919 do_type_pointcut_spec
920 end
921
922 it "should accept {:type(s) => [T1, ...], :methods => m} " do
923 @pointcut_hash = {:type => [Aquarium::AspectInvocationTestClass], :methods => :public_test_method}
924 do_type_pointcut_spec
925 end
926
927 it "should accept {:type(s) => [T1, ...], :methods => /m/} " do
928 @pointcut_hash = {:type => [Aquarium::AspectInvocationTestClass], :methods => /test_method/}
929 do_type_pointcut_spec
930 end
931
932 it "should accept {:type(s)_and_ancestors => [T1, ...], :methods => /m/} " do
933 @pointcut_hash = {:type_and_ancestors => [Aquarium::AspectInvocationTestClass], :methods => /test_method/}
934 do_type_pointcut_spec
935 end
936
937 it "should accept {:type(s)_and_descendents => [T1, ...], :methods => /m/} " do
938 @pointcut_hash = {:type_and_descendents => [Aquarium::AspectInvocationTestClass], :methods => /test_method/}
939 do_type_pointcut_spec
940 end
941
942 it "should accept {:type(s)_and_nested_types => [T1, ...], :methods => /m/} " do
943 @pointcut_hash = {:type_and_nested_types => [Aquarium::AspectInvocationTestClass], :methods => /test_method/}
944 do_type_pointcut_spec
945 end
946
947 it "should accept {:type(s) => T1, :methods => [m, ...]} " do
948 @pointcut_hash = {:type => Aquarium::AspectInvocationTestClass, :methods => [:public_test_method]}
949 do_type_pointcut_spec
950 end
951
952 it "should accept {:type(s) => T1, :methods => m} " do
953 @pointcut_hash = {:type => Aquarium::AspectInvocationTestClass, :methods => :public_test_method}
954 do_type_pointcut_spec
955 end
956
957 it "should accept {:type(s) => T1, :methods => /m/} " do
958 @pointcut_hash = {:type => Aquarium::AspectInvocationTestClass, :methods => /test_method/}
959 do_type_pointcut_spec
960 end
961
962 it "should accept {:type(s)_and_ancestors => T1, :methods => /m/} " do
963 @pointcut_hash = {:type_and_ancestors => Aquarium::AspectInvocationTestClass, :methods => /test_method/}
964 do_type_pointcut_spec
965 end
966
967 it "should accept {:type(s)_and_descendents => T1, :methods => /m/} " do
968 @pointcut_hash = {:type_and_descendents => Aquarium::AspectInvocationTestClass, :methods => /test_method/}
969 do_type_pointcut_spec
970 end
971
972 it "should accept {:type(s)_and_nested_types => T1, :methods => /m/} " do
973 @pointcut_hash = {:type_and_nested_types => Aquarium::AspectInvocationTestClass, :methods => /test_method/}
974 do_type_pointcut_spec
975 end
976
977 it "should accept {:type(s) => /T1/, :methods => [m, ...]} " do
978 @pointcut_hash = {:type => /Aquarium::AspectInvocationTestClass/, :methods => [:public_test_method]}
979 do_type_pointcut_spec
980 end
981
982 it "should accept {:type(s) => /T1/, :methods => m} " do
983 @pointcut_hash = {:type => /Aquarium::AspectInvocationTestClass/, :methods => :public_test_method}
984 do_type_pointcut_spec
985 end
986
987 it "should accept {:type(s) => /T1/, :methods => /m/} " do
988 @pointcut_hash = {:type => /Aquarium::AspectInvocationTestClass/, :methods => /test_method/}
989 do_type_pointcut_spec
990 end
991
992 it "should accept {:type(s)_and_ancestors => /T1/, :methods => /m/} " do
993 @pointcut_hash = {:type_and_ancestors => /Aquarium::AspectInvocationTestClass/, :methods => /test_method/}
994 do_type_pointcut_spec
995 end
996
997 it "should accept {:type(s)_and_descendents => /T1/, :methods => /m/} " do
998 @pointcut_hash = {:type_and_descendents => /Aquarium::AspectInvocationTestClass/, :methods => /test_method/}
999 do_type_pointcut_spec
1000 end
1001
1002 it "should accept {:type(s)_and_nested_types => /T1/, :methods => /m/} " do
1003 @pointcut_hash = {:type_and_nested_types => /Aquarium::AspectInvocationTestClass/, :methods => /test_method/}
1004 do_type_pointcut_spec
1005 end
1006
1007 %w[public protected private].each do |protection|
1008 it "should accept {:type(s) => T1, :methods => /m/, :method_options =>[:instance, #{protection}]} " do
1009 @protection = protection
1010 @pointcut_hash = {:type => Aquarium::AspectInvocationTestClass, :methods => /test_method/, :method_options =>[:instance, protection.intern]}
1011 do_type_pointcut_spec
1012 end
1013 end
1014
1015 %w[public private].each do |protection|
1016 it "should accept {:type(s) => T1, :methods => /m/, :method_options =>[:class, #{protection}]} " do
1017 @pointcut_hash = {:type => Aquarium::AspectInvocationTestClass, :methods => /class_test_method/, :method_options =>[:class, protection.intern]}
1018 @protection = protection
1019 @are_class_methods = true
1020 do_type_pointcut_spec
1021 end
1022 end
1023
1024 it "should accept {:type(s) => T1, :methods => /m/, :method_options =>[:instance]} defaults to public methods" do
1025 @pointcut_hash = {:type => Aquarium::AspectInvocationTestClass, :methods => /test_method/, :method_options =>[:instance]}
1026 do_type_pointcut_spec
1027 end
1028
1029 it "should accept {:type(s) => T1, :methods => /m/, :method_options =>[:class]} defaults to public class methods" do
1030 @pointcut_hash = {:type => Aquarium::AspectInvocationTestClass, :methods => /test_method/, :method_options =>[:class]}
1031 @are_class_methods = true
1032 do_type_pointcut_spec
1033 end
1034 end
1035
1036 describe Aspect, ".new (with a :pointcut parameter taking a hash with object specifications)" do
1037 before :each do
1038 @protection = 'public'
1039 @expected_advice_count = 2
1040 @object1 = Aquarium::AspectInvocationTestClass.new
1041 @object2 = Aquarium::AspectInvocationTestClass.new
1042 end
1043
1044 def do_object_pointcut_spec
1045 aspect = nil
1046 advice_count = 0
1047 aspect = Aspect.new :before, :pointcut => @pointcut_hash do |jp, obj, *args|
1048 advice_count += 1
1049 jp.should_not be_nil
1050 args.size.should == 4
1051 args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
1052 end
1053 @object1.method("#{@protection}_test_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
1054 @object2.method("#{@protection}_test_method".intern).call :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
1055 advice_count.should == @expected_advice_count
1056 aspect.unadvise
1057 end
1058
1059 it "should accept {:objects => [o1, ...], :methods => [m, ...]} " do
1060 @pointcut_hash = {:objects => [@object1, @object2], :methods => [:public_test_method]}
1061 do_object_pointcut_spec
1062 end
1063
1064 it "should accept {:objects => [o1, ...], :methods => m} " do
1065 @pointcut_hash = {:objects => [@object1, @object2], :methods => :public_test_method}
1066 do_object_pointcut_spec
1067 end
1068
1069 it "should accept {:objects => [o1, ...], :methods => /m/} " do
1070 @pointcut_hash = {:objects => [@object1, @object2], :methods => /test_method/}
1071 do_object_pointcut_spec
1072 end
1073
1074 it "should accept {:object => o1, :methods => [m, ...]} " do
1075 @expected_advice_count = 1
1076 @pointcut_hash = {:object => @object1, :methods => [:public_test_method]}
1077 do_object_pointcut_spec
1078 end
1079
1080 it "should accept {:objects => o1, :methods => m} " do
1081 @expected_advice_count = 1
1082 @pointcut_hash = {:objects => @object1, :methods => :public_test_method}
1083 do_object_pointcut_spec
1084 end
1085
1086 it "should accept {:objects => o1, :methods => /m/} " do
1087 @expected_advice_count = 1
1088 @pointcut_hash = {:objects => @object1, :methods => /test_method/}
1089 do_object_pointcut_spec
1090 end
1091 end
1092
1093 describe Aspect, ".new (with a :pointcut parameter and a Pointcut object or an array of Pointcuts)" do
1094 def do_pointcut_pointcut_spec
1095 aspect = nil
1096 advice_called = false
1097 aspect = Aspect.new :before, :pointcut => @pointcuts do |jp, obj, *args|
1098 advice_called = true
1099 jp.should_not be_nil
1100 args.size.should == 4
1101 args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
1102 end
1103 Aquarium::AspectInvocationTestClass.new.public_test_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
1104 advice_called.should be_true
1105 aspect.unadvise
1106 end
1107
1108 it "should accept a single Pointcut object." do
1109 @pointcuts = Pointcut.new :type => [Aquarium::AspectInvocationTestClass], :methods => :public_test_method
1110 do_pointcut_pointcut_spec
1111 end
1112
1113 it "should accept an array of Pointcut objects." do
1114 pointcut1 = Pointcut.new :type => [Aquarium::AspectInvocationTestClass], :methods => :public_test_method
1115 pointcut2 = Pointcut.new :type => [Aquarium::AspectInvocationTestClass], :methods => :public_class_test_method, :method_options => [:class]
1116 @pointcuts = [pointcut1, pointcut2]
1117 do_pointcut_pointcut_spec
1118 end
1119 end
1120
1121 describe Aspect, ".new (with a :pointcut parameter and an array of Pointcuts)" do
1122 it "should treat the array as if it is one Pointcut \"or'ed\" together." do
1123 advice_called = 0
1124 advice = Proc.new {|jp, obj, *args|
1125 advice_called += 1
1126 jp.should_not be_nil
1127 args.size.should == 4
1128 args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
1129 }
1130 pointcut1 = Pointcut.new :type => [Aquarium::AspectInvocationTestClass], :methods => :public_test_method
1131 pointcut2 = Pointcut.new :type => [Aquarium::AspectInvocationTestClass], :methods => :public_class_test_method, :method_options => [:class]
1132 pointcut12 = pointcut1.or pointcut2