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