aquarium 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +4 -0
- data/EXAMPLES.rd +4 -0
- data/MIT-LICENSE +20 -0
- data/README +250 -0
- data/RELEASE-PLAN +1 -0
- data/Rakefile +236 -0
- data/UPGRADE +3 -0
- data/examples/aspect_design_example.rb +36 -0
- data/examples/design_by_contract_example.rb +88 -0
- data/examples/method_missing_example.rb +44 -0
- data/examples/method_tracing_example.rb +64 -0
- data/lib/aquarium.rb +7 -0
- data/lib/aquarium/aspects.rb +6 -0
- data/lib/aquarium/aspects/advice.rb +189 -0
- data/lib/aquarium/aspects/aspect.rb +577 -0
- data/lib/aquarium/aspects/default_object_handler.rb +27 -0
- data/lib/aquarium/aspects/dsl.rb +1 -0
- data/lib/aquarium/aspects/dsl/aspect_dsl.rb +61 -0
- data/lib/aquarium/aspects/join_point.rb +158 -0
- data/lib/aquarium/aspects/pointcut.rb +254 -0
- data/lib/aquarium/aspects/pointcut_composition.rb +36 -0
- data/lib/aquarium/extensions.rb +5 -0
- data/lib/aquarium/extensions/hash.rb +85 -0
- data/lib/aquarium/extensions/regexp.rb +20 -0
- data/lib/aquarium/extensions/set.rb +49 -0
- data/lib/aquarium/extensions/string.rb +13 -0
- data/lib/aquarium/extensions/symbol.rb +22 -0
- data/lib/aquarium/extras.rb +4 -0
- data/lib/aquarium/extras/design_by_contract.rb +64 -0
- data/lib/aquarium/finders.rb +4 -0
- data/lib/aquarium/finders/finder_result.rb +121 -0
- data/lib/aquarium/finders/method_finder.rb +228 -0
- data/lib/aquarium/finders/object_finder.rb +74 -0
- data/lib/aquarium/finders/type_finder.rb +127 -0
- data/lib/aquarium/utils.rb +9 -0
- data/lib/aquarium/utils/array_utils.rb +29 -0
- data/lib/aquarium/utils/hash_utils.rb +28 -0
- data/lib/aquarium/utils/html_escaper.rb +17 -0
- data/lib/aquarium/utils/invalid_options.rb +9 -0
- data/lib/aquarium/utils/method_utils.rb +18 -0
- data/lib/aquarium/utils/nil_object.rb +13 -0
- data/lib/aquarium/utils/set_utils.rb +32 -0
- data/lib/aquarium/version.rb +30 -0
- data/rake_tasks/examples.rake +7 -0
- data/rake_tasks/examples_specdoc.rake +8 -0
- data/rake_tasks/examples_with_rcov.rake +8 -0
- data/rake_tasks/verify_rcov.rake +7 -0
- data/spec/aquarium/aspects/advice_chain_node_spec.rb +34 -0
- data/spec/aquarium/aspects/advice_spec.rb +103 -0
- data/spec/aquarium/aspects/aspect_invocation_spec.rb +111 -0
- data/spec/aquarium/aspects/aspect_spec.rb +978 -0
- data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +129 -0
- data/spec/aquarium/aspects/concurrent_aspects_spec.rb +423 -0
- data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +103 -0
- data/spec/aquarium/aspects/concurrently_accessed.rb +21 -0
- data/spec/aquarium/aspects/dsl/aspect_dsl_spec.rb +514 -0
- data/spec/aquarium/aspects/join_point_spec.rb +302 -0
- data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +131 -0
- data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +111 -0
- data/spec/aquarium/aspects/pointcut_spec.rb +800 -0
- data/spec/aquarium/extensions/hash_spec.rb +187 -0
- data/spec/aquarium/extensions/regex_spec.rb +40 -0
- data/spec/aquarium/extensions/set_spec.rb +105 -0
- data/spec/aquarium/extensions/string_spec.rb +25 -0
- data/spec/aquarium/extensions/symbol_spec.rb +37 -0
- data/spec/aquarium/extras/design_by_contract_spec.rb +68 -0
- data/spec/aquarium/finders/finder_result_spec.rb +359 -0
- data/spec/aquarium/finders/method_finder_spec.rb +878 -0
- data/spec/aquarium/finders/method_sorting_spec.rb +16 -0
- data/spec/aquarium/finders/object_finder_spec.rb +230 -0
- data/spec/aquarium/finders/type_finder_spec.rb +210 -0
- data/spec/aquarium/spec_example_classes.rb +117 -0
- data/spec/aquarium/spec_helper.rb +3 -0
- data/spec/aquarium/utils/array_utils_spec.rb +47 -0
- data/spec/aquarium/utils/hash_utils_spec.rb +48 -0
- data/spec/aquarium/utils/html_escaper_spec.rb +18 -0
- data/spec/aquarium/utils/method_utils_spec.rb +50 -0
- data/spec/aquarium/utils/nil_object_spec.rb +19 -0
- data/spec/aquarium/utils/set_utils_spec.rb +60 -0
- metadata +132 -0
@@ -0,0 +1,129 @@
|
|
1
|
+
|
2
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
3
|
+
require File.dirname(__FILE__) + '/../spec_example_classes'
|
4
|
+
require 'aquarium/aspects'
|
5
|
+
|
6
|
+
include Aquarium::Aspects
|
7
|
+
|
8
|
+
# Explicitly check that nested types are handled correctly.
|
9
|
+
|
10
|
+
module Nested1
|
11
|
+
module Nested2
|
12
|
+
class MyClass
|
13
|
+
def do1 *args
|
14
|
+
yield
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module MyModule
|
19
|
+
def do2 *args
|
20
|
+
yield
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe Aspect, "#new when advising methods in a nested class" do
|
27
|
+
after(:each) do
|
28
|
+
@aspect.unadvise if @aspect
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should correctly advise methods in a nested class." do
|
32
|
+
myclass = Nested1::Nested2::MyClass.new
|
33
|
+
context = nil
|
34
|
+
@aspect = Aspect.new :before, :pointcut => {:type => Nested1::Nested2::MyClass, :methods => :do1} do |jp, *args|
|
35
|
+
context = jp.context
|
36
|
+
end
|
37
|
+
block_called = 0
|
38
|
+
myclass.do1(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
39
|
+
block_called.should == 1
|
40
|
+
context.advice_kind.should == :before
|
41
|
+
context.advised_object.should == myclass
|
42
|
+
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
43
|
+
context.returned_value.should == nil
|
44
|
+
context.raised_exception.should == nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should correctly advise methods in an instance of the nested class." do
|
48
|
+
myclass = Nested1::Nested2::MyClass.new
|
49
|
+
context = nil
|
50
|
+
@aspect = Aspect.new :before, :pointcut => {:object => myclass, :methods => :do1} do |jp, *args|
|
51
|
+
context = jp.context
|
52
|
+
end
|
53
|
+
block_called = 0
|
54
|
+
myclass.do1(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
55
|
+
block_called.should == 1
|
56
|
+
context.advice_kind.should == :before
|
57
|
+
context.advised_object.should == myclass
|
58
|
+
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
59
|
+
context.returned_value.should == nil
|
60
|
+
context.raised_exception.should == nil
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe Aspect, "#new when advising methods in a nested module included by a class" do
|
65
|
+
after(:each) do
|
66
|
+
@aspect.unadvise if @aspect
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should correctly advise the module's methods when the nested module is specified." do
|
70
|
+
class MyClassWithModule1
|
71
|
+
include Nested1::Nested2::MyModule
|
72
|
+
end
|
73
|
+
|
74
|
+
myclass = MyClassWithModule1.new
|
75
|
+
context = nil
|
76
|
+
@aspect = Aspect.new :before, :pointcut => {:type => Nested1::Nested2::MyModule, :methods => :do2} do |jp, *args|
|
77
|
+
context = jp.context
|
78
|
+
end
|
79
|
+
block_called = 0
|
80
|
+
myclass.do2(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
81
|
+
block_called.should == 1
|
82
|
+
context.advice_kind.should == :before
|
83
|
+
context.advised_object.should == myclass
|
84
|
+
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
85
|
+
context.returned_value.should == nil
|
86
|
+
context.raised_exception.should == nil
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should correctly advise the module's methods when the class is specified." do
|
90
|
+
class MyClassWithModule2
|
91
|
+
include Nested1::Nested2::MyModule
|
92
|
+
end
|
93
|
+
|
94
|
+
myclass = MyClassWithModule2.new
|
95
|
+
context = nil
|
96
|
+
@aspect = Aspect.new :before, :pointcut => {:type => MyClassWithModule2, :methods => :do2} do |jp, *args|
|
97
|
+
context = jp.context
|
98
|
+
end
|
99
|
+
block_called = 0
|
100
|
+
myclass.do2(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
101
|
+
block_called.should == 1
|
102
|
+
context.advice_kind.should == :before
|
103
|
+
context.advised_object.should == myclass
|
104
|
+
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
105
|
+
context.returned_value.should == nil
|
106
|
+
context.raised_exception.should == nil
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should correctly advise the module's methods when an instance of the class is specified." do
|
110
|
+
class MyClassWithModule3
|
111
|
+
include Nested1::Nested2::MyModule
|
112
|
+
end
|
113
|
+
|
114
|
+
myclass = MyClassWithModule3.new
|
115
|
+
context = nil
|
116
|
+
@aspect = Aspect.new :before, :pointcut => {:object => myclass, :methods => :do2} do |jp, *args|
|
117
|
+
context = jp.context
|
118
|
+
end
|
119
|
+
block_called = 0
|
120
|
+
myclass.do2(:a1, :a2, :a3, :h1 => 'h1', :h2 => 'h2') { |*args| block_called += 1 }
|
121
|
+
block_called.should == 1
|
122
|
+
context.advice_kind.should == :before
|
123
|
+
context.advised_object.should == myclass
|
124
|
+
context.parameters.should == [:a1, :a2, :a3, {:h1 => 'h1', :h2 => 'h2'}]
|
125
|
+
context.returned_value.should == nil
|
126
|
+
context.raised_exception.should == nil
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
@@ -0,0 +1,423 @@
|
|
1
|
+
# Specifically tests behavior when two or more advices apply to the same join point(s).
|
2
|
+
|
3
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
4
|
+
require File.dirname(__FILE__) + '/../spec_example_classes'
|
5
|
+
require File.dirname(__FILE__) + '/concurrently_accessed'
|
6
|
+
require 'aquarium/aspects'
|
7
|
+
|
8
|
+
module ConcurrentAspectsSpecSupport
|
9
|
+
def add_m_then_remove_n_aspects_and_run iteration, for_type
|
10
|
+
reset_attrs
|
11
|
+
add_all_aspects_then_unadvise iteration, for_type
|
12
|
+
invoke
|
13
|
+
check_results_for iteration
|
14
|
+
unadvise_remaining iteration
|
15
|
+
end
|
16
|
+
|
17
|
+
def reset_attrs
|
18
|
+
@contexts = []
|
19
|
+
@argss = []
|
20
|
+
@aspects = []
|
21
|
+
@advice_invocation_counts = []
|
22
|
+
@accessed = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_all_aspects_then_unadvise number_to_unadvise, for_type
|
26
|
+
@accessed = ConcurrentlyAccessed.new
|
27
|
+
@advice_kinds.size.times do |n|
|
28
|
+
make_aspect_for_index n, for_type
|
29
|
+
end
|
30
|
+
number_to_unadvise.times {|n| @aspects[n].unadvise}
|
31
|
+
end
|
32
|
+
|
33
|
+
def invoke accessed = @accessed, advice_kinds = @advice_kinds
|
34
|
+
advice_kinds.size.times do |n|
|
35
|
+
(advice_kinds[n] == :after_raising) ? do_invoke_raises(accessed) : do_invoke(accessed)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def do_invoke_raises accessed
|
40
|
+
lambda {accessed.invoke_raises :a1, :a2}.should raise_error(ConcurrentlyAccessed::Error)
|
41
|
+
end
|
42
|
+
|
43
|
+
def do_invoke accessed
|
44
|
+
accessed.invoke :a1, :a2
|
45
|
+
end
|
46
|
+
|
47
|
+
def check_results_for iteration
|
48
|
+
number_of_unadvised_aspects = iteration + 1
|
49
|
+
@accessed.invoked_count.should == @aspects.size
|
50
|
+
@accessed.invoked_args.should == [:a1, :a2]
|
51
|
+
iteration.times do |n|
|
52
|
+
@advice_invocation_counts[n].should == 0
|
53
|
+
@contexts[n].should be_nil
|
54
|
+
@argss[n].should be_nil
|
55
|
+
end
|
56
|
+
(@aspects.size - iteration).times do |n|
|
57
|
+
n2 = n + iteration
|
58
|
+
@advice_invocation_counts[n2].should == expected_number_of_advice_invocations(@advice_kinds, n2)
|
59
|
+
@contexts[n2].should_not be_nil
|
60
|
+
@argss[n2].should == [:a1, :a2]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def unadvise_remaining number_to_unadvise
|
65
|
+
(@aspects.size - number_to_unadvise).times {|n| @aspects[n + number_to_unadvise].unadvise}
|
66
|
+
end
|
67
|
+
|
68
|
+
def make_aspect_for_index n, for_type
|
69
|
+
method = @advice_kinds[n] == :after_raising ? :invoke_raises : :invoke
|
70
|
+
@advice_invocation_counts[n] = 0
|
71
|
+
if for_type
|
72
|
+
pointcut = Aquarium::Aspects::Pointcut.new(:methods => method, :type => ConcurrentlyAccessed)
|
73
|
+
else
|
74
|
+
pointcut = Aquarium::Aspects::Pointcut.new(:methods => method, :object => @accessed)
|
75
|
+
end
|
76
|
+
@aspects[n] = advise @advice_kinds[n], :pointcut => pointcut do |jp, *args|
|
77
|
+
@contexts[n] = jp.context
|
78
|
+
@argss[n] = *args
|
79
|
+
@advice_invocation_counts[n] += 1
|
80
|
+
jp.proceed if @advice_kinds[n] == :around
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Because after_raising advice is invoked by calling ConcurrentlyAccessed#invoke_raises
|
85
|
+
# instead of ConcurrentlyAccessed#invoke, we get a lower count, due to non-overlapping JPs.
|
86
|
+
def expected_number_of_advice_invocations advice_kinds, n
|
87
|
+
advice_kinds.size - after_raising_factor(advice_kinds, n)
|
88
|
+
end
|
89
|
+
|
90
|
+
def after_raising_factor advice_kinds, n
|
91
|
+
raising, not_raising = advice_kinds.partition {|x| x == :after_raising}
|
92
|
+
total = advice_kinds.size
|
93
|
+
total - ((advice_kinds[n] == :after_raising) ? raising.size : not_raising.size)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "concurrent advice", :shared => true do
|
98
|
+
include ConcurrentAspectsSpecSupport
|
99
|
+
|
100
|
+
before :all do
|
101
|
+
@advice_kinds = []
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should allow concurrent advice on the same join point, where type-based advices can be added and removed independently" do
|
105
|
+
(@advice_kinds.size+1).times do |n|
|
106
|
+
add_m_then_remove_n_aspects_and_run n, true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should allow concurrent advice on the same join point, where object-based advices can be added and removed independently" do
|
111
|
+
(@advice_kinds.size+1).times do |n|
|
112
|
+
add_m_then_remove_n_aspects_and_run n, false
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "Using two :before advices" do
|
118
|
+
setup do
|
119
|
+
@advice_kinds = [:before, :before]
|
120
|
+
end
|
121
|
+
it_should_behave_like "concurrent advice"
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "Using two :after advices" do
|
125
|
+
setup do
|
126
|
+
@advice_kinds = [:after, :after]
|
127
|
+
end
|
128
|
+
it_should_behave_like "concurrent advice"
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "Using two :after_returning advices" do
|
132
|
+
setup do
|
133
|
+
@advice_kinds = [:after_returning, :after_returning]
|
134
|
+
end
|
135
|
+
it_should_behave_like "concurrent advice"
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "Using two :after_raising advices" do
|
139
|
+
setup do
|
140
|
+
@advice_kinds = [:after_raising, :after_raising]
|
141
|
+
end
|
142
|
+
it_should_behave_like "concurrent advice"
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "Using two :around advices" do
|
146
|
+
setup do
|
147
|
+
@advice_kinds = [:around, :around]
|
148
|
+
end
|
149
|
+
it_should_behave_like "concurrent advice"
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "Using :before advice and :after advice" do
|
153
|
+
setup do
|
154
|
+
@advice_kinds = [:before, :after]
|
155
|
+
end
|
156
|
+
it_should_behave_like "concurrent advice"
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "Using :before advice and :after_returning advice" do
|
160
|
+
setup do
|
161
|
+
@advice_kinds = [:before, :after_returning]
|
162
|
+
end
|
163
|
+
it_should_behave_like "concurrent advice"
|
164
|
+
end
|
165
|
+
|
166
|
+
describe "Using :before advice and :after_raising advice" do
|
167
|
+
setup do
|
168
|
+
@advice_kinds = [:before, :after_raising]
|
169
|
+
end
|
170
|
+
it_should_behave_like "concurrent advice"
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "Using :before advice and :around advice" do
|
174
|
+
setup do
|
175
|
+
@advice_kinds = [:before, :around]
|
176
|
+
end
|
177
|
+
it_should_behave_like "concurrent advice"
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "Using :after advice and :after_returning advice" do
|
181
|
+
setup do
|
182
|
+
@advice_kinds = [:after, :after_returning]
|
183
|
+
end
|
184
|
+
it_should_behave_like "concurrent advice"
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "Using :after advice and :after_raising advice" do
|
188
|
+
setup do
|
189
|
+
@advice_kinds = [:after, :after_raising]
|
190
|
+
end
|
191
|
+
it_should_behave_like "concurrent advice"
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "Using :after advice and :around advice" do
|
195
|
+
setup do
|
196
|
+
@advice_kinds = [:after, :around]
|
197
|
+
end
|
198
|
+
it_should_behave_like "concurrent advice"
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
describe "Using :after_returning advice and :after_raising advice" do
|
203
|
+
setup do
|
204
|
+
@advice_kinds = [:after_returning, :after_raising]
|
205
|
+
end
|
206
|
+
it_should_behave_like "concurrent advice"
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "Using :after_returning advice and :around advice" do
|
210
|
+
setup do
|
211
|
+
@advice_kinds = [:after_returning, :around]
|
212
|
+
end
|
213
|
+
it_should_behave_like "concurrent advice"
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "Using :after_raising advice and :around advice" do
|
217
|
+
setup do
|
218
|
+
@advice_kinds = [:after_raising, :around]
|
219
|
+
end
|
220
|
+
it_should_behave_like "concurrent advice"
|
221
|
+
end
|
222
|
+
|
223
|
+
describe "Using three :before advices" do
|
224
|
+
setup do
|
225
|
+
3.times {|i| @advice_kinds[i] = :before}
|
226
|
+
end
|
227
|
+
it_should_behave_like "concurrent advice"
|
228
|
+
end
|
229
|
+
|
230
|
+
describe "Using three :before advices" do
|
231
|
+
setup do
|
232
|
+
3.times {|i| @advice_kinds[i] = :before}
|
233
|
+
end
|
234
|
+
it_should_behave_like "concurrent advice"
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "Using three :after advices" do
|
238
|
+
setup do
|
239
|
+
3.times {|i| @advice_kinds[i] = :after}
|
240
|
+
end
|
241
|
+
it_should_behave_like "concurrent advice"
|
242
|
+
end
|
243
|
+
|
244
|
+
describe "Using three :after_returning advices" do
|
245
|
+
setup do
|
246
|
+
3.times {|i| @advice_kinds[i] = :after_returning}
|
247
|
+
end
|
248
|
+
it_should_behave_like "concurrent advice"
|
249
|
+
end
|
250
|
+
|
251
|
+
describe "Using three :after_raising advices" do
|
252
|
+
setup do
|
253
|
+
3.times {|i| @advice_kinds[i] = :after_raising}
|
254
|
+
end
|
255
|
+
it_should_behave_like "concurrent advice"
|
256
|
+
end
|
257
|
+
|
258
|
+
describe "Using three :around advices" do
|
259
|
+
setup do
|
260
|
+
3.times {|i| @advice_kinds[i] = :around}
|
261
|
+
end
|
262
|
+
it_should_behave_like "concurrent advice"
|
263
|
+
end
|
264
|
+
|
265
|
+
describe "Using two :before advices and one :after advice" do
|
266
|
+
setup do
|
267
|
+
2.times {|i| @advice_kinds[i] = :before}
|
268
|
+
@advice_kinds[2] = :after
|
269
|
+
end
|
270
|
+
it_should_behave_like "concurrent advice"
|
271
|
+
end
|
272
|
+
|
273
|
+
describe "Using two :before advices and one :after_returning advice" do
|
274
|
+
setup do
|
275
|
+
2.times {|i| @advice_kinds[i] = :before}
|
276
|
+
@advice_kinds[2] = :after_returning
|
277
|
+
end
|
278
|
+
it_should_behave_like "concurrent advice"
|
279
|
+
end
|
280
|
+
|
281
|
+
describe "Using two :before advices and one :after_raising advice" do
|
282
|
+
setup do
|
283
|
+
2.times {|i| @advice_kinds[i] = :before}
|
284
|
+
@advice_kinds[2] = :after_raising
|
285
|
+
end
|
286
|
+
it_should_behave_like "concurrent advice"
|
287
|
+
end
|
288
|
+
|
289
|
+
describe "Using two :before advices and one :around advice" do
|
290
|
+
setup do
|
291
|
+
2.times {|i| @advice_kinds[i] = :before}
|
292
|
+
@advice_kinds[2] = :around
|
293
|
+
end
|
294
|
+
it_should_behave_like "concurrent advice"
|
295
|
+
end
|
296
|
+
|
297
|
+
describe "Using two :after advices and one :before advice" do
|
298
|
+
setup do
|
299
|
+
2.times {|i| @advice_kinds[i] = :after}
|
300
|
+
@advice_kinds[2] = :before
|
301
|
+
end
|
302
|
+
it_should_behave_like "concurrent advice"
|
303
|
+
end
|
304
|
+
|
305
|
+
describe "Using two :after advices and one :after_returning advice" do
|
306
|
+
setup do
|
307
|
+
2.times {|i| @advice_kinds[i] = :after}
|
308
|
+
@advice_kinds[2] = :after_returning
|
309
|
+
end
|
310
|
+
it_should_behave_like "concurrent advice"
|
311
|
+
end
|
312
|
+
|
313
|
+
describe "Using two :after advices and one :after_raising advice" do
|
314
|
+
setup do
|
315
|
+
2.times {|i| @advice_kinds[i] = :after}
|
316
|
+
@advice_kinds[2] = :after_raising
|
317
|
+
end
|
318
|
+
it_should_behave_like "concurrent advice"
|
319
|
+
end
|
320
|
+
|
321
|
+
describe "Using two :after advices and one :around advice" do
|
322
|
+
setup do
|
323
|
+
2.times {|i| @advice_kinds[i] = :after}
|
324
|
+
@advice_kinds[2] = :around
|
325
|
+
end
|
326
|
+
it_should_behave_like "concurrent advice"
|
327
|
+
end
|
328
|
+
|
329
|
+
describe "Using two :after_returning advices and one :before advice" do
|
330
|
+
setup do
|
331
|
+
2.times {|i| @advice_kinds[i] = :after_returning}
|
332
|
+
@advice_kinds[2] = :before
|
333
|
+
end
|
334
|
+
it_should_behave_like "concurrent advice"
|
335
|
+
end
|
336
|
+
|
337
|
+
describe "Using two :after_returning advices and one :after advice" do
|
338
|
+
setup do
|
339
|
+
2.times {|i| @advice_kinds[i] = :after_returning}
|
340
|
+
@advice_kinds[2] = :after
|
341
|
+
end
|
342
|
+
it_should_behave_like "concurrent advice"
|
343
|
+
end
|
344
|
+
|
345
|
+
describe "Using two :after_returning advices and one :after_raising advice" do
|
346
|
+
setup do
|
347
|
+
2.times {|i| @advice_kinds[i] = :after_returning}
|
348
|
+
@advice_kinds[2] = :after_raising
|
349
|
+
end
|
350
|
+
it_should_behave_like "concurrent advice"
|
351
|
+
end
|
352
|
+
|
353
|
+
describe "Using two :after_returning advices and one :around advice" do
|
354
|
+
setup do
|
355
|
+
2.times {|i| @advice_kinds[i] = :after_returning}
|
356
|
+
@advice_kinds[2] = :around
|
357
|
+
end
|
358
|
+
it_should_behave_like "concurrent advice"
|
359
|
+
end
|
360
|
+
|
361
|
+
describe "Using two :after_raising advices and one :before advice" do
|
362
|
+
setup do
|
363
|
+
2.times {|i| @advice_kinds[i] = :after_raising}
|
364
|
+
@advice_kinds[2] = :before
|
365
|
+
end
|
366
|
+
it_should_behave_like "concurrent advice"
|
367
|
+
end
|
368
|
+
|
369
|
+
describe "Using two :after_raising advices and one :after advice" do
|
370
|
+
setup do
|
371
|
+
2.times {|i| @advice_kinds[i] = :after_raising}
|
372
|
+
@advice_kinds[2] = :after
|
373
|
+
end
|
374
|
+
it_should_behave_like "concurrent advice"
|
375
|
+
end
|
376
|
+
|
377
|
+
describe "Using two :after_raising advices and one :after_raising advice" do
|
378
|
+
setup do
|
379
|
+
2.times {|i| @advice_kinds[i] = :after_raising}
|
380
|
+
@advice_kinds[2] = :after_raising
|
381
|
+
end
|
382
|
+
it_should_behave_like "concurrent advice"
|
383
|
+
end
|
384
|
+
|
385
|
+
describe "Using two :after_raising advices and one :around advice" do
|
386
|
+
setup do
|
387
|
+
2.times {|i| @advice_kinds[i] = :after_raising}
|
388
|
+
@advice_kinds[2] = :around
|
389
|
+
end
|
390
|
+
it_should_behave_like "concurrent advice"
|
391
|
+
end
|
392
|
+
|
393
|
+
describe "Using two :around advices and one :before advice" do
|
394
|
+
setup do
|
395
|
+
2.times {|i| @advice_kinds[i] = :around}
|
396
|
+
@advice_kinds[2] = :before
|
397
|
+
end
|
398
|
+
it_should_behave_like "concurrent advice"
|
399
|
+
end
|
400
|
+
|
401
|
+
describe "Using two :around advices and one :after advice" do
|
402
|
+
setup do
|
403
|
+
2.times {|i| @advice_kinds[i] = :around}
|
404
|
+
@advice_kinds[2] = :after
|
405
|
+
end
|
406
|
+
it_should_behave_like "concurrent advice"
|
407
|
+
end
|
408
|
+
|
409
|
+
describe "Using two :around advices and one :after_returning advice" do
|
410
|
+
setup do
|
411
|
+
2.times {|i| @advice_kinds[i] = :around}
|
412
|
+
@advice_kinds[2] = :after_returning
|
413
|
+
end
|
414
|
+
it_should_behave_like "concurrent advice"
|
415
|
+
end
|
416
|
+
|
417
|
+
describe "Using two :around advices and one :after_raising advice" do
|
418
|
+
setup do
|
419
|
+
2.times {|i| @advice_kinds[i] = :around}
|
420
|
+
@advice_kinds[2] = :after_raising
|
421
|
+
end
|
422
|
+
it_should_behave_like "concurrent advice"
|
423
|
+
end
|