C0 code coverage information
Generated on Sun Oct 26 11:18:06 -0500 2008 with rcov 0.8.1.2
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # Specifically tests behavior when two or more advices apply to the same join point(s).
2
3 require File.dirname(__FILE__) + '/../spec_helper'
4 require 'aquarium/spec_example_types'
5 require 'aquarium/aspects/concurrently_accessed'
6 require 'aquarium/aspects'
7
8 include Aquarium::Aspects
9
10 module ConcurrentAspectsSpecSupport
11 def add_m_then_remove_n_aspects_and_run iteration, for_type
12 reset_attrs
13 add_all_aspects_then_unadvise iteration, for_type
14 invoke
15 check_results_for iteration
16 unadvise_remaining iteration
17 end
18
19 def reset_attrs
20 @contexts = []
21 @argss = []
22 @aspects = []
23 @advice_invocation_counts = []
24 @accessed = nil
25 end
26
27 def add_all_aspects_then_unadvise number_to_unadvise, for_type
28 @accessed = ConcurrentlyAccessed.new
29 @advice_kinds.size.times do |n|
30 make_aspect_for_index n, for_type
31 end
32 number_to_unadvise.times {|n| @aspects[n].unadvise}
33 end
34
35 def invoke accessed = @accessed, advice_kinds = @advice_kinds
36 advice_kinds.size.times do |n|
37 (advice_kinds[n] == :after_raising) ? do_invoke_raises(accessed) : do_invoke(accessed)
38 end
39 end
40
41 def do_invoke_raises accessed
42 lambda {accessed.invoke_raises :a1, :a2}.should raise_error(ConcurrentlyAccessed::Error)
43 end
44
45 def do_invoke accessed
46 accessed.invoke :a1, :a2
47 end
48
49 def check_results_for iteration
50 @accessed.invoked_count.should == @aspects.size
51 @accessed.invoked_args.should == [:a1, :a2]
52 iteration.times do |n|
53 @advice_invocation_counts[n].should == 0
54 @contexts[n].should be_nil
55 @argss[n].should be_nil
56 end
57 (@aspects.size - iteration).times do |n|
58 n2 = n + iteration
59 @advice_invocation_counts[n2].should == expected_number_of_advice_invocations(@advice_kinds, n2)
60 @contexts[n2].should_not be_nil
61 @argss[n2].should == [:a1, :a2]
62 end
63 end
64
65 def unadvise_remaining number_to_unadvise
66 (@aspects.size - number_to_unadvise).times {|n| @aspects[n + number_to_unadvise].unadvise}
67 end
68
69 def make_aspect_for_index n, for_type
70 method = @advice_kinds[n] == :after_raising ? :invoke_raises : :invoke
71 @advice_invocation_counts[n] = 0
72 if for_type
73 pointcut = Pointcut.new(:methods => method, :type => ConcurrentlyAccessed)
74 else
75 pointcut = Pointcut.new(:methods => method, :object => @accessed)
76 end
77 @aspects[n] = Aspect.new @advice_kinds[n], :pointcut => pointcut do |jp, obj, *args|
78 @contexts[n] = jp.context
79 @argss[n] = *args
80 @advice_invocation_counts[n] += 1
81 jp.proceed if @advice_kinds[n] == :around
82 end
83 end
84
85 # Because after_raising advice is invoked by calling ConcurrentlyAccessed#invoke_raises
86 # instead of ConcurrentlyAccessed#invoke, we get a lower count, due to non-overlapping JPs.
87 def expected_number_of_advice_invocations advice_kinds, n
88 advice_kinds.size - after_raising_factor(advice_kinds, n)
89 end
90
91 def after_raising_factor advice_kinds, n
92 raising, not_raising = advice_kinds.partition {|x| x == :after_raising}
93 total = advice_kinds.size
94 total - ((advice_kinds[n] == :after_raising) ? raising.size : not_raising.size)
95 end
96 end
97
98 describe "concurrent advice", :shared => true do
99 include ConcurrentAspectsSpecSupport
100
101 before :all do
102 @advice_kinds = []
103 end
104
105 it "should allow concurrent advice on the same join point, where type-based advices can be added and removed independently" do
106 (@advice_kinds.size+1).times do |n|
107 add_m_then_remove_n_aspects_and_run n, true
108 end
109 end
110
111 it "should allow concurrent advice on the same join point, where object-based advices can be added and removed independently" do
112 (@advice_kinds.size+1).times do |n|
113 add_m_then_remove_n_aspects_and_run n, false
114 end
115 end
116 end
117
118 describe "Using two :before advices" do
119 setup do
120 @advice_kinds = [:before, :before]
121 end
122 it_should_behave_like "concurrent advice"
123 end
124
125 describe "Using two :after advices" do
126 setup do
127 @advice_kinds = [:after, :after]
128 end
129 it_should_behave_like "concurrent advice"
130 end
131
132 describe "Using two :after_returning advices" do
133 setup do
134 @advice_kinds = [:after_returning, :after_returning]
135 end
136 it_should_behave_like "concurrent advice"
137 end
138
139 describe "Using two :after_raising advices" do
140 setup do
141 @advice_kinds = [:after_raising, :after_raising]
142 end
143 it_should_behave_like "concurrent advice"
144 end
145
146 describe "Using two :around advices" do
147 setup do
148 @advice_kinds = [:around, :around]
149 end
150 it_should_behave_like "concurrent advice"
151 end
152
153 describe "Using :before advice and :after advice" do
154 setup do
155 @advice_kinds = [:before, :after]
156 end
157 it_should_behave_like "concurrent advice"
158 end
159
160 describe "Using :before advice and :after_returning advice" do
161 setup do
162 @advice_kinds = [:before, :after_returning]
163 end
164 it_should_behave_like "concurrent advice"
165 end
166
167 describe "Using :before advice and :after_raising advice" do
168 setup do
169 @advice_kinds = [:before, :after_raising]
170 end
171 it_should_behave_like "concurrent advice"
172 end
173
174 describe "Using :before advice and :around advice" do
175 setup do
176 @advice_kinds = [:before, :around]
177 end
178 it_should_behave_like "concurrent advice"
179 end
180
181 describe "Using :after advice and :after_returning advice" do
182 setup do
183 @advice_kinds = [:after, :after_returning]
184 end
185 it_should_behave_like "concurrent advice"
186 end
187
188 describe "Using :after advice and :after_raising advice" do
189 setup do
190 @advice_kinds = [:after, :after_raising]
191 end
192 it_should_behave_like "concurrent advice"
193 end
194
195 describe "Using :after advice and :around advice" do
196 setup do
197 @advice_kinds = [:after, :around]
198 end
199 it_should_behave_like "concurrent advice"
200 end
201
202
203 describe "Using :after_returning advice and :after_raising advice" do
204 setup do
205 @advice_kinds = [:after_returning, :after_raising]
206 end
207 it_should_behave_like "concurrent advice"
208 end
209
210 describe "Using :after_returning advice and :around advice" do
211 setup do
212 @advice_kinds = [:after_returning, :around]
213 end
214 it_should_behave_like "concurrent advice"
215 end
216
217 describe "Using :after_raising advice and :around advice" do
218 setup do
219 @advice_kinds = [:after_raising, :around]
220 end
221 it_should_behave_like "concurrent advice"
222 end
223
224 describe "Using three :before advices" do
225 setup do
226 3.times {|i| @advice_kinds[i] = :before}
227 end
228 it_should_behave_like "concurrent advice"
229 end
230
231 describe "Using three :before advices" do
232 setup do
233 3.times {|i| @advice_kinds[i] = :before}
234 end
235 it_should_behave_like "concurrent advice"
236 end
237
238 describe "Using three :after advices" do
239 setup do
240 3.times {|i| @advice_kinds[i] = :after}
241 end
242 it_should_behave_like "concurrent advice"
243 end
244
245 describe "Using three :after_returning advices" do
246 setup do
247 3.times {|i| @advice_kinds[i] = :after_returning}
248 end
249 it_should_behave_like "concurrent advice"
250 end
251
252 describe "Using three :after_raising advices" do
253 setup do
254 3.times {|i| @advice_kinds[i] = :after_raising}
255 end
256 it_should_behave_like "concurrent advice"
257 end
258
259 describe "Using three :around advices" do
260 setup do
261 3.times {|i| @advice_kinds[i] = :around}
262 end
263 it_should_behave_like "concurrent advice"
264 end
265
266 describe "Using two :before advices and one :after advice" do
267 setup do
268 2.times {|i| @advice_kinds[i] = :before}
269 @advice_kinds[2] = :after
270 end
271 it_should_behave_like "concurrent advice"
272 end
273
274 describe "Using two :before advices and one :after_returning advice" do
275 setup do
276 2.times {|i| @advice_kinds[i] = :before}
277 @advice_kinds[2] = :after_returning
278 end
279 it_should_behave_like "concurrent advice"
280 end
281
282 describe "Using two :before advices and one :after_raising advice" do
283 setup do
284 2.times {|i| @advice_kinds[i] = :before}
285 @advice_kinds[2] = :after_raising
286 end
287 it_should_behave_like "concurrent advice"
288 end
289
290 describe "Using two :before advices and one :around advice" do
291 setup do
292 2.times {|i| @advice_kinds[i] = :before}
293 @advice_kinds[2] = :around
294 end
295 it_should_behave_like "concurrent advice"
296 end
297
298 describe "Using two :after advices and one :before advice" do
299 setup do
300 2.times {|i| @advice_kinds[i] = :after}
301 @advice_kinds[2] = :before
302 end
303 it_should_behave_like "concurrent advice"
304 end
305
306 describe "Using two :after advices and one :after_returning advice" do
307 setup do
308 2.times {|i| @advice_kinds[i] = :after}
309 @advice_kinds[2] = :after_returning
310 end
311 it_should_behave_like "concurrent advice"
312 end
313
314 describe "Using two :after advices and one :after_raising advice" do
315 setup do
316 2.times {|i| @advice_kinds[i] = :after}
317 @advice_kinds[2] = :after_raising
318 end
319 it_should_behave_like "concurrent advice"
320 end
321
322 describe "Using two :after advices and one :around advice" do
323 setup do
324 2.times {|i| @advice_kinds[i] = :after}
325 @advice_kinds[2] = :around
326 end
327 it_should_behave_like "concurrent advice"
328 end
329
330 describe "Using two :after_returning advices and one :before advice" do
331 setup do
332 2.times {|i| @advice_kinds[i] = :after_returning}
333 @advice_kinds[2] = :before
334 end
335 it_should_behave_like "concurrent advice"
336 end
337
338 describe "Using two :after_returning advices and one :after advice" do
339 setup do
340 2.times {|i| @advice_kinds[i] = :after_returning}
341 @advice_kinds[2] = :after
342 end
343 it_should_behave_like "concurrent advice"
344 end
345
346 describe "Using two :after_returning advices and one :after_raising advice" do
347 setup do
348 2.times {|i| @advice_kinds[i] = :after_returning}
349 @advice_kinds[2] = :after_raising
350 end
351 it_should_behave_like "concurrent advice"
352 end
353
354 describe "Using two :after_returning advices and one :around advice" do
355 setup do
356 2.times {|i| @advice_kinds[i] = :after_returning}
357 @advice_kinds[2] = :around
358 end
359 it_should_behave_like "concurrent advice"
360 end
361
362 describe "Using two :after_raising advices and one :before advice" do
363 setup do
364 2.times {|i| @advice_kinds[i] = :after_raising}
365 @advice_kinds[2] = :before
366 end
367 it_should_behave_like "concurrent advice"
368 end
369
370 describe "Using two :after_raising advices and one :after advice" do
371 setup do
372 2.times {|i| @advice_kinds[i] = :after_raising}
373 @advice_kinds[2] = :after
374 end
375 it_should_behave_like "concurrent advice"
376 end
377
378 describe "Using two :after_raising advices and one :after_raising advice" do
379 setup do
380 2.times {|i| @advice_kinds[i] = :after_raising}
381 @advice_kinds[2] = :after_raising
382 end
383 it_should_behave_like "concurrent advice"
384 end
385
386 describe "Using two :after_raising advices and one :around advice" do
387 setup do
388 2.times {|i| @advice_kinds[i] = :after_raising}
389 @advice_kinds[2] = :around
390 end
391 it_should_behave_like "concurrent advice"
392 end
393
394 describe "Using two :around advices and one :before advice" do
395 setup do
396 2.times {|i| @advice_kinds[i] = :around}
397 @advice_kinds[2] = :before
398 end
399 it_should_behave_like "concurrent advice"
400 end
401
402 describe "Using two :around advices and one :after advice" do
403 setup do
404 2.times {|i| @advice_kinds[i] = :around}
405 @advice_kinds[2] = :after
406 end
407 it_should_behave_like "concurrent advice"
408 end
409
410 describe "Using two :around advices and one :after_returning advice" do
411 setup do
412 2.times {|i| @advice_kinds[i] = :around}
413 @advice_kinds[2] = :after_returning
414 end
415 it_should_behave_like "concurrent advice"
416 end
417
418 describe "Using two :around advices and one :after_raising advice" do
419 setup do
420 2.times {|i| @advice_kinds[i] = :around}
421 @advice_kinds[2] = :after_raising
422 end
423 it_should_behave_like "concurrent advice"
424 end
Generated using the rcov code coverage analysis tool for Ruby version 0.8.1.2.