aquarium 0.2.0 → 0.3.0

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 (59) hide show
  1. data/CHANGES +35 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README +66 -20
  4. data/Rakefile +1 -1
  5. data/UPGRADE +5 -0
  6. data/examples/aspect_design_example.rb +5 -4
  7. data/examples/aspect_design_example_spec.rb +6 -5
  8. data/examples/design_by_contract_example.rb +3 -3
  9. data/examples/design_by_contract_example_spec.rb +4 -4
  10. data/examples/method_missing_example.rb +1 -1
  11. data/examples/method_missing_example_spec.rb +2 -2
  12. data/examples/method_tracing_example.rb +3 -3
  13. data/examples/method_tracing_example_spec.rb +6 -6
  14. data/lib/aquarium/aspects/advice.rb +2 -3
  15. data/lib/aquarium/aspects/aspect.rb +100 -246
  16. data/lib/aquarium/aspects/{default_object_handler.rb → default_objects_handler.rb} +7 -6
  17. data/lib/aquarium/aspects/dsl/aspect_dsl.rb +2 -2
  18. data/lib/aquarium/aspects/pointcut.rb +190 -107
  19. data/lib/aquarium/finders/method_finder.rb +120 -34
  20. data/lib/aquarium/finders/type_finder.rb +2 -5
  21. data/lib/aquarium/utils.rb +1 -0
  22. data/lib/aquarium/utils/array_utils.rb +11 -3
  23. data/lib/aquarium/utils/options_utils.rb +74 -0
  24. data/lib/aquarium/utils/type_utils.rb +25 -11
  25. data/lib/aquarium/version.rb +1 -1
  26. data/spec/aquarium/aspects/advice_chain_node_spec.rb +1 -1
  27. data/spec/aquarium/aspects/advice_spec.rb +1 -1
  28. data/spec/aquarium/aspects/aspect_invocation_spec.rb +179 -145
  29. data/spec/aquarium/aspects/aspect_spec.rb +1 -1
  30. data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +1 -1
  31. data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +1 -1
  32. data/spec/aquarium/aspects/concurrent_aspects_spec.rb +1 -1
  33. data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +1 -1
  34. data/spec/aquarium/aspects/default_objects_handler_spec.rb +147 -0
  35. data/spec/aquarium/aspects/dsl/aspect_dsl_spec.rb +72 -121
  36. data/spec/aquarium/aspects/join_point_spec.rb +1 -1
  37. data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +1 -1
  38. data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +48 -47
  39. data/spec/aquarium/aspects/pointcut_spec.rb +727 -410
  40. data/spec/aquarium/extensions/hash_spec.rb +1 -1
  41. data/spec/aquarium/extensions/regex_spec.rb +1 -1
  42. data/spec/aquarium/extensions/set_spec.rb +1 -1
  43. data/spec/aquarium/extensions/string_spec.rb +1 -1
  44. data/spec/aquarium/extensions/symbol_spec.rb +1 -1
  45. data/spec/aquarium/extras/design_by_contract_spec.rb +1 -1
  46. data/spec/aquarium/finders/finder_result_spec.rb +1 -1
  47. data/spec/aquarium/finders/method_finder_spec.rb +49 -16
  48. data/spec/aquarium/finders/type_finder_spec.rb +1 -1
  49. data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +16 -1
  50. data/spec/aquarium/utils/array_utils_spec.rb +31 -6
  51. data/spec/aquarium/utils/hash_utils_spec.rb +1 -1
  52. data/spec/aquarium/utils/html_escaper_spec.rb +1 -1
  53. data/spec/aquarium/utils/logic_error_spec.rb +1 -1
  54. data/spec/aquarium/utils/method_utils_spec.rb +1 -1
  55. data/spec/aquarium/utils/name_utils_spec.rb +1 -1
  56. data/spec/aquarium/utils/nil_object_spec.rb +1 -1
  57. data/spec/aquarium/utils/set_utils_spec.rb +1 -1
  58. data/spec/aquarium/utils/type_utils_spec.rb +1 -1
  59. metadata +9 -7
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper.rb'
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
2
  require File.dirname(__FILE__) + '/../spec_example_classes'
3
3
  require 'aquarium'
4
4
 
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper.rb'
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
2
  require File.dirname(__FILE__) + '/../spec_example_classes'
3
3
  require 'aquarium/aspects/advice'
4
4
  require 'aquarium/aspects/aspect'
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/../spec_helper.rb'
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
2
  require File.dirname(__FILE__) + '/../spec_example_classes'
3
3
  require 'aquarium/aspects/aspect'
4
4
  require 'aquarium/aspects/dsl'
@@ -44,7 +44,7 @@ module Aquarium
44
44
  end
45
45
  end
46
46
 
47
- describe Aspect, ".new parameters that specify the kind of advice" do
47
+ describe Aspect, ".new (parameters that specify the kind of advice)" do
48
48
  it "should require the kind of advice as the first parameter." do
49
49
  lambda { Aspect.new :pointcut => {:type => Aquarium::AspectInvocationTestClass} }.should raise_error(Aquarium::Utils::InvalidOptions)
50
50
  end
@@ -73,92 +73,142 @@ describe Aspect, ".new parameters that specify the kind of advice" do
73
73
  it "should allow :before to be specified with :after_raising." do
74
74
  lambda { Aspect.new :before, :after_raising, :pointcut => {:type => Aquarium::AspectInvocationTestClass}, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
75
75
  end
76
+
77
+ it "should accept a single exception specified with :after_raising." do
78
+ lambda { Aspect.new :before, :after_raising => Exception, :pointcut => {:type => Aquarium::AspectInvocationTestClass}, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
79
+ end
80
+
81
+ it "should accept a a list of exceptions specified with :after_raising." do
82
+ lambda { Aspect.new :before, :after_raising => [Exception, String], :pointcut => {:type => Aquarium::AspectInvocationTestClass}, :noop => true }.should_not raise_error(Aquarium::Utils::InvalidOptions)
83
+ end
76
84
  end
77
85
 
78
- describe Aspect, ".new parameters that specify join points" do
86
+ describe Aspect, ".new (parameters that specify pointcuts)" do
79
87
  it "should contain at least one of :method(s), :pointcut(s), :type(s), or :object(s)." do
80
88
  lambda {Aspect.new(:after) {|jp, obj, *args| true}}.should raise_error(Aquarium::Utils::InvalidOptions)
81
89
  end
82
90
 
83
- it "should contain at least one of :pointcut(s), :type(s), or :object(s) unless :default_object => object is given." do
84
- aspect = Aspect.new(:after, :default_object => Aquarium::AspectInvocationTestClass.new, :methods => :public_test_method) {|jp, obj, *args| true}
91
+ it "should contain at least one of :pointcut(s), :type(s), or :object(s) unless :default_objects => object is given." do
92
+ aspect = Aspect.new(:after, :default_objects => Aquarium::AspectInvocationTestClass.new, :methods => :public_test_method) {|jp, obj, *args| true}
85
93
  aspect.unadvise
86
94
  end
87
95
 
96
+ Aspect::CANONICAL_OPTIONS["default_objects"].each do |key|
97
+ it "should accept :#{key} as a synonym for :default_objects." do
98
+ aspect = Aspect.new(:after, key.intern => Aquarium::AspectInvocationTestClass.new, :methods => :public_test_method) {|jp, obj, *args| true}
99
+ aspect.unadvise
100
+ end
101
+ end
102
+
88
103
  it "should not contain :pointcut(s) and either :type(s) or :object(s)." do
89
104
  lambda {Aspect.new(:after, :pointcuts => {:type => Aquarium::AspectInvocationTestClass, :methods => :public_test_method}, :type => Aquarium::AspectInvocationTestClass, :methods => :public_test_method) {|jp, obj, *args| true}}.should raise_error(Aquarium::Utils::InvalidOptions)
90
105
  lambda {Aspect.new(:after, :pointcuts => {:type => Aquarium::AspectInvocationTestClass, :methods => :public_test_method}, :object => Aquarium::AspectInvocationTestClass.new, :methods => :public_test_method) {|jp, obj, *args| true}}.should raise_error(Aquarium::Utils::InvalidOptions)
91
106
  end
107
+ end
92
108
 
93
- it "should include an advice block or :advice => advice parameter." do
94
- lambda {Aspect.new(:after, :type => Aquarium::AspectInvocationTestClass, :methods => :public_test_method)}.should raise_error(Aquarium::Utils::InvalidOptions)
109
+
110
+ describe Aspect, ".new (:types parameter)" do
111
+ Aspect::CANONICAL_OPTIONS["types"].each do |key|
112
+ it "should accept :#{key} as a synonym for :types." do
113
+ @advice = Proc.new {}
114
+ @expected_methods = [:public_test_method]
115
+ aspect1 = Aspect.new :before, key.intern => Aquarium::AspectInvocationTestClass, :method => @expected_methods, :advice => @advice
116
+ aspect2 = Aspect.new :before, :types => Aquarium::AspectInvocationTestClass, :method => @expected_methods, :advice => @advice
117
+ aspects_should_be_equal 1, aspect1, aspect2
118
+ aspect1.unadvise
119
+ aspect2.unadvise
120
+ end
95
121
  end
96
122
  end
97
123
 
124
+ describe Aspect, ".new (:pointcuts parameter)" do
125
+ Aspect::CANONICAL_OPTIONS["pointcuts"].each do |key|
126
+ it "should accept :#{key} as a synonym for :pointcuts." do
127
+ @advice = Proc.new {}
128
+ @expected_methods = [:public_test_method]
129
+ aspect1 = Aspect.new :before, key.intern => {:type => Aquarium::AspectInvocationTestClass, :method => @expected_methods}, :advice => @advice
130
+ aspect2 = Aspect.new :before, :pointcuts => {:type => Aquarium::AspectInvocationTestClass, :method => @expected_methods}, :advice => @advice
131
+ aspects_should_be_equal 1, aspect1, aspect2
132
+ aspect1.unadvise
133
+ aspect2.unadvise
134
+ end
135
+ end
136
+ end
98
137
 
99
- describe Aspect, ".new :type parameter" do
100
- it "should be accepted as a synonym for :types" do
101
- @advice = Proc.new {}
102
- @expected_methods = [:public_test_method]
103
- aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :method => @expected_methods, :advice => @advice
104
- aspect2 = Aspect.new :before, :types => Aquarium::AspectInvocationTestClass, :method => @expected_methods, :advice => @advice
105
- aspects_should_be_equal 1, aspect1, aspect2
106
- aspect1.unadvise
107
- aspect2.unadvise
138
+ describe Aspect, ".new (:objects parameter)" do
139
+ Aspect::CANONICAL_OPTIONS["objects"].each do |key|
140
+ it "should accept :#{key} as a synonym for :objects." do
141
+ @advice = Proc.new {}
142
+ @expected_methods = [:public_test_method]
143
+ object = Aquarium::AspectInvocationTestClass.new
144
+ aspect1 = Aspect.new :before, key.intern => object, :method => @expected_methods, :advice => @advice
145
+ aspect2 = Aspect.new :before, :objects => object, :method => @expected_methods, :advice => @advice
146
+ aspects_should_be_equal 1, aspect1, aspect2
147
+ aspect1.unadvise
148
+ aspect2.unadvise
149
+ end
108
150
  end
109
151
  end
110
152
 
111
- describe Aspect, ".new :pointcut parameter" do
112
- it "should be accepted as a synonym for :pointcuts" do
113
- @advice = Proc.new {}
114
- @expected_methods = [:public_test_method]
115
- aspect1 = Aspect.new :before, :pointcut => {:type => Aquarium::AspectInvocationTestClass, :method => @expected_methods}, :advice => @advice
116
- aspect2 = Aspect.new :before, :pointcuts => {:type => Aquarium::AspectInvocationTestClass, :method => @expected_methods}, :advice => @advice
117
- aspects_should_be_equal 1, aspect1, aspect2
118
- aspect1.unadvise
119
- aspect2.unadvise
153
+ describe Aspect, ".new (:methods parameter)" do
154
+ Aspect::CANONICAL_OPTIONS["methods"].each do |key|
155
+ it "should accept :#{key} as a synonym for :methods." do
156
+ @advice = Proc.new {}
157
+ @expected_methods = [:public_test_method]
158
+ aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, key.intern => @expected_methods, :advice => @advice
159
+ aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :methods => @expected_methods, :advice => @advice
160
+ aspects_should_be_equal 1, aspect1, aspect2
161
+ aspect1.unadvise
162
+ aspect2.unadvise
163
+ end
120
164
  end
121
165
  end
122
166
 
123
- describe Aspect, ".new :object parameter" do
124
- it "should be accepted as a synonym for :objects" do
167
+ describe Aspect, ".new (:attributes parameter)" do
168
+ Aspect::CANONICAL_OPTIONS["attributes"].each do |key|
169
+ it "should accept :#{key} as a synonym for :attributes." do
170
+ @advice = Proc.new {}
171
+ @expected_methods = [:public_test_method_args, :public_test_method_args=]
172
+ aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, key.intern => @expected_methods, :advice => @advice
173
+ aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :attributes => @expected_methods, :advice => @advice
174
+ aspects_should_be_equal 2, aspect1, aspect2
175
+ aspect1.unadvise
176
+ aspect2.unadvise
177
+ end
178
+ end
179
+
180
+ it "should accept :reading => ... as a synonym for :attributes => ..., :attribute_options => [:readers]." do
125
181
  @advice = Proc.new {}
126
- @expected_methods = [:public_test_method]
127
- object = Aquarium::AspectInvocationTestClass.new
128
- aspect1 = Aspect.new :before, :object => object, :method => @expected_methods, :advice => @advice
129
- aspect2 = Aspect.new :before, :objects => object, :method => @expected_methods, :advice => @advice
182
+ @expected_methods = [:public_test_method_args]
183
+ aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :reading => :public_test_method_args, :advice => @advice
184
+ aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :attributes => :public_test_method_args, :attribute_options => [:readers], :advice => @advice
130
185
  aspects_should_be_equal 1, aspect1, aspect2
131
186
  aspect1.unadvise
132
187
  aspect2.unadvise
133
188
  end
134
- end
135
189
 
136
- describe Aspect, ".new :method parameter" do
137
- it "should be accepted as a synonym for :methods" do
190
+ it "should accept :writing => ... as a synonym for :attributes => ..., :attribute_options => [:writer]." do
138
191
  @advice = Proc.new {}
139
- @expected_methods = [:public_test_method]
140
- aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :method => @expected_methods, :advice => @advice
141
- aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :methods => @expected_methods, :advice => @advice
192
+ @expected_methods = [:public_test_method_args=]
193
+ aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :writing => :public_test_method_args, :advice => @advice
194
+ aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :attributes => :public_test_method_args, :attribute_options => [:writers], :advice => @advice
142
195
  aspects_should_be_equal 1, aspect1, aspect2
143
196
  aspect1.unadvise
144
197
  aspect2.unadvise
145
198
  end
146
- end
147
199
 
148
- describe Aspect, ".new :attribute parameter" do
149
- it "should be accepted as a synonym for :attributes" do
200
+ it "should accept :changing => ... as a synonym for :attributes => ..., :attribute_options => [:writer]." do
150
201
  @advice = Proc.new {}
151
- @expected_methods = [:public_test_method_args, :public_test_method_args=]
152
- aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :attribute => @expected_methods, :advice => @advice
153
- aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :attributes => @expected_methods, :advice => @advice
154
- aspects_should_be_equal 2, aspect1, aspect2
202
+ @expected_methods = [:public_test_method_args=]
203
+ aspect1 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :changing => :public_test_method_args, :advice => @advice
204
+ aspect2 = Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :attributes => :public_test_method_args, :attribute_options => [:writers], :advice => @advice
205
+ aspects_should_be_equal 1, aspect1, aspect2
155
206
  aspect1.unadvise
156
207
  aspect2.unadvise
157
208
  end
158
209
  end
159
210
 
160
-
161
- describe Aspect, ".new with a :type(s) parameter and a :method(s) parameter" do
211
+ describe Aspect, ".new (with a :type(s) parameter and a :method(s) parameter)" do
162
212
  before :each do
163
213
  @protection = 'public'
164
214
  @are_class_methods = false
@@ -325,7 +375,7 @@ describe Aspect, ".new with a :type(s) parameter and a :method(s) parameter" do
325
375
  end
326
376
 
327
377
 
328
- describe Aspect, ".new with a :type(s) parameter and a :attribute(s) parameter" do
378
+ describe Aspect, ".new (with a :type(s) parameter and a :attribute(s) parameter)" do
329
379
  before :each do
330
380
  @protection = 'public'
331
381
  @attribute_options = []
@@ -462,7 +512,7 @@ describe Aspect, ".new with a :type(s) parameter and a :attribute(s) parameter"
462
512
  end
463
513
  end
464
514
 
465
- describe Aspect, ".new with a :object(s) parameter and a :method(s) parameter" do
515
+ describe Aspect, ".new (with a :object(s) parameter and a :method(s) parameter)" do
466
516
  before :each do
467
517
  @object1 = Aquarium::AspectInvocationTestClass.new
468
518
  @object2 = Aquarium::AspectInvocationTestClass.new
@@ -554,7 +604,7 @@ describe Aspect, ".new with a :object(s) parameter and a :method(s) parameter" d
554
604
  end
555
605
  end
556
606
 
557
- describe Aspect, ".new with a :object(s) parameter and a :attribute(s) parameter" do
607
+ describe Aspect, ".new (with a :object(s) parameter and a :attribute(s) parameter)" do
558
608
  before :each do
559
609
  @object1 = Aquarium::AspectInvocationTestClass.new
560
610
  @object2 = Aquarium::AspectInvocationTestClass.new
@@ -654,7 +704,7 @@ describe Aspect, ".new with a :object(s) parameter and a :attribute(s) parameter
654
704
  end
655
705
  end
656
706
 
657
- describe Aspect, ".new with a :pointcut parameter taking a hash with type specifications" do
707
+ describe Aspect, ".new (with a :pointcut parameter taking a hash with type specifications)" do
658
708
  before :each do
659
709
  @protection = 'public'
660
710
  @are_class_methods = false
@@ -782,7 +832,7 @@ describe Aspect, ".new with a :pointcut parameter taking a hash with type specif
782
832
  end
783
833
  end
784
834
 
785
- describe Aspect, ".new with a :pointcut parameter taking a hash with object specifications" do
835
+ describe Aspect, ".new (with a :pointcut parameter taking a hash with object specifications)" do
786
836
  before :each do
787
837
  @protection = 'public'
788
838
  @expected_advice_count = 2
@@ -839,7 +889,7 @@ describe Aspect, ".new with a :pointcut parameter taking a hash with object spec
839
889
  end
840
890
  end
841
891
 
842
- describe Aspect, ".new with a :pointcut parameter and a Pointcut object or an array of Pointcuts" do
892
+ describe Aspect, ".new (with a :pointcut parameter and a Pointcut object or an array of Pointcuts)" do
843
893
  def do_pointcut_pointcut_spec
844
894
  aspect = nil
845
895
  advice_called = false
@@ -867,7 +917,7 @@ describe Aspect, ".new with a :pointcut parameter and a Pointcut object or an ar
867
917
  end
868
918
  end
869
919
 
870
- describe Aspect, ".new with a :pointcut parameter and an array of Pointcuts" do
920
+ describe Aspect, ".new (with a :pointcut parameter and an array of Pointcuts)" do
871
921
  it "should treat the array as if it is one Pointcut \"or'ed\" together." do
872
922
  advice_called = 0
873
923
  advice = Proc.new {|jp, obj, *args|
@@ -894,7 +944,7 @@ describe Aspect, ".new with a :pointcut parameter and an array of Pointcuts" do
894
944
  end
895
945
  end
896
946
 
897
- describe Aspect, ".new with a :type(s) parameter and a :method(s) parameter or one of several equivalent :pointcut parameters" do
947
+ describe Aspect, ".new (with a :type(s) parameter and a :method(s) parameter or one of several equivalent :pointcut parameters)" do
898
948
  before :each do
899
949
  @advice = proc {|jp, obj, *args| "advice"}
900
950
  @expected_methods = [:public_test_method]
@@ -973,7 +1023,7 @@ describe Aspect, ".new with a :type(s) parameter and a :method(s) parameter or o
973
1023
 
974
1024
  end
975
1025
 
976
- describe Aspect, ".new with a :type(s) parameter and an :attributes(s) parameter or one of several equivalent :pointcut parameters" do
1026
+ describe Aspect, ".new (with a :type(s) parameter and an :attributes(s) parameter or one of several equivalent :pointcut parameters)" do
977
1027
  class ClassWithAttrib1
978
1028
  def dummy; end
979
1029
  attr_accessor :state
@@ -1030,7 +1080,7 @@ describe Aspect, ".new with a :type(s) parameter and an :attributes(s) parameter
1030
1080
  end
1031
1081
  end
1032
1082
 
1033
- describe Aspect, ".new with a :object(s) parameter and a :method(s) parameter or one of several equivalent :pointcut parameters" do
1083
+ describe Aspect, ".new (with a :object(s) parameter and a :method(s) parameter or one of several equivalent :pointcut parameters)" do
1034
1084
  before :each do
1035
1085
  @advice = proc {|jp, obj, *args| "advice"}
1036
1086
  @expected_methods = [:public_test_method]
@@ -1064,7 +1114,7 @@ describe Aspect, ".new with a :object(s) parameter and a :method(s) parameter or
1064
1114
  end
1065
1115
  end
1066
1116
 
1067
- describe Aspect, ".new with a :object(s) parameter and an :attributes(s) parameter or one of several equivalent :pointcut parameters" do
1117
+ describe Aspect, ".new (with a :object(s) parameter and an :attributes(s) parameter or one of several equivalent :pointcut parameters)" do
1068
1118
  class ClassWithAttrib2
1069
1119
  def initialize *args
1070
1120
  @state = args
@@ -1125,7 +1175,7 @@ describe Aspect, ".new with a :object(s) parameter and an :attributes(s) paramet
1125
1175
  end
1126
1176
  end
1127
1177
 
1128
- describe Aspect, ".new block for advice" do
1178
+ describe Aspect, ".new (block for advice)" do
1129
1179
  it "should accept a block as the advice to use." do
1130
1180
  object = Aquarium::AspectInvocationTestClass.new
1131
1181
  advice_called = false
@@ -1155,57 +1205,37 @@ describe Aspect, ".new block for advice" do
1155
1205
  aspect.unadvise
1156
1206
  end
1157
1207
 
1158
- it "should accept a :call => Proc parameter as a synonym for :advice." do
1159
- object = Aquarium::AspectInvocationTestClass.new
1160
- advice_called = false
1161
- advice = Proc.new {|jp, obj, *args|
1162
- advice_called = true
1163
- jp.should_not be_nil
1164
- args.size.should == 4
1165
- args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
1166
- }
1167
- aspect = Aspect.new :before, :object => object, :methods => :public_test_method, :call => advice
1168
- object.public_test_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
1169
- advice_called.should be_true
1170
- aspect.unadvise
1171
- end
1172
-
1173
- it "should accept a :invoke => Proc parameter as a synonym for :advice." do
1174
- object = Aquarium::AspectInvocationTestClass.new
1175
- advice_called = false
1176
- advice = Proc.new {|jp, obj, *args|
1177
- advice_called = true
1178
- jp.should_not be_nil
1179
- args.size.should == 4
1180
- args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
1181
- }
1182
- aspect = Aspect.new :before, :object => object, :methods => :public_test_method, :invoke => advice
1183
- object.public_test_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
1184
- advice_called.should be_true
1185
- aspect.unadvise
1208
+ Aspect::CANONICAL_OPTIONS["advice"].each do |key|
1209
+ it "should accept :#{key} => proc as a synonym for :advice." do
1210
+ object = Aquarium::AspectInvocationTestClass.new
1211
+ advice_called = false
1212
+ advice = Proc.new {|jp, obj, *args|
1213
+ advice_called = true
1214
+ jp.should_not be_nil
1215
+ args.size.should == 4
1216
+ args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
1217
+ }
1218
+ aspect = Aspect.new :before, :object => object, :methods => :public_test_method, key.intern => advice
1219
+ object.public_test_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
1220
+ advice_called.should be_true
1221
+ aspect.unadvise
1222
+ end
1186
1223
  end
1187
-
1188
- it "should accept a :advise_with => Proc parameter as a synonym for :advice." do
1224
+
1225
+ it "should allow only one :advice object to be specified (including synonyms)." do
1189
1226
  object = Aquarium::AspectInvocationTestClass.new
1190
1227
  advice_called = false
1191
- advice = Proc.new {|jp, obj, *args|
1192
- advice_called = true
1193
- jp.should_not be_nil
1194
- args.size.should == 4
1195
- args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
1196
- }
1197
- aspect = Aspect.new :before, :object => object, :methods => :public_test_method, :advise_with => advice
1198
- object.public_test_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
1199
- advice_called.should be_true
1200
- aspect.unadvise
1228
+ advice1 = Proc.new {|jp, obj, *args| fail "advice1"}
1229
+ advice2 = Proc.new {|jp, obj, *args| fail "advice2"}
1230
+ lambda {Aspect.new :before, :object => object, :methods => :public_test_method, :advice => advice1, :invoke => advice2}.should raise_error(Aquarium::Utils::InvalidOptions)
1201
1231
  end
1202
1232
 
1203
- it "should ignore all other advice parameters if a block is given." do
1233
+ it "should allow ignore an :advice option if a block is given." do
1204
1234
  object = Aquarium::AspectInvocationTestClass.new
1205
1235
  advice_called = false
1206
1236
  advice1 = Proc.new {|jp, obj, *args| fail "advice1"}
1207
1237
  advice2 = Proc.new {|jp, obj, *args| fail "advice2"}
1208
- aspect = Aspect.new :before, :object => object, :methods => :public_test_method, :advice => advice1, :invoke => advice2 do |jp, obj, *args|
1238
+ aspect = Aspect.new :before, :object => object, :methods => :public_test_method, :advice => advice1 do |jp, obj, *args|
1209
1239
  advice_called = true
1210
1240
  end
1211
1241
  object.public_test_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
@@ -1213,24 +1243,13 @@ describe Aspect, ".new block for advice" do
1213
1243
  aspect.unadvise
1214
1244
  end
1215
1245
 
1216
- it "should ignore all but the last advice parameter, using any synonym, if there is no advice block." do
1217
- object = Aquarium::AspectInvocationTestClass.new
1218
- advice_called = false
1219
- advice1 = Proc.new {|jp, obj, *args|
1220
- advice_called = true
1221
- jp.should_not be_nil
1222
- args.size.should == 4
1223
- args.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
1224
- }
1225
- advice2 = Proc.new {|jp, obj, *args| raise "should not be called"}
1226
- aspect = Aspect.new :before, :object => object, :methods => :public_test_method, :advice => advice2, :advice => advice1
1227
- object.public_test_method :a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2'
1228
- advice_called.should be_true
1229
- aspect.unadvise
1230
- end
1231
1246
  end
1232
1247
 
1233
- describe Aspect, ".new advice block or proc parameter list" do
1248
+ describe Aspect, ".new (advice block or proc parameter list)" do
1249
+ it "should raise unless an advice block or :advice => advice parameter is specified." do
1250
+ lambda {Aspect.new(:after, :type => Aquarium::AspectInvocationTestClass, :methods => :public_test_method)}.should raise_error(Aquarium::Utils::InvalidOptions)
1251
+ end
1252
+
1234
1253
  it "should raise if obsolete |jp, *args| list is used." do
1235
1254
  lambda { Aspect.new :before, :type => Aquarium::AspectInvocationTestClass, :methods => :public_test_method do |jp, *args|; end }.should raise_error(Aquarium::Utils::InvalidOptions)
1236
1255
  end
@@ -1282,7 +1301,7 @@ class Exclude1c < Exclude1
1282
1301
  def doit3; end
1283
1302
  end
1284
1303
 
1285
- 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
1304
+ 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
1286
1305
  def do_exclude_types exclude_type_sym
1287
1306
  included_types = [DontExclude1, DontExclude2]
1288
1307
  excluded_types = [Exclude1, Exclude2]
@@ -1309,29 +1328,36 @@ describe Aspect, ".new with a :type(s) parameter and an :exclude_type(s), and :e
1309
1328
  do_exclude_types :exclude_types
1310
1329
  end
1311
1330
 
1312
- it "should accept :exclude_type as a synonym for :exclude_types" do
1313
- do_exclude_types :exclude_type
1331
+ Aspect::CANONICAL_OPTIONS["exclude_types"].each do |key|
1332
+ it "should accept :#{key} as a synonym for :exclude_types." do
1333
+ do_exclude_types key.intern
1334
+ end
1314
1335
  end
1315
1336
 
1316
1337
  it "should accept :type(s) => [T1, ...], :exclude_types_and_ancestors => [T2, ...] and exclude join points in the excluded types" do
1317
1338
  do_exclude_types :exclude_types_and_ancestors
1318
1339
  end
1319
1340
 
1320
- it "should accept :exclude_type_and_ancestors as a synonym for :exclude_types_and_ancestors" do
1321
- do_exclude_types :exclude_type_and_ancestors
1341
+ Aspect::CANONICAL_OPTIONS["exclude_types_and_ancestors"].each do |key|
1342
+ it "should accept :#{key} as a synonym for :exclude_types_and_ancestors." do
1343
+ do_exclude_types key.intern
1344
+ end
1322
1345
  end
1323
1346
 
1324
1347
  it "should accept :type(s) => [T1, ...], :exclude_types_and_descendents => [T2, ...] and exclude join points in the excluded types" do
1325
1348
  do_exclude_types :exclude_types_and_descendents
1326
1349
  end
1327
1350
 
1328
- it "should accept :exclude_type_and_descendents as a synonym for :exclude_types_and_descendents" do
1329
- do_exclude_types :exclude_type_and_descendents
1351
+ Aspect::CANONICAL_OPTIONS["exclude_types_and_descendents"].each do |key|
1352
+ it "should accept :#{key} as a synonym for :exclude_types_and_descendents." do
1353
+ do_exclude_types key.intern
1354
+ end
1330
1355
  end
1356
+
1331
1357
  end
1332
1358
 
1333
1359
 
1334
- describe Aspect, ".new with a :object(s) parameter and an :exclude_object(s) parameter" do
1360
+ describe Aspect, ".new (with a :object(s) parameter and an :exclude_object(s) parameter)" do
1335
1361
  def do_exclude_objects exclude_object_sym
1336
1362
  dontExclude1 = DontExclude1.new(1)
1337
1363
  dontExclude2 = DontExclude1.new(2)
@@ -1362,13 +1388,15 @@ describe Aspect, ".new with a :object(s) parameter and an :exclude_object(s) par
1362
1388
  do_exclude_objects :exclude_objects
1363
1389
  end
1364
1390
 
1365
- it "should accept :exclude_object as a synonym for :exclude_objects" do
1366
- do_exclude_objects :exclude_object
1391
+ Aspect::CANONICAL_OPTIONS["exclude_objects"].each do |key|
1392
+ it "should accept :#{key} as a synonym for :exclude_objects." do
1393
+ do_exclude_objects key.intern
1394
+ end
1367
1395
  end
1368
1396
  end
1369
1397
 
1370
1398
 
1371
- describe Aspect, ".new with a :pointcut(s), :type(s), :type(s)_with_ancestors, :type(s)_with_descendents, :object(s), and :method(s) parameter and an :exclude_join_point(s) parameter" do
1399
+ describe Aspect, ".new (with a :pointcut(s), :type(s), :type(s)_with_ancestors, :type(s)_with_descendents, :object(s), and :method(s) parameter and an :exclude_join_point(s) parameter)" do
1372
1400
  def do_exclude_join_points exclude_join_points_sym
1373
1401
  dontExclude1 = DontExclude1.new(1)
1374
1402
  dontExclude2 = DontExclude1.new(2)
@@ -1399,10 +1427,12 @@ describe Aspect, ".new with a :pointcut(s), :type(s), :type(s)_with_ancestors, :
1399
1427
  aspect.unadvise
1400
1428
  end
1401
1429
 
1402
- it "should accept :exclude_join_point as a synonym for :exclude_join_points" do
1403
- do_exclude_join_points :exclude_join_point
1430
+ Aspect::CANONICAL_OPTIONS["exclude_join_points"].each do |key|
1431
+ it "should accept :#{key} as a synonym for :exclude_join_points." do
1432
+ do_exclude_join_points key.intern
1433
+ end
1404
1434
  end
1405
-
1435
+
1406
1436
  it "should accept :object(s) => [o1, ...], :exclude_join_point(s) => [jps], where [jps] are the list of join points for the objects and methods to exclude" do
1407
1437
  do_exclude_join_points :exclude_join_points
1408
1438
  end
@@ -1497,7 +1527,7 @@ describe Aspect, ".new with a :pointcut(s), :type(s), :type(s)_with_ancestors, :
1497
1527
  end
1498
1528
  end
1499
1529
 
1500
- describe Aspect, ".new with a :pointcut(s), :type(s), :object(s), and :method(s) parameter and an :exclude_pointcut(s) parameter" do
1530
+ describe Aspect, ".new (with a :pointcut(s), :type(s), :object(s), and :method(s) parameter and an :exclude_pointcut(s) parameter)" do
1501
1531
  def do_exclude_pointcuts exclude_pointcuts_sym
1502
1532
  dontExclude1 = DontExclude1.new(1)
1503
1533
  dontExclude2 = DontExclude1.new(2)
@@ -1528,10 +1558,12 @@ describe Aspect, ".new with a :pointcut(s), :type(s), :object(s), and :method(s)
1528
1558
  aspect.unadvise
1529
1559
  end
1530
1560
 
1531
- it "should accept :exclude_pointcut as a synonym for :exclude_pointcuts" do
1532
- do_exclude_pointcuts :exclude_pointcut
1561
+ Aspect::CANONICAL_OPTIONS["exclude_pointcuts"].each do |key|
1562
+ it "should accept :#{key} as a synonym for :exclude_pointcuts." do
1563
+ do_exclude_pointcuts key.intern
1564
+ end
1533
1565
  end
1534
-
1566
+
1535
1567
  it "should accept :object(s) => [o1, ...], :exclude_pointcut(s) => [pcs], where [pcs] are the list of pointcuts for the objects and methods to exclude" do
1536
1568
  do_exclude_pointcuts :exclude_pointcuts
1537
1569
  end
@@ -1590,7 +1622,7 @@ describe Aspect, ".new with a :pointcut(s), :type(s), :object(s), and :method(s)
1590
1622
  end
1591
1623
  end
1592
1624
 
1593
- describe Aspect, ".new with type-based :pointcut(s) and :exclude_type(s) parameter" do
1625
+ describe Aspect, ".new (with type-based :pointcut(s) and :exclude_type(s) parameter)" do
1594
1626
  it "should accept :pointcut(s) => [P1, ...], :exclude_type(s) => [types], where join points with [types] are excluded" do
1595
1627
  included_types = [DontExclude1, DontExclude2]
1596
1628
  excluded_types = [Exclude1, Exclude2]
@@ -1617,7 +1649,7 @@ describe Aspect, ".new with type-based :pointcut(s) and :exclude_type(s) paramet
1617
1649
  end
1618
1650
  end
1619
1651
 
1620
- describe Aspect, ".new with type-based :pointcut(s) and :exclude_type(s)_and_ancestors parameter" do
1652
+ describe Aspect, ".new (with type-based :pointcut(s) and :exclude_type(s)_and_ancestors parameter)" do
1621
1653
  it "should accept :pointcut(s) => [P1, ...], :exclude_type(s)_and_ancestors => [types], where join points with [types] are excluded" do
1622
1654
  excluded_types = [ClassWithPublicInstanceMethod, ModuleWithPublicInstanceMethod]
1623
1655
  types = excluded_types + [ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod]
@@ -1633,7 +1665,7 @@ describe Aspect, ".new with type-based :pointcut(s) and :exclude_type(s)_and_anc
1633
1665
  end
1634
1666
  end
1635
1667
 
1636
- describe Aspect, ".new with type-based :pointcut(s) and :exclude_type(s)_and_descendents parameter" do
1668
+ describe Aspect, ".new (with type-based :pointcut(s) and :exclude_type(s)_and_descendents parameter)" do
1637
1669
  it "should accept :pointcut(s) => [P1, ...], :exclude_type(s)_and_descendents => [types], where join points with [types] are excluded" do
1638
1670
  excluded_types = [ClassWithPublicInstanceMethod, ModuleWithPublicInstanceMethod]
1639
1671
  types = excluded_types + [ClassDerivedFromClassIncludingModuleWithPublicInstanceMethod]
@@ -1646,7 +1678,7 @@ describe Aspect, ".new with type-based :pointcut(s) and :exclude_type(s)_and_des
1646
1678
  end
1647
1679
 
1648
1680
 
1649
- describe Aspect, ".new with object-based :pointcut(s) and :exclude_object(s) or :exclude_method(s) parameter" do
1681
+ describe Aspect, ".new (with object-based :pointcut(s) and :exclude_object(s) or :exclude_method(s) parameter)" do
1650
1682
 
1651
1683
  it "should accept :pointcut(s) => [P1, ...], :exclude_object(s) => [objects], where join points with [objects] are excluded" do
1652
1684
  dontExclude1 = DontExclude1.new(1)
@@ -1677,7 +1709,7 @@ describe Aspect, ".new with object-based :pointcut(s) and :exclude_object(s) or
1677
1709
  end
1678
1710
  end
1679
1711
 
1680
- describe Aspect, ".new with :method(s) and :exclude_method(s) parameter" do
1712
+ describe Aspect, ".new (with :method(s) and :exclude_method(s) parameter)" do
1681
1713
  before :each do
1682
1714
  @dontExclude1 = DontExclude1.new(1)
1683
1715
  @dontExclude2 = DontExclude1.new(2)
@@ -1695,9 +1727,9 @@ describe Aspect, ".new with :method(s) and :exclude_method(s) parameter" do
1695
1727
  @pointcut4 = Pointcut.new :types => @excluded_types, :method => /doit/
1696
1728
  end
1697
1729
 
1698
- def do_method_exclusion parameter_hash, types_were_specified
1730
+ def do_method_exclusion parameter_hash, types_were_specified, option_key = :exclude_methods
1699
1731
  parameter_hash[:before] = ''
1700
- parameter_hash[:exclude_method] = :doit3
1732
+ parameter_hash[option_key] = :doit3
1701
1733
  aspect = nil
1702
1734
  advice_called = false
1703
1735
  aspect = Aspect.new parameter_hash do |jp, obj, *args|
@@ -1729,11 +1761,13 @@ describe Aspect, ".new with :method(s) and :exclude_method(s) parameter" do
1729
1761
  aspect.unadvise
1730
1762
  end
1731
1763
 
1732
- it "should accept :exclude_method as a synonym for exclude_methods" do
1733
- parameter_hash = { :pointcuts => [@pointcut1, @pointcut2, @pointcut3, @pointcut4] }
1734
- do_method_exclusion parameter_hash, true
1764
+ Aspect::CANONICAL_OPTIONS["exclude_methods"].each do |key|
1765
+ it "should accept :#{key} as a synonym for :exclude_methods." do
1766
+ parameter_hash = { :pointcuts => [@pointcut1, @pointcut2, @pointcut3, @pointcut4] }
1767
+ do_method_exclusion parameter_hash, true, key.intern
1768
+ end
1735
1769
  end
1736
-
1770
+
1737
1771
  it "should accept :pointcut(s) => [P1, ...], :exclude_method(s) => [methods], where join points with [methods] are excluded" do
1738
1772
  parameter_hash = { :pointcuts => [@pointcut1, @pointcut2, @pointcut3, @pointcut4] }
1739
1773
  do_method_exclusion parameter_hash, true