C0 code coverage information
Generated on Sun Oct 26 11:18:11 -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/utils/invalid_options'
5 require 'aquarium/extensions/hash'
6 require 'aquarium/aspects/join_point'
7 require 'aquarium/aspects/pointcut'
8 require 'aquarium/utils'
9
10 include Aquarium::Aspects
11
12 def before_exclude_spec
13 @jp11 = JoinPoint.new :type => ExcludeTestOne, :method_name => :method11
14 @jp12 = JoinPoint.new :type => ExcludeTestOne, :method_name => :method12
15 @jp13 = JoinPoint.new :type => ExcludeTestOne, :method_name => :method13
16 @jp21 = JoinPoint.new :type => ExcludeTestTwo, :method_name => :method21
17 @jp22 = JoinPoint.new :type => ExcludeTestTwo, :method_name => :method22
18 @jp23 = JoinPoint.new :type => ExcludeTestTwo, :method_name => :method23
19 @jp31 = JoinPoint.new :type => ExcludeTestThree, :method_name => :method31
20 @jp32 = JoinPoint.new :type => ExcludeTestThree, :method_name => :method32
21 @jp33 = JoinPoint.new :type => ExcludeTestThree, :method_name => :method33
22 @et1 = ExcludeTestOne.new
23 @et2 = ExcludeTestTwo.new
24 @et3 = ExcludeTestThree.new
25 @ojp11 = JoinPoint.new :object => @et1, :method_name => :method11
26 @ojp12 = JoinPoint.new :object => @et1, :method_name => :method12
27 @ojp13 = JoinPoint.new :object => @et1, :method_name => :method13
28 @ojp21 = JoinPoint.new :object => @et2, :method_name => :method21
29 @ojp22 = JoinPoint.new :object => @et2, :method_name => :method22
30 @ojp23 = JoinPoint.new :object => @et2, :method_name => :method23
31 @ojp31 = JoinPoint.new :object => @et3, :method_name => :method31
32 @ojp32 = JoinPoint.new :object => @et3, :method_name => :method32
33 @ojp33 = JoinPoint.new :object => @et3, :method_name => :method33
34 @all_type_jps = [@jp11, @jp12, @jp13, @jp21, @jp22, @jp23, @jp31, @jp32, @jp33]
35 @all_object_jps = [@ojp11, @ojp12, @ojp13, @ojp21, @ojp22, @ojp23, @ojp31, @ojp32, @ojp33]
36 @all_jps = @all_type_jps + @all_object_jps
37 end
38
39 def before_pointcut_class_spec
40 @example_classes_without_public_instance_method =
41 [ClassWithProtectedInstanceMethod, ClassWithPrivateInstanceMethod, ClassWithPublicClassMethod, ClassWithPrivateClassMethod]
42 @example_classes = ([ClassWithPublicInstanceMethod] + @example_classes_without_public_instance_method)
43 @pub_jp = JoinPoint.new :type => ClassWithPublicInstanceMethod, :method_name => :public_instance_test_method
44 @pro_jp = JoinPoint.new :type => ClassWithProtectedInstanceMethod, :method_name => :protected_instance_test_method
45 @pri_jp = JoinPoint.new :type => ClassWithPrivateInstanceMethod, :method_name => :private_instance_test_method
46 @cpub_jp = JoinPoint.new :type => ClassWithPublicClassMethod, :method_name => :public_class_test_method, :class_method => true
47 @cpri_jp = JoinPoint.new :type => ClassWithPrivateClassMethod, :method_name => :private_class_test_method, :class_method => true
48 @apro_jp = JoinPoint.new :type => ClassWithProtectedInstanceMethod, :method_name => :all
49 @apri_jp = JoinPoint.new :type => ClassWithPrivateInstanceMethod, :method_name => :all
50 @acpub_jp = JoinPoint.new :type => ClassWithPublicClassMethod, :method_name => :all
51 @acpri_jp = JoinPoint.new :type => ClassWithPrivateClassMethod, :method_name => :all
52 @cdcimpub_jp = JoinPoint.new :type => ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod, :method_name => :public_instance_class_derived_from_class_including_module_test_method
53 @expected_classes_matched_jps = Set.new [@pub_jp]
54 @expected_classes_not_matched_jps = Set.new [@apro_jp, @apri_jp, @acpub_jp, @acpri_jp]
55 end
56
57 def before_pointcut_module_spec
58 @example_modules_with_public_instance_method = [
59 ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod,
60 ClassIncludingModuleWithPublicInstanceMethod,
61 ModuleIncludingModuleWithPublicInstanceMethod,
62 ModuleWithPublicInstanceMethod]
63 @example_modules_without_public_instance_method = [
64 ClassIncludingModuleWithProtectedInstanceMethod,
65 ClassIncludingModuleWithPrivateInstanceMethod,
66 ClassIncludingModuleWithPublicClassMethod,
67 ClassIncludingModuleWithPrivateClassMethod,
68 ModuleWithProtectedInstanceMethod,
69 ModuleWithPrivateInstanceMethod,
70 ModuleWithPublicClassMethod,
71 ModuleWithPrivateClassMethod]
72 @example_modules = (@example_modules_with_public_instance_method + @example_modules_without_public_instance_method)
73 @mimpub_jp = JoinPoint.new :type => ModuleIncludingModuleWithPublicInstanceMethod, :method_name => :public_instance_module_including_module_test_method
74 @mpub_jp = JoinPoint.new :type => ModuleWithPublicInstanceMethod, :method_name => :public_instance_module_test_method
75 @mpro_jp = JoinPoint.new :type => ModuleWithProtectedInstanceMethod, :method_name => :protected_instance_module_test_method
76 @mpri_jp = JoinPoint.new :type => ModuleWithPrivateInstanceMethod, :method_name => :private_instance_module_test_method
77 @cmpub_jp = JoinPoint.new :type => ModuleWithPublicClassMethod, :method_name => :public_class_module_test_method, :class_method => true
78 @cmpri_jp = JoinPoint.new :type => ModuleWithPrivateClassMethod, :method_name => :private_class_module_test_method, :class_method => true
79 @ampro_jp = JoinPoint.new :type => ModuleWithProtectedInstanceMethod, :method_name => :all
80 @ampri_jp = JoinPoint.new :type => ModuleWithPrivateInstanceMethod, :method_name => :all
81 @acmpub_jp = JoinPoint.new :type => ModuleWithPublicClassMethod, :method_name => :all
82 @acmpri_jp = JoinPoint.new :type => ModuleWithPrivateClassMethod, :method_name => :all
83 @cdcimpub_jp = JoinPoint.new :type => ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod, :method_name => :public_instance_class_derived_from_class_including_module_test_method
84 @cimpub_jp = JoinPoint.new :type => ClassIncludingModuleWithPublicInstanceMethod, :method_name => :public_instance_class_including_module_test_method
85 @cimpro_jp = JoinPoint.new :type => ClassIncludingModuleWithProtectedInstanceMethod, :method_name => :protected_instance_class_including_module_test_method
86 @cimpri_jp = JoinPoint.new :type => ClassIncludingModuleWithPrivateInstanceMethod, :method_name => :private_instance_class_including_module_test_method
87 @ccimpub_jp = JoinPoint.new :type => ClassIncludingModuleWithPublicClassMethod, :method_name => :public_class_class_including_module_test_method, :class_method => true
88 @ccimpri_jp = JoinPoint.new :type => ClassIncludingModuleWithPrivateClassMethod, :method_name => :private_class_class_including_module_test_method, :class_method => true
89 @acimpro_jp = JoinPoint.new :type => ClassIncludingModuleWithProtectedInstanceMethod, :method_name => :all
90 @acimpri_jp = JoinPoint.new :type => ClassIncludingModuleWithPrivateInstanceMethod, :method_name => :all
91 @accimpub_jp = JoinPoint.new :type => ClassIncludingModuleWithPublicClassMethod, :method_name => :all
92 @accimpri_jp = JoinPoint.new :type => ClassIncludingModuleWithPrivateClassMethod, :method_name => :all
93 @expected_modules_matched_jps = Set.new [@mimpub_jp, @mpub_jp, @cdcimpub_jp, @cimpub_jp]
94 @expected_modules_not_matched_jps = Set.new [@ampro_jp, @ampri_jp, @acmpub_jp, @acmpri_jp, @acimpro_jp, @acimpri_jp, @accimpub_jp, @accimpri_jp]
95 end
96
97 def ignored_join_point jp
98 # Ignore any types introduced by RSpec, other Aquarium types, and the "pretty printer" module (which Rake uses?)
99 jp.target_type.name =~ /^Spec/ or jp.target_type.name =~ /^Aquarium::(Aspects|Extras|Utils|PointcutFinderTestClasses)/ or jp.target_type.name =~ /^PP/
100 end
101
102 describe Pointcut, "methods" do
103 include Aquarium::TypeUtilsStub
104
105 before :all do
106 stub_type_utils_descendents
107 end
108 after :all do
109 unstub_type_utils_descendents
110 end
111
112 describe Pointcut, ".new (invalid arguments)" do
113 it "should raise if an unknown argument is specified" do
114 lambda { Pointcut.new :foo => :bar }.should raise_error(Aquarium::Utils::InvalidOptions)
115 end
116 end
117
118 describe Pointcut, ".new (empty)" do
119 it "should match no join points by default." do
120 pc = Pointcut.new
121 pc.should be_empty
122 end
123
124 it "should match no join points if nil is the only argument specified." do
125 pc = Pointcut.new nil
126 pc.should be_empty
127 end
128
129 it "should match no join points if types = [] specified." do
130 pc = Pointcut.new :types => []
131 pc.should be_empty
132 end
133
134 it "should match no join points if types = nil specified." do
135 pc = Pointcut.new :types => nil
136 pc.should be_empty
137 end
138
139 it "should match no join points if objects = [] specified." do
140 pc = Pointcut.new :objects => []
141 pc.should be_empty
142 end
143
144 it "should match no join points if objects = nil specified." do
145 pc = Pointcut.new :objects => nil
146 pc.should be_empty
147 end
148
149 it "should match no join points if join_points = nil specified." do
150 pc = Pointcut.new :join_points => nil
151 pc.should be_empty
152 end
153
154 it "should match no join points if join_points = [] specified." do
155 pc = Pointcut.new :join_points => []
156 pc.should be_empty
157 end
158 end
159
160 describe Pointcut, ".new (classes specified using regular expressions)" do
161 before(:each) do
162 before_pointcut_class_spec
163 end
164
165 it "should match multiple classes using regular expressions that cover the full class names." do
166 pc = Pointcut.new :types => /\AClass(?!IncludingModule).*Method\Z/, :method_options => :exclude_ancestor_methods
167 pc.join_points_matched.should == (@expected_classes_matched_jps + [@cdcimpub_jp])
168 pc.join_points_not_matched.should == @expected_classes_not_matched_jps
169 end
170
171 it "should match clases using regular expressions that only cover partial class names." do
172 pc = Pointcut.new :types => /lass(?!IncludingModule).*Pro.*Inst.*Met/, :method_options => [:public, :protected, :exclude_ancestor_methods]
173 pc.join_points_matched.should == Set.new([@pro_jp])
174 pc.join_points_not_matched.size.should == 0
175 end
176 end
177
178 describe Pointcut, ".new (classes specified using names)" do
179 before(:each) do
180 before_pointcut_class_spec
181 end
182
183 it "should match multiple classes using names." do
184 pc = Pointcut.new :types => @example_classes.map {|t| t.to_s}, :method_options => :exclude_ancestor_methods
185 pc.join_points_matched.should == @expected_classes_matched_jps
186 pc.join_points_not_matched.should == @expected_classes_not_matched_jps
187 end
188
189 it "should match multiple classes using classes themselves." do
190 pc = Pointcut.new :types => @example_classes, :method_options => :exclude_ancestor_methods
191 pc.join_points_matched.should == @expected_classes_matched_jps
192 pc.join_points_not_matched.should == @expected_classes_not_matched_jps
193 end
194
195 it "should match :all public instance methods for classes by default." do
196 pc = Pointcut.new :types => @example_classes, :method_options => :exclude_ancestor_methods
197 pc.join_points_matched.should == @expected_classes_matched_jps
198 pc.join_points_not_matched.should == @expected_classes_not_matched_jps
199 end
200
201 it "should match all public instance methods for classes if :methods => :all specified." do
202 pc = Pointcut.new :types => @example_classes, :methods => :all, :method_options => :exclude_ancestor_methods
203 pc.join_points_matched.should == @expected_classes_matched_jps
204 pc.join_points_not_matched.should == @expected_classes_not_matched_jps
205 end
206
207 it "should match all public instance methods for classes if :methods => :all_methods specified." do
208 pc = Pointcut.new :types => @example_classes, :methods => :all_methods, :method_options => :exclude_ancestor_methods
209 pc.join_points_matched.should == @expected_classes_matched_jps
210 pc.join_points_not_matched.should == @expected_classes_not_matched_jps
211 end
212
213 it "should support MethodFinder's :exclude_ancestor_methods option when using classes." do
214 pc = Pointcut.new :types => @example_classes, :method_options => :exclude_ancestor_methods
215 pc.join_points_matched.should == @expected_classes_matched_jps
216 pc.join_points_not_matched.should == @expected_classes_not_matched_jps
217 end
218
219 Pointcut::CANONICAL_OPTIONS["types"].each do |key|
220 it "should accept :#{key} as a synonym for :types." do
221 pc = Pointcut.new key.intern => @example_classes, :method_options => :exclude_ancestor_methods
222 pc.join_points_matched.should == @expected_classes_matched_jps
223 pc.join_points_not_matched.should == @expected_classes_not_matched_jps
224 end
225 end
226 end
227
228 describe Pointcut, ".new (modules specified using regular expressions)" do
229 it "should match multiple types using regular expressions that cover the full module names." do
230 pc = Pointcut.new :types => /\AModule.*Method\Z/, :method_options => :exclude_ancestor_methods
231 pc.join_points_matched.size.should == 2
232 pc.join_points_matched.each do |jp|
233 [ModuleIncludingModuleWithPublicInstanceMethod, ModuleWithPublicInstanceMethod].should include(jp.target_type)
234 end
235 pc.join_points_not_matched.size.should == 4
236 pc.join_points_not_matched.each do |jp|
237 [ModuleWithPrivateInstanceMethod, ModuleWithProtectedInstanceMethod,
238 ModuleWithPublicClassMethod, ModuleWithPrivateClassMethod].should include(jp.target_type)
239 end
240 end
241 end
242
243 describe Pointcut, ".new (modules specified using names)" do
244 def do_module type_spec
245 pc = Pointcut.new :types => type_spec, :method_options => :exclude_ancestor_methods
246 pc.join_points_matched.size.should == 1
247 pc.join_points_matched.each do |jp|
248 jp.target_type.should == ModuleWithPublicInstanceMethod
249 jp.method_name.should == :public_instance_module_test_method
250 end
251 pc.join_points_not_matched.size.should == 1
252 pc.join_points_not_matched.each do |jp|
253 jp.target_type.should == ModuleWithPublicClassMethod
254 jp.method_name.should == :all
255 end
256 end
257
258 it "should match multiple types using module names." do
259 do_module ["ModuleWithPublicInstanceMethod", "ModuleWithPublicClassMethod"]
260 end
261
262 it "should match multiple types using module-name regular expressions." do
263 do_module /^ModuleWithPublic.*Method/
264 end
265
266 it "should match multiple types using modules themselves." do
267 do_module [ModuleWithPublicInstanceMethod, ModuleWithPublicClassMethod]
268 end
269
270 it "should match :all public instance methods for modules by default." do
271 do_module [ModuleWithPublicInstanceMethod, ModuleWithPublicClassMethod]
272 end
273
274 it "should support MethodFinder's :exclude_ancestor_methods option when using modules." do
275 do_module [ModuleWithPublicInstanceMethod, ModuleWithPublicClassMethod]
276 end
277 end
278
279 describe Pointcut, ".new (types and their ancestors and descendents)" do
280 before(:each) do
281 before_pointcut_module_spec
282 end
283
284 it "should match classes specified and their ancestor and descendent modules and classes." do
285 pc = Pointcut.new :types_and_ancestors => /^Class(Including|DerivedFrom).*Method/, :types_and_descendents => /^Class(Including|DerivedFrom).*Method/, :methods => :all, :method_options => :exclude_ancestor_methods
286 expected_types = @example_modules_with_public_instance_method + [Kernel, Module, Object]
287 pc.join_points_matched.each do |jp|
288 next if ignored_join_point(jp)
289 expected_types.should include(jp.target_type)
290 end
291 not_expected_types = @expected_modules_not_matched_jps.map {|jp| jp.target_type}
292 pc.join_points_not_matched.each do |jp|
293 next if ignored_join_point(jp)
294 not_expected_types.should include(jp.target_type)
295 end
296 end
297
298 it "should match modules specified, their ancestor and descendent modules, and including classes." do
299 pc = Pointcut.new :types_and_ancestors => /^Module.*Method/, :types_and_descendents => /^Module.*Method/, :methods => :all, :method_options => :exclude_ancestor_methods
300 pc.join_points_matched.should == (@expected_modules_matched_jps + [@mimpub_jp])
301 pc.join_points_not_matched.should == @expected_modules_not_matched_jps
302 end
303
304 Aspect::CANONICAL_OPTIONS["types_and_ancestors"].reject{|key| key.eql?("types_and_ancestors")}.each do |key|
305 it "should accept :#{key} as a synonym for :types_and_ancestors." do
306 lambda {Pointcut.new key.intern => /^Module.*Method/, :methods => :all, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
307 end
308 end
309
310 Aspect::CANONICAL_OPTIONS["types_and_descendents"].reject{|key| key.eql?("types_and_descendents")}.each do |key|
311 it "should accept :#{key} as a synonym for :types_and_descendents." do
312 lambda {Pointcut.new key.intern => /^Module.*Method/, :methods => :all, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
313 end
314 end
315 end
316
317 describe Pointcut, ".new (types and their nested types)" do
318 before(:each) do
319 before_pointcut_module_spec
320 end
321
322 it "should match types specified and their nested types." do
323 pc = Pointcut.new :types_and_nested_types => Aquarium::NestedTestTypes, :methods => :all, :method_options => :exclude_ancestor_methods
324 expected_types = Aquarium::NestedTestTypes.nested_in_NestedTestTypes[Aquarium::NestedTestTypes]
325 pc.join_points_matched.size.should == expected_types.size
326 pc.join_points_matched.each do |jp|
327 expected_types.should include(jp.target_type)
328 end
329 pc.join_points_not_matched.size.should == 0
330 end
331
332 Aspect::CANONICAL_OPTIONS["types_and_nested_types"].reject{|key| key.eql?("types_and_nested_types")}.each do |key|
333 it "should accept :#{key} as a synonym for :types_and_nested_types." do
334 lambda {Pointcut.new key.intern => /^Module.*Method/, :methods => :all, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
335 end
336 end
337 end
338
339 describe Pointcut, ".new (objects specified)" do
340 before(:each) do
341 before_pointcut_class_spec
342 end
343
344 it "should match :all public instance methods for objects by default." do
345 pub, pro = ClassWithPublicInstanceMethod.new, ClassWithProtectedInstanceMethod.new
346 pc = Pointcut.new :objects => [pub, pro], :method_options => :exclude_ancestor_methods
347 pc.join_points_matched.should == Set.new([JoinPoint.new(:object => pub, :method_name => :public_instance_test_method)])
348 pc.join_points_not_matched.should == Set.new([JoinPoint.new(:object => pro, :method_name => :all)])
349 end
350
351 it "should support MethodFinder's :exclude_ancestor_methods option when using objects." do
352 pub, pro = ClassWithPublicInstanceMethod.new, ClassWithProtectedInstanceMethod.new
353 pc = Pointcut.new :objects => [pub, pro], :method_options => :exclude_ancestor_methods
354 pc.join_points_matched.should == Set.new([JoinPoint.new(:object => pub, :method_name => :public_instance_test_method)])
355 pc.join_points_not_matched.should == Set.new([JoinPoint.new(:object => pro, :method_name => :all)])
356 end
357
358 it "should match all possible methods on the specified objects." do
359 pub, pro = ClassWithPublicInstanceMethod.new, ClassWithProtectedInstanceMethod.new
360 pc = Pointcut.new :objects => [pub, pro], :methods => :all, :method_options => [:public, :protected, :exclude_ancestor_methods]
361 pc.join_points_matched.size.should == 2
362 pc.join_points_not_matched.size.should == 0
363 pc.join_points_matched.should == Set.new([
364 JoinPoint.new(:object => pro, :method_name => :protected_instance_test_method),
365 JoinPoint.new(:object => pub, :method_name => :public_instance_test_method)])
366 end
367
368 Aspect::CANONICAL_OPTIONS["objects"].reject{|key| key.eql?("objects")}.each do |key|
369 it "should accept :#{key} as a synonym for :objects." do
370 pub, pro = ClassWithPublicInstanceMethod.new, ClassWithProtectedInstanceMethod.new
371 pc = Pointcut.new key.intern => [pub, pro], :methods => :all, :method_options => [:public, :protected, :exclude_ancestor_methods]
372 pc.join_points_matched.size.should == 2
373 pc.join_points_not_matched.size.should == 0
374 pc.join_points_matched.should == Set.new([
375 JoinPoint.new(:object => pro, :method_name => :protected_instance_test_method),
376 JoinPoint.new(:object => pub, :method_name => :public_instance_test_method)])
377 end
378 end
379
380 it "does confuse strings specified with :objects as type names." do
381 string = "mystring"
382 lambda { Pointcut.new :object => string, :methods => :capitalize }.should raise_error(NameError)
383 end
384
385 it "does confuse symbols specified with :objects as type names." do
386 symbol = :mystring
387 lambda { Pointcut.new :object => symbol, :methods => :capitalize }.should raise_error(NameError)
388 end
389 end
390
391 describe Pointcut, ".new (default_objects specified)" do
392 it "should use the :default_objects if specified and no other :join_point, :type, or :object is given." do
393 object1 = ClassWithPublicInstanceMethod.new
394 pc = Pointcut.new :default_objects => object1, :method => :public_instance_test_method
395 pc.join_points_matched.size.should == 1
396 pc.join_points_matched.each {|jp| jp.type_or_object.should == object1}
397 end
398
399 it "should ignore the :default_objects if at least one other :object is given and the :default_objects are objects." do
400 object1 = ClassWithPublicInstanceMethod.new
401 object2 = ClassWithPublicInstanceMethod.new
402 pc = Pointcut.new :default_objects => object1, :object => object2, :method => :public_instance_test_method
403 pc.join_points_matched.size.should == 1
404 pc.join_points_matched.each {|jp| jp.type_or_object.should == object2}
405 end
406
407 it "should ignore the :default_objects if at least one other :object is given and the :default_objects are types." do
408 object = ClassWithProtectedInstanceMethod.new
409 pc = Pointcut.new :default_objects => ClassWithPublicInstanceMethod, :object => object, :method => /_instance_test_method/, :method_options => [:public, :protected, :exclude_ancestor_methods]
410 pc.join_points_matched.size.should == 1
411 pc.join_points_matched.each {|jp| jp.type_or_object.should_not == ClassWithPublicInstanceMethod}
412 end
413
414 it "should ignore the :default_objects if at least one :join_point is given and the :default_objects are objects." do
415 join_point = JoinPoint.new :type => ClassWithProtectedInstanceMethod, :method => :protected_instance_test_method
416 object = ClassWithProtectedInstanceMethod.new
417 pc = Pointcut.new :default_objects => object, :join_point => join_point, :method => /_instance_test_method/, :method_options => [:public, :protected, :exclude_ancestor_methods]
418 pc.join_points_matched.size.should == 1
419 pc.join_points_matched.each {|jp| jp.type_or_object.should_not == ClassWithPublicInstanceMethod}
420 end
421
422 it "should ignore the :default_objects if at least one :pointcut is given and the :default_objects are types." do
423 join_point = JoinPoint.new :type => ClassWithProtectedInstanceMethod, :method => :protected_instance_test_method
424 object = ClassWithProtectedInstanceMethod.new
425 pc = Pointcut.new :default_objects => ClassWithPublicInstanceMethod, :join_point => join_point, :method => /_instance_test_method/, :method_options => [:public, :protected, :exclude_ancestor_methods]
426 pc.join_points_matched.size.should == 1
427 pc.join_points_matched.each {|jp| jp.type_or_object.should_not == ClassWithPublicInstanceMethod}
428 end
429
430 [:type, :type_and_descendents, :type_and_ancestors].each do |type_key|
431 it "should ignore the :default_objects if at least one :#{type_key} is given and the :default_objects are objects." do
432 object = ClassWithPublicInstanceMethod.new
433 pc = Pointcut.new :default_objects => object, type_key => ClassWithProtectedInstanceMethod, :method => /_instance_test_method/, :method_options => [:public, :protected, :exclude_ancestor_methods]
434 pc.join_points_matched.size.should == 1
435 pc.join_points_matched.each {|jp| jp.type_or_object.should_not == ClassWithPublicInstanceMethod}
436 end
437
438 it "should ignore the :default_objects if at least one :#{type_key} is given and the :default_objects are types." do
439 pc = Pointcut.new :default_objects => ClassWithPublicInstanceMethod, type_key => ClassWithProtectedInstanceMethod, :method => /_instance_test_method/, :method_options => [:public, :protected, :exclude_ancestor_methods]
440 pc.join_points_matched.size.should == 1
441 pc.join_points_matched.each {|jp| jp.type_or_object.should_not == ClassWithPublicInstanceMethod}
442 end
443 end
444
445 Aspect::CANONICAL_OPTIONS["default_objects"].each do |key|
446 it "should accept :#{key} as a synonym for :default_objects." do
447 pc = Pointcut.new key.intern => ClassWithPublicInstanceMethod.new, :method => :public_instance_test_method
448 end
449 end
450 end
451
452 describe Pointcut, ".new (:exclude_types => types specified)" do
453 before(:each) do
454 before_exclude_spec
455 end
456
457 it "should remove from a list of explicitly-specified types the set of explicitly-specified excluded types." do
458 pc = Pointcut.new :types => [ExcludeTestOne, ExcludeTestTwo, ExcludeTestThree], :exclude_type => ExcludeTestTwo, :method_options => :exclude_ancestor_methods
459 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
460 actual.size.should == 2
461 actual.should include(ExcludeTestOne)
462 actual.should include(ExcludeTestThree)
463 pc.join_points_not_matched.size.should == 0
464 end
465
466 it "should remove from a list of explicitly-specified types the set of excluded types specified by regular expression." do
467 pc = Pointcut.new :types => [ExcludeTestOne, ExcludeTestTwo, ExcludeTestThree], :exclude_types => /Two$/, :method_options => :exclude_ancestor_methods
468 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
469 actual.size.should == 2
470 actual.should include(ExcludeTestOne)
471 actual.should include(ExcludeTestThree)
472 pc.join_points_not_matched.size.should == 0
473 end
474
475 it "should remove from a list of explicitly-specified types the set of excluded types specified by name." do
476 pc = Pointcut.new :types => [ExcludeTestOne, ExcludeTestTwo, ExcludeTestThree], :exclude_type => "ExcludeTestTwo", :method_options => :exclude_ancestor_methods
477 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
478 actual.size.should == 2
479 actual.should include(ExcludeTestOne)
480 actual.should include(ExcludeTestThree)
481 pc.join_points_not_matched.size.should == 0
482 end
483
484 it "should remove from the types specified by regular expression the explicitly-specified excluded types." do
485 pc = Pointcut.new :types => /ExcludeTest/, :exclude_type => ExcludeTestTwo, :method_options => :exclude_ancestor_methods
486 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
487 actual.size.should == 2
488 actual.should include(ExcludeTestOne)
489 actual.should include(ExcludeTestThree)
490 pc.join_points_not_matched.size.should == 0
491 end
492
493 it "should remove from the types specified by regular expression the excluded types specified by regular expression." do
494 pc = Pointcut.new :types => /ExcludeTest/, :exclude_type => /Two$/, :method_options => :exclude_ancestor_methods
495 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
496 actual.size.should == 2
497 actual.should include(ExcludeTestOne)
498 actual.should include(ExcludeTestThree)
499 pc.join_points_not_matched.size.should == 0
500 end
501
502 it "should remove from the types specified by regular expression the excluded types specified by name." do
503 pc = Pointcut.new :types => /ExcludeTest/, :exclude_type => "ExcludeTestTwo", :method_options => :exclude_ancestor_methods
504 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
505 actual.size.should == 2
506 actual.should include(ExcludeTestOne)
507 actual.should include(ExcludeTestThree)
508 pc.join_points_not_matched.size.should == 0
509 end
510
511 it "should remove from the join points corresponding to the excluded types, specified by name." do
512 pc = Pointcut.new :join_points => @all_type_jps, :exclude_type => "ExcludeTestTwo", :method_options => :exclude_ancestor_methods
513 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
514 actual.size.should == 2
515 actual.should include(ExcludeTestOne)
516 actual.should include(ExcludeTestThree)
517 pc.join_points_not_matched.size.should == 0
518 end
519
520 it "should remove the specified join points corresponding to the excluded types, specified by regular expression." do
521 pc = Pointcut.new :join_points => @all_type_jps, :exclude_type => /Exclude.*Two/, :method_options => :exclude_ancestor_methods
522 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
523 actual.size.should == 2
524 actual.should include(ExcludeTestOne)
525 actual.should include(ExcludeTestThree)
526 pc.join_points_not_matched.size.should == 0
527 end
528
529 it "should not add excluded types to the #not_matched results." do
530 pc = Pointcut.new :types => /ExcludeTest/, :exclude_type => ExcludeTestTwo, :method_options => :exclude_ancestor_methods
531 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
532 pc.join_points_not_matched.size.should == 0
533 end
534
535 Aspect::CANONICAL_OPTIONS["exclude_types"].reject{|key| key.eql?("exclude_types")}.each do |key|
536 it "should accept :#{key} as a synonym for :exclude_types." do
537 pc = Pointcut.new :types => /ExcludeTest/, key.intern => [ExcludeTestTwo, ExcludeTestThree], :method_options => :exclude_ancestor_methods
538 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
539 actual.size.should == 1
540 actual.should include(ExcludeTestOne)
541 pc.join_points_not_matched.size.should == 0
542 end
543 end
544 end
545
546 describe Pointcut, ".new (exclude types and their descendents and ancestors)" do
547 before(:each) do
548 before_pointcut_module_spec
549 end
550
551 def check_module_ancestors pc
552 expected_types = [
553 ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod,
554 ClassIncludingModuleWithPublicInstanceMethod,
555 Kernel,
556 Object]
557 found_types = {}
558 pc.join_points_matched.each do |jp|
559 next if ignored_join_point(jp)
560 expected_types.should include(jp.target_type)
561 found_types[jp.target_type] = true
562 end
563 found_types.size.should == 4
564 not_expected_types = @expected_modules_not_matched_jps.map {|jp| jp.target_type}
565 pc.join_points_not_matched.each do |jp|
566 next if ignored_join_point(jp)
567 not_expected_types.should include(jp.target_type)
568 end
569 end
570
571 it "should exclude modules specified and their included modules when excluding ancestors." do
572 pc = Pointcut.new :types_and_ancestors => /^Class(Including|DerivedFrom).*Method/,
573 :exclude_types_and_ancestors => ModuleIncludingModuleWithPublicInstanceMethod, :methods => :all, :method_options => :exclude_ancestor_methods
574 check_module_ancestors pc
575 end
576 it "should exclude join_points whose types match an excluded ancestor modules." do
577 pc = Pointcut.new :join_point => @mimpub_jp, :types_and_ancestors => /^Class(Including|DerivedFrom).*Method/,
578 :exclude_types_and_ancestors => ModuleIncludingModuleWithPublicInstanceMethod, :methods => :all, :method_options => :exclude_ancestor_methods
579 check_module_ancestors pc
580 end
581
582 def check_module_descendents pc
583 expected_types = [Kernel, Object]
584 found_types = {}
585 pc.join_points_matched.each do |jp|
586 next if ignored_join_point(jp)
587 expected_types.should include(jp.target_type)
588 found_types[jp.target_type] = true
589 end
590 found_types.size.should == 2
591 not_expected_types = @expected_modules_not_matched_jps.map {|jp| jp.target_type}
592 pc.join_points_not_matched.each do |jp|
593 next if ignored_join_point(jp)
594 not_expected_types.should include(jp.target_type)
595 end
596 end
597
598 it "should exclude modules specified and their including modules and classes when excluding descendents." do
599 pc = Pointcut.new :types_and_ancestors => /^Class(Including|DerivedFrom).*Method/,
600 :exclude_types_and_descendents => ModuleWithPublicInstanceMethod, :methods => :all, :method_options => :exclude_ancestor_methods
601 check_module_descendents pc
602 end
603 it "should exclude join_points whose types match an excluded descendent modules." do
604 pc = Pointcut.new :join_point => @mpub_jp, :types_and_ancestors => /^Class(Including|DerivedFrom).*Method/,
605 :exclude_types_and_descendents => ModuleWithPublicInstanceMethod, :methods => :all, :method_options => :exclude_ancestor_methods
606 check_module_descendents pc
607 end
608
609 def check_class_ancestors pc
610 expected_types = [ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod, ModuleIncludingModuleWithPublicInstanceMethod]
611 found_types = {}
612 pc.join_points_matched.each do |jp|
613 next if ignored_join_point(jp)
614 expected_types.should include(jp.target_type)
615 found_types[jp.target_type] = true
616 end
617 found_types.size.should == 2
618 not_expected_types = @expected_modules_not_matched_jps.map {|jp| jp.target_type}
619 pc.join_points_not_matched.each do |jp|
620 next if ignored_join_point(jp)
621 not_expected_types.should include(jp.target_type)
622 end
623 end
624
625 it "should exclude classes specified and their included modules and ancestor classes when excluding ancestors." do
626 pc = Pointcut.new :types_and_ancestors => /^Class(Including|DerivedFrom).*Method/,
627 :exclude_types_and_ancestors => ClassIncludingModuleWithPublicInstanceMethod, :methods => :all, :method_options => :exclude_ancestor_methods
628 check_class_ancestors pc
629 end
630 it "should exclude join_points whose types match an excluded ancestor classes." do
631 pc = Pointcut.new :join_point => @cimpub_jp, :types_and_ancestors => /^Class(Including|DerivedFrom).*Method/,
632 :exclude_types_and_ancestors => ClassIncludingModuleWithPublicInstanceMethod, :methods => :all, :method_options => :exclude_ancestor_methods
633 check_class_ancestors pc
634 end
635
636 def check_class_descendents pc
637 expected_types = [Kernel, ModuleIncludingModuleWithPublicInstanceMethod, ModuleWithPublicInstanceMethod, Object]
638 found_types = {}
639 pc.join_points_matched.each do |jp|
640 next if ignored_join_point(jp)
641 expected_types.should include(jp.target_type)
642 found_types[jp.target_type] = true
643 end
644 found_types.size.should == 4
645 not_expected_types = @expected_modules_not_matched_jps.map {|jp| jp.target_type}
646 pc.join_points_not_matched.each do |jp|
647 next if ignored_join_point(jp)
648 not_expected_types.should include(jp.target_type)
649 end
650 end
651
652 it "should exclude classes specified and their including modules and descendent classes when excluding descendents." do
653 pc = Pointcut.new :types_and_ancestors => /^Class(Including|DerivedFrom).*Method/,
654 :exclude_types_and_descendents => ClassIncludingModuleWithPublicInstanceMethod, :methods => :all, :method_options => :exclude_ancestor_methods
655 check_class_descendents pc
656 end
657 it "should exclude join_points whose types match an excluded descendent types." do
658 pc = Pointcut.new :join_point => @cimpub_jp, :types_and_ancestors => /^Class(Including|DerivedFrom).*Method/,
659 :exclude_types_and_descendents => ClassIncludingModuleWithPublicInstanceMethod, :methods => :all, :method_options => :exclude_ancestor_methods
660 check_class_descendents pc
661 end
662
663 Aspect::CANONICAL_OPTIONS["exclude_types_and_descendents"].reject{|key| key.eql?("exclude_types_and_descendents")}.each do |key|
664 it "should accept :#{key} as a synonym for :exclude_types_and_descendents." do
665 lambda {Pointcut.new :types => /ExcludeTest/, key.intern => [ExcludeTestTwo, ExcludeTestThree], :method_options => :exclude_ancestor_methods, :noop => true}.should_not raise_error
666 end
667 end
668
669 Aspect::CANONICAL_OPTIONS["exclude_types_and_ancestors"].reject{|key| key.eql?("exclude_types_and_ancestors")}.each do |key|
670 it "should accept :#{key} as a synonym for :exclude_types_and_ancestors." do
671 lambda {Pointcut.new :types => /ExcludeTest/, key.intern => [ExcludeTestTwo, ExcludeTestThree], :method_options => :exclude_ancestor_methods, :noop => true}.should_not raise_error
672 end
673 end
674 end
675
676 describe Pointcut, ".new (:exclude_objects => objects specified)" do
677 before(:each) do
678 @e11 = ExcludeTestOne.new
679 @e12 = ExcludeTestOne.new
680 @e21 = ExcludeTestTwo.new
681 @e22 = ExcludeTestTwo.new
682 @e31 = ExcludeTestThree.new
683 @e32 = ExcludeTestThree.new
684 @objects = [@e11, @e12, @e21, @e22, @e31, @e32]
685 end
686
687 it "should remove from the matched objects the excluded objects." do
688 pc = Pointcut.new :objects => @objects, :exclude_objects => [@e22, @e31], :method_options => :exclude_ancestor_methods
689 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
690 actual.size.should == 4
691 [@e11, @e12, @e21, @e32].each {|e| actual.should include(e)}
692 pc.join_points_not_matched.size.should == 0
693 end
694
695 it "should remove the specified join points corresponding to the excluded objects." do
696 jps11 = JoinPoint.new :object => @e11, :method => :method11
697 jps21 = JoinPoint.new :object => @e21, :method => :method21
698 jps22 = JoinPoint.new :object => @e22, :method => :method22
699 jps31 = JoinPoint.new :object => @e31, :method => :method31
700 jps = [jps11, jps21, jps22, jps31]
701 pc = Pointcut.new :join_points => jps, :exclude_objects => [@e22, @e31], :method_options => :exclude_ancestor_methods
702 pc.join_points_matched.size.should == 2
703 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
704 [@e11, @e21].each {|e| actual.should include(e)}
705 pc.join_points_not_matched.size.should == 0
706 end
707
708 it "should not add excluded objects to the #not_matched results." do
709 pc = Pointcut.new :objects => @objects, :exclude_objects => [@e22, @e31], :method_options => :exclude_ancestor_methods
710 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
711 pc.join_points_not_matched.size.should == 0
712 end
713
714 Aspect::CANONICAL_OPTIONS["exclude_objects"].reject{|key| key.eql?("exclude_objects")}.each do |key|
715 it "should accept :#{key} as a synonym for :exclude_objects." do
716 pc = Pointcut.new :objects => @objects, key.intern => @e22, :method_options => :exclude_ancestor_methods
717 actual = pc.join_points_matched.collect {|jp| jp.type_or_object}.uniq
718 actual.size.should == 5
719 [@e11, @e12, @e21, @e31, @e32].each {|e| actual.should include(e)}
720 pc.join_points_not_matched.size.should == 0
721 end
722 end
723 end
724
725 describe Pointcut, ".new (:exclude_join_points => join_points specified)" do
726 before(:each) do
727 before_exclude_spec
728 end
729
730 it "should remove from a list of explicitly-specified join points the set of explicitly-specified excluded join points." do
731 excluded = [@jp12, @jp33, @ojp11, @ojp13, @ojp23]
732 expected = [@jp11, @jp13, @jp21, @jp22, @jp23, @jp31, @jp32, @ojp12, @ojp21, @ojp22, @ojp31, @ojp32, @ojp33]
733 pc = Pointcut.new :join_points => @all_jps, :exclude_join_points => excluded
734 pc.join_points_matched.should == Set.new(expected)
735 pc.join_points_not_matched.size.should == 0
736 end
737
738 it "should remove from the list of generated, type-based join points the set of explicitly-specified excluded join points." do
739 excluded = [@jp11, @jp22, @jp33]
740 expected = [@jp12, @jp13, @jp21, @jp23, @jp31, @jp32]
741 pc = Pointcut.new :types => /ExcludeTest/, :exclude_join_points => excluded, :method_options => :exclude_ancestor_methods
742 pc.join_points_matched.should == Set.new(expected)
743 pc.join_points_not_matched.size.should == 0
744 end
745
746 it "should remove from the list of generated, object-based join points the set of explicitly-specified excluded join points." do
747 excluded = [@ojp12, @ojp23, @ojp31]
748 expected = [@ojp11, @ojp13, @ojp21, @ojp22, @ojp32, @ojp33]
749 pc = Pointcut.new :objects => [@et1, @et2, @et3], :exclude_join_points => excluded, :method_options => :exclude_ancestor_methods
750 pc.join_points_matched.should == Set.new(expected)
751 pc.join_points_not_matched.size.should == 0
752 end
753
754 it "should not add excluded types to the #not_matched results." do
755 excluded = [@jp12, @jp33, @ojp11, @ojp13, @ojp23]
756 pc = Pointcut.new :join_points => @all_jps, :exclude_join_points => excluded
757 pc.join_points_not_matched.size.should == 0
758 end
759
760 Aspect::CANONICAL_OPTIONS["exclude_join_points"].reject{|key| key.eql?("exclude_join_points")}.each do |key|
761 it "should accept :#{key} as a synonym for :exclude_join_points." do
762 excluded = [@jp12, @jp33, @ojp11, @ojp13, @ojp23]
763 expected = [@jp11, @jp13, @jp21, @jp22, @jp23, @jp31, @jp32, @ojp12, @ojp21, @ojp22, @ojp31, @ojp32, @ojp33]
764 pc = Pointcut.new :join_points => @all_jps, key.intern => excluded
765 pc.join_points_matched.should == Set.new(expected)
766 pc.join_points_not_matched.size.should == 0
767 end
768 end
769 end
770
771 describe Pointcut, ".new (:exclude_pointcuts => pointcuts specified)" do
772 before(:each) do
773 before_exclude_spec
774 end
775
776 it "should remove from a list of explicitly-specified join points the set of explicitly-specified excluded pointcuts." do
777 excluded_jps = [@jp12, @jp33, @ojp11, @ojp13, @ojp23]
778 excluded = Pointcut.new :join_points => excluded_jps
779 expected = [@jp11, @jp13, @jp21, @jp22, @jp23, @jp31, @jp32, @ojp12, @ojp21, @ojp22, @ojp31, @ojp32, @ojp33]
780 pc = Pointcut.new :join_points => @all_jps, :exclude_pointcuts => excluded
781 pc.join_points_matched.should == Set.new(expected)
782 pc.join_points_not_matched.size.should == 0
783 end
784
785 it "should remove from the list of generated, type-based join points the set of explicitly-specified excluded pointcuts." do
786 excluded_jps = [@jp11, @jp22, @jp33]
787 excluded = Pointcut.new :join_points => excluded_jps
788 expected = [@jp12, @jp13, @jp21, @jp23, @jp31, @jp32]
789 pc = Pointcut.new :types => /ExcludeTest/, :exclude_pointcuts => excluded, :method_options => :exclude_ancestor_methods
790 pc.join_points_matched.should == Set.new(expected)
791 pc.join_points_not_matched.size.should == 0
792 end
793
794 it "should remove from the list of generated, object-based join points the set of explicitly-specified excluded pointcuts." do
795 excluded_jps = [@ojp12, @ojp23, @ojp31]
796 excluded = Pointcut.new :join_points => excluded_jps
797 expected = [@ojp11, @ojp13, @ojp21, @ojp22, @ojp32, @ojp33]
798 pc = Pointcut.new :objects => [@et1, @et2, @et3], :exclude_pointcuts => excluded, :method_options => :exclude_ancestor_methods
799 pc.join_points_matched.should == Set.new(expected)
800 pc.join_points_not_matched.size.should == 0
801 end
802
803 it "should not add excluded types to the #not_matched results." do
804 excluded_jps = [@jp12, @jp33, @ojp11, @ojp13, @ojp23]
805 excluded = Pointcut.new :join_points => excluded_jps
806 pc = Pointcut.new :join_points => @all_jps, :exclude_pointcuts => excluded
807 pc.join_points_not_matched.size.should == 0
808 end
809
810 it "should result in an empty pointcut if the join points in the :exclude_pointcuts are a superset of the matched join points." do
811 excluded = Pointcut.new :join_points => @all_jps
812 pc = Pointcut.new :join_points => @all_jps, :exclude_pointcut => excluded
813 pc.join_points_matched.size.should == 0
814 pc.join_points_not_matched.size.should == 0
815 end
816
817 Aspect::CANONICAL_OPTIONS["exclude_pointcuts"].reject{|key| key.eql?("exclude_pointcuts")}.each do |key|
818 it "should accept :#{key} as a synonym for :exclude_pointcuts." do
819 excluded_jps = [@jp12, @jp33, @ojp11, @ojp13, @ojp23]
820 excluded = Pointcut.new :join_points => excluded_jps
821 expected = [@jp11, @jp13, @jp21, @jp22, @jp23, @jp31, @jp32, @ojp12, @ojp21, @ojp22, @ojp31, @ojp32, @ojp33]
822 pc = Pointcut.new :join_points => @all_jps, key.intern => excluded
823 pc.join_points_matched.should == Set.new(expected)
824 pc.join_points_not_matched.size.should == 0
825 end
826 end
827 end
828
829 describe Pointcut, ".new (:method_options synonyms)" do
830 before(:each) do
831 before_pointcut_class_spec
832 end
833
834 Aspect::CANONICAL_OPTIONS["method_options"].reject{|key| key.eql?("method_options")}.each do |key|
835 it "should accept :#{key} as a synonym for :method_options." do
836 pc = Pointcut.new :types => ClassWithPublicInstanceMethod, key.intern => [:public, :instance, :exclude_ancestor_methods]
837 pc.join_points_matched.should be_eql(Set.new([@pub_jp]))
838 pc.join_points_not_matched.size.should == 0
839 end
840 end
841 end
842
843 describe Pointcut, ".new (types or objects specified with public instance methods)" do
844 before(:each) do
845 before_pointcut_class_spec
846 end
847
848 it "should support MethodFinder's :public and :instance options for the specified types." do
849 pc = Pointcut.new :types => ClassWithPublicInstanceMethod, :method_options => [:public, :instance, :exclude_ancestor_methods]
850 pc.join_points_matched.should be_eql(Set.new([@pub_jp]))
851 pc.join_points_not_matched.size.should == 0
852 end
853
854 it "should support MethodFinder's :public and :instance options for the specified objects." do
855 pub = ClassWithPublicInstanceMethod.new
856 pc = Pointcut.new :objects => pub, :method_options => [:public, :instance, :exclude_ancestor_methods]
857 pc.join_points_matched.should be_eql(Set.new([JoinPoint.new(:object => pub, :method_name => :public_instance_test_method)]))
858 pc.join_points_not_matched.size.should == 0
859 end
860 end
861
862 describe Pointcut, ".new (types or objects specified with protected instance methods)" do
863 before(:each) do
864 before_pointcut_class_spec
865 end
866
867 it "should support MethodFinder's :protected and :instance options for the specified types." do
868 pc = Pointcut.new :types => ClassWithProtectedInstanceMethod, :method_options => [:protected, :instance, :exclude_ancestor_methods]
869 pc.join_points_matched.should be_eql(Set.new([@pro_jp]))
870 pc.join_points_not_matched.size.should == 0
871 end
872
873 it "should support MethodFinder's :protected and :instance options for the specified objects." do
874 pro = ClassWithProtectedInstanceMethod.new
875 pc = Pointcut.new :objects => pro, :method_options => [:protected, :instance, :exclude_ancestor_methods]
876 pc.join_points_matched.should be_eql(Set.new([JoinPoint.new(:object => pro, :method_name => :protected_instance_test_method)]))
877 pc.join_points_not_matched.size.should == 0
878 end
879 end
880
881 describe Pointcut, ".new (types or objects specified with private instance methods)" do
882 before(:each) do
883 before_pointcut_class_spec
884 end
885
886 it "should support MethodFinder's :private and :instance options for the specified types." do
887 pc = Pointcut.new :types => ClassWithPrivateInstanceMethod, :method_options => [:private, :instance, :exclude_ancestor_methods]
888 pc.join_points_matched.should be_eql(Set.new([@pri_jp]))
889 pc.join_points_not_matched.size.should == 0
890 end
891
892 it "should support MethodFinder's :private and :instance options for the specified objects." do
893 pro = ClassWithPrivateInstanceMethod.new
894 pc = Pointcut.new :objects => pro, :method_options => [:private, :instance, :exclude_ancestor_methods]
895 pc.join_points_matched.should be_eql(Set.new([JoinPoint.new(:object => pro, :method_name => :private_instance_test_method)]))
896 pc.join_points_not_matched.size.should == 0
897 end
898 end
899
900 describe Pointcut, ".new (types or objects specified with public class methods)" do
901 before(:each) do
902 before_pointcut_class_spec
903 end
904
905 it "should support MethodFinder's :public and :class options for the specified types." do
906 pc = Pointcut.new :types => ClassWithPublicClassMethod, :method_options => [:public, :class, :exclude_ancestor_methods]
907 pc.join_points_matched.should be_eql(Set.new([@cpub_jp]))
908 pc.join_points_not_matched.size.should == 0
909 end
910
911 it "should support MethodFinder's :public and :class options for the specified objects, which will return no methods." do
912 pub = ClassWithPublicInstanceMethod.new
913 pc = Pointcut.new :objects => pub, :method_options => [:public, :class, :exclude_ancestor_methods]
914 pc.join_points_matched.size.should == 0
915 pc.join_points_not_matched.size.should == 1
916 pc.join_points_not_matched.should be_eql(Set.new([JoinPoint.new(:object => pub, :method_name => :all, :class_method => true)]))
917 end
918 end
919
920 describe Pointcut, ".new (types or objects specified with private class methods)" do
921 before(:each) do
922 before_pointcut_class_spec
923 end
924
925 it "should support MethodFinder's :private and :class options for the specified types." do
926 pc = Pointcut.new :types => ClassWithPrivateClassMethod, :method_options => [:private, :class, :exclude_ancestor_methods]
927 pc.join_points_matched.should be_eql(Set.new([@cpri_jp]))
928 pc.join_points_not_matched.size.should == 0
929 end
930
931 it "should support MethodFinder's :private and :class options for the specified objects, which will return no methods." do
932 pri = ClassWithPrivateInstanceMethod.new
933 pc = Pointcut.new :objects => pri, :method_options => [:private, :class, :exclude_ancestor_methods]
934 pc.join_points_not_matched.should be_eql(Set.new([JoinPoint.new(:object => pri, :method_name => :all, :class_method => true)]))
935 pc.join_points_not_matched.size.should == 1
936 end
937 end
938
939 describe Pointcut, ".new (types or objects specified with method regular expressions)" do
940 before(:each) do
941 before_pointcut_class_spec
942 @jp_rwe = JoinPoint.new :type => ClassWithAttribs, :method_name => :attrRW_ClassWithAttribs=
943 @jp_rw = JoinPoint.new :type => ClassWithAttribs, :method_name => :attrRW_ClassWithAttribs
944 @jp_we = JoinPoint.new :type => ClassWithAttribs, :method_name => :attrW_ClassWithAttribs=
945 @jp_r = JoinPoint.new :type => ClassWithAttribs, :method_name => :attrR_ClassWithAttribs
946 @expected_for_types = Set.new([@jp_rw, @jp_rwe, @jp_r, @jp_we])
947 @object_of_ClassWithAttribs = ClassWithAttribs.new
948 @jp_rwe_o = JoinPoint.new :object => @object_of_ClassWithAttribs, :method_name => :attrRW_ClassWithAttribs=
949 @jp_rw_o = JoinPoint.new :object => @object_of_ClassWithAttribs, :method_name => :attrRW_ClassWithAttribs
950 @jp_we_o = JoinPoint.new :object => @object_of_ClassWithAttribs, :method_name => :attrW_ClassWithAttribs=
951 @jp_r_o = JoinPoint.new :object => @object_of_ClassWithAttribs, :method_name => :attrR_ClassWithAttribs
952 @expected_for_objects = Set.new([@jp_rw_o, @jp_rwe_o, @jp_r_o, @jp_we_o])
953 end
954
955 it "should match on public method readers and writers for type names by default." do
956 pc = Pointcut.new :types => "ClassWithAttribs", :methods => [/^attr/]
957 pc.join_points_matched.should == @expected_for_types
958 end
959
960 it "should match on public method readers and writers for types by default." do
961 pc = Pointcut.new :types => ClassWithAttribs, :methods => [/^attr/]
962 pc.join_points_matched.should == @expected_for_types
963 end
964
965 it "should match on public method readers and writers for objects by default." do
966 pc = Pointcut.new :object => @object_of_ClassWithAttribs, :methods => [/^attr/]
967 pc.join_points_matched.should == @expected_for_objects
968 end
969 end
970
971 describe Pointcut, ".new (synonyms of :methods)" do
972 before(:each) do
973 before_pointcut_class_spec
974 @jp_rwe = JoinPoint.new :type => ClassWithAttribs, :method_name => :attrRW_ClassWithAttribs=
975 @jp_rw = JoinPoint.new :type => ClassWithAttribs, :method_name => :attrRW_ClassWithAttribs
976 @jp_we = JoinPoint.new :type => ClassWithAttribs, :method_name => :attrW_ClassWithAttribs=
977 @jp_r = JoinPoint.new :type => ClassWithAttribs, :method_name => :attrR_ClassWithAttribs
978 @expected_for_types = Set.new([@jp_rw, @jp_rwe, @jp_r, @jp_we])
979 @object_of_ClassWithAttribs = ClassWithAttribs.new
980 @jp_rwe_o = JoinPoint.new :object => @object_of_ClassWithAttribs, :method_name => :attrRW_ClassWithAttribs=
981 @jp_rw_o = JoinPoint.new :object => @object_of_ClassWithAttribs, :method_name => :attrRW_ClassWithAttribs
982 @jp_we_o = JoinPoint.new :object => @object_of_ClassWithAttribs, :method_name => :attrW_ClassWithAttribs=
983 @jp_r_o = JoinPoint.new :object => @object_of_ClassWithAttribs, :method_name => :attrR_ClassWithAttribs
984 @expected_for_objects = Set.new([@jp_rw_o, @jp_rwe_o, @jp_r_o, @jp_we_o])
985 end
986
987 Aspect::CANONICAL_OPTIONS["methods"].reject{|key| key.eql?("methods")}.each do |key|
988 it "should accept :#{key} as a synonym for :methods." do
989 pc = Pointcut.new :types => "ClassWithAttribs", key.intern => [/^attr/]
990 pc.join_points_matched.should == @expected_for_types
991 end
992 end
993 end
994
995 describe Pointcut, ".new (:exclude_methods => methods specified)" do
996 before(:each) do
997 before_exclude_spec
998 end
999
1000 it "should remove type-specified JoinPoints matching the excluded methods specified by name." do
1001 pc = Pointcut.new :types => [ExcludeTestOne, ExcludeTestTwo, ExcludeTestThree], :exclude_methods => [:method11, :method23], :method_options => :exclude_ancestor_methods
1002 pc.join_points_matched.size.should == 7
1003 pc.join_points_matched.should == Set.new([@jp12, @jp13, @jp21, @jp22, @jp31, @jp32, @jp33])
1004 pc.join_points_not_matched.size.should == 0
1005 end
1006
1007 it "should remove type-specified JoinPoints matching the excluded methods specified by regular expression." do
1008 pc = Pointcut.new :types => [ExcludeTestOne, ExcludeTestTwo, ExcludeTestThree], :exclude_methods => /method[12][13]/, :method_options => :exclude_ancestor_methods
1009 pc.join_points_matched.size.should == 5
1010 pc.join_points_matched.should == Set.new([@jp12, @jp22, @jp31, @jp32, @jp33])
1011 pc.join_points_not_matched.size.should == 0
1012 end
1013
1014 it "should remove object-specified JoinPoints matching the excluded methods specified by name." do
1015 pc = Pointcut.new :objects => [@et1, @et2, @et3], :exclude_methods => [:method11, :method23], :method_options => :exclude_ancestor_methods
1016 pc.join_points_matched.size.should == 7
1017 pc.join_points_matched.should == Set.new([@ojp12, @ojp13, @ojp21, @ojp22, @ojp31, @ojp32, @ojp33])
1018 pc.join_points_not_matched.size.should == 0
1019 end
1020
1021 it "should remove object-specified JoinPoints matching the excluded methods specified by regular expression." do
1022 pc = Pointcut.new :objects => [@et1, @et2, @et3], :exclude_methods => /method[12][13]/, :method_options => :exclude_ancestor_methods
1023 pc.join_points_matched.size.should == 5
1024 pc.join_points_matched.should == Set.new([@ojp12, @ojp22, @ojp31, @ojp32, @ojp33])
1025 pc.join_points_not_matched.size.should == 0
1026 end
1027
1028 it "should remove join-point-specified JoinPoints matching the excluded methods specified by name." do
1029 pc = Pointcut.new :join_points => @all_jps, :exclude_methods => [:method11, :method23], :method_options => :exclude_ancestor_methods
1030 pc.join_points_matched.size.should == 14
1031 pc.join_points_matched.should == Set.new([@jp12, @jp13, @jp21, @jp22, @jp31, @jp32, @jp33, @ojp12, @ojp13, @ojp21, @ojp22, @ojp31, @ojp32, @ojp33])
1032 pc.join_points_not_matched.size.should == 0
1033 end
1034
1035 it "should remove join-point-specified JoinPoints matching the excluded methods specified by regular expression." do