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.
Name Total lines Lines of code Total coverage Code coverage
spec/aquarium/aspects/pointcut_spec.rb 1850 1609
100.0% 
100.0% 
   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