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.
- data/Aquarium-IDEA.ipr +252 -0
- data/Aquarium-IDEA.iws +493 -0
- data/Aquarium.ipr +1 -1
- data/Aquarium.iws +133 -138
- data/CHANGES +63 -0
- data/ParseTreePlay.rb +25 -0
- data/README +55 -3
- data/RELEASE-PLAN +9 -1
- data/TODO.rb +175 -15
- data/examples/aspect_design_example.rb +13 -1
- data/examples/aspect_design_example_spec.rb +20 -2
- data/examples/introductions_example.rb +35 -0
- data/examples/introductions_example_spec.rb +37 -0
- data/examples/method_missing_example.rb +2 -1
- data/lib/aquarium/aspects/advice.rb +127 -74
- data/lib/aquarium/aspects/aspect.rb +139 -72
- data/lib/aquarium/aspects/default_objects_handler.rb +6 -4
- data/lib/aquarium/aspects/exclusion_handler.rb +15 -3
- data/lib/aquarium/aspects/join_point.rb +60 -55
- data/lib/aquarium/aspects/pointcut.rb +153 -124
- data/lib/aquarium/aspects/pointcut_composition.rb +1 -1
- data/lib/aquarium/dsl/aspect_dsl.rb +13 -5
- data/lib/aquarium/dsl/object_dsl.rb +4 -2
- data/lib/aquarium/extras/design_by_contract.rb +9 -5
- data/lib/aquarium/finders.rb +1 -0
- data/lib/aquarium/finders/finder_result.rb +13 -5
- data/lib/aquarium/finders/method_finder.rb +75 -70
- data/lib/aquarium/finders/pointcut_finder.rb +166 -0
- data/lib/aquarium/finders/type_finder.rb +104 -62
- data/lib/aquarium/utils/array_utils.rb +1 -1
- data/lib/aquarium/utils/invalid_options.rb +2 -0
- data/lib/aquarium/utils/name_utils.rb +3 -2
- data/lib/aquarium/utils/nil_object.rb +7 -3
- data/lib/aquarium/utils/options_utils.rb +38 -27
- data/lib/aquarium/utils/set_utils.rb +2 -2
- data/lib/aquarium/utils/type_utils.rb +11 -0
- data/lib/aquarium/version.rb +1 -1
- data/spec/aquarium/aspects/advice_spec.rb +147 -32
- data/spec/aquarium/aspects/aspect_invocation_spec.rb +252 -43
- data/spec/aquarium/aspects/aspect_spec.rb +148 -88
- data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +40 -34
- data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +39 -3
- data/spec/aquarium/aspects/join_point_spec.rb +190 -227
- data/spec/aquarium/aspects/pointcut_spec.rb +24 -1
- data/spec/aquarium/dsl/aspect_dsl_spec.rb +17 -17
- data/spec/aquarium/finders/method_finder_spec.rb +8 -2
- data/spec/aquarium/finders/pointcut_finder_spec.rb +193 -0
- data/spec/aquarium/finders/pointcut_finder_spec_test_classes.rb +90 -0
- data/spec/aquarium/finders/type_finder_spec.rb +17 -0
- data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +4 -4
- data/spec/aquarium/finders/type_finder_with_nested_types.rb +47 -0
- data/spec/aquarium/utils/nil_object_spec.rb +21 -0
- data/spec/aquarium/utils/type_utils_sample_nested_types.rb +51 -0
- data/spec/aquarium/utils/type_utils_spec.rb +18 -1
- metadata +13 -3
@@ -5,8 +5,7 @@ require 'aquarium/aspects'
|
|
5
5
|
|
6
6
|
include Aquarium::Aspects
|
7
7
|
|
8
|
-
# Explicitly check that advising subtypes works correctly.
|
9
|
-
# TODO Tests with modules included in classes.
|
8
|
+
# Explicitly check that advising subtypes and included modules works correctly.
|
10
9
|
module SubTypeAspects
|
11
10
|
class Base
|
12
11
|
attr_reader :base_state
|
@@ -24,9 +23,27 @@ module SubTypeAspects
|
|
24
23
|
yield args
|
25
24
|
end
|
26
25
|
end
|
26
|
+
|
27
|
+
module BaseModule
|
28
|
+
attr_reader :base_state
|
29
|
+
def doit *args
|
30
|
+
@base_state = args
|
31
|
+
yield args
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class IncludingClass
|
36
|
+
include BaseModule
|
37
|
+
attr_reader :derived_state
|
38
|
+
def doit *args
|
39
|
+
@derived_state = args
|
40
|
+
super
|
41
|
+
yield args
|
42
|
+
end
|
43
|
+
end
|
27
44
|
end
|
28
45
|
|
29
|
-
describe Aspect, " when advising overridden methods that call super" do
|
46
|
+
describe Aspect, " when advising overridden inherited methods that call super" do
|
30
47
|
after(:each) do
|
31
48
|
@aspect.unadvise if @aspect
|
32
49
|
end
|
@@ -46,4 +63,23 @@ describe Aspect, " when advising overridden methods that call super" do
|
|
46
63
|
end
|
47
64
|
end
|
48
65
|
|
66
|
+
describe Aspect, " when advising overridden methods included through modules that call super" do
|
67
|
+
after(:each) do
|
68
|
+
@aspect.unadvise if @aspect
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should correctly invoke and advise overridden and original methods." do
|
72
|
+
advised_types = []
|
73
|
+
@aspect = Aspect.new :before, :pointcut => {:types => /SubTypeAspects::.*/, :methods => :doit} do |jp, obj, *args|
|
74
|
+
advised_types << jp.target_type
|
75
|
+
end
|
76
|
+
derived = SubTypeAspects::IncludingClass.new
|
77
|
+
block_called = 0
|
78
|
+
derived.doit(:a1, :a2, :a3) { |*args| block_called += 1 }
|
79
|
+
block_called.should == 2
|
80
|
+
advised_types.should == [SubTypeAspects::IncludingClass, SubTypeAspects::BaseModule]
|
81
|
+
derived.base_state.should == [:a1, :a2, :a3]
|
82
|
+
derived.derived_state.should == [:a1, :a2, :a3]
|
83
|
+
end
|
84
|
+
end
|
49
85
|
|
@@ -2,7 +2,9 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
2
|
require File.dirname(__FILE__) + '/../spec_example_types'
|
3
3
|
|
4
4
|
require 'aquarium/extensions/hash'
|
5
|
+
require 'aquarium/utils/nil_object'
|
5
6
|
require 'aquarium/aspects/join_point'
|
7
|
+
require 'aquarium/aspects/advice'
|
6
8
|
|
7
9
|
class Dummy
|
8
10
|
def eql?; false; end
|
@@ -20,187 +22,189 @@ class ProtectionExample
|
|
20
22
|
private_class_method :private_class_m
|
21
23
|
end
|
22
24
|
|
23
|
-
|
25
|
+
include Aquarium::Aspects
|
26
|
+
|
27
|
+
describe JoinPoint, "#initialize with invalid parameters" do
|
24
28
|
|
25
29
|
it "should require either a :type or an :object parameter, but not both." do
|
26
|
-
lambda {
|
27
|
-
lambda {
|
30
|
+
lambda { JoinPoint.new :method_name => :count }.should raise_error(Aquarium::Utils::InvalidOptions)
|
31
|
+
lambda { JoinPoint.new :type => String, :object => "", :method_name => :count }.should raise_error(Aquarium::Utils::InvalidOptions)
|
28
32
|
end
|
29
33
|
|
30
34
|
it "should require a :method_name." do
|
31
|
-
lambda {
|
35
|
+
lambda { JoinPoint.new :type => String }.should raise_error(Aquarium::Utils::InvalidOptions)
|
32
36
|
end
|
33
37
|
|
34
38
|
it "should except :method as a synonym for :method_name." do
|
35
|
-
lambda {
|
39
|
+
lambda { JoinPoint.new :type => String, :method => :split }.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
36
40
|
end
|
37
41
|
|
38
42
|
it "should require a valid type name if a name is specified." do
|
39
|
-
lambda {
|
40
|
-
lambda {
|
43
|
+
lambda { JoinPoint.new :type => "String", :method => :split }.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
44
|
+
lambda { JoinPoint.new :type => "Stringgy", :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
41
45
|
end
|
42
46
|
|
43
47
|
it "should require a valid type name symbol if a name is specified." do
|
44
|
-
lambda {
|
45
|
-
lambda {
|
48
|
+
lambda { JoinPoint.new :type => :String, :method => :split }.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
49
|
+
lambda { JoinPoint.new :type => :Stringgy, :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
46
50
|
end
|
47
51
|
|
48
52
|
it "should require a valid type name regular expression if one is specified." do
|
49
|
-
lambda {
|
50
|
-
lambda {
|
53
|
+
lambda { JoinPoint.new :type => /^String$/, :method => :split }.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
54
|
+
lambda { JoinPoint.new :type => /^Stringgy$/, :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
51
55
|
end
|
52
56
|
|
53
57
|
it "should reject a regular expression that matches no types." do
|
54
|
-
lambda {
|
58
|
+
lambda { JoinPoint.new :type => /^Stringgy$/, :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
55
59
|
end
|
56
60
|
|
57
61
|
it "should reject a regular expression that matches more than one type." do
|
58
|
-
lambda {
|
62
|
+
lambda { JoinPoint.new :type => /^M/, :method => :split }.should raise_error(Aquarium::Utils::InvalidOptions)
|
59
63
|
end
|
60
64
|
end
|
61
65
|
|
62
|
-
describe
|
66
|
+
describe JoinPoint, "#initialize with parameters that specify class vs. instance methods" do
|
63
67
|
it "should assume the :method_name refers to an instance method, by default." do
|
64
|
-
jp =
|
68
|
+
jp = JoinPoint.new :type => String, :method => :split
|
65
69
|
jp.instance_method?.should be_true
|
66
70
|
jp.class_method?.should be_false
|
67
71
|
end
|
68
72
|
|
69
73
|
it "should treat the :method_name as refering to an instance method if :instance_method is specified as true." do
|
70
|
-
jp =
|
74
|
+
jp = JoinPoint.new :type => String, :method => :split, :instance_method => true
|
71
75
|
jp.instance_method?.should be_true
|
72
76
|
jp.class_method?.should be_false
|
73
77
|
end
|
74
78
|
|
75
79
|
it "should treat the :method_name as refering to a class method if :instance_method is specified as false." do
|
76
|
-
jp =
|
80
|
+
jp = JoinPoint.new :type => String, :method => :split, :instance_method => false
|
77
81
|
jp.instance_method?.should be_false
|
78
82
|
jp.class_method?.should be_true
|
79
83
|
end
|
80
84
|
|
81
85
|
it "should treat the :method_name as refering to an instance method if :class_method is specified as false." do
|
82
|
-
jp =
|
86
|
+
jp = JoinPoint.new :type => String, :method => :split, :class_method => false
|
83
87
|
jp.instance_method?.should be_true
|
84
88
|
jp.class_method?.should be_false
|
85
89
|
end
|
86
90
|
|
87
91
|
it "should treat the :method_name as refering to a class method if :class_method is specified as true." do
|
88
|
-
jp =
|
92
|
+
jp = JoinPoint.new :type => String, :method => :split, :class_method => true
|
89
93
|
jp.instance_method?.should be_false
|
90
94
|
jp.class_method?.should be_true
|
91
95
|
end
|
92
96
|
|
93
97
|
it "should treat give precedence to :instance_method if appears with :class_method." do
|
94
|
-
jp =
|
98
|
+
jp = JoinPoint.new :type => String, :method => :split, :instance_method => false, :class_method => true
|
95
99
|
jp.instance_method?.should be_false
|
96
100
|
jp.class_method?.should be_true
|
97
|
-
jp =
|
101
|
+
jp = JoinPoint.new :type => String, :method => :split, :instance_method => true, :class_method => false
|
98
102
|
jp.instance_method?.should be_true
|
99
103
|
jp.class_method?.should be_false
|
100
104
|
end
|
101
105
|
end
|
102
106
|
|
103
|
-
describe
|
107
|
+
describe JoinPoint, "#visibility" do
|
104
108
|
it "should return :public for public instance methods." do
|
105
|
-
jp =
|
109
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :public_instance_m
|
106
110
|
jp.visibility.should == :public
|
107
111
|
end
|
108
112
|
|
109
113
|
it "should return :public for public instance methods, when only instance methods are specified." do
|
110
|
-
jp =
|
114
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :public_instance_m, :instance_method => true
|
111
115
|
jp.visibility.should == :public
|
112
116
|
end
|
113
117
|
|
114
118
|
it "should return :public for public class methods, when only class methods are specified using :instance_method => false." do
|
115
|
-
jp =
|
119
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :public_class_m, :instance_method => false
|
116
120
|
jp.visibility.should == :public
|
117
121
|
end
|
118
122
|
|
119
123
|
it "should return :public for public instance methods, when only instance methods are specified using :class_method => false." do
|
120
|
-
jp =
|
124
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :public_instance_m, :class_method => false
|
121
125
|
jp.visibility.should == :public
|
122
126
|
end
|
123
127
|
|
124
128
|
it "should return :public for public class methods, when only class methods are specified." do
|
125
|
-
jp =
|
129
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :public_class_m, :class_method => true
|
126
130
|
jp.visibility.should == :public
|
127
131
|
end
|
128
132
|
|
129
133
|
it "should return :protected for protected instance methods." do
|
130
|
-
jp =
|
134
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :protected_instance_m
|
131
135
|
jp.visibility.should == :protected
|
132
136
|
end
|
133
137
|
|
134
138
|
it "should return :protected for protected instance methods, when only instance methods are specified." do
|
135
|
-
jp =
|
139
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :protected_instance_m, :instance_method => true
|
136
140
|
jp.visibility.should == :protected
|
137
141
|
end
|
138
142
|
|
139
143
|
it "should return nil for protected class methods, when only class methods are specified using :instance_method => false." do
|
140
|
-
jp =
|
144
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :protected_class_method, :instance_method => false
|
141
145
|
jp.visibility.should == nil
|
142
146
|
end
|
143
147
|
|
144
148
|
it "should return :protected for protected instance methods, when only instance methods are specified using :class_method => false." do
|
145
|
-
jp =
|
149
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :protected_instance_m, :class_method => false
|
146
150
|
jp.visibility.should == :protected
|
147
151
|
end
|
148
152
|
|
149
153
|
it "should return nil for protected class methods, when only class methods are specified." do
|
150
|
-
jp =
|
154
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :protected_class_method, :class_method => true
|
151
155
|
jp.visibility.should == nil
|
152
156
|
end
|
153
157
|
|
154
158
|
it "should return :private for private instance methods." do
|
155
|
-
jp =
|
159
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :private_instance_m
|
156
160
|
jp.visibility.should == :private
|
157
161
|
end
|
158
162
|
|
159
163
|
it "should return :private for private instance methods, when only instance methods are specified." do
|
160
|
-
jp =
|
164
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :private_instance_m, :instance_method => true
|
161
165
|
jp.visibility.should == :private
|
162
166
|
end
|
163
167
|
|
164
168
|
it "should return :private for private class methods, when only class methods are specified using :instance_method => false." do
|
165
|
-
jp =
|
169
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :private_class_m, :instance_method => false
|
166
170
|
jp.visibility.should == :private
|
167
171
|
end
|
168
172
|
|
169
173
|
it "should return :private for private instance methods, when only instance methods are specified using :class_method => false." do
|
170
|
-
jp =
|
174
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :private_instance_m, :class_method => false
|
171
175
|
jp.visibility.should == :private
|
172
176
|
end
|
173
177
|
|
174
178
|
it "should return :private for private class methods, when only class methods are specified." do
|
175
|
-
jp =
|
179
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :private_class_m, :class_method => true
|
176
180
|
jp.visibility.should == :private
|
177
181
|
end
|
178
182
|
|
179
183
|
it "should return nil for non-existent methods." do
|
180
|
-
jp =
|
184
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :foo
|
181
185
|
jp.visibility.should == nil
|
182
|
-
jp =
|
186
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :foo, :instance_method => true
|
183
187
|
jp.visibility.should == nil
|
184
|
-
jp =
|
188
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :foo, :instance_method => false
|
185
189
|
jp.visibility.should == nil
|
186
|
-
jp =
|
190
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :foo, :class_method => true
|
187
191
|
jp.visibility.should == nil
|
188
|
-
jp =
|
192
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :foo, :class_method => false
|
189
193
|
jp.visibility.should == nil
|
190
194
|
end
|
191
195
|
end
|
192
196
|
|
193
|
-
describe
|
197
|
+
describe JoinPoint, "#target_type" do
|
194
198
|
it "should return the type at the JoinPoint" do
|
195
|
-
jp =
|
199
|
+
jp = JoinPoint.new :type => ProtectionExample, :method => :foo
|
196
200
|
jp.target_type.should be_eql(ProtectionExample)
|
197
201
|
end
|
198
202
|
end
|
199
203
|
|
200
|
-
describe
|
204
|
+
describe JoinPoint, "#target_object" do
|
201
205
|
it "should return the object at the JoinPoint" do
|
202
206
|
example = ProtectionExample.new
|
203
|
-
jp =
|
207
|
+
jp = JoinPoint.new :object => example, :method => :foo
|
204
208
|
jp.target_object.should be_eql(example)
|
205
209
|
end
|
206
210
|
end
|
@@ -210,49 +214,35 @@ class InvokeOriginalClass
|
|
210
214
|
def called; @called; end
|
211
215
|
end
|
212
216
|
|
213
|
-
describe
|
214
|
-
it "should raise when the join point doesn't have a context" do
|
215
|
-
jp = Aquarium::Aspects::JoinPoint.new :type => InvokeOriginalClass, :method => :invoke
|
216
|
-
lambda { jp.proceed }.should raise_error(Aquarium::Aspects::JoinPoint::ContextNotDefined)
|
217
|
-
end
|
218
|
-
|
217
|
+
describe JoinPoint, "#proceed" do
|
219
218
|
it "should raise when the the context object doesn't have a 'proceed proc'" do
|
220
|
-
jp =
|
219
|
+
jp = JoinPoint.new :type => InvokeOriginalClass, :method => :invoke
|
221
220
|
ioc = InvokeOriginalClass.new
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
}
|
228
|
-
jp2 = jp.make_current_context_join_point context_opts
|
229
|
-
lambda { jp2.proceed }.should raise_error(Aquarium::Aspects::JoinPoint::ProceedMethodNotAvailable)
|
221
|
+
jp.context.advice_kind = :around
|
222
|
+
jp.context.advised_object = ioc
|
223
|
+
jp.context.parameters = []
|
224
|
+
jp.context.proceed_proc = nil
|
225
|
+
lambda { jp.proceed }.should raise_error(JoinPoint::ProceedMethodNotAvailable)
|
230
226
|
end
|
231
227
|
|
232
228
|
it "should not raise when the advice is :around advice" do
|
233
|
-
jp =
|
229
|
+
jp = JoinPoint.new :type => InvokeOriginalClass, :method => :invoke
|
234
230
|
ioc = InvokeOriginalClass.new
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
}
|
241
|
-
jp2 = jp.make_current_context_join_point context_opts
|
242
|
-
lambda { jp2.proceed }.should_not raise_error(Aquarium::Aspects::JoinPoint::ProceedMethodNotAvailable)
|
231
|
+
jp.context.advice_kind = :around
|
232
|
+
jp.context.advised_object = ioc
|
233
|
+
jp.context.parameters = []
|
234
|
+
jp.context.proceed_proc = Aquarium::Aspects::NoAdviceChainNode.new(:alias_method_name => :invoke)
|
235
|
+
lambda { jp.proceed }.should_not raise_error(JoinPoint::ProceedMethodNotAvailable)
|
243
236
|
end
|
244
237
|
|
245
238
|
it "should invoke the actual join point" do
|
246
|
-
jp =
|
239
|
+
jp = JoinPoint.new :type => InvokeOriginalClass, :method => :invoke
|
247
240
|
ioc = InvokeOriginalClass.new
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
}
|
254
|
-
jp2 = jp.make_current_context_join_point context_opts
|
255
|
-
jp2.proceed
|
241
|
+
jp.context.advice_kind = :around
|
242
|
+
jp.context.advised_object = ioc
|
243
|
+
jp.context.parameters = []
|
244
|
+
jp.context.proceed_proc = Aquarium::Aspects::NoAdviceChainNode.new(:alias_method_name => :invoke)
|
245
|
+
jp.proceed
|
256
246
|
ioc.called.should be_true
|
257
247
|
end
|
258
248
|
end
|
@@ -262,43 +252,40 @@ class InvokeOriginalClass
|
|
262
252
|
def called; @called; end
|
263
253
|
end
|
264
254
|
|
265
|
-
describe
|
266
|
-
it "should raise when the join point
|
267
|
-
jp =
|
268
|
-
lambda { jp.invoke_original_join_point }.should raise_error(
|
255
|
+
describe JoinPoint, "#invoke_original_join_point" do
|
256
|
+
it "should raise when the join point has an empty context" do
|
257
|
+
jp = JoinPoint.new :type => InvokeOriginalClass, :method => :invoke
|
258
|
+
lambda { jp.invoke_original_join_point }.should raise_error(JoinPoint::ContextNotCorrectlyDefined)
|
269
259
|
end
|
270
260
|
|
271
261
|
it "should invoke the original join point" do
|
272
|
-
jp =
|
262
|
+
jp = JoinPoint.new :type => InvokeOriginalClass, :method => :invoke
|
273
263
|
ioc = InvokeOriginalClass.new
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
}
|
280
|
-
jp2 = jp.make_current_context_join_point context_opts
|
281
|
-
jp2.invoke_original_join_point
|
264
|
+
jp.context.advice_kind = :around
|
265
|
+
jp.context.advised_object = ioc
|
266
|
+
jp.context.parameters = []
|
267
|
+
jp.context.current_advice_node = Aquarium::Aspects::NoAdviceChainNode.new(:alias_method_name => :invoke)
|
268
|
+
jp.invoke_original_join_point
|
282
269
|
ioc.called.should be_true
|
283
270
|
end
|
284
271
|
end
|
285
272
|
|
286
273
|
|
287
|
-
describe
|
274
|
+
describe JoinPoint, "#dup" do
|
288
275
|
it "should duplicate the fields in the join point." do
|
289
|
-
jp =
|
276
|
+
jp = JoinPoint.new :type => String, :method_name => :count
|
290
277
|
jp2 = jp.dup
|
291
278
|
jp2.should eql(jp)
|
292
279
|
end
|
293
280
|
end
|
294
281
|
|
295
|
-
describe
|
282
|
+
describe JoinPoint, "#eql?" do
|
296
283
|
setup do
|
297
|
-
@jp1 =
|
298
|
-
@jp2 =
|
299
|
-
@jp3 =
|
300
|
-
@jp4 =
|
301
|
-
@jp5 =
|
284
|
+
@jp1 = JoinPoint.new :type => Dummy, :method_name => :count
|
285
|
+
@jp2 = JoinPoint.new :type => Dummy, :method_name => :count
|
286
|
+
@jp3 = JoinPoint.new :type => Array, :method_name => :size
|
287
|
+
@jp4 = JoinPoint.new :object => [], :method_name => :size
|
288
|
+
@jp5 = JoinPoint.new :object => [], :method_name => :size
|
302
289
|
end
|
303
290
|
|
304
291
|
it "should return true for the same join point." do
|
@@ -326,13 +313,13 @@ describe Aquarium::Aspects::JoinPoint, "#eql?" do
|
|
326
313
|
end
|
327
314
|
end
|
328
315
|
|
329
|
-
describe
|
316
|
+
describe JoinPoint, "#==" do
|
330
317
|
setup do
|
331
|
-
@jp1 =
|
332
|
-
@jp2 =
|
333
|
-
@jp3 =
|
334
|
-
@jp4 =
|
335
|
-
@jp5 =
|
318
|
+
@jp1 = JoinPoint.new :type => Dummy, :method_name => :count
|
319
|
+
@jp2 = JoinPoint.new :type => Dummy, :method_name => :count
|
320
|
+
@jp3 = JoinPoint.new :type => Array, :method_name => :size
|
321
|
+
@jp4 = JoinPoint.new :object => [], :method_name => :size
|
322
|
+
@jp5 = JoinPoint.new :object => [], :method_name => :size
|
336
323
|
end
|
337
324
|
|
338
325
|
it "should return true for the same join point." do
|
@@ -360,29 +347,29 @@ describe Aquarium::Aspects::JoinPoint, "#==" do
|
|
360
347
|
end
|
361
348
|
end
|
362
349
|
|
363
|
-
describe
|
350
|
+
describe JoinPoint, "#<=>" do
|
364
351
|
setup do
|
365
|
-
@jp1
|
366
|
-
@
|
367
|
-
@
|
368
|
-
@
|
369
|
-
@
|
370
|
-
|
371
|
-
@
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
352
|
+
@jp1 = JoinPoint.new :type => Dummy, :method_name => :count
|
353
|
+
@jp1nc = JoinPoint.new :type => Dummy, :method_name => :count
|
354
|
+
@jp2 = JoinPoint.new :type => Dummy, :method_name => :count
|
355
|
+
@jp2nc = JoinPoint.new :type => Dummy, :method_name => :count
|
356
|
+
@jp3 = JoinPoint.new :type => Array, :method_name => :size
|
357
|
+
@jp4 = JoinPoint.new :object => [], :method_name => :size
|
358
|
+
@jp5 = JoinPoint.new :object => [], :method_name => :size
|
359
|
+
dummy = Dummy.new
|
360
|
+
@jp6 = JoinPoint.new :object => dummy, :method_name => :size
|
361
|
+
@jp6nc = JoinPoint.new :object => dummy, :method_name => :size
|
362
|
+
@jp7 = JoinPoint.new :object => dummy, :method_name => :size
|
363
|
+
@jp7nc = JoinPoint.new :object => dummy, :method_name => :size
|
364
|
+
[@jp1, @jp2, @jp6, @jp7].each do |jp|
|
365
|
+
jp.context.advice_kind = :before
|
366
|
+
jp.context.advised_object = dummy
|
367
|
+
jp.context.parameters = []
|
368
|
+
jp.context.block_for_method = nil
|
369
|
+
jp.context.returned_value = nil
|
370
|
+
jp.context.raised_exception = nil
|
371
|
+
jp.context.proceed_proc = nil
|
372
|
+
end
|
386
373
|
end
|
387
374
|
|
388
375
|
it "should return 1 of the second object is nil" do
|
@@ -390,101 +377,84 @@ describe Aquarium::Aspects::JoinPoint, "#<=>" do
|
|
390
377
|
end
|
391
378
|
|
392
379
|
it "should return 0 for the same join point with no context" do
|
393
|
-
(@
|
394
|
-
(@
|
380
|
+
(@jp1nc <=> @jp1nc).should == 0
|
381
|
+
(@jp6nc <=> @jp6nc).should == 0
|
395
382
|
end
|
396
383
|
|
397
384
|
it "should return 0 for the same join point with equivalent contexts" do
|
398
|
-
(@
|
399
|
-
(@
|
385
|
+
(@jp1 <=> @jp1).should == 0
|
386
|
+
(@jp6 <=> @jp6).should == 0
|
400
387
|
end
|
401
388
|
|
402
389
|
it "should return 0 for equivalent join points with no context" do
|
403
|
-
(@
|
404
|
-
(@
|
390
|
+
(@jp1nc <=>@jp2nc).should == 0
|
391
|
+
(@jp6nc <=>@jp7nc).should == 0
|
405
392
|
end
|
406
393
|
|
407
394
|
it "should return 0 for equivalent join points with equivalent contexts" do
|
408
|
-
(@
|
409
|
-
(@
|
395
|
+
(@jp1 <=> @jp2).should == 0
|
396
|
+
(@jp6 <=> @jp7).should == 0
|
410
397
|
end
|
411
398
|
|
412
|
-
it "should return +1 for join points that equivalent except for the context, where the first join point has a context and the second
|
413
|
-
(@
|
414
|
-
(@
|
399
|
+
it "should return +1 for join points that are equivalent except for the context, where the first join point has a context and the second has an 'empty' context" do
|
400
|
+
(@jp1 <=> @jp2nc).should == 1
|
401
|
+
(@jp6 <=> @jp7nc).should == 1
|
415
402
|
end
|
416
403
|
|
417
|
-
it "should return -1 for join points that equivalent except for the context, where the second join point has a context and the first
|
418
|
-
(@
|
419
|
-
(@
|
404
|
+
it "should return -1 for join points that are equivalent except for the context, where the second join point has a context and the first has an 'empty' context" do
|
405
|
+
(@jp1nc <=> @jp2).should == -1
|
406
|
+
(@jp6nc <=> @jp6).should == -1
|
420
407
|
end
|
421
408
|
|
422
409
|
it "should sort by type name first" do
|
423
410
|
end
|
424
411
|
end
|
425
412
|
|
426
|
-
describe
|
427
|
-
it "should return a new join_point that contains the non-context information of the advised_object plus a new Aquarium::Aspects::JoinPoint::Context with the specified context information." do
|
428
|
-
jp = Aquarium::Aspects::JoinPoint.new :type => String, :method_name => :split
|
429
|
-
jp.context.should be_nil
|
430
|
-
object = "12,34"
|
431
|
-
jp_with_context = jp.make_current_context_join_point :advice_kind => :before, :advised_object => object, :parameters => [","], :returned_value => ["12", "34"]
|
432
|
-
jp_with_context.object_id.should_not == jp.object_id
|
433
|
-
jp.context.should be_nil
|
434
|
-
jp_with_context.context.should_not be_nil
|
435
|
-
jp_with_context.context.advice_kind.should == :before
|
436
|
-
jp_with_context.context.advised_object.should == object
|
437
|
-
jp_with_context.context.parameters.should == [","]
|
438
|
-
jp_with_context.context.returned_value.should == ["12", "34"]
|
439
|
-
jp_with_context.context.raised_exception.should be_nil
|
440
|
-
end
|
441
|
-
end
|
442
|
-
|
443
|
-
describe Aquarium::Aspects::JoinPoint, "#type_or_object" do
|
413
|
+
describe JoinPoint, "#type_or_object" do
|
444
414
|
it "should return the type if the object is nil" do
|
445
|
-
jp =
|
415
|
+
jp = JoinPoint.new :type => String, :method_name => :split
|
446
416
|
jp.type_or_object.should eql(String)
|
447
417
|
end
|
448
418
|
|
449
419
|
it "should return the object if the type is nil" do
|
450
|
-
jp =
|
420
|
+
jp = JoinPoint.new :object => String.new, :method_name => :split
|
451
421
|
jp.type_or_object.should eql("")
|
452
422
|
end
|
453
423
|
end
|
454
424
|
|
455
|
-
describe
|
425
|
+
describe JoinPoint, "#exists?" do
|
456
426
|
it "should return false if the join point represents a non-existent join point for an instance method in the runtime environment" do
|
457
|
-
jp =
|
427
|
+
jp = JoinPoint.new :type => ProtectionExample, :method_name => :foo
|
458
428
|
jp.exists?.should be_false
|
459
429
|
end
|
460
430
|
|
461
431
|
it "should return false if the join point represents a non-existent join point for a class method in the runtime environment" do
|
462
|
-
jp =
|
432
|
+
jp = JoinPoint.new :type => ProtectionExample, :method_name => :foo, :class_method => true
|
463
433
|
jp.exists?.should be_false
|
464
434
|
end
|
465
435
|
|
466
436
|
it "should return true if the join point represents a real join point for a public instance method in the runtime environment" do
|
467
|
-
jp =
|
437
|
+
jp = JoinPoint.new :type => ProtectionExample, :method_name => :public_instance_m
|
468
438
|
jp.exists?.should be_true
|
469
439
|
end
|
470
440
|
|
471
441
|
it "should return true if the join point represents a real join point for a protected instance method in the runtime environment" do
|
472
|
-
jp =
|
442
|
+
jp = JoinPoint.new :type => ProtectionExample, :method_name => :protected_instance_m
|
473
443
|
jp.exists?.should be_true
|
474
444
|
end
|
475
445
|
|
476
446
|
it "should return true if the join point represents a real join point for a private instance method in the runtime environment" do
|
477
|
-
jp =
|
447
|
+
jp = JoinPoint.new :type => ProtectionExample, :method_name => :private_instance_m
|
478
448
|
jp.exists?.should be_true
|
479
449
|
end
|
480
450
|
|
481
451
|
it "should return true if the join point represents a real join point for a public class method in the runtime environment" do
|
482
|
-
jp =
|
452
|
+
jp = JoinPoint.new :type => ProtectionExample, :method_name => :public_class_m, :class_method => true
|
483
453
|
jp.exists?.should be_true
|
484
454
|
end
|
485
455
|
|
486
456
|
it "should return true if the join point represents a real join point for a private class method in the runtime environment" do
|
487
|
-
jp =
|
457
|
+
jp = JoinPoint.new :type => ProtectionExample, :method_name => :private_class_m, :class_method => true
|
488
458
|
jp.exists?.should be_true
|
489
459
|
end
|
490
460
|
|
@@ -501,79 +471,72 @@ describe Aquarium::Aspects::JoinPoint, "#exists?" do
|
|
501
471
|
|
502
472
|
end
|
503
473
|
|
504
|
-
describe
|
505
|
-
it "should
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
jp.context.advice_kind.should == :before
|
514
|
-
jp.context.advised_object.should == object
|
515
|
-
jp.context.parameters.should == [","]
|
516
|
-
jp.context.returned_value.should == ["12", "34"]
|
517
|
-
jp.context.raised_exception.should be_nil
|
518
|
-
jp_after.context.advice_kind.should == :after
|
519
|
-
jp_after.context.advised_object.should == object
|
520
|
-
jp_after.context.parameters.should == [","]
|
521
|
-
jp_after.context.returned_value.should == ["12", "34", "56"]
|
522
|
-
jp_after.context.raised_exception.should == exception
|
474
|
+
describe JoinPoint::Context, "#initialize" do
|
475
|
+
it "should initialize :advice_kind to Advice::UNKNOWN_ADVICE_KIND if not specified." do
|
476
|
+
context = JoinPoint::Context.new
|
477
|
+
context.advice_kind.should equal(Advice::UNKNOWN_ADVICE_KIND)
|
478
|
+
end
|
479
|
+
|
480
|
+
it "should initialize :advised_object to equal a NilObject if not specified." do
|
481
|
+
context = JoinPoint::Context.new
|
482
|
+
context.advised_object.should eql(Aquarium::Utils::NilObject.new)
|
523
483
|
end
|
524
|
-
end
|
525
484
|
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
lambda { Aquarium::Aspects::JoinPoint::Context.new :advice_kind => :before, :parameters => [","]}.should raise_error(Aquarium::Utils::InvalidOptions)
|
530
|
-
lambda { Aquarium::Aspects::JoinPoint::Context.new :advice_kind => :before, :advised_object => "object"}.should raise_error(Aquarium::Utils::InvalidOptions)
|
531
|
-
lambda { Aquarium::Aspects::JoinPoint::Context.new :advice_kind => :before, :advised_object => "object", :parameters => [","]}.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
485
|
+
it "should initialize :parameters to [] if not specified." do
|
486
|
+
context = JoinPoint::Context.new
|
487
|
+
context.parameters.should eql([])
|
532
488
|
end
|
533
489
|
|
534
490
|
it "should accept a :returned_value argument." do
|
535
|
-
lambda {
|
491
|
+
lambda { JoinPoint::Context.new :advice_kind => :before, :advised_object => "object", :parameters => [","], :returned_value => ["12", "34"]}.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
536
492
|
end
|
537
493
|
|
538
494
|
it "should accept a :raised_exception argument." do
|
539
|
-
lambda {
|
495
|
+
lambda { JoinPoint::Context.new :advice_kind => :before, :advised_object => "object", :parameters => [","], :raised_exception => NameError.new}.should_not raise_error(Aquarium::Utils::InvalidOptions)
|
540
496
|
end
|
541
497
|
|
542
498
|
end
|
543
499
|
|
544
|
-
describe
|
500
|
+
describe JoinPoint::Context, "#target_object" do
|
545
501
|
it "should be a synonym for #advised_object." do
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
end
|
551
|
-
end
|
552
|
-
|
553
|
-
describe Aquarium::Aspects::JoinPoint::Context, "#target_object=" do
|
554
|
-
it "should be a synonym for #advised_object=." do
|
555
|
-
@object = "12,34"
|
556
|
-
@object2 = "12,34,56"
|
557
|
-
@jp = Aquarium::Aspects::JoinPoint.new :type => String, :method_name => :split
|
558
|
-
@jp_with_context = @jp.make_current_context_join_point :advice_kind => :before, :advised_object => @object, :parameters => [","], :returned_value => ["12", "34"]
|
559
|
-
@jp_with_context.context.target_object = @object2
|
560
|
-
@jp_with_context.context.target_object.should == @object2
|
561
|
-
@jp_with_context.context.advised_object.should == @object2
|
502
|
+
object = "12,34"
|
503
|
+
jp = JoinPoint.new :type => String, :method_name => :split
|
504
|
+
jp.context.advised_object = @object
|
505
|
+
jp.context.target_object.should == jp.context.advised_object
|
562
506
|
end
|
563
507
|
end
|
564
508
|
|
565
509
|
def do_common_eql_setup
|
566
510
|
@object = "12,34"
|
567
511
|
@object2 = "12,34,56"
|
568
|
-
@
|
569
|
-
@
|
570
|
-
@
|
571
|
-
@
|
572
|
-
@
|
573
|
-
@
|
512
|
+
@jp_with_context1 = JoinPoint.new :type => String, :method_name => :split
|
513
|
+
@jp_with_context2 = JoinPoint.new :type => String, :method_name => :split
|
514
|
+
@jp_with_context2b = JoinPoint.new :type => String, :method_name => :split
|
515
|
+
@jp_with_context2c = JoinPoint.new :type => String, :method_name => :split
|
516
|
+
@jp_with_context2d = JoinPoint.new :type => String, :method_name => :split
|
517
|
+
@jp_with_context1.context.advice_kind = :before
|
518
|
+
@jp_with_context1.context.advised_object = @object
|
519
|
+
@jp_with_context1.context.parameters = [","]
|
520
|
+
@jp_with_context1.context.returned_value = ["12", "34"]
|
521
|
+
@jp_with_context2.context.advice_kind = :before
|
522
|
+
@jp_with_context2.context.advised_object = @object
|
523
|
+
@jp_with_context2.context.parameters = [","]
|
524
|
+
@jp_with_context2.context.returned_value = ["12", "34"]
|
525
|
+
@jp_with_context2b.context.advice_kind = :after
|
526
|
+
@jp_with_context2b.context.advised_object = @object
|
527
|
+
@jp_with_context2b.context.parameters = [","]
|
528
|
+
@jp_with_context2b.context.returned_value = ["12", "34"]
|
529
|
+
@jp_with_context2c.context.advice_kind = :before
|
530
|
+
@jp_with_context2c.context.advised_object = @object2
|
531
|
+
@jp_with_context2c.context.parameters = [","]
|
532
|
+
@jp_with_context2c.context.returned_value = ["12", "34"]
|
533
|
+
@jp_with_context2d.context.advice_kind = :before
|
534
|
+
@jp_with_context2d.context.advised_object = @object
|
535
|
+
@jp_with_context2d.context.parameters = ["2"]
|
536
|
+
@jp_with_context2d.context.returned_value = ["1", ",34"]
|
574
537
|
end
|
575
538
|
|
576
|
-
describe
|
539
|
+
describe JoinPoint::Context, "#eql?" do
|
577
540
|
setup do
|
578
541
|
do_common_eql_setup
|
579
542
|
end
|
@@ -589,13 +552,13 @@ describe Aquarium::Aspects::JoinPoint::Context, "#eql?" do
|
|
589
552
|
end
|
590
553
|
|
591
554
|
it "should return false if two equal but different objects are specified." do
|
592
|
-
|
593
|
-
jp_with_diff_object
|
555
|
+
jp_with_diff_object = JoinPoint.new :type => String, :method_name => :split
|
556
|
+
jp_with_diff_object.context.advised_object = "12,34"
|
594
557
|
@jp_with_context1.context.should_not eql(jp_with_diff_object.context)
|
595
558
|
end
|
596
559
|
end
|
597
560
|
|
598
|
-
describe
|
561
|
+
describe JoinPoint::Context, "#==" do
|
599
562
|
setup do
|
600
563
|
do_common_eql_setup
|
601
564
|
end
|
@@ -611,8 +574,8 @@ describe Aquarium::Aspects::JoinPoint::Context, "#==" do
|
|
611
574
|
end
|
612
575
|
|
613
576
|
it "should return false if two equal but different objects are specified." do
|
614
|
-
|
615
|
-
jp_with_diff_object
|
577
|
+
jp_with_diff_object = JoinPoint.new :type => String, :method_name => :split
|
578
|
+
jp_with_diff_object.context.advised_object = "12,34"
|
616
579
|
@jp_with_context1.context.should_not == jp_with_diff_object.context
|
617
580
|
end
|
618
581
|
end
|