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
@@ -6,15 +6,15 @@ include Aquarium::Aspects
6
6
 
7
7
  describe Advice, "#sort_by_priority_order" do
8
8
  it "should return an empty array for empty input" do
9
- Aquarium::Aspects::Advice.sort_by_priority_order([]).should == []
9
+ Advice.sort_by_priority_order([]).should == []
10
10
  end
11
11
 
12
12
  it "should return a properly-sorted array for arbitrary input of valid advice kind symbols" do
13
- Aquarium::Aspects::Advice.sort_by_priority_order([:after_raising, :after_returning, :before, :after, :around]).should == [:around, :before, :after, :after_returning, :after_raising]
13
+ Advice.sort_by_priority_order([:after_raising, :after_returning, :before, :after, :around]).should == [:around, :before, :after, :after_returning, :after_raising]
14
14
  end
15
15
 
16
16
  it "should accept strings for the advice kinds, but return sorted symbols" do
17
- Aquarium::Aspects::Advice.sort_by_priority_order(["after_raising", "after_returning", "before", "after", "around"]).should == [:around, :before, :after, :after_returning, :after_raising]
17
+ Advice.sort_by_priority_order(["after_raising", "after_returning", "before", "after", "around"]).should == [:around, :before, :after, :after_returning, :after_raising]
18
18
  end
19
19
  end
20
20
 
@@ -53,16 +53,20 @@ describe Advice, "#invoke_original_join_point" do
53
53
  end
54
54
  end
55
55
 
56
+ def should_raise_expected_exception_with_message message
57
+ begin
58
+ yield ; fail
59
+ rescue => e
60
+ e.message.should include(message)
61
+ end
62
+ end
63
+
56
64
  describe Advice, "that raises an exception" do
57
65
  it "should add the kind of advice to the exception message." do
58
66
  aspect = Aspect.new :before, :pointcut => {:type => Watchful, :methods => :public_watchful_method} do |jp, obj, *args|
59
67
  raise SpecExceptionForTesting.new("advice called with args: #{args.inspect}")
60
68
  end
61
- begin
62
- Watchful.new.public_watchful_method(:a1, :a2) || fail
63
- rescue => e
64
- e.message.should include("\"before\" advice")
65
- end
69
+ should_raise_expected_exception_with_message("\"before\" advice") {Watchful.new.public_watchful_method(:a1, :a2)}
66
70
  aspect.unadvise
67
71
  end
68
72
 
@@ -70,11 +74,7 @@ describe Advice, "that raises an exception" do
70
74
  aspect = Aspect.new :before, :pointcut => {:type => Watchful, :methods => :public_watchful_method} do |jp, obj, *args|
71
75
  raise "advice called with args: #{args.inspect}"
72
76
  end
73
- begin
74
- Watchful.new.public_watchful_method(:a1, :a2) || fail
75
- rescue => e
76
- e.message.should include("Watchful#public_watchful_method")
77
- end
77
+ should_raise_expected_exception_with_message("Watchful#public_watchful_method") {Watchful.new.public_watchful_method(:a1, :a2)}
78
78
  aspect.unadvise
79
79
  end
80
80
 
@@ -82,29 +82,25 @@ describe Advice, "that raises an exception" do
82
82
  aspect = Aspect.new :before, :pointcut => {:type => Watchful, :methods => :public_class_watchful_method, :method_options => [:class]} do |jp, obj, *args|
83
83
  raise "advice called with args: #{args.inspect}"
84
84
  end
85
- begin
86
- Watchful.public_class_watchful_method(:a1, :a2) || fail
87
- rescue => e
88
- e.message.should include("Watchful.public_class_watchful_method")
89
- end
85
+ should_raise_expected_exception_with_message("Watchful.public_class_watchful_method") {Watchful.public_class_watchful_method(:a1, :a2)}
90
86
  aspect.unadvise
91
87
  end
92
88
 
93
89
  it "should rethrow an exception of the same type as the original exception." do
94
- class MyException < Exception; end
90
+ class MyException1 < Exception; end
95
91
  aspect = Aspect.new :before, :pointcut => {:type => Watchful, :methods => :public_class_watchful_method, :method_options => [:class]} do |jp, obj, *args|
96
- raise MyException.new("advice called with args: #{args.inspect}")
92
+ raise MyException1.new("advice called with args: #{args.inspect}")
97
93
  end
98
- lambda { Watchful.public_class_watchful_method :a1, :a2 }.should raise_error(MyException)
94
+ lambda { Watchful.public_class_watchful_method :a1, :a2 }.should raise_error(MyException1)
99
95
  aspect.unadvise
100
96
  end
101
97
 
102
98
  it "should rethrow an exception with the same backtrace as the original exception." do
103
- class MyException < Exception; end
99
+ class MyException2 < Exception; end
104
100
  @backtrace = nil
105
101
  aspect = Aspect.new :before, :pointcut => {:type => Watchful, :methods => :public_class_watchful_method, :method_options => [:class]} do |jp, obj, *args|
106
102
  begin
107
- exception = MyException.new("advice called with args: #{args.inspect}")
103
+ exception = MyException2.new("advice called with args: #{args.inspect}")
108
104
  raise exception
109
105
  rescue Exception => e
110
106
  @backtrace = e.backtrace
@@ -112,7 +108,89 @@ describe Advice, "that raises an exception" do
112
108
  end
113
109
  end
114
110
  begin
115
- Watchful.public_class_watchful_method(:a1, :a2) || fail
111
+ Watchful.public_class_watchful_method(:a1, :a2) ; fail
112
+ rescue Exception => e
113
+ e.backtrace.should == @backtrace
114
+ end
115
+ aspect.unadvise
116
+ end
117
+ end
118
+
119
+ describe Advice, "#invoke_original_join_point that raises an exception" do
120
+ class InvokeOriginalJoinPointRaisingException
121
+ class IOJPRException < Exception; end
122
+ def raise_exception *args
123
+ raise IOJPRException.new(":raise_exception called with args: #{args.inspect}")
124
+ end
125
+ def self.class_raise_exception *args
126
+ raise IOJPRException.new(":class_raise_exception called with args: #{args.inspect}")
127
+ end
128
+ end
129
+
130
+ it "should add the kind of advice to the exception message." do
131
+ aspect = Aspect.new :before,
132
+ :pointcut => {:type => InvokeOriginalJoinPointRaisingException, :methods => :raise_exception} do |jp, obj, *args|
133
+ jp.invoke_original_join_point
134
+ end
135
+ begin
136
+ InvokeOriginalJoinPointRaisingException.new.raise_exception(:a1, :a2) ; fail
137
+ rescue InvokeOriginalJoinPointRaisingException::IOJPRException => e
138
+ e.message.should include("\"before\" advice")
139
+ end
140
+ aspect.unadvise
141
+ end
142
+
143
+ it "should add the \"Class#method\" of the advised object's type and method to the exception message." do
144
+ aspect = Aspect.new :before,
145
+ :pointcut => {:type => InvokeOriginalJoinPointRaisingException, :methods => :raise_exception} do |jp, obj, *args|
146
+ jp.invoke_original_join_point
147
+ end
148
+ begin
149
+ InvokeOriginalJoinPointRaisingException.new.raise_exception(:a1, :a2) ; fail
150
+ rescue InvokeOriginalJoinPointRaisingException::IOJPRException => e
151
+ e.message.should include("InvokeOriginalJoinPointRaisingException#raise_exception")
152
+ end
153
+ aspect.unadvise
154
+ end
155
+
156
+ it "should add the \"Class.method\" of the advised type's class method to the exception message." do
157
+ aspect = Aspect.new :before,
158
+ :pointcut => {:type => InvokeOriginalJoinPointRaisingException, :methods => :class_raise_exception,
159
+ :method_options => [:class]} do |jp, obj, *args|
160
+ jp.invoke_original_join_point
161
+ end
162
+ begin
163
+ InvokeOriginalJoinPointRaisingException.class_raise_exception(:a1, :a2) ; fail
164
+ rescue InvokeOriginalJoinPointRaisingException::IOJPRException => e
165
+ e.message.should include("InvokeOriginalJoinPointRaisingException.class_raise_exception")
166
+ end
167
+ aspect.unadvise
168
+ end
169
+
170
+ it "should rethrow an exception of the same type as the original exception." do
171
+ aspect = Aspect.new :before,
172
+ :pointcut => {:type => InvokeOriginalJoinPointRaisingException, :methods => :class_raise_exception,
173
+ :method_options => [:class]} do |jp, obj, *args|
174
+ jp.invoke_original_join_point
175
+ end
176
+ lambda { InvokeOriginalJoinPointRaisingException.class_raise_exception :a1, :a2 }.should raise_error(InvokeOriginalJoinPointRaisingException::IOJPRException)
177
+ aspect.unadvise
178
+ end
179
+
180
+ it "should rethrow an exception with the same backtrace as the original exception." do
181
+ @backtrace = nil
182
+ aspect = Aspect.new :before,
183
+ :pointcut => {:type => InvokeOriginalJoinPointRaisingException, :methods => :class_raise_exception,
184
+ :method_options => [:class]} do |jp, obj, *args|
185
+ begin
186
+ jp.invoke_original_join_point
187
+ rescue Exception => e
188
+ @backtrace = e.backtrace
189
+ raise e
190
+ end
191
+ end
192
+ begin
193
+ InvokeOriginalJoinPointRaisingException.class_raise_exception(:a1, :a2) ; fail
116
194
  rescue Exception => e
117
195
  e.backtrace.should == @backtrace
118
196
  end
@@ -120,19 +198,56 @@ describe Advice, "that raises an exception" do
120
198
  end
121
199
  end
122
200
 
201
+ describe Advice, ".compare_advice_kinds with nil or UNKNOWN_ADVICE_KIND" do
202
+ it "should return 0 when comparing nil to nil" do
203
+ Advice.compare_advice_kinds(nil, nil).should == 0
204
+ end
205
+ it "should return 0 when comparing UNKNOWN_ADVICE_KIND to UNKNOWN_ADVICE_KIND" do
206
+ Advice.compare_advice_kinds(Advice::UNKNOWN_ADVICE_KIND, Advice::UNKNOWN_ADVICE_KIND).should == 0
207
+ end
208
+ it "should return 1 when comparing UNKNOWN_ADVICE_KIND to nil" do
209
+ Advice.compare_advice_kinds(Advice::UNKNOWN_ADVICE_KIND, nil).should == 1
210
+ end
211
+ it "should return -1 when comparing nil to UNKNOWN_ADVICE_KIND" do
212
+ Advice.compare_advice_kinds(nil, Advice::UNKNOWN_ADVICE_KIND).should == -1
213
+ end
214
+
215
+ Advice::KINDS_IN_PRIORITY_ORDER.each do |kind|
216
+ it "should return 1 when comparing :#{kind} to UNKNOWN_ADVICE_KIND" do
217
+ Advice.compare_advice_kinds(kind, Advice::UNKNOWN_ADVICE_KIND).should == 1
218
+ end
219
+ end
220
+ Advice::KINDS_IN_PRIORITY_ORDER.each do |kind|
221
+ it "should return -1 when comparing UNKNOWN_ADVICE_KIND to :#{kind}" do
222
+ Advice.compare_advice_kinds(Advice::UNKNOWN_ADVICE_KIND, kind).should == -1
223
+ end
224
+ end
225
+ end
226
+
227
+ describe Advice, ".compare_advice_kinds between 'real' advice kinds" do
228
+ Advice::KINDS_IN_PRIORITY_ORDER.each do |kind1|
229
+ Advice::KINDS_IN_PRIORITY_ORDER.each do |kind2|
230
+ expected = Advice::KINDS_IN_PRIORITY_ORDER.index(kind1) <=> Advice::KINDS_IN_PRIORITY_ORDER.index(kind2)
231
+ it "should return #{expected} when comparing :#{kind1} to :#{kind2} (using priority order)" do
232
+ Advice.compare_advice_kinds(kind1, kind2).should == expected
233
+ end
234
+ end
235
+ end
236
+ end
237
+
123
238
  describe AdviceChainNodeFactory, "#make_node" do
124
239
  it "should raise if an unknown advice kind is specified" do
125
- lambda {Aquarium::Aspects::AdviceChainNodeFactory.make_node :advice_kind => :foo}.should raise_error(Aquarium::Utils::InvalidOptions)
240
+ lambda {AdviceChainNodeFactory.make_node :advice_kind => :foo}.should raise_error(Aquarium::Utils::InvalidOptions)
126
241
  end
127
242
 
128
243
  it "should return a node of the type corresponding to the input advice kind" do
129
- Aquarium::Aspects::AdviceChainNodeFactory.make_node(:advice_kind => :no).kind_of?(Aquarium::Aspects::NoAdviceChainNode).should be_true
130
- Aquarium::Aspects::AdviceChainNodeFactory.make_node(:advice_kind => :none).kind_of?(Aquarium::Aspects::NoAdviceChainNode).should be_true
131
- Aquarium::Aspects::AdviceChainNodeFactory.make_node(:advice_kind => :before).kind_of?(Aquarium::Aspects::BeforeAdviceChainNode).should be_true
132
- Aquarium::Aspects::AdviceChainNodeFactory.make_node(:advice_kind => :after).kind_of?(Aquarium::Aspects::AfterAdviceChainNode).should be_true
133
- Aquarium::Aspects::AdviceChainNodeFactory.make_node(:advice_kind => :after_raising).kind_of?(Aquarium::Aspects::AfterRaisingAdviceChainNode).should be_true
134
- Aquarium::Aspects::AdviceChainNodeFactory.make_node(:advice_kind => :after_returning).kind_of?(Aquarium::Aspects::AfterReturningAdviceChainNode).should be_true
135
- Aquarium::Aspects::AdviceChainNodeFactory.make_node(:advice_kind => :around).kind_of?(Aquarium::Aspects::AroundAdviceChainNode).should be_true
244
+ AdviceChainNodeFactory.make_node(:advice_kind => :no).kind_of?(NoAdviceChainNode).should be_true
245
+ AdviceChainNodeFactory.make_node(:advice_kind => :none).kind_of?(NoAdviceChainNode).should be_true
246
+ AdviceChainNodeFactory.make_node(:advice_kind => :before).kind_of?(BeforeAdviceChainNode).should be_true
247
+ AdviceChainNodeFactory.make_node(:advice_kind => :after).kind_of?(AfterAdviceChainNode).should be_true
248
+ AdviceChainNodeFactory.make_node(:advice_kind => :after_raising).kind_of?(AfterRaisingAdviceChainNode).should be_true
249
+ AdviceChainNodeFactory.make_node(:advice_kind => :after_returning).kind_of?(AfterReturningAdviceChainNode).should be_true
250
+ AdviceChainNodeFactory.make_node(:advice_kind => :around).kind_of?(AroundAdviceChainNode).should be_true
136
251
  end
137
252
  end
138
253
 
@@ -1,13 +1,16 @@
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/aspects/aspect'
4
- require 'aquarium/aspects/dsl'
5
+ require 'aquarium/dsl'
5
6
  require 'aquarium/utils/array_utils'
7
+ require File.dirname(__FILE__) + '/../finders/pointcut_finder_spec_test_classes'
6
8
 
7
9
  require 'profiler'
8
10
 
9
11
  include Aquarium::Aspects
10
12
  include Aquarium::Utils::ArrayUtils
13
+ include Aquarium::PointcutFinderTestClasses
11
14
 
12
15
 
13
16
  def aspects_should_be_equal num_jps, aspect1, aspect2
@@ -132,18 +135,18 @@ describe Aspect, "methods" do
132
135
  it "should reject the :exceptions argument unless specified with :after_raising." do
133
136
  lambda { Aspect.new :before, :after, :exceptions => [Exception, String], :pointcut => @pointcut_opts, :noop => true }.should raise_error(Aquarium::Utils::InvalidOptions)
134
137
  end
135
- end
138
+ end
136
139
 
137
140
  describe Aspect, ".new (parameters that specify pointcuts)" do
138
141
  before :all do
139
142
  @pointcut_opts = {:type => Aquarium::AspectInvocationTestClass}
140
143
  end
141
144
 
142
- it "should contain at least one of :method(s), :pointcut(s), :type(s), or :object(s)." do
145
+ it "should contain at least one of :method(s), :pointcut(s), :named_pointcut(s), :type(s), or :object(s)." do
143
146
  lambda {Aspect.new(:after, :ignore_no_matching_join_points => true) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
144
147
  end
145
148
 
146
- it "should contain at least one of :pointcut(s), :type(s), or :object(s) unless :default_objects => object is given." do
149
+ it "should contain at least one of :pointcut(s), :named_pointcut(s), :type(s), or :object(s) unless :default_objects => object is given." do
147
150
  aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass.new, :method => :public_test_method, :noop => true) {true}
148
151
  end
149
152
 
@@ -163,7 +166,7 @@ end
163
166
  aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == Aquarium::AspectInvocationTestClass}
164
167
  end
165
168
 
166
- it "should ignore the :default_objects if at least one :pointcut is given and the :default_objects are objects." do
169
+ it "should ignore the :default_objects if at least one :pointcut is given even if the :default_objects => object are given." do
167
170
  object = Aquarium::AspectInvocationTestClass.new
168
171
  aspect = Aspect.new(:after, :default_objects => object,
169
172
  :pointcut => {:type => Aquarium::AspectInvocationTestClass2, :method => :public_test_method}, :method => :public_test_method) {true}
@@ -171,7 +174,7 @@ end
171
174
  aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == object}
172
175
  end
173
176
 
174
- it "should ignore the :default_objects if at least one :pointcut is given and the :default_objects are types." do
177
+ it "should ignore the :default_objects if at least one :pointcut is given even if the :default_objects => type are given." do
175
178
  aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass,
176
179
  :pointcut => {:type => Aquarium::AspectInvocationTestClass2, :method => :public_test_method}, :method => :public_test_method) {true}
177
180
  aspect.join_points_matched.size.should == 1
@@ -193,7 +196,7 @@ end
193
196
  aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == Aquarium::AspectInvocationTestClass}
194
197
  end
195
198
 
196
- [:type, :type_and_descendents, :type_and_ancestors].each do |type_key|
199
+ [:type, :type_and_descendents, :type_and_ancestors, :type_and_nested_types].each do |type_key|
197
200
  it "should ignore the :default_objects if at least one :#{type_key} is given and the :default_objects are objects." do
198
201
  object = Aquarium::AspectInvocationTestClass.new
199
202
  aspect = Aspect.new(:after, :default_objects => object, type_key => Aquarium::AspectInvocationTestClass2, :method => :public_test_method, :method => :public_test_method) {true}
@@ -220,7 +223,37 @@ end
220
223
  end
221
224
  end
222
225
 
226
+ describe Aspect, ".new (parameters that specify named constant and/or class variable pointcuts)" do
227
+ it "should contain at least one :types or TypeFinder synonym for :types." do
228
+ lambda {Aspect.new(:after, :named_pointcuts => {}, :noop => true) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
229
+ lambda {Aspect.new(:after, :named_pointcuts => {:types => all_pointcut_classes}, :noop => true) {true}}.should_not raise_error(Aquarium::Utils::InvalidOptions)
230
+ end
231
+
232
+ it "should ignore the :default_objects if at least one :named_pointcut is given even if the :default_objects => object are given." do
233
+ object = Aquarium::AspectInvocationTestClass.new
234
+ aspect = Aspect.new(:after, :default_objects => object, :named_pointcut => {:types => Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1}) {true}
235
+ aspect.join_points_matched.size.should == 1
236
+ aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == object}
237
+ end
238
+
239
+ it "should ignore the :default_objects if at least one :named_pointcut is given even if the :default_objects => type are given." do
240
+ aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass, :named_pointcut => {:types => Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1}) {true}
241
+ aspect.join_points_matched.size.should == 1
242
+ aspect.join_points_matched.each {|jp| jp.type_or_object.should_not == Aquarium::AspectInvocationTestClass}
243
+ end
244
+
245
+ Aspect::CANONICAL_OPTIONS["named_pointcuts"].each do |key|
246
+ it "should accept :#{key} as a synonym for :named_pointcuts." do
247
+ lambda { Aspect.new :before, key.intern => {:types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes}, :noop => true do; end }.should_not raise_error
248
+ end
249
+ end
223
250
 
251
+ it "should not contain :named_pointcut(s) and either :type(s) or :object(s)." do
252
+ lambda {Aspect.new(:after, :named_pointcuts => {:types => Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1}, :type => Aquarium::AspectInvocationTestClass, :method => :public_test_method) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
253
+ lambda {Aspect.new(:after, :named_pointcuts => {:types => Aquarium::PointcutFinderTestClasses::PointcutClassVariableHolder1}, :object => Aquarium::AspectInvocationTestClass.new, :method => :public_test_method) {true}}.should raise_error(Aquarium::Utils::InvalidOptions)
254
+ end
255
+ end
256
+
224
257
  describe Aspect, ".new with :types parameter" do
225
258
  it "should advise the specified types." do
226
259
  @advice_called = false
@@ -462,6 +495,27 @@ end
462
495
  do_type_spec
463
496
  end
464
497
 
498
+ it "should accept :type(s)_and_nested_types => T1, :methods => [m, ...]" do
499
+ @types_option = :types_and_nested_types
500
+ @type_spec = Aquarium::AspectInvocationTestClass
501
+ @method_spec = [:public_test_method]
502
+ do_type_spec
503
+ end
504
+
505
+ it "should accept :type(s)_and_nested_types => [T1, ...], :methods => [m, ...]" do
506
+ @types_option = :types_and_nested_types
507
+ @type_spec = [Aquarium::AspectInvocationTestClass]
508
+ @method_spec = [:public_test_method]
509
+ do_type_spec
510
+ end
511
+
512
+ it "should accept :type(s)_and_nested_types => /T1/, :methods => [m, ...]" do
513
+ @types_option = :types_and_nested_types
514
+ @type_spec = /Aquarium::AspectInvocationTestClass/
515
+ @method_spec = [:public_test_method]
516
+ do_type_spec
517
+ end
518
+
465
519
  it "should accept :type(s) => ..., :methods => ..., :method_options => [:exclude_ancestor_methods] to exclude methods defined in ancestors" do
466
520
  @type_spec = /Aquarium::AspectInvocationTestClass/
467
521
  @method_spec = /test_method/
@@ -885,6 +939,11 @@ end
885
939
  do_type_pointcut_spec
886
940
  end
887
941
 
942
+ it "should accept {:type(s)_and_nested_types => [T1, ...], :methods => /m/} " do
943
+ @pointcut_hash = {:type_and_nested_types => [Aquarium::AspectInvocationTestClass], :methods => /test_method/}
944
+ do_type_pointcut_spec
945
+ end
946
+
888
947
  it "should accept {:type(s) => T1, :methods => [m, ...]} " do
889
948
  @pointcut_hash = {:type => Aquarium::AspectInvocationTestClass, :methods => [:public_test_method]}
890
949
  do_type_pointcut_spec
@@ -910,6 +969,11 @@ end
910
969
  do_type_pointcut_spec
911
970
  end
912
971
 
972
+ it "should accept {:type(s)_and_nested_types => T1, :methods => /m/} " do
973
+ @pointcut_hash = {:type_and_nested_types => Aquarium::AspectInvocationTestClass, :methods => /test_method/}
974
+ do_type_pointcut_spec
975
+ end
976
+
913
977
  it "should accept {:type(s) => /T1/, :methods => [m, ...]} " do
914
978
  @pointcut_hash = {:type => /Aquarium::AspectInvocationTestClass/, :methods => [:public_test_method]}
915
979
  do_type_pointcut_spec
@@ -935,6 +999,11 @@ end
935
999
  do_type_pointcut_spec
936
1000
  end
937
1001
 
1002
+ it "should accept {:type(s)_and_nested_types => /T1/, :methods => /m/} " do
1003
+ @pointcut_hash = {:type_and_nested_types => /Aquarium::AspectInvocationTestClass/, :methods => /test_method/}
1004
+ do_type_pointcut_spec
1005
+ end
1006
+
938
1007
  %w[public protected private].each do |protection|
939
1008
  it "should accept {:type(s) => T1, :methods => /m/, :method_options =>[:instance, #{protection}]} " do
940
1009
  @protection = protection
@@ -1153,6 +1222,26 @@ end
1153
1222
  aspects_should_be_equal 1, @aspect1, @aspect2
1154
1223
  end
1155
1224
 
1225
+ it "should advise equivalent join points when :type_and_nested_types => T and :method => m is used or :pointcut =>{:type_and_nested_types => T, :method => m} is used." do
1226
+ @aspect1 = Aspect.new :after, :type_and_nested_types => Aquarium::AspectInvocationTestClass, :method => :public_test_method, &@advice
1227
+ @aspect2 = Aspect.new :after, :pointcut => {:type_and_nested_types => Aquarium::AspectInvocationTestClass, :method => :public_test_method}, &@advice
1228
+ aspects_should_be_equal 1, @aspect1, @aspect2
1229
+ end
1230
+
1231
+ it "should advise equivalent join points when :type_and_nested_types => T and :method => m is used or :pointcut => pointcut is used, where pointcut matches :type_and_nested_types => T and :method => m." do
1232
+ @aspect1 = Aspect.new :after, :type_and_nested_types => Aquarium::AspectInvocationTestClass, :method => :public_test_method, &@advice
1233
+ pointcut = Aquarium::Aspects::Pointcut.new :type_and_nested_types => Aquarium::AspectInvocationTestClass, :method => :public_test_method
1234
+ @aspect2 = Aspect.new :after, :pointcut => pointcut, &@advice
1235
+ aspects_should_be_equal 1, @aspect1, @aspect2
1236
+ end
1237
+
1238
+ it "should advise equivalent join points when :pointcut =>{:type_and_nested_types => T, :method => m} is used or :pointcut => pointcut is used, where pointcut matches :type_and_nested_types => T and :method => m." do
1239
+ @aspect1 = Aspect.new :after, :pointcut => {:type_and_nested_types => Aquarium::AspectInvocationTestClass, :method => :public_test_method}, &@advice
1240
+ pointcut = Aquarium::Aspects::Pointcut.new :type_and_nested_types => Aquarium::AspectInvocationTestClass, :method => :public_test_method
1241
+ @aspect2 = Aspect.new :after, :pointcut => pointcut, &@advice
1242
+ aspects_should_be_equal 1, @aspect1, @aspect2
1243
+ end
1244
+
1156
1245
  end
1157
1246
 
1158
1247
  describe Aspect, ".new (with a :type(s) parameter and an :attributes(s) parameter or one of several equivalent :pointcut parameters)" do
@@ -1407,7 +1496,7 @@ end
1407
1496
  end
1408
1497
 
1409
1498
  describe Aspect, ".new (advice block to around advice with just the join_point parameter - Bug #19262)" do
1410
- it "should work not raise an error" do
1499
+ it "should not raise an error" do
1411
1500
  aspect = Aspect.new :around, :type => Aquarium::AspectInvocationTestClass, :methods => :public_test_method do |jp|; jp.proceed; end
1412
1501
  Aquarium::AspectInvocationTestClass.new.public_test_method
1413
1502
  aspect.unadvise
@@ -1439,7 +1528,7 @@ end
1439
1528
  def doit3; end
1440
1529
  end
1441
1530
 
1442
- describe Aspect, ".new (with a :type(s) parameter and an :exclude_type(s), and :exclude_type(s)_and_ancestors, or an :exclude_type(s)_and_descendents parameter)" do
1531
+ describe Aspect, ".new (with a :type(s) parameter and an :exclude_type(s), and :exclude_type(s)_and_ancestors, an :exclude_type(s)_and_descendents, or an :exclude_type(s)_and_nested_types parameter)" do
1443
1532
  before :all do
1444
1533
  @included_types = [DontExclude1, DontExclude2]
1445
1534
  @excluded_types = [Exclude1, Exclude2]
@@ -1496,6 +1585,16 @@ end
1496
1585
  end
1497
1586
  end
1498
1587
 
1588
+ it "should accept :type(s) => [T1, ...], :exclude_types_and_nested_types => [T2, ...] and exclude join points in the excluded types" do
1589
+ do_exclude_types :exclude_types_and_nested_types
1590
+ end
1591
+
1592
+ Aspect::CANONICAL_OPTIONS["exclude_types_and_nested_types"].each do |key|
1593
+ it "should accept :#{key} as a synonym for :exclude_types_and_nested_types." do
1594
+ lambda { Aspect.new :before, :types => @all_types, key.intern => @excluded_types, :methods => :doit, :noop => true do; end }.should_not raise_error
1595
+ end
1596
+ end
1597
+
1499
1598
  end
1500
1599
 
1501
1600
 
@@ -1650,6 +1749,27 @@ end
1650
1749
  end
1651
1750
  end
1652
1751
 
1752
+ describe Aspect, ".new (with a :type(s)_and_nested_types parameter and an :exclude_join_point(s) parameter)" do
1753
+ it "should accept :type(s)_and_nested_types => [T1, ...], :exclude_join_point(s) => [jps], where [jps] are the list of join points for the types and methods to exclude" do
1754
+ included_types = [ClassWithPublicInstanceMethod, ModuleWithPublicInstanceMethod]
1755
+ excluded_join_point1 = JoinPoint.new :type => ClassWithPublicInstanceMethod, :method => :public_instance_test_method
1756
+ excluded_join_point2 = JoinPoint.new :type => ModuleWithPublicInstanceMethod, :method => :public_instance_module_test_method
1757
+ excluded_join_points = [excluded_join_point1, excluded_join_point2]
1758
+ aspect = nil
1759
+ advice_called = false
1760
+ aspect = Aspect.new :before, :types_and_nested_types => included_types, :methods => :doit,
1761
+ :exclude_join_points => excluded_join_points, :ignore_no_matching_join_points => true do |jp, obj, *args|; advice_called = true; end
1762
+
1763
+ advice_called = false
1764
+ ClassWithPublicInstanceMethod.new.public_instance_test_method
1765
+ advice_called.should be_false
1766
+ advice_called = false
1767
+ ClassIncludingModuleWithPublicInstanceMethod.new.public_instance_module_test_method
1768
+ advice_called.should be_false
1769
+ aspect.unadvise
1770
+ end
1771
+ end
1772
+
1653
1773
  describe Aspect, ".new (with a :pointcut(s) parameter and an :exclude_join_point(s) parameter)" do
1654
1774
  it "should accept :pointcut(s) => [P1, ...], :exclude_join_point(s) => [jps], where [jps] are the list of join points for the types and methods to exclude" do
1655
1775
  included_types = [DontExclude1, DontExclude2]
@@ -1716,7 +1836,7 @@ end
1716
1836
 
1717
1837
  Aspect::CANONICAL_OPTIONS["exclude_pointcuts"].each do |key|
1718
1838
  it "should accept :#{key} as a synonym for :exclude_pointcuts." do
1719
- lambda {aspect = Aspect.new :before, :objects => @all_objects, :exclude_pointcuts => @excluded_pointcuts, :methods => :doit, :noop => true do; end}.should_not raise_error
1839
+ lambda {aspect = Aspect.new :before, :objects => @all_objects, key.intern => @excluded_pointcuts, :methods => :doit, :noop => true do; end}.should_not raise_error
1720
1840
  end
1721
1841
  end
1722
1842
  end
@@ -1787,40 +1907,82 @@ end
1787
1907
  end
1788
1908
  end
1789
1909
 
1790
- describe Aspect, ".new (with type-based :pointcut(s) and :exclude_type(s) parameter)" do
1791
- it "should accept :pointcut(s) => [P1, ...], :exclude_type(s) => [types], where join points with [types] are excluded" do
1792
- included_types = [DontExclude1, DontExclude2]
1793
- excluded_types = [Exclude1, Exclude2]
1794
- pointcut1 = Pointcut.new :types => included_types, :method => :doit
1795
- pointcut2 = Pointcut.new :types => excluded_types, :method => :doit
1910
+ describe Aspect, ".new (with a :pointcut(s) and an :exclude_named_pointcut(s) parameter)" do
1911
+ it "should accept :pointcut(s) => [P1, ...], :exclude_named_pointcut(s) => {...}, where any pointcuts matching the latter are excluded" do
1796
1912
  aspect = nil
1797
1913
  advice_called = false
1798
- aspect = Aspect.new :before, :pointcuts => [pointcut1, pointcut2], :exclude_types => excluded_types do |jp, obj, *args|
1914
+ aspect = Aspect.new :before, :pointcuts => Aquarium::PointcutFinderTestClasses.all_pointcuts,
1915
+ :exclude_named_pointcuts => {:matching => /POINTCUT/, :in_types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes} do |jp, obj, *args|
1799
1916
  advice_called = true
1800
- excluded_types.should_not include(jp.target_type)
1917
+ Aquarium::PointcutFinderTestClasses.all_constants_pointcut_classes.should_not include(jp.target_type)
1801
1918
  end
1919
+ Aquarium::PointcutFinderTestClasses.all_class_variables_pointcut_classes.each do |type|
1920
+ advice_called = false
1921
+ type.new.doit
1922
+ advice_called.should be_true
1923
+ end
1924
+ Aquarium::PointcutFinderTestClasses.all_constants_pointcut_classes.each do |type|
1925
+ advice_called = false
1926
+ type.new.doit
1927
+ advice_called.should_not be_true
1928
+ end
1929
+ aspect.unadvise
1930
+ end
1802
1931
 
1803
- included_types.each do |type|
1932
+ Aspect::CANONICAL_OPTIONS["exclude_named_pointcuts"].each do |key|
1933
+ it "should accept :#{key} as a synonym for :exclude_named_pointcuts." do
1934
+ lambda {aspect = Aspect.new :before, :pointcuts => Aquarium::PointcutFinderTestClasses.all_pointcuts,
1935
+ key.intern => {:matching => /POINTCUT/, :in_types => Aquarium::PointcutFinderTestClasses.all_pointcut_classes},
1936
+ :noop => true do; end}.should_not raise_error
1937
+ end
1938
+ end
1939
+ end
1940
+
1941
+ describe Aspect, ".new (with type-based :pointcut(s) and :exclude_type(s) parameter)" do
1942
+ before :all do
1943
+ @included_types = [DontExclude1, DontExclude2]
1944
+ @excluded_types = [Exclude1, Exclude2]
1945
+ @pointcut1 = Pointcut.new :types => @included_types, :method => :doit
1946
+ @pointcut2 = Pointcut.new :types => @excluded_types, :method => :doit
1947
+ end
1948
+
1949
+ it "should accept :pointcut(s) => [P1, ...], :exclude_type(s) => [types], where join points with [types] are excluded" do
1950
+ advice_called = false
1951
+ aspect = Aspect.new :before, :pointcuts => [@pointcut1, @pointcut2], :exclude_types => @excluded_types do |jp, obj, *args|
1952
+ advice_called = true
1953
+ @excluded_types.should_not include(jp.target_type)
1954
+ end
1955
+
1956
+ @included_types.each do |type|
1804
1957
  advice_called = false
1805
1958
  type.new(1).doit
1806
1959
  advice_called.should be_true
1807
1960
  end
1808
- excluded_types.each do |type|
1961
+ @excluded_types.each do |type|
1809
1962
  advice_called = false
1810
1963
  type.new(1).doit
1811
1964
  advice_called.should_not be_true
1812
1965
  end
1813
1966
  aspect.unadvise
1814
1967
  end
1968
+
1969
+ Aspect::CANONICAL_OPTIONS["exclude_types"].each do |key|
1970
+ it "should accept :#{key} as a synonym for :exclude_types." do
1971
+ lambda {aspect = Aspect.new :before, :pointcuts => [@pointcut1, @pointcut2], key.intern => @excluded_types,
1972
+ :noop => true do; end}.should_not raise_error
1973
+ end
1974
+ end
1815
1975
  end
1816
1976
 
1817
1977
  describe Aspect, ".new (with type-based :pointcut(s) and :exclude_type(s)_and_ancestors parameter)" do
1978
+ before :all do
1979
+ @excluded_types = [ClassWithPublicInstanceMethod, ModuleWithPublicInstanceMethod]
1980
+ @types = @excluded_types + [ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod]
1981
+ @pointcut1 = Pointcut.new :types => @types, :method => :all, :method_options => [:exclude_ancestor_methods]
1982
+ end
1983
+
1818
1984
  it "should accept :pointcut(s) => [P1, ...], :exclude_type(s)_and_ancestors => [types], where join points with [types] are excluded" do
1819
- excluded_types = [ClassWithPublicInstanceMethod, ModuleWithPublicInstanceMethod]
1820
- types = excluded_types + [ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod]
1821
- pointcut1 = Pointcut.new :types => types, :method => :all, :method_options => [:exclude_ancestor_methods]
1822
- advice_called = false
1823
- aspect = Aspect.new :before, :pointcuts => pointcut1, :exclude_types_and_ancestors => excluded_types do |jp, obj, *args|; end
1985
+ aspect = Aspect.new :before, :pointcuts => @pointcut1, :exclude_types_and_ancestors => @excluded_types do |jp, obj, *args|; end
1824
1986
  aspect.pointcuts.each do |pc|
1825
1987
  pc.join_points_matched.each do |jp|
1826
1988
  jp.target_type.should == ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod
@@ -1828,48 +1990,95 @@ end
1828
1990
  end
1829
1991
  aspect.unadvise
1830
1992
  end
1993
+
1994
+ Aspect::CANONICAL_OPTIONS["exclude_types_and_ancestors"].each do |key|
1995
+ it "should accept :#{key} as a synonym for :exclude_types_and_ancestors." do
1996
+ lambda {aspect = Aspect.new :before, :pointcuts => @pointcut1, key.intern => @excluded_types,
1997
+ :noop => true do; end}.should_not raise_error
1998
+ end
1999
+ end
1831
2000
  end
1832
2001
 
1833
2002
  describe Aspect, ".new (with type-based :pointcut(s) and :exclude_type(s)_and_descendents parameter)" do
2003
+ before :all do
2004
+ @excluded_types = [ClassWithPublicInstanceMethod, ModuleWithPublicInstanceMethod]
2005
+ @types = @excluded_types + [ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod]
2006
+ @pointcut1 = Pointcut.new :types => @types, :method => :all, :method_options => [:exclude_ancestor_methods]
2007
+ end
1834
2008
  it "should accept :pointcut(s) => [P1, ...], :exclude_type(s)_and_descendents => [types], where join points with [types] are excluded" do
1835
- excluded_types = [ClassWithPublicInstanceMethod, ModuleWithPublicInstanceMethod]
1836
- types = excluded_types + [ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod]
1837
- pointcut1 = Pointcut.new :types => types, :method => :all, :method_options => [:exclude_ancestor_methods]
1838
- advice_called = false
1839
- aspect = Aspect.new :before, :pointcuts => pointcut1, :exclude_types_and_descendents => excluded_types, :ignore_no_matching_join_points => true do |jp, obj, *args|; end
2009
+ aspect = Aspect.new :before, :pointcuts => @pointcut1, :exclude_types_and_descendents => @excluded_types,
2010
+ :ignore_no_matching_join_points => true do |jp, obj, *args|; end
1840
2011
  aspect.pointcuts.size.should == 0
1841
2012
  aspect.unadvise
1842
2013
  end
2014
+
2015
+ Aspect::CANONICAL_OPTIONS["exclude_types_and_descendents"].each do |key|
2016
+ it "should accept :#{key} as a synonym for :exclude_types_and_descendents." do
2017
+ lambda {aspect = Aspect.new :before, :pointcuts => @pointcut1, key.intern => @excluded_types,
2018
+ :ignore_no_matching_join_points => true, :noop => true do; end}.should_not raise_error
2019
+ end
2020
+ end
2021
+ end
2022
+
2023
+ describe Aspect, ".new (with type-based :pointcut(s) and :exclude_type(s)_and_nested_types parameter)" do
2024
+ before :all do
2025
+ @excluded_types = [ClassWithPublicInstanceMethod, ModuleWithPublicInstanceMethod]
2026
+ @types = @excluded_types + [ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod]
2027
+ @pointcut1 = Pointcut.new :types => @types, :method => :all, :method_options => [:exclude_ancestor_methods]
2028
+ end
2029
+ it "should accept :pointcut(s) => [P1, ...], :exclude_type(s)_and_nested_types => [types], where join points with [types] are excluded" do
2030
+ aspect = Aspect.new :before, :pointcuts => @pointcut1, :exclude_types_and_nested_types => @excluded_types,
2031
+ :ignore_no_matching_join_points => true do |jp, obj, *args|; end
2032
+ aspect.pointcuts.size.should == 1
2033
+ aspect.unadvise
2034
+ end
2035
+
2036
+ Aspect::CANONICAL_OPTIONS["exclude_types_and_nested_types"].each do |key|
2037
+ it "should accept :#{key} as a synonym for :exclude_types_and_nested_types." do
2038
+ lambda {aspect = Aspect.new :before, :pointcuts => @pointcut1, key.intern => @excluded_types,
2039
+ :ignore_no_matching_join_points => true, :noop => true do; end}.should_not raise_error
2040
+ end
2041
+ end
1843
2042
  end
1844
2043
 
1845
- describe Aspect, ".new (with object-based :pointcut(s) and :exclude_object(s) or :exclude_method(s) parameter)" do
2044
+ describe Aspect, ".new (with object-based :pointcut(s) and :exclude_object(s) parameter)" do
2045
+ before :all do
2046
+ @dontExclude1 = DontExclude1.new(1)
2047
+ @dontExclude2 = DontExclude1.new(2)
2048
+ @exclude1 = DontExclude1.new(3)
2049
+ @exclude2 = DontExclude1.new(4)
2050
+ @included_objects = [@dontExclude1, @dontExclude2]
2051
+ @excluded_objects = [@exclude1, @exclude2]
2052
+ @pointcut1 = Pointcut.new :objects => @included_objects, :method => :doit
2053
+ @pointcut2 = Pointcut.new :objects => @excluded_objects, :method => :doit
2054
+ end
2055
+
1846
2056
  it "should accept :pointcut(s) => [P1, ...], :exclude_object(s) => [objects], where join points with [objects] are excluded" do
1847
- dontExclude1 = DontExclude1.new(1)
1848
- dontExclude2 = DontExclude1.new(2)
1849
- exclude1 = DontExclude1.new(3)
1850
- exclude2 = DontExclude1.new(4)
1851
- included_objects = [dontExclude1, dontExclude2]
1852
- excluded_objects = [exclude1, exclude2]
1853
- pointcut1 = Pointcut.new :objects => included_objects, :method => :doit
1854
- pointcut2 = Pointcut.new :objects => excluded_objects, :method => :doit
1855
2057
  aspect = nil
1856
2058
  advice_called = false
1857
- aspect = Aspect.new :before, :pointcuts => [pointcut1, pointcut2], :exclude_objects => excluded_objects do |jp, obj, *args|
2059
+ aspect = Aspect.new :before, :pointcuts => [@pointcut1, @pointcut2], :exclude_objects => @excluded_objects do |jp, obj, *args|
1858
2060
  advice_called = true
1859
- excluded_objects.should_not include(obj)
2061
+ @excluded_objects.should_not include(obj)
1860
2062
  end
1861
- included_objects.each do |object|
2063
+ @included_objects.each do |object|
1862
2064
  advice_called = false
1863
2065
  object.doit
1864
2066
  advice_called.should be_true
1865
2067
  end
1866
- excluded_objects.each do |object|
2068
+ @excluded_objects.each do |object|
1867
2069
  advice_called = false
1868
2070
  object.doit
1869
2071
  advice_called.should_not be_true
1870
2072
  end
1871
2073
  aspect.unadvise
1872
2074
  end
2075
+
2076
+ Aspect::CANONICAL_OPTIONS["exclude_objects"].each do |key|
2077
+ it "should accept :#{key} as a synonym for :exclude_objects." do
2078
+ lambda {aspect = Aspect.new :before, :pointcuts => [@pointcut1, @pointcut2], key.intern => @excluded_objects,
2079
+ :noop => true do; end}.should_not raise_error
2080
+ end
2081
+ end
1873
2082
  end
1874
2083
 
1875
2084
  describe Aspect, ".new (with :method(s) and :exclude_method(s) parameter)" do