aquarium 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. data/Aquarium-IDEA.ipr +252 -0
  2. data/Aquarium-IDEA.iws +493 -0
  3. data/Aquarium.ipr +1 -1
  4. data/Aquarium.iws +133 -138
  5. data/CHANGES +63 -0
  6. data/ParseTreePlay.rb +25 -0
  7. data/README +55 -3
  8. data/RELEASE-PLAN +9 -1
  9. data/TODO.rb +175 -15
  10. data/examples/aspect_design_example.rb +13 -1
  11. data/examples/aspect_design_example_spec.rb +20 -2
  12. data/examples/introductions_example.rb +35 -0
  13. data/examples/introductions_example_spec.rb +37 -0
  14. data/examples/method_missing_example.rb +2 -1
  15. data/lib/aquarium/aspects/advice.rb +127 -74
  16. data/lib/aquarium/aspects/aspect.rb +139 -72
  17. data/lib/aquarium/aspects/default_objects_handler.rb +6 -4
  18. data/lib/aquarium/aspects/exclusion_handler.rb +15 -3
  19. data/lib/aquarium/aspects/join_point.rb +60 -55
  20. data/lib/aquarium/aspects/pointcut.rb +153 -124
  21. data/lib/aquarium/aspects/pointcut_composition.rb +1 -1
  22. data/lib/aquarium/dsl/aspect_dsl.rb +13 -5
  23. data/lib/aquarium/dsl/object_dsl.rb +4 -2
  24. data/lib/aquarium/extras/design_by_contract.rb +9 -5
  25. data/lib/aquarium/finders.rb +1 -0
  26. data/lib/aquarium/finders/finder_result.rb +13 -5
  27. data/lib/aquarium/finders/method_finder.rb +75 -70
  28. data/lib/aquarium/finders/pointcut_finder.rb +166 -0
  29. data/lib/aquarium/finders/type_finder.rb +104 -62
  30. data/lib/aquarium/utils/array_utils.rb +1 -1
  31. data/lib/aquarium/utils/invalid_options.rb +2 -0
  32. data/lib/aquarium/utils/name_utils.rb +3 -2
  33. data/lib/aquarium/utils/nil_object.rb +7 -3
  34. data/lib/aquarium/utils/options_utils.rb +38 -27
  35. data/lib/aquarium/utils/set_utils.rb +2 -2
  36. data/lib/aquarium/utils/type_utils.rb +11 -0
  37. data/lib/aquarium/version.rb +1 -1
  38. data/spec/aquarium/aspects/advice_spec.rb +147 -32
  39. data/spec/aquarium/aspects/aspect_invocation_spec.rb +252 -43
  40. data/spec/aquarium/aspects/aspect_spec.rb +148 -88
  41. data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +40 -34
  42. data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +39 -3
  43. data/spec/aquarium/aspects/join_point_spec.rb +190 -227
  44. data/spec/aquarium/aspects/pointcut_spec.rb +24 -1
  45. data/spec/aquarium/dsl/aspect_dsl_spec.rb +17 -17
  46. data/spec/aquarium/finders/method_finder_spec.rb +8 -2
  47. data/spec/aquarium/finders/pointcut_finder_spec.rb +193 -0
  48. data/spec/aquarium/finders/pointcut_finder_spec_test_classes.rb +90 -0
  49. data/spec/aquarium/finders/type_finder_spec.rb +17 -0
  50. data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +4 -4
  51. data/spec/aquarium/finders/type_finder_with_nested_types.rb +47 -0
  52. data/spec/aquarium/utils/nil_object_spec.rb +21 -0
  53. data/spec/aquarium/utils/type_utils_sample_nested_types.rb +51 -0
  54. data/spec/aquarium/utils/type_utils_spec.rb +18 -1
  55. metadata +13 -3
@@ -1,5 +1,6 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
  require File.dirname(__FILE__) + '/../spec_example_types'
3
+ require File.dirname(__FILE__) + '/../utils/type_utils_sample_nested_types'
3
4
  require 'aquarium/utils/invalid_options'
4
5
  require 'aquarium/extensions/hash'
5
6
  require 'aquarium/aspects/join_point'
@@ -95,7 +96,7 @@ end
95
96
 
96
97
  def ignored_join_point jp
97
98
  # Ignore any types introduced by RSpec, other Aquarium types, and the "pretty printer" module (which Rake uses?)
98
- jp.target_type.name =~ /^Spec/ or jp.target_type.name =~ /^Aquarium::(Aspects|Extras|Utils)/ or jp.target_type.name =~ /^PP/
99
+ jp.target_type.name =~ /^Spec/ or jp.target_type.name =~ /^Aquarium::(Aspects|Extras|Utils|PointcutFinderTestClasses)/ or jp.target_type.name =~ /^PP/
99
100
  end
100
101
 
101
102
  describe Pointcut, "methods" do
@@ -313,6 +314,28 @@ describe Pointcut, "methods" do
313
314
  end
314
315
  end
315
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
+
316
339
  describe Pointcut, ".new (objects specified)" do
317
340
  before(:each) do
318
341
  before_pointcut_class_spec
@@ -559,25 +559,25 @@ describe "Aquarium::DSL" do
559
559
  PC2::POINTCUT.join_points_not_matched.should == pointcut2.join_points_not_matched
560
560
  end
561
561
  end
562
-
563
- class OldDSLClass
564
- include Aquarium::Aspects::DSL::AspectDSL
562
+ end
563
+
564
+ class OldDSLClass
565
+ include Aquarium::Aspects::DSL::AspectDSL
566
+ end
567
+ describe "DSL methods available through the old package Aquarium::Aspects::DSL::AspectDSL" do
568
+ before :each do
569
+ @dsl = OldDSLClass.new
570
+ @advice = proc {|jp, obj, *args| "advice"}
571
+ @aspects = []
572
+ end
573
+ after :each do
574
+ @aspects.each {|a| a.unadvise}
565
575
  end
566
- describe "DSL methods available through the old package Aquarium::Aspects::DSL::AspectDSL" do
567
- before :each do
568
- @dsl = OldDSLClass.new
569
- @advice = proc {|jp, obj, *args| "advice"}
570
- @aspects = []
571
- end
572
- after :each do
573
- @aspects.each {|a| a.unadvise}
574
- end
575
576
 
576
- it "should be equivalent to advice kind :around." do
577
- @aspects << OldDSLClass.advise(:around, :noop => true, :pointcut => @pointcut_opts, &@advice)
578
- @aspects << OldDSLClass.around( :noop => true, :pointcut => @pointcut_opts, &@advice)
579
- @aspects[1].should == @aspects[0]
580
- end
577
+ it "should be equivalent to advice kind :around." do
578
+ @aspects << OldDSLClass.advise(:around, :noop => true, :pointcut => @pointcut_opts, &@advice)
579
+ @aspects << OldDSLClass.around( :noop => true, :pointcut => @pointcut_opts, &@advice)
580
+ @aspects[1].should == @aspects[0]
581
581
  end
582
582
  end
583
583
 
@@ -79,6 +79,7 @@ end
79
79
 
80
80
  describe Aquarium::Finders::MethodFinder, "#find (synonymous input parameters)" do
81
81
  before(:each) do
82
+ @logger_stream = StringIO.new
82
83
  before_method_finder_spec
83
84
  end
84
85
 
@@ -109,11 +110,16 @@ describe Aquarium::Finders::MethodFinder, "#find (synonymous input parameters)"
109
110
 
110
111
  Aquarium::Finders::MethodFinder::CANONICAL_OPTIONS["method_options"].each do |key|
111
112
  it "should accept :#{key} as a synonym for :method_options." do
112
- expected = Aquarium::Finders::MethodFinder.new.find :types => Derived, :methods => [/^mder/, /^mmod/], :method_options => [:exclude_ancestor_methods]
113
- actual = Aquarium::Finders::MethodFinder.new.find :types => Derived, :methods => [/^mder/, /^mmod/], key.intern => [:exclude_ancestor_methods]
113
+ expected = Aquarium::Finders::MethodFinder.new.find :types => Derived, :methods => [/^mder/, /^mmod/], :method_options => [:exclude_ancestor_methods], :logger_stream => @logger_stream
114
+ actual = Aquarium::Finders::MethodFinder.new.find :types => Derived, :methods => [/^mder/, /^mmod/], key.intern => [:exclude_ancestor_methods], :logger_stream => @logger_stream
114
115
  actual.should == expected
115
116
  end
116
117
  end
118
+
119
+ it "should warn that :options as a synonym for :method_options is deprecated." do
120
+ expected = Aquarium::Finders::MethodFinder.new.find :types => Derived, :methods => [/^mder/, /^mmod/], :options => [:exclude_ancestor_methods], :logger_stream => @logger_stream
121
+ @logger_stream.to_s.grep(/WARN.*deprecated/).should_not be_nil
122
+ end
117
123
 
118
124
  end
119
125
 
@@ -0,0 +1,193 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'aquarium/dsl'
3
+ require 'aquarium/finders/pointcut_finder'
4
+ require File.dirname(__FILE__) + '/pointcut_finder_spec_test_classes'
5
+
6
+ describe Aquarium::Finders::PointcutFinder, "#find with invalid invocation parameters" do
7
+ it "should raise if no options are specified." do
8
+ lambda { Aquarium::Finders::PointcutFinder.new.find}.should raise_error(Aquarium::Utils::InvalidOptions)
9
+ end
10
+ it "should raise if no type options are specified." do
11
+ lambda { Aquarium::Finders::PointcutFinder.new.find :matching => :foo}.should raise_error(Aquarium::Utils::InvalidOptions)
12
+ end
13
+ end
14
+
15
+ describe Aquarium::Finders::PointcutFinder, "#find with valid type invocation parameters" do
16
+ it "should accept :types with a single type." do
17
+ lambda { Aquarium::Finders::PointcutFinder.new.find :types => Aquarium::PointcutFinderTestClasses::PointcutConstantHolder1, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
18
+ end
19
+ it "should accept :types with an array of types." do
20
+ lambda { Aquarium::Finders::PointcutFinder.new.find :types => [Aquarium::PointcutFinderTestClasses::PointcutConstantHolder1, Aquarium::PointcutFinderTestClasses::PointcutConstantHolder2], :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
21
+ end
22
+ it "should accept :types with a regular expression for types." do
23
+ lambda { Aquarium::Finders::PointcutFinder.new.find :types => /Aquarium::PointcutFinderTestClasses::PointcutConstantHolder/, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
24
+ end
25
+ Aquarium::Finders::PointcutFinder::CANONICAL_OPTIONS["types"].each do |synonym|
26
+ it "should accept :#{synonym} as a synonym for :types." do
27
+ lambda { Aquarium::Finders::PointcutFinder.new.find synonym.intern => /Aquarium::PointcutFinderTestClasses::PointcutConstantHolder/, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe Aquarium::Finders::PointcutFinder, "#find with nonexistent types specified" do
33
+ it "should return an empty FinderResult." do
34
+ found = Aquarium::Finders::PointcutFinder.new.find :types => /UndefinedType/
35
+ found.matched.should be_empty
36
+ found.not_matched.keys.should eql([/UndefinedType/])
37
+ end
38
+ end
39
+
40
+ describe Aquarium::Finders::PointcutFinder, "#find with no pointcut name parameter" do
41
+ it "should return all constant and class variable pointcuts in the specified types." do
42
+ found = Aquarium::Finders::PointcutFinder.new.find :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
43
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_pointcuts
44
+ end
45
+ end
46
+
47
+ variants = {'constant and class variable ' => '', 'constant ' => 'constants_', 'class variable ' => 'class_variables_'}.each do |name, prefix|
48
+ describe Aquarium::Finders::PointcutFinder, "#find with valid #{name}name invocation parameters" do
49
+ it "should accept :#{prefix}matching => :all and match all #{name} pointcuts in the specified types." do
50
+ found = Aquarium::Finders::PointcutFinder.new.find "#{prefix}matching".intern => :all, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
51
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, eval("Aquarium::PointcutFinderTestClasses.all_#{prefix}pointcuts")
52
+ end
53
+ it "should accept :#{prefix}matching with a single pointcut name." do
54
+ lambda { Aquarium::Finders::PointcutFinder.new.find "#{prefix}matching".intern => :POINTCUT1, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
55
+ end
56
+ it "should accept :#{prefix}matching with an array of pointcut names." do
57
+ lambda { Aquarium::Finders::PointcutFinder.new.find "#{prefix}matching".intern => [:POINTCUT1, :POINTCUT2], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
58
+ end
59
+ it "should accept :#{prefix}matching with a regular expression for pointcut names." do
60
+ lambda { Aquarium::Finders::PointcutFinder.new.find "#{prefix}matching".intern => /POINTCUT/, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
61
+ end
62
+ Aquarium::Finders::PointcutFinder::CANONICAL_OPTIONS["#{prefix}matching"].each do |synonym|
63
+ it "should accept :#{synonym} as a synonym for :#{prefix}matching." do
64
+ lambda { Aquarium::Finders::PointcutFinder.new.find synonym.intern => /POINTCUT/, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes, :noop => true}.should_not raise_error(Aquarium::Utils::InvalidOptions)
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ describe Aquarium::Finders::PointcutFinder, "#find with :matching => single pointcut name" do
71
+ it "should return all constant and class variable pointcuts that match the specified name exactly." do
72
+ found = Aquarium::Finders::PointcutFinder.new.find :matching => :POINTCUT1, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
73
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, [Aquarium::PointcutFinderTestClasses::PointcutConstantHolder1::POINTCUT1]
74
+ found = Aquarium::Finders::PointcutFinder.new.find :matching => :pointcut1, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
75
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, [Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1.pointcut1]
76
+ end
77
+ end
78
+ describe Aquarium::Finders::PointcutFinder, "#find with :constants_matching => single pointcut name" do
79
+ it "should return all constant pointcuts and no class variable pointcuts that match the specified name exactly." do
80
+ found = Aquarium::Finders::PointcutFinder.new.find :constants_matching => :POINTCUT1, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
81
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, [Aquarium::PointcutFinderTestClasses::PointcutConstantHolder1::POINTCUT1]
82
+ found = Aquarium::Finders::PointcutFinder.new.find :constants_matching => :pointcut1, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
83
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, []
84
+ end
85
+ end
86
+ describe Aquarium::Finders::PointcutFinder, "#find with :class_variables_matching => single pointcut name" do
87
+ it "should return all class variable pointcuts and no constant pointcuts that match the specified name exactly." do
88
+ found = Aquarium::Finders::PointcutFinder.new.find :class_variables_matching => :POINTCUT1, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
89
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, []
90
+ found = Aquarium::Finders::PointcutFinder.new.find :class_variables_matching => :pointcut1, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
91
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, [Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1.pointcut1]
92
+ end
93
+ end
94
+
95
+ describe Aquarium::Finders::PointcutFinder, "#find with :matching => /pointcut regexps/" do
96
+ it "should return all constant and class variable pointcuts that match the specified regular expressions." do
97
+ found = Aquarium::Finders::PointcutFinder.new.find :matching => /POINTCUT(1+|2)/, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
98
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_constants_pointcuts
99
+ found = Aquarium::Finders::PointcutFinder.new.find :matching => /pointcut1/, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
100
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_class_variables_pointcuts
101
+ end
102
+ end
103
+ describe Aquarium::Finders::PointcutFinder, "#find with :constants_matching => /pointcut regexps/" do
104
+ it "should return all constant pointcuts and no class variable pointcuts that match the specified regular expressions." do
105
+ found = Aquarium::Finders::PointcutFinder.new.find :constants_matching => /POINTCUT(1+|2)/, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
106
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_constants_pointcuts
107
+ found = Aquarium::Finders::PointcutFinder.new.find :constants_matching => /pointcut1/, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
108
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, []
109
+ end
110
+ end
111
+ describe Aquarium::Finders::PointcutFinder, "#find with :class_variables_matching => /pointcut regexps/" do
112
+ it "should return all class variable pointcuts and no constant pointcuts that match the specified regular expressions." do
113
+ found = Aquarium::Finders::PointcutFinder.new.find :class_variables_matching => /POINTCUT(1+|2)/, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
114
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, []
115
+ found = Aquarium::Finders::PointcutFinder.new.find :class_variables_matching => /pointcut1/, :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
116
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_class_variables_pointcuts
117
+ end
118
+ end
119
+
120
+ describe Aquarium::Finders::PointcutFinder, "#find with :matching => [pointcut names]" do
121
+ it "should return all constant and class variable pointcuts that match the specified names exactly." do
122
+ found = Aquarium::Finders::PointcutFinder.new.find :matching => [:POINTCUT1, :POINTCUT11, :POINTCUT2], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
123
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_constants_pointcuts
124
+ found = Aquarium::Finders::PointcutFinder.new.find :matching => [:pointcut1, :pointcut11], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
125
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_class_variables_pointcuts
126
+ end
127
+ end
128
+ describe Aquarium::Finders::PointcutFinder, "#find with :constants_matching => [pointcut names]" do
129
+ it "should return all constant pointcuts and no class variable pointcuts that match the specified names exactly." do
130
+ found = Aquarium::Finders::PointcutFinder.new.find :constants_matching => [:POINTCUT1, :POINTCUT11, :POINTCUT2], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
131
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_constants_pointcuts
132
+ found = Aquarium::Finders::PointcutFinder.new.find :constants_matching => [:pointcut1, :pointcut11], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
133
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, []
134
+ end
135
+ end
136
+ describe Aquarium::Finders::PointcutFinder, "#find with :class_variables_matching => [pointcut names]" do
137
+ it "should return all class variable pointcuts and no constant pointcuts that match the specified names and regular expressions." do
138
+ found = Aquarium::Finders::PointcutFinder.new.find :class_variables_matching => [:POINTCUT1, :POINTCUT11, :POINTCUT2], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
139
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, []
140
+ found = Aquarium::Finders::PointcutFinder.new.find :class_variables_matching => [:pointcut1, :pointcut11], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
141
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_class_variables_pointcuts
142
+ end
143
+ end
144
+
145
+ describe Aquarium::Finders::PointcutFinder, "#find with :matching => [pointcut names and regular expressions]" do
146
+ it "should return all constant and class variable pointcuts that match the specified names exactly." do
147
+ found = Aquarium::Finders::PointcutFinder.new.find :matching => [:POINTCUT1, :POINTCUT11, /CUT2/], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
148
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_constants_pointcuts
149
+ found = Aquarium::Finders::PointcutFinder.new.find :matching => [:pointcut1, /cut11$/], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
150
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_class_variables_pointcuts
151
+ end
152
+ end
153
+ describe Aquarium::Finders::PointcutFinder, "#find with :constants_matching => [pointcut names and regular expressions]" do
154
+ it "should return all constant pointcuts and no class variable pointcuts that match the specified names and regular expressions." do
155
+ found = Aquarium::Finders::PointcutFinder.new.find :constants_matching => [:POINTCUT1, :POINTCUT11, /CUT2/], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
156
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_constants_pointcuts
157
+ found = Aquarium::Finders::PointcutFinder.new.find :constants_matching => [:pointcut1, /cut11$/], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
158
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, []
159
+ end
160
+ end
161
+ describe Aquarium::Finders::PointcutFinder, "#find with :class_variables_matching => [pointcut names and regular expressions]" do
162
+ it "should return all class variable pointcuts and no constant pointcuts that match the specified names and regular expressions." do
163
+ found = Aquarium::Finders::PointcutFinder.new.find :class_variables_matching => [:POINTCUT1, :POINTCUT11, /CUT2/], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
164
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, []
165
+ found = Aquarium::Finders::PointcutFinder.new.find :class_variables_matching => [:pointcut1, /cut11$/], :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes
166
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_class_variables_pointcuts
167
+ end
168
+ end
169
+
170
+ describe Aquarium::Finders::PointcutFinder, "#find with any combination of :matching, :constant_matching, and/or :class_variables_matching" do
171
+ it "should return the union of all matching pointcuts." do
172
+ found = Aquarium::Finders::PointcutFinder.new.find :types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes,
173
+ :matching => [:POINTCUT1],
174
+ :constants_matching => /CUT[12]/,
175
+ :class_variables_matching => /pointcut/
176
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, Aquarium::PointcutFinderTestClasses.all_pointcuts
177
+ end
178
+ end
179
+
180
+ describe Aquarium::Finders::PointcutFinder, "#find with :types_and_descendents." do
181
+ it "should return the matching pointcuts in the hierarchy." do
182
+ found = Aquarium::Finders::PointcutFinder.new.find :types_and_descendents => Aquarium::PointcutFinderTestClasses::ParentOfPointcutHolder
183
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, [Aquarium::PointcutFinderTestClasses::PointcutConstantHolderChild::POINTCUT]
184
+ end
185
+ end
186
+
187
+ describe Aquarium::Finders::PointcutFinder, "#find with :types_and_ancestors." do
188
+ it "should return the matching pointcuts in the hierarchy." do
189
+ found = Aquarium::Finders::PointcutFinder.new.find :types_and_ancestors => Aquarium::PointcutFinderTestClasses::DescendentOfPointcutConstantHolderChild
190
+ Aquarium::PointcutFinderTestClasses.found_pointcuts_should_match found, [Aquarium::PointcutFinderTestClasses::PointcutConstantHolderChild::POINTCUT]
191
+ end
192
+ end
193
+
@@ -0,0 +1,90 @@
1
+
2
+ module Aquarium
3
+ module PointcutFinderTestClasses
4
+ class PointcutConstantHolder1
5
+ include Aquarium::DSL
6
+ def mc1; end
7
+ def doit; mc1; end
8
+ POINTCUT1 = pointcut :calls_to => :mc1 unless const_defined?("POINTCUT1")
9
+ end
10
+ class PointcutConstantHolder2
11
+ include Aquarium::DSL
12
+ def mc2; end
13
+ def doit; mc2; end
14
+ POINTCUT2 = pointcut :calls_to => :mc2 unless const_defined?("POINTCUT2")
15
+ end
16
+ class PointcutClassVariableHolder1
17
+ include Aquarium::DSL
18
+ def mcv1; end
19
+ def doit; mcv1; end
20
+ @@pointcut1 = pointcut :calls_to => :mcv1
21
+ def self.pointcut1; @@pointcut1; end
22
+ end
23
+ class OuterPointcutHolder
24
+ class NestedPointcutConstantHolder1
25
+ include Aquarium::DSL
26
+ def mc11; end
27
+ def doit; mc11; end
28
+ POINTCUT11 = pointcut :calls_to => :mc11 unless const_defined?("POINTCUT11")
29
+ end
30
+ class NestedPointcutClassVariableHolder1
31
+ include Aquarium::DSL
32
+ def mcv11; end
33
+ def doit; mcv11; end
34
+ @@pointcut11 = pointcut :calls_to => :mcv11
35
+ def self.pointcut11; @@pointcut11; end
36
+ end
37
+ end
38
+ class ParentOfPointcutHolder; end
39
+ class PointcutConstantHolderChild < ParentOfPointcutHolder
40
+ include Aquarium::DSL
41
+ def mc; end
42
+ def doit; mc; end
43
+ POINTCUT = pointcut :calls_to => :mc unless const_defined?("POINTCUT")
44
+ end
45
+ class DescendentOfPointcutConstantHolderChild < PointcutConstantHolderChild; end
46
+
47
+ def self.sort_pc_array pc_array
48
+ pc_array.sort{|x,y| x.object_id <=> y.object_id}
49
+ end
50
+ def self.found_pointcuts_should_match found_result_set, expected_found_pc_array, expected_not_found_type_array = []
51
+ found_result_set.matched.size.should == expected_found_pc_array.size
52
+ found_result_set.not_matched.size.should == expected_not_found_type_array.size
53
+ self.sort_pc_array(found_result_set.found_pointcuts).should == expected_found_pc_array
54
+ end
55
+
56
+ def self.all_pointcut_classes
57
+ [Aquarium::PointcutFinderTestClasses::PointcutConstantHolder1,
58
+ Aquarium::PointcutFinderTestClasses::PointcutConstantHolder2,
59
+ Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1,
60
+ Aquarium::PointcutFinderTestClasses::OuterPointcutHolder::NestedPointcutConstantHolder1,
61
+ Aquarium::PointcutFinderTestClasses::OuterPointcutHolder::NestedPointcutClassVariableHolder1]
62
+ end
63
+ def self.all_constants_pointcut_classes
64
+ [Aquarium::PointcutFinderTestClasses::PointcutConstantHolder1,
65
+ Aquarium::PointcutFinderTestClasses::PointcutConstantHolder2,
66
+ Aquarium::PointcutFinderTestClasses::OuterPointcutHolder::NestedPointcutConstantHolder1]
67
+ end
68
+ def self.all_class_variables_pointcut_classes
69
+ [Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1,
70
+ Aquarium::PointcutFinderTestClasses::OuterPointcutHolder::NestedPointcutClassVariableHolder1]
71
+ end
72
+
73
+ def self.all_pointcuts
74
+ sort_pc_array [Aquarium::PointcutFinderTestClasses::PointcutConstantHolder1::POINTCUT1,
75
+ Aquarium::PointcutFinderTestClasses::PointcutConstantHolder2::POINTCUT2,
76
+ Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1.pointcut1,
77
+ Aquarium::PointcutFinderTestClasses::OuterPointcutHolder::NestedPointcutConstantHolder1::POINTCUT11,
78
+ Aquarium::PointcutFinderTestClasses::OuterPointcutHolder::NestedPointcutClassVariableHolder1.pointcut11]
79
+ end
80
+ def self.all_constants_pointcuts
81
+ sort_pc_array [Aquarium::PointcutFinderTestClasses::PointcutConstantHolder1::POINTCUT1,
82
+ Aquarium::PointcutFinderTestClasses::PointcutConstantHolder2::POINTCUT2,
83
+ Aquarium::PointcutFinderTestClasses::OuterPointcutHolder::NestedPointcutConstantHolder1::POINTCUT11]
84
+ end
85
+ def self.all_class_variables_pointcuts
86
+ sort_pc_array [Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1.pointcut1,
87
+ Aquarium::PointcutFinderTestClasses::OuterPointcutHolder::NestedPointcutClassVariableHolder1.pointcut11]
88
+ end
89
+ end
90
+ end
@@ -229,6 +229,23 @@ describe Aquarium::Finders::TypeFinder, "#find with :types_and_ancestors" do
229
229
  end
230
230
  end
231
231
 
232
+ describe Aquarium::Finders::TypeFinder, "#each returns found types" do
233
+ it "should return only types that were found" do
234
+ expected_found_types = [Class, Kernel, Module, Object]
235
+ expected_unfound_exps = %w[TestCase Unknown1 Unknown2]
236
+ actual = Aquarium::Finders::TypeFinder.new.find :types=> %w[Kernel Module Object Class TestCase Unknown1 Unknown2]
237
+ actual.each {|t| expected_found_types.include?(t) and not expected_unfound_exps.include?(t.name)}
238
+ end
239
+
240
+ it "should return the same types returned by #matched_keys" do
241
+ expected_found_types = [Class, Kernel, Module, Object]
242
+ expected_unfound_exps = %w[TestCase Unknown1 Unknown2]
243
+ actual = Aquarium::Finders::TypeFinder.new.find :types=> %w[Kernel Module Object Class TestCase Unknown1 Unknown2]
244
+ actual.each {|t| actual.matched_keys.include?(t)}
245
+ count = actual.inject(0) {|count, t| count += 1}
246
+ count.should == actual.matched_keys.size
247
+ end
248
+ end
232
249
 
233
250
  # This is a spec for a protected method. It's primarily to keep the code coverage 100%, because there is rarely-invoked error handling code...
234
251
  describe Aquarium::Finders::TypeFinder, "#get_type_from_parent should" do
@@ -5,14 +5,14 @@ require 'aquarium/finders/type_finder'
5
5
  include Aquarium::Utils
6
6
 
7
7
  def purge_actuals actuals
8
- # Remove extra stuff inserted by RSpec, Aquarium, and "pretty printer" (rake?), possibly in other specs! (TODO undo those when finished...)
8
+ # Remove extra stuff inserted by RSpec, Aquarium, and "pretty printer" (rake?), possibly in other specs!
9
9
  actuals.matched_keys.reject do |t2|
10
- t2.name.include?("Spec::") or t2.name =~ /Aquarium::(Utils|Extras|Examples|Aspects)/ or t2.name =~ /^PP/
10
+ t2.name.include?("Spec::") or t2.name =~ /Aquarium::(Utils|Extras|Examples|Aspects|PointcutFinderTestClasses)/ or t2.name =~ /^PP/
11
11
  end
12
12
  end
13
13
 
14
14
  describe TypeUtils, "#find types and their descendents, using :types_and_descendents" do
15
- it "should find the matching types and their descendent subclasses, even in different nested modules." do
15
+ it "should find the matching types and their descendent subtypes, even in different nested modules." do
16
16
  TypeUtils.sample_types.each do |t|
17
17
  actual = Aquarium::Finders::TypeFinder.new.find :types_and_descendents => (t.name)
18
18
  actual_keys = purge_actuals actual
@@ -29,7 +29,7 @@ describe TypeUtils, "#find types and their descendents, using :types_and_descend
29
29
  end
30
30
 
31
31
  describe TypeUtils, "#find types subtracting out excluded types and descendents, using :exclude_types_and_descendents" do
32
- it "should find the matching types and their descendent subclasses, minus the excluded type hierarchies." do
32
+ it "should find the matching types and their descendent subtypes, minus the excluded type hierarchies." do
33
33
  actual = Aquarium::Finders::TypeFinder.new.find :types_and_descendents => ModuleForDescendents, :exclude_types_and_descendents => D1ForDescendents
34
34
  actual_keys = purge_actuals actual
35
35
  expected = TypeUtils.sample_types_descendents[ModuleForDescendents].reject do |c|