aquarium 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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