classx 0.0.3 → 0.0.4
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/ChangeLog +354 -0
- data/README +5 -0
- data/Rakefile +2 -2
- data/bench/attribute_get.rb +73 -0
- data/bench/attribute_set.rb +53 -19
- data/bench/define_attribute.rb +226 -0
- data/bench/initialize.rb +25 -7
- data/doc/output/coverage/index.html +74 -128
- data/doc/output/coverage/lib-classx-attribute_rb.html +291 -190
- data/doc/output/coverage/lib-classx-attributes_rb.html +167 -101
- data/doc/output/coverage/lib-classx-bracketable_rb.html +671 -0
- data/doc/output/coverage/lib-classx-class_attributes_rb.html +775 -0
- data/doc/output/coverage/lib-classx-commandable_rb.html +727 -0
- data/doc/output/coverage/{-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-block_rb.html → lib-classx-declare_rb.html} +60 -62
- data/doc/output/coverage/lib-classx-validate_rb.html +43 -41
- data/doc/output/coverage/lib-classx_rb.html +208 -78
- data/example/commandable.rb +1 -0
- data/lib/classx.rb +146 -16
- data/lib/classx/attribute.rb +244 -143
- data/lib/classx/attributes.rb +93 -27
- data/lib/classx/bracketable.rb +61 -0
- data/lib/classx/class_attributes.rb +165 -0
- data/lib/classx/commandable.rb +55 -4
- data/lib/classx/declare.rb +40 -3
- data/lib/classx/role/logger.rb +17 -13
- data/lib/classx/validate.rb +26 -24
- data/spec/classx/handles_spec.rb +21 -6
- data/spec/classx/serialize_spec.rb +57 -0
- data/spec/classx/{with_coerce.rb → with_coerce_spec.rb} +0 -0
- data/spec/classx/with_extend_spec.rb +58 -0
- data/spec/classx/with_include_spec.rb +58 -0
- data/spec/classx/with_validate_spec.rb +363 -0
- data/spec/classx/without_anyoption_spec.rb +1 -1
- data/spec/classx/writable_option_spec.rb +29 -4
- data/spec/classx_bracketable_spec.rb +160 -0
- data/spec/classx_class_attributes/default_option_spec.rb +121 -0
- data/spec/classx_class_attributes/dsl_accessor_spec.rb +88 -0
- data/spec/classx_class_attributes/handles_spec.rb +77 -0
- data/spec/classx_class_attributes/with_coerce_spec.rb +119 -0
- data/spec/classx_class_attributes/with_extend_spec.rb +64 -0
- data/spec/classx_class_attributes/with_include_spec.rb +64 -0
- data/spec/classx_class_attributes/with_multiple_class_spec.rb +60 -0
- data/spec/classx_class_attributes/with_validate_spec.rb +248 -0
- data/spec/classx_class_attributes/without_accessor_spec.rb +19 -0
- data/spec/classx_class_attributes/without_anyoption_spec.rb +21 -0
- data/spec/classx_class_attributes/writable_option_spec.rb +100 -0
- data/spec/classx_declare_spec.rb +117 -0
- data/spec/classx_validate_spec.rb +1 -3
- data/tasks/basic_tasks.rake +1 -1
- metadata +36 -26
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-callbacks_rb.html +0 -932
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-change_rb.html +0 -779
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs-hunk_rb.html +0 -867
- data/doc/output/coverage/-Library-Ruby-Gems-gems-diff-lcs-1_1_2-lib-diff-lcs_rb.html +0 -1715
- data/doc/output/coverage/-Library-Ruby-Gems-gems-rcov-0_8_1_2_0-lib-rcov_rb.html +0 -1598
- data/spec/classx/with_extend.rb +0 -27
- data/spec/classx/with_include.rb +0 -27
@@ -1,1598 +0,0 @@
|
|
1
|
-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
2
|
-
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'><head><title>/Library/Ruby/Gems/gems/rcov-0.8.1.2.0/lib/rcov.rb - C0 code coverage information</title>
|
3
|
-
<style type='text/css'>body { background-color: rgb(240, 240, 245); }</style>
|
4
|
-
<style type='text/css'>span.cross-ref-title {
|
5
|
-
font-size: 140%;
|
6
|
-
}
|
7
|
-
span.cross-ref a {
|
8
|
-
text-decoration: none;
|
9
|
-
}
|
10
|
-
span.cross-ref {
|
11
|
-
background-color:#f3f7fa;
|
12
|
-
border: 1px dashed #333;
|
13
|
-
margin: 1em;
|
14
|
-
padding: 0.5em;
|
15
|
-
overflow: hidden;
|
16
|
-
}
|
17
|
-
a.crossref-toggle {
|
18
|
-
text-decoration: none;
|
19
|
-
}
|
20
|
-
span.marked0 {
|
21
|
-
background-color: rgb(185, 210, 200);
|
22
|
-
display: block;
|
23
|
-
}
|
24
|
-
span.marked1 {
|
25
|
-
background-color: rgb(190, 215, 205);
|
26
|
-
display: block;
|
27
|
-
}
|
28
|
-
span.inferred0 {
|
29
|
-
background-color: rgb(175, 200, 200);
|
30
|
-
display: block;
|
31
|
-
}
|
32
|
-
span.inferred1 {
|
33
|
-
background-color: rgb(180, 205, 205);
|
34
|
-
display: block;
|
35
|
-
}
|
36
|
-
span.uncovered0 {
|
37
|
-
background-color: rgb(225, 110, 110);
|
38
|
-
display: block;
|
39
|
-
}
|
40
|
-
span.uncovered1 {
|
41
|
-
background-color: rgb(235, 120, 120);
|
42
|
-
display: block;
|
43
|
-
}
|
44
|
-
span.overview {
|
45
|
-
border-bottom: 8px solid black;
|
46
|
-
}
|
47
|
-
div.overview {
|
48
|
-
border-bottom: 8px solid black;
|
49
|
-
}
|
50
|
-
body {
|
51
|
-
font-family: verdana, arial, helvetica;
|
52
|
-
}
|
53
|
-
div.footer {
|
54
|
-
font-size: 68%;
|
55
|
-
margin-top: 1.5em;
|
56
|
-
}
|
57
|
-
h1, h2, h3, h4, h5, h6 {
|
58
|
-
margin-bottom: 0.5em;
|
59
|
-
}
|
60
|
-
h5 {
|
61
|
-
margin-top: 0.5em;
|
62
|
-
}
|
63
|
-
.hidden {
|
64
|
-
display: none;
|
65
|
-
}
|
66
|
-
div.separator {
|
67
|
-
height: 10px;
|
68
|
-
}
|
69
|
-
/* Commented out for better readability, esp. on IE */
|
70
|
-
/*
|
71
|
-
table tr td, table tr th {
|
72
|
-
font-size: 68%;
|
73
|
-
}
|
74
|
-
td.value table tr td {
|
75
|
-
font-size: 11px;
|
76
|
-
}
|
77
|
-
*/
|
78
|
-
table.percent_graph {
|
79
|
-
height: 12px;
|
80
|
-
border: #808080 1px solid;
|
81
|
-
empty-cells: show;
|
82
|
-
}
|
83
|
-
table.percent_graph td.covered {
|
84
|
-
height: 10px;
|
85
|
-
background: #00f000;
|
86
|
-
}
|
87
|
-
table.percent_graph td.uncovered {
|
88
|
-
height: 10px;
|
89
|
-
background: #e00000;
|
90
|
-
}
|
91
|
-
table.percent_graph td.NA {
|
92
|
-
height: 10px;
|
93
|
-
background: #eaeaea;
|
94
|
-
}
|
95
|
-
table.report {
|
96
|
-
border-collapse: collapse;
|
97
|
-
width: 100%;
|
98
|
-
}
|
99
|
-
table.report td.heading {
|
100
|
-
background: #dcecff;
|
101
|
-
border: #d0d0d0 1px solid;
|
102
|
-
font-weight: bold;
|
103
|
-
text-align: center;
|
104
|
-
}
|
105
|
-
table.report td.heading:hover {
|
106
|
-
background: #c0ffc0;
|
107
|
-
}
|
108
|
-
table.report td.text {
|
109
|
-
border: #d0d0d0 1px solid;
|
110
|
-
}
|
111
|
-
table.report td.value,
|
112
|
-
table.report td.lines_total,
|
113
|
-
table.report td.lines_code {
|
114
|
-
text-align: right;
|
115
|
-
border: #d0d0d0 1px solid;
|
116
|
-
}
|
117
|
-
table.report tr.light {
|
118
|
-
background-color: rgb(240, 240, 245);
|
119
|
-
}
|
120
|
-
table.report tr.dark {
|
121
|
-
background-color: rgb(230, 230, 235);
|
122
|
-
}
|
123
|
-
</style>
|
124
|
-
<script type='text/javascript'>
|
125
|
-
// <![CDATA[
|
126
|
-
function toggleCode( id ) {
|
127
|
-
if ( document.getElementById )
|
128
|
-
elem = document.getElementById( id );
|
129
|
-
else if ( document.all )
|
130
|
-
elem = eval( "document.all." + id );
|
131
|
-
else
|
132
|
-
return false;
|
133
|
-
|
134
|
-
elemStyle = elem.style;
|
135
|
-
|
136
|
-
if ( elemStyle.display != "block" ) {
|
137
|
-
elemStyle.display = "block"
|
138
|
-
} else {
|
139
|
-
elemStyle.display = "none"
|
140
|
-
}
|
141
|
-
|
142
|
-
return true;
|
143
|
-
}
|
144
|
-
|
145
|
-
// Make cross-references hidden by default
|
146
|
-
document.writeln( "<style type=\"text/css\">span.cross-ref { display: none }</style>" )
|
147
|
-
// ]]>
|
148
|
-
</script>
|
149
|
-
<style type='text/css'>span.run0 {
|
150
|
-
background-color: rgb(178, 204, 255);
|
151
|
-
display: block;
|
152
|
-
}
|
153
|
-
span.run1 {
|
154
|
-
background-color: rgb(178, 206, 255);
|
155
|
-
display: block;
|
156
|
-
}
|
157
|
-
span.run2 {
|
158
|
-
background-color: rgb(178, 209, 255);
|
159
|
-
display: block;
|
160
|
-
}
|
161
|
-
span.run3 {
|
162
|
-
background-color: rgb(178, 211, 255);
|
163
|
-
display: block;
|
164
|
-
}
|
165
|
-
span.run4 {
|
166
|
-
background-color: rgb(178, 214, 255);
|
167
|
-
display: block;
|
168
|
-
}
|
169
|
-
span.run5 {
|
170
|
-
background-color: rgb(178, 218, 255);
|
171
|
-
display: block;
|
172
|
-
}
|
173
|
-
span.run6 {
|
174
|
-
background-color: rgb(178, 220, 255);
|
175
|
-
display: block;
|
176
|
-
}
|
177
|
-
span.run7 {
|
178
|
-
background-color: rgb(178, 223, 255);
|
179
|
-
display: block;
|
180
|
-
}
|
181
|
-
span.run8 {
|
182
|
-
background-color: rgb(178, 225, 255);
|
183
|
-
display: block;
|
184
|
-
}
|
185
|
-
span.run9 {
|
186
|
-
background-color: rgb(178, 228, 255);
|
187
|
-
display: block;
|
188
|
-
}
|
189
|
-
span.run10 {
|
190
|
-
background-color: rgb(178, 232, 255);
|
191
|
-
display: block;
|
192
|
-
}
|
193
|
-
span.run11 {
|
194
|
-
background-color: rgb(178, 234, 255);
|
195
|
-
display: block;
|
196
|
-
}
|
197
|
-
span.run12 {
|
198
|
-
background-color: rgb(178, 237, 255);
|
199
|
-
display: block;
|
200
|
-
}
|
201
|
-
span.run13 {
|
202
|
-
background-color: rgb(178, 239, 255);
|
203
|
-
display: block;
|
204
|
-
}
|
205
|
-
span.run14 {
|
206
|
-
background-color: rgb(178, 242, 255);
|
207
|
-
display: block;
|
208
|
-
}
|
209
|
-
span.run15 {
|
210
|
-
background-color: rgb(178, 246, 255);
|
211
|
-
display: block;
|
212
|
-
}
|
213
|
-
span.run16 {
|
214
|
-
background-color: rgb(178, 248, 255);
|
215
|
-
display: block;
|
216
|
-
}
|
217
|
-
span.run17 {
|
218
|
-
background-color: rgb(178, 251, 255);
|
219
|
-
display: block;
|
220
|
-
}
|
221
|
-
span.run18 {
|
222
|
-
background-color: rgb(178, 253, 255);
|
223
|
-
display: block;
|
224
|
-
}
|
225
|
-
span.run19 {
|
226
|
-
background-color: rgb(178, 255, 253);
|
227
|
-
display: block;
|
228
|
-
}
|
229
|
-
span.run20 {
|
230
|
-
background-color: rgb(178, 255, 249);
|
231
|
-
display: block;
|
232
|
-
}
|
233
|
-
span.run21 {
|
234
|
-
background-color: rgb(178, 255, 247);
|
235
|
-
display: block;
|
236
|
-
}
|
237
|
-
span.run22 {
|
238
|
-
background-color: rgb(178, 255, 244);
|
239
|
-
display: block;
|
240
|
-
}
|
241
|
-
span.run23 {
|
242
|
-
background-color: rgb(178, 255, 242);
|
243
|
-
display: block;
|
244
|
-
}
|
245
|
-
span.run24 {
|
246
|
-
background-color: rgb(178, 255, 239);
|
247
|
-
display: block;
|
248
|
-
}
|
249
|
-
span.run25 {
|
250
|
-
background-color: rgb(178, 255, 235);
|
251
|
-
display: block;
|
252
|
-
}
|
253
|
-
span.run26 {
|
254
|
-
background-color: rgb(178, 255, 233);
|
255
|
-
display: block;
|
256
|
-
}
|
257
|
-
span.run27 {
|
258
|
-
background-color: rgb(178, 255, 230);
|
259
|
-
display: block;
|
260
|
-
}
|
261
|
-
span.run28 {
|
262
|
-
background-color: rgb(178, 255, 228);
|
263
|
-
display: block;
|
264
|
-
}
|
265
|
-
span.run29 {
|
266
|
-
background-color: rgb(178, 255, 225);
|
267
|
-
display: block;
|
268
|
-
}
|
269
|
-
span.run30 {
|
270
|
-
background-color: rgb(178, 255, 221);
|
271
|
-
display: block;
|
272
|
-
}
|
273
|
-
span.run31 {
|
274
|
-
background-color: rgb(178, 255, 219);
|
275
|
-
display: block;
|
276
|
-
}
|
277
|
-
span.run32 {
|
278
|
-
background-color: rgb(178, 255, 216);
|
279
|
-
display: block;
|
280
|
-
}
|
281
|
-
span.run33 {
|
282
|
-
background-color: rgb(178, 255, 214);
|
283
|
-
display: block;
|
284
|
-
}
|
285
|
-
span.run34 {
|
286
|
-
background-color: rgb(178, 255, 211);
|
287
|
-
display: block;
|
288
|
-
}
|
289
|
-
span.run35 {
|
290
|
-
background-color: rgb(178, 255, 207);
|
291
|
-
display: block;
|
292
|
-
}
|
293
|
-
span.run36 {
|
294
|
-
background-color: rgb(178, 255, 205);
|
295
|
-
display: block;
|
296
|
-
}
|
297
|
-
span.run37 {
|
298
|
-
background-color: rgb(178, 255, 202);
|
299
|
-
display: block;
|
300
|
-
}
|
301
|
-
span.run38 {
|
302
|
-
background-color: rgb(178, 255, 200);
|
303
|
-
display: block;
|
304
|
-
}
|
305
|
-
span.run39 {
|
306
|
-
background-color: rgb(178, 255, 197);
|
307
|
-
display: block;
|
308
|
-
}
|
309
|
-
span.run40 {
|
310
|
-
background-color: rgb(178, 255, 193);
|
311
|
-
display: block;
|
312
|
-
}
|
313
|
-
span.run41 {
|
314
|
-
background-color: rgb(178, 255, 191);
|
315
|
-
display: block;
|
316
|
-
}
|
317
|
-
span.run42 {
|
318
|
-
background-color: rgb(178, 255, 188);
|
319
|
-
display: block;
|
320
|
-
}
|
321
|
-
span.run43 {
|
322
|
-
background-color: rgb(178, 255, 186);
|
323
|
-
display: block;
|
324
|
-
}
|
325
|
-
span.run44 {
|
326
|
-
background-color: rgb(178, 255, 183);
|
327
|
-
display: block;
|
328
|
-
}
|
329
|
-
span.run45 {
|
330
|
-
background-color: rgb(178, 255, 179);
|
331
|
-
display: block;
|
332
|
-
}
|
333
|
-
span.run46 {
|
334
|
-
background-color: rgb(179, 255, 178);
|
335
|
-
display: block;
|
336
|
-
}
|
337
|
-
span.run47 {
|
338
|
-
background-color: rgb(182, 255, 178);
|
339
|
-
display: block;
|
340
|
-
}
|
341
|
-
span.run48 {
|
342
|
-
background-color: rgb(184, 255, 178);
|
343
|
-
display: block;
|
344
|
-
}
|
345
|
-
span.run49 {
|
346
|
-
background-color: rgb(187, 255, 178);
|
347
|
-
display: block;
|
348
|
-
}
|
349
|
-
span.run50 {
|
350
|
-
background-color: rgb(191, 255, 178);
|
351
|
-
display: block;
|
352
|
-
}
|
353
|
-
span.run51 {
|
354
|
-
background-color: rgb(193, 255, 178);
|
355
|
-
display: block;
|
356
|
-
}
|
357
|
-
span.run52 {
|
358
|
-
background-color: rgb(196, 255, 178);
|
359
|
-
display: block;
|
360
|
-
}
|
361
|
-
span.run53 {
|
362
|
-
background-color: rgb(198, 255, 178);
|
363
|
-
display: block;
|
364
|
-
}
|
365
|
-
span.run54 {
|
366
|
-
background-color: rgb(201, 255, 178);
|
367
|
-
display: block;
|
368
|
-
}
|
369
|
-
span.run55 {
|
370
|
-
background-color: rgb(205, 255, 178);
|
371
|
-
display: block;
|
372
|
-
}
|
373
|
-
span.run56 {
|
374
|
-
background-color: rgb(207, 255, 178);
|
375
|
-
display: block;
|
376
|
-
}
|
377
|
-
span.run57 {
|
378
|
-
background-color: rgb(210, 255, 178);
|
379
|
-
display: block;
|
380
|
-
}
|
381
|
-
span.run58 {
|
382
|
-
background-color: rgb(212, 255, 178);
|
383
|
-
display: block;
|
384
|
-
}
|
385
|
-
span.run59 {
|
386
|
-
background-color: rgb(215, 255, 178);
|
387
|
-
display: block;
|
388
|
-
}
|
389
|
-
span.run60 {
|
390
|
-
background-color: rgb(219, 255, 178);
|
391
|
-
display: block;
|
392
|
-
}
|
393
|
-
span.run61 {
|
394
|
-
background-color: rgb(221, 255, 178);
|
395
|
-
display: block;
|
396
|
-
}
|
397
|
-
span.run62 {
|
398
|
-
background-color: rgb(224, 255, 178);
|
399
|
-
display: block;
|
400
|
-
}
|
401
|
-
span.run63 {
|
402
|
-
background-color: rgb(226, 255, 178);
|
403
|
-
display: block;
|
404
|
-
}
|
405
|
-
span.run64 {
|
406
|
-
background-color: rgb(229, 255, 178);
|
407
|
-
display: block;
|
408
|
-
}
|
409
|
-
span.run65 {
|
410
|
-
background-color: rgb(233, 255, 178);
|
411
|
-
display: block;
|
412
|
-
}
|
413
|
-
span.run66 {
|
414
|
-
background-color: rgb(235, 255, 178);
|
415
|
-
display: block;
|
416
|
-
}
|
417
|
-
span.run67 {
|
418
|
-
background-color: rgb(238, 255, 178);
|
419
|
-
display: block;
|
420
|
-
}
|
421
|
-
span.run68 {
|
422
|
-
background-color: rgb(240, 255, 178);
|
423
|
-
display: block;
|
424
|
-
}
|
425
|
-
span.run69 {
|
426
|
-
background-color: rgb(243, 255, 178);
|
427
|
-
display: block;
|
428
|
-
}
|
429
|
-
span.run70 {
|
430
|
-
background-color: rgb(247, 255, 178);
|
431
|
-
display: block;
|
432
|
-
}
|
433
|
-
span.run71 {
|
434
|
-
background-color: rgb(249, 255, 178);
|
435
|
-
display: block;
|
436
|
-
}
|
437
|
-
span.run72 {
|
438
|
-
background-color: rgb(252, 255, 178);
|
439
|
-
display: block;
|
440
|
-
}
|
441
|
-
span.run73 {
|
442
|
-
background-color: rgb(255, 255, 178);
|
443
|
-
display: block;
|
444
|
-
}
|
445
|
-
span.run74 {
|
446
|
-
background-color: rgb(255, 252, 178);
|
447
|
-
display: block;
|
448
|
-
}
|
449
|
-
span.run75 {
|
450
|
-
background-color: rgb(255, 248, 178);
|
451
|
-
display: block;
|
452
|
-
}
|
453
|
-
span.run76 {
|
454
|
-
background-color: rgb(255, 246, 178);
|
455
|
-
display: block;
|
456
|
-
}
|
457
|
-
span.run77 {
|
458
|
-
background-color: rgb(255, 243, 178);
|
459
|
-
display: block;
|
460
|
-
}
|
461
|
-
span.run78 {
|
462
|
-
background-color: rgb(255, 240, 178);
|
463
|
-
display: block;
|
464
|
-
}
|
465
|
-
span.run79 {
|
466
|
-
background-color: rgb(255, 238, 178);
|
467
|
-
display: block;
|
468
|
-
}
|
469
|
-
span.run80 {
|
470
|
-
background-color: rgb(255, 234, 178);
|
471
|
-
display: block;
|
472
|
-
}
|
473
|
-
span.run81 {
|
474
|
-
background-color: rgb(255, 232, 178);
|
475
|
-
display: block;
|
476
|
-
}
|
477
|
-
span.run82 {
|
478
|
-
background-color: rgb(255, 229, 178);
|
479
|
-
display: block;
|
480
|
-
}
|
481
|
-
span.run83 {
|
482
|
-
background-color: rgb(255, 226, 178);
|
483
|
-
display: block;
|
484
|
-
}
|
485
|
-
span.run84 {
|
486
|
-
background-color: rgb(255, 224, 178);
|
487
|
-
display: block;
|
488
|
-
}
|
489
|
-
span.run85 {
|
490
|
-
background-color: rgb(255, 220, 178);
|
491
|
-
display: block;
|
492
|
-
}
|
493
|
-
span.run86 {
|
494
|
-
background-color: rgb(255, 218, 178);
|
495
|
-
display: block;
|
496
|
-
}
|
497
|
-
span.run87 {
|
498
|
-
background-color: rgb(255, 215, 178);
|
499
|
-
display: block;
|
500
|
-
}
|
501
|
-
span.run88 {
|
502
|
-
background-color: rgb(255, 212, 178);
|
503
|
-
display: block;
|
504
|
-
}
|
505
|
-
span.run89 {
|
506
|
-
background-color: rgb(255, 210, 178);
|
507
|
-
display: block;
|
508
|
-
}
|
509
|
-
span.run90 {
|
510
|
-
background-color: rgb(255, 206, 178);
|
511
|
-
display: block;
|
512
|
-
}
|
513
|
-
span.run91 {
|
514
|
-
background-color: rgb(255, 204, 178);
|
515
|
-
display: block;
|
516
|
-
}
|
517
|
-
span.run92 {
|
518
|
-
background-color: rgb(255, 201, 178);
|
519
|
-
display: block;
|
520
|
-
}
|
521
|
-
span.run93 {
|
522
|
-
background-color: rgb(255, 198, 178);
|
523
|
-
display: block;
|
524
|
-
}
|
525
|
-
span.run94 {
|
526
|
-
background-color: rgb(255, 196, 178);
|
527
|
-
display: block;
|
528
|
-
}
|
529
|
-
span.run95 {
|
530
|
-
background-color: rgb(255, 192, 178);
|
531
|
-
display: block;
|
532
|
-
}
|
533
|
-
span.run96 {
|
534
|
-
background-color: rgb(255, 189, 178);
|
535
|
-
display: block;
|
536
|
-
}
|
537
|
-
span.run97 {
|
538
|
-
background-color: rgb(255, 187, 178);
|
539
|
-
display: block;
|
540
|
-
}
|
541
|
-
span.run98 {
|
542
|
-
background-color: rgb(255, 184, 178);
|
543
|
-
display: block;
|
544
|
-
}
|
545
|
-
span.run99 {
|
546
|
-
background-color: rgb(255, 182, 178);
|
547
|
-
display: block;
|
548
|
-
}
|
549
|
-
span.run100 {
|
550
|
-
background-color: rgb(255, 178, 178);
|
551
|
-
display: block;
|
552
|
-
}
|
553
|
-
</style>
|
554
|
-
</head>
|
555
|
-
<body><h3>C0 code coverage information</h3>
|
556
|
-
<p>Generated on Sat Aug 23 14:29:19 +0900 2008 with <a href='http://eigenclass.org/hiki/rcov'>rcov 0.8.1.2</a>
|
557
|
-
</p>
|
558
|
-
<hr/>
|
559
|
-
<pre><span class='marked0'>Code reported as executed by Ruby looks like this...
|
560
|
-
</span><span class='marked1'>and this: this line is also marked as covered.
|
561
|
-
</span><span class='inferred0'>Lines considered as run by rcov, but not reported by Ruby, look like this,
|
562
|
-
</span><span class='inferred1'>and this: these lines were inferred by rcov (using simple heuristics).
|
563
|
-
</span><span class='uncovered0'>Finally, here's a line marked as not executed.
|
564
|
-
</span></pre>
|
565
|
-
<table class='report'><thead><tr><td class='heading'>Name</td>
|
566
|
-
<td class='heading'>Total lines</td>
|
567
|
-
<td class='heading'>Lines of code</td>
|
568
|
-
<td class='heading'>Total coverage</td>
|
569
|
-
<td class='heading'>Code coverage</td>
|
570
|
-
</tr>
|
571
|
-
</thead>
|
572
|
-
<tbody><tr class='light'><td><a href='-Library-Ruby-Gems-gems-rcov-0_8_1_2_0-lib-rcov_rb.html'>/Library/Ruby/Gems/gems/rcov-0.8.1.2.0/lib/rcov.rb</a>
|
573
|
-
</td>
|
574
|
-
<td class='lines_total'><tt>988</tt>
|
575
|
-
</td>
|
576
|
-
<td class='lines_code'><tt>602</tt>
|
577
|
-
</td>
|
578
|
-
<td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_total'>3.3%</tt>
|
579
|
-
</td>
|
580
|
-
<td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='3'/>
|
581
|
-
<td class='uncovered' width='97'/>
|
582
|
-
</tr>
|
583
|
-
</table>
|
584
|
-
</td>
|
585
|
-
</tr>
|
586
|
-
</table>
|
587
|
-
</td>
|
588
|
-
<td><table cellspacing='0' cellpadding='0' align='right'><tr><td><tt class='coverage_code'>2.8%</tt>
|
589
|
-
</td>
|
590
|
-
<td><table cellspacing='0' class='percent_graph' cellpadding='0' width='100'><tr><td class='covered' width='3'/>
|
591
|
-
<td class='uncovered' width='97'/>
|
592
|
-
</tr>
|
593
|
-
</table>
|
594
|
-
</td>
|
595
|
-
</tr>
|
596
|
-
</table>
|
597
|
-
</td>
|
598
|
-
</tr>
|
599
|
-
</tbody>
|
600
|
-
</table>
|
601
|
-
<pre><span class="uncovered1"><a name="line1"></a> 1 # rcov Copyright (c) 2004-2006 Mauricio Fernandez <mfp@acm.org>
|
602
|
-
</span><span class="uncovered0"><a name="line2"></a> 2 #
|
603
|
-
</span><span class="uncovered1"><a name="line3"></a> 3 # See LEGAL and LICENSE for licensing information.
|
604
|
-
</span><span class="uncovered0"><a name="line4"></a> 4
|
605
|
-
</span><span class="uncovered1"><a name="line5"></a> 5 # NOTE: if you're reading this in the XHTML code coverage report generated by
|
606
|
-
</span><span class="uncovered0"><a name="line6"></a> 6 # rcov, you'll notice that only code inside methods is reported as covered,
|
607
|
-
</span><span class="uncovered1"><a name="line7"></a> 7 # very much like what happens when you run it with --test-unit-only.
|
608
|
-
</span><span class="uncovered0"><a name="line8"></a> 8 # This is due to the fact that we're running rcov on itself: the code below is
|
609
|
-
</span><span class="uncovered1"><a name="line9"></a> 9 # already loaded before coverage tracing is activated, so only code inside
|
610
|
-
</span><span class="uncovered0"><a name="line10"></a> 10 # methods is actually executed under rcov's inspection.
|
611
|
-
</span><span class="uncovered1"><a name="line11"></a> 11
|
612
|
-
</span><span class="uncovered0"><a name="line12"></a> 12 require 'rcov/version'
|
613
|
-
</span><span class="uncovered1"><a name="line13"></a> 13
|
614
|
-
</span><span class="uncovered0"><a name="line14"></a> 14 SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
|
615
|
-
</span><span class="uncovered1"><a name="line15"></a> 15
|
616
|
-
</span><span class="uncovered0"><a name="line16"></a> 16 module Rcov
|
617
|
-
</span><span class="uncovered1"><a name="line17"></a> 17
|
618
|
-
</span><span class="uncovered0"><a name="line18"></a> 18 # Rcov::CoverageInfo is but a wrapper for an array, with some additional
|
619
|
-
</span><span class="uncovered1"><a name="line19"></a> 19 # checks. It is returned by FileStatistics#coverage.
|
620
|
-
</span><span class="uncovered0"><a name="line20"></a> 20 class CoverageInfo
|
621
|
-
</span><span class="uncovered1"><a name="line21"></a> 21 def initialize(coverage_array)
|
622
|
-
</span><span class="uncovered0"><a name="line22"></a> 22 @cover = coverage_array.clone
|
623
|
-
</span><span class="uncovered1"><a name="line23"></a> 23 end
|
624
|
-
</span><span class="uncovered0"><a name="line24"></a> 24
|
625
|
-
</span><span class="uncovered1"><a name="line25"></a> 25 # Return the coverage status for the requested line. There are four possible
|
626
|
-
</span><span class="uncovered0"><a name="line26"></a> 26 # return values:
|
627
|
-
</span><span class="uncovered1"><a name="line27"></a> 27 # * nil if there's no information for the requested line (i.e. it doesn't exist)
|
628
|
-
</span><span class="uncovered0"><a name="line28"></a> 28 # * true if the line was reported by Ruby as executed
|
629
|
-
</span><span class="uncovered1"><a name="line29"></a> 29 # * :inferred if rcov inferred it was executed, despite not being reported
|
630
|
-
</span><span class="uncovered0"><a name="line30"></a> 30 # by Ruby.
|
631
|
-
</span><span class="uncovered1"><a name="line31"></a> 31 # * false otherwise, i.e. if it was not reported by Ruby and rcov's
|
632
|
-
</span><span class="uncovered0"><a name="line32"></a> 32 # heuristics indicated that it was not executed
|
633
|
-
</span><span class="uncovered1"><a name="line33"></a> 33 def [](line)
|
634
|
-
</span><span class="uncovered0"><a name="line34"></a> 34 @cover[line]
|
635
|
-
</span><span class="uncovered1"><a name="line35"></a> 35 end
|
636
|
-
</span><span class="uncovered0"><a name="line36"></a> 36
|
637
|
-
</span><span class="uncovered1"><a name="line37"></a> 37 def []=(line, val) # :nodoc:
|
638
|
-
</span><span class="uncovered0"><a name="line38"></a> 38 unless [true, false, :inferred].include? val
|
639
|
-
</span><span class="uncovered1"><a name="line39"></a> 39 raise RuntimeError, "What does #{val} mean?"
|
640
|
-
</span><span class="uncovered0"><a name="line40"></a> 40 end
|
641
|
-
</span><span class="uncovered1"><a name="line41"></a> 41 return if line < 0 || line >= @cover.size
|
642
|
-
</span><span class="uncovered0"><a name="line42"></a> 42 @cover[line] = val
|
643
|
-
</span><span class="uncovered1"><a name="line43"></a> 43 end
|
644
|
-
</span><span class="uncovered0"><a name="line44"></a> 44
|
645
|
-
</span><span class="uncovered1"><a name="line45"></a> 45 # Return an Array holding the code coverage information.
|
646
|
-
</span><span class="uncovered0"><a name="line46"></a> 46 def to_a
|
647
|
-
</span><span class="uncovered1"><a name="line47"></a> 47 @cover.clone
|
648
|
-
</span><span class="uncovered0"><a name="line48"></a> 48 end
|
649
|
-
</span><span class="uncovered1"><a name="line49"></a> 49
|
650
|
-
</span><span class="uncovered0"><a name="line50"></a> 50 def method_missing(meth, *a, &b) # :nodoc:
|
651
|
-
</span><span class="uncovered1"><a name="line51"></a> 51 @cover.send(meth, *a, &b)
|
652
|
-
</span><span class="uncovered0"><a name="line52"></a> 52 end
|
653
|
-
</span><span class="uncovered1"><a name="line53"></a> 53 end
|
654
|
-
</span><span class="uncovered0"><a name="line54"></a> 54
|
655
|
-
</span><span class="uncovered1"><a name="line55"></a> 55 # A FileStatistics object associates a filename to:
|
656
|
-
</span><span class="uncovered0"><a name="line56"></a> 56 # 1. its source code
|
657
|
-
</span><span class="uncovered1"><a name="line57"></a> 57 # 2. the per-line coverage information after correction using rcov's heuristics
|
658
|
-
</span><span class="uncovered0"><a name="line58"></a> 58 # 3. the per-line execution counts
|
659
|
-
</span><span class="uncovered1"><a name="line59"></a> 59 #
|
660
|
-
</span><span class="uncovered0"><a name="line60"></a> 60 # A FileStatistics object can be therefore be built given the filename, the
|
661
|
-
</span><span class="uncovered1"><a name="line61"></a> 61 # associated source code, and an array holding execution counts (i.e. how many
|
662
|
-
</span><span class="uncovered0"><a name="line62"></a> 62 # times each line has been executed).
|
663
|
-
</span><span class="uncovered1"><a name="line63"></a> 63 #
|
664
|
-
</span><span class="uncovered0"><a name="line64"></a> 64 # FileStatistics is relatively intelligent: it handles normal comments,
|
665
|
-
</span><span class="uncovered1"><a name="line65"></a> 65 # <tt>=begin/=end</tt>, heredocs, many multiline-expressions... It uses a
|
666
|
-
</span><span class="uncovered0"><a name="line66"></a> 66 # number of heuristics to determine what is code and what is a comment, and to
|
667
|
-
</span><span class="uncovered1"><a name="line67"></a> 67 # refine the initial (incomplete) coverage information.
|
668
|
-
</span><span class="uncovered0"><a name="line68"></a> 68 #
|
669
|
-
</span><span class="uncovered1"><a name="line69"></a> 69 # Basic usage is as follows:
|
670
|
-
</span><span class="uncovered0"><a name="line70"></a> 70 # sf = FileStatistics.new("foo.rb", ["puts 1", "if true &&", " false",
|
671
|
-
</span><span class="uncovered1"><a name="line71"></a> 71 # "puts 2", "end"], [1, 1, 0, 0, 0])
|
672
|
-
</span><span class="uncovered0"><a name="line72"></a> 72 # sf.num_lines # => 5
|
673
|
-
</span><span class="uncovered1"><a name="line73"></a> 73 # sf.num_code_lines # => 5
|
674
|
-
</span><span class="uncovered0"><a name="line74"></a> 74 # sf.coverage[2] # => true
|
675
|
-
</span><span class="uncovered1"><a name="line75"></a> 75 # sf.coverage[3] # => :inferred
|
676
|
-
</span><span class="uncovered0"><a name="line76"></a> 76 # sf.code_coverage # => 0.6
|
677
|
-
</span><span class="uncovered1"><a name="line77"></a> 77 #
|
678
|
-
</span><span class="uncovered0"><a name="line78"></a> 78 # The array of strings representing the source code and the array of execution
|
679
|
-
</span><span class="uncovered1"><a name="line79"></a> 79 # counts would normally be obtained from a Rcov::CodeCoverageAnalyzer.
|
680
|
-
</span><span class="uncovered0"><a name="line80"></a> 80 class FileStatistics
|
681
|
-
</span><span class="uncovered1"><a name="line81"></a> 81 attr_reader :name, :lines, :coverage, :counts
|
682
|
-
</span><span class="uncovered0"><a name="line82"></a> 82 def initialize(name, lines, counts, comments_run_by_default = false)
|
683
|
-
</span><span class="uncovered1"><a name="line83"></a> 83 @name = name
|
684
|
-
</span><span class="uncovered0"><a name="line84"></a> 84 @lines = lines
|
685
|
-
</span><span class="uncovered1"><a name="line85"></a> 85 initial_coverage = counts.map{|x| (x || 0) > 0 ? true : false }
|
686
|
-
</span><span class="uncovered0"><a name="line86"></a> 86 @coverage = CoverageInfo.new initial_coverage
|
687
|
-
</span><span class="uncovered1"><a name="line87"></a> 87 @counts = counts
|
688
|
-
</span><span class="uncovered0"><a name="line88"></a> 88 @is_begin_comment = nil
|
689
|
-
</span><span class="uncovered1"><a name="line89"></a> 89 # points to the line defining the heredoc identifier
|
690
|
-
</span><span class="uncovered0"><a name="line90"></a> 90 # but only if it was marked (we don't care otherwise)
|
691
|
-
</span><span class="uncovered1"><a name="line91"></a> 91 @heredoc_start = Array.new(lines.size, false)
|
692
|
-
</span><span class="uncovered0"><a name="line92"></a> 92 @multiline_string_start = Array.new(lines.size, false)
|
693
|
-
</span><span class="uncovered1"><a name="line93"></a> 93 extend_heredocs
|
694
|
-
</span><span class="uncovered0"><a name="line94"></a> 94 find_multiline_strings
|
695
|
-
</span><span class="uncovered1"><a name="line95"></a> 95 precompute_coverage comments_run_by_default
|
696
|
-
</span><span class="uncovered0"><a name="line96"></a> 96 end
|
697
|
-
</span><span class="uncovered1"><a name="line97"></a> 97
|
698
|
-
</span><span class="uncovered0"><a name="line98"></a> 98 # Merge code coverage and execution count information.
|
699
|
-
</span><span class="uncovered1"><a name="line99"></a> 99 # As for code coverage, a line will be considered
|
700
|
-
</span><span class="uncovered0"><a name="line100"></a>100 # * covered for sure (true) if it is covered in either +self+ or in the
|
701
|
-
</span><span class="uncovered1"><a name="line101"></a>101 # +coverage+ array
|
702
|
-
</span><span class="uncovered0"><a name="line102"></a>102 # * considered <tt>:inferred</tt> if the neither +self+ nor the +coverage+ array
|
703
|
-
</span><span class="uncovered1"><a name="line103"></a>103 # indicate that it was definitely executed, but it was <tt>inferred</tt>
|
704
|
-
</span><span class="uncovered0"><a name="line104"></a>104 # in either one
|
705
|
-
</span><span class="uncovered1"><a name="line105"></a>105 # * not covered (<tt>false</tt>) if it was uncovered in both
|
706
|
-
</span><span class="uncovered0"><a name="line106"></a>106 #
|
707
|
-
</span><span class="uncovered1"><a name="line107"></a>107 # Execution counts are just summated on a per-line basis.
|
708
|
-
</span><span class="uncovered0"><a name="line108"></a>108 def merge(lines, coverage, counts)
|
709
|
-
</span><span class="uncovered1"><a name="line109"></a>109 coverage.each_with_index do |v, idx|
|
710
|
-
</span><span class="uncovered0"><a name="line110"></a>110 case @coverage[idx]
|
711
|
-
</span><span class="uncovered1"><a name="line111"></a>111 when :inferred
|
712
|
-
</span><span class="uncovered0"><a name="line112"></a>112 @coverage[idx] = v || @coverage[idx]
|
713
|
-
</span><span class="uncovered1"><a name="line113"></a>113 when false
|
714
|
-
</span><span class="uncovered0"><a name="line114"></a>114 @coverage[idx] ||= v
|
715
|
-
</span><span class="uncovered1"><a name="line115"></a>115 end
|
716
|
-
</span><span class="uncovered0"><a name="line116"></a>116 end
|
717
|
-
</span><span class="uncovered1"><a name="line117"></a>117 counts.each_with_index{|v, idx| @counts[idx] += v }
|
718
|
-
</span><span class="uncovered0"><a name="line118"></a>118 precompute_coverage false
|
719
|
-
</span><span class="uncovered1"><a name="line119"></a>119 end
|
720
|
-
</span><span class="uncovered0"><a name="line120"></a>120
|
721
|
-
</span><span class="uncovered1"><a name="line121"></a>121 # Total coverage rate if comments are also considered "executable", given as
|
722
|
-
</span><span class="uncovered0"><a name="line122"></a>122 # a fraction, i.e. from 0 to 1.0.
|
723
|
-
</span><span class="uncovered1"><a name="line123"></a>123 # A comment is attached to the code following it (RDoc-style): it will be
|
724
|
-
</span><span class="uncovered0"><a name="line124"></a>124 # considered executed if the the next statement was executed.
|
725
|
-
</span><span class="uncovered1"><a name="line125"></a>125 def total_coverage
|
726
|
-
</span><span class="uncovered0"><a name="line126"></a>126 return 0 if @coverage.size == 0
|
727
|
-
</span><span class="uncovered1"><a name="line127"></a>127 @coverage.inject(0.0) {|s,a| s + (a ? 1:0) } / @coverage.size
|
728
|
-
</span><span class="uncovered0"><a name="line128"></a>128 end
|
729
|
-
</span><span class="uncovered1"><a name="line129"></a>129
|
730
|
-
</span><span class="uncovered0"><a name="line130"></a>130 # Code coverage rate: fraction of lines of code executed, relative to the
|
731
|
-
</span><span class="uncovered1"><a name="line131"></a>131 # total amount of lines of code (loc). Returns a float from 0 to 1.0.
|
732
|
-
</span><span class="uncovered0"><a name="line132"></a>132 def code_coverage
|
733
|
-
</span><span class="uncovered1"><a name="line133"></a>133 indices = (0...@lines.size).select{|i| is_code? i }
|
734
|
-
</span><span class="uncovered0"><a name="line134"></a>134 return 0 if indices.size == 0
|
735
|
-
</span><span class="uncovered1"><a name="line135"></a>135 count = 0
|
736
|
-
</span><span class="uncovered0"><a name="line136"></a>136 indices.each {|i| count += 1 if @coverage[i] }
|
737
|
-
</span><span class="uncovered1"><a name="line137"></a>137 1.0 * count / indices.size
|
738
|
-
</span><span class="uncovered0"><a name="line138"></a>138 end
|
739
|
-
</span><span class="uncovered1"><a name="line139"></a>139
|
740
|
-
</span><span class="uncovered0"><a name="line140"></a>140 # Number of lines of code (loc).
|
741
|
-
</span><span class="uncovered1"><a name="line141"></a>141 def num_code_lines
|
742
|
-
</span><span class="uncovered0"><a name="line142"></a>142 (0...@lines.size).select{|i| is_code? i}.size
|
743
|
-
</span><span class="uncovered1"><a name="line143"></a>143 end
|
744
|
-
</span><span class="uncovered0"><a name="line144"></a>144
|
745
|
-
</span><span class="uncovered1"><a name="line145"></a>145 # Total number of lines.
|
746
|
-
</span><span class="uncovered0"><a name="line146"></a>146 def num_lines
|
747
|
-
</span><span class="uncovered1"><a name="line147"></a>147 @lines.size
|
748
|
-
</span><span class="uncovered0"><a name="line148"></a>148 end
|
749
|
-
</span><span class="uncovered1"><a name="line149"></a>149
|
750
|
-
</span><span class="uncovered0"><a name="line150"></a>150 # Returns true if the given line number corresponds to code, as opposed to a
|
751
|
-
</span><span class="uncovered1"><a name="line151"></a>151 # comment (either # or =begin/=end blocks).
|
752
|
-
</span><span class="uncovered0"><a name="line152"></a>152 def is_code?(lineno)
|
753
|
-
</span><span class="uncovered1"><a name="line153"></a>153 unless @is_begin_comment
|
754
|
-
</span><span class="uncovered0"><a name="line154"></a>154 @is_begin_comment = Array.new(@lines.size, false)
|
755
|
-
</span><span class="uncovered1"><a name="line155"></a>155 pending = []
|
756
|
-
</span><span class="uncovered0"><a name="line156"></a>156 state = :code
|
757
|
-
</span><span class="uncovered1"><a name="line157"></a>157 @lines.each_with_index do |line, index|
|
758
|
-
</span><span class="uncovered0"><a name="line158"></a>158 case state
|
759
|
-
</span><span class="uncovered1"><a name="line159"></a>159 when :code
|
760
|
-
</span><span class="uncovered0"><a name="line160"></a>160 if /^=begin\b/ =~ line
|
761
|
-
</span><span class="uncovered1"><a name="line161"></a>161 state = :comment
|
762
|
-
</span><span class="uncovered0"><a name="line162"></a>162 pending << index
|
763
|
-
</span><span class="uncovered1"><a name="line163"></a>163 end
|
764
|
-
</span><span class="uncovered0"><a name="line164"></a>164 when :comment
|
765
|
-
</span><span class="uncovered1"><a name="line165"></a>165 pending << index
|
766
|
-
</span><span class="uncovered0"><a name="line166"></a>166 if /^=end\b/ =~ line
|
767
|
-
</span><span class="uncovered1"><a name="line167"></a>167 state = :code
|
768
|
-
</span><span class="uncovered0"><a name="line168"></a>168 pending.each{|idx| @is_begin_comment[idx] = true}
|
769
|
-
</span><span class="uncovered1"><a name="line169"></a>169 pending.clear
|
770
|
-
</span><span class="uncovered0"><a name="line170"></a>170 end
|
771
|
-
</span><span class="uncovered1"><a name="line171"></a>171 end
|
772
|
-
</span><span class="uncovered0"><a name="line172"></a>172 end
|
773
|
-
</span><span class="uncovered1"><a name="line173"></a>173 end
|
774
|
-
</span><span class="uncovered0"><a name="line174"></a>174 @lines[lineno] && !@is_begin_comment[lineno] &&
|
775
|
-
</span><span class="uncovered1"><a name="line175"></a>175 @lines[lineno] !~ /^\s*(#|$)/
|
776
|
-
</span><span class="uncovered0"><a name="line176"></a>176 end
|
777
|
-
</span><span class="uncovered1"><a name="line177"></a>177
|
778
|
-
</span><span class="uncovered0"><a name="line178"></a>178 private
|
779
|
-
</span><span class="uncovered1"><a name="line179"></a>179
|
780
|
-
</span><span class="uncovered0"><a name="line180"></a>180 def find_multiline_strings
|
781
|
-
</span><span class="uncovered1"><a name="line181"></a>181 state = :awaiting_string
|
782
|
-
</span><span class="uncovered0"><a name="line182"></a>182 wanted_delimiter = nil
|
783
|
-
</span><span class="uncovered1"><a name="line183"></a>183 string_begin_line = 0
|
784
|
-
</span><span class="uncovered0"><a name="line184"></a>184 @lines.each_with_index do |line, i|
|
785
|
-
</span><span class="uncovered1"><a name="line185"></a>185 matching_delimiters = Hash.new{|h,k| k}
|
786
|
-
</span><span class="uncovered0"><a name="line186"></a>186 matching_delimiters.update("{" => "}", "[" => "]", "(" => ")")
|
787
|
-
</span><span class="uncovered1"><a name="line187"></a>187 case state
|
788
|
-
</span><span class="uncovered0"><a name="line188"></a>188 when :awaiting_string
|
789
|
-
</span><span class="uncovered1"><a name="line189"></a>189 # very conservative, doesn't consider the last delimited string but
|
790
|
-
</span><span class="uncovered0"><a name="line190"></a>190 # only the very first one
|
791
|
-
</span><span class="uncovered1"><a name="line191"></a>191 if md = /^[^#]*%(?:[qQ])?(.)/.match(line)
|
792
|
-
</span><span class="uncovered0"><a name="line192"></a>192 wanted_delimiter = /(?!\\).#{Regexp.escape(matching_delimiters[md[1]])}/
|
793
|
-
</span><span class="uncovered1"><a name="line193"></a>193 # check if closed on the very same line
|
794
|
-
</span><span class="uncovered0"><a name="line194"></a>194 # conservative again, we might have several quoted strings with the
|
795
|
-
</span><span class="uncovered1"><a name="line195"></a>195 # same delimiter on the same line, leaving the last one open
|
796
|
-
</span><span class="uncovered0"><a name="line196"></a>196 unless wanted_delimiter.match(md.post_match)
|
797
|
-
</span><span class="uncovered1"><a name="line197"></a>197 state = :want_end_delimiter
|
798
|
-
</span><span class="uncovered0"><a name="line198"></a>198 string_begin_line = i
|
799
|
-
</span><span class="uncovered1"><a name="line199"></a>199 end
|
800
|
-
</span><span class="uncovered0"><a name="line200"></a>200 end
|
801
|
-
</span><span class="uncovered1"><a name="line201"></a>201 when :want_end_delimiter
|
802
|
-
</span><span class="uncovered0"><a name="line202"></a>202 @multiline_string_start[i] = string_begin_line
|
803
|
-
</span><span class="uncovered1"><a name="line203"></a>203 if wanted_delimiter.match(line)
|
804
|
-
</span><span class="uncovered0"><a name="line204"></a>204 state = :awaiting_string
|
805
|
-
</span><span class="uncovered1"><a name="line205"></a>205 end
|
806
|
-
</span><span class="uncovered0"><a name="line206"></a>206 end
|
807
|
-
</span><span class="uncovered1"><a name="line207"></a>207 end
|
808
|
-
</span><span class="uncovered0"><a name="line208"></a>208 end
|
809
|
-
</span><span class="uncovered1"><a name="line209"></a>209
|
810
|
-
</span><span class="uncovered0"><a name="line210"></a>210 def precompute_coverage(comments_run_by_default = true)
|
811
|
-
</span><span class="uncovered1"><a name="line211"></a>211 changed = false
|
812
|
-
</span><span class="uncovered0"><a name="line212"></a>212 lastidx = lines.size - 1
|
813
|
-
</span><span class="uncovered1"><a name="line213"></a>213 if (!is_code?(lastidx) || /^__END__$/ =~ @lines[-1]) && !@coverage[lastidx]
|
814
|
-
</span><span class="uncovered0"><a name="line214"></a>214 # mark the last block of comments
|
815
|
-
</span><span class="uncovered1"><a name="line215"></a>215 @coverage[lastidx] ||= :inferred
|
816
|
-
</span><span class="uncovered0"><a name="line216"></a>216 (lastidx-1).downto(0) do |i|
|
817
|
-
</span><span class="uncovered1"><a name="line217"></a>217 break if is_code?(i)
|
818
|
-
</span><span class="uncovered0"><a name="line218"></a>218 @coverage[i] ||= :inferred
|
819
|
-
</span><span class="uncovered1"><a name="line219"></a>219 end
|
820
|
-
</span><span class="uncovered0"><a name="line220"></a>220 end
|
821
|
-
</span><span class="uncovered1"><a name="line221"></a>221 (0...lines.size).each do |i|
|
822
|
-
</span><span class="uncovered0"><a name="line222"></a>222 next if @coverage[i]
|
823
|
-
</span><span class="uncovered1"><a name="line223"></a>223 line = @lines[i]
|
824
|
-
</span><span class="uncovered0"><a name="line224"></a>224 if /^\s*(begin|ensure|else|case)\s*(?:#.*)?$/ =~ line && next_expr_marked?(i) or
|
825
|
-
</span><span class="uncovered1"><a name="line225"></a>225 /^\s*(?:end|\})\s*(?:#.*)?$/ =~ line && prev_expr_marked?(i) or
|
826
|
-
</span><span class="uncovered0"><a name="line226"></a>226 /^\s*(?:end\b|\})/ =~ line && prev_expr_marked?(i) && next_expr_marked?(i) or
|
827
|
-
</span><span class="uncovered1"><a name="line227"></a>227 /^\s*rescue\b/ =~ line && next_expr_marked?(i) or
|
828
|
-
</span><span class="uncovered0"><a name="line228"></a>228 /(do|\{)\s*(\|[^|]*\|\s*)?(?:#.*)?$/ =~ line && next_expr_marked?(i) or
|
829
|
-
</span><span class="uncovered1"><a name="line229"></a>229 prev_expr_continued?(i) && prev_expr_marked?(i) or
|
830
|
-
</span><span class="uncovered0"><a name="line230"></a>230 comments_run_by_default && !is_code?(i) or
|
831
|
-
</span><span class="uncovered1"><a name="line231"></a>231 /^\s*((\)|\]|\})\s*)+(?:#.*)?$/ =~ line && prev_expr_marked?(i) or
|
832
|
-
</span><span class="uncovered0"><a name="line232"></a>232 prev_expr_continued?(i+1) && next_expr_marked?(i)
|
833
|
-
</span><span class="uncovered1"><a name="line233"></a>233 @coverage[i] ||= :inferred
|
834
|
-
</span><span class="uncovered0"><a name="line234"></a>234 changed = true
|
835
|
-
</span><span class="uncovered1"><a name="line235"></a>235 end
|
836
|
-
</span><span class="uncovered0"><a name="line236"></a>236 end
|
837
|
-
</span><span class="uncovered1"><a name="line237"></a>237 (@lines.size-1).downto(0) do |i|
|
838
|
-
</span><span class="uncovered0"><a name="line238"></a>238 next if @coverage[i]
|
839
|
-
</span><span class="uncovered1"><a name="line239"></a>239 if !is_code?(i) and @coverage[i+1]
|
840
|
-
</span><span class="uncovered0"><a name="line240"></a>240 @coverage[i] = :inferred
|
841
|
-
</span><span class="uncovered1"><a name="line241"></a>241 changed = true
|
842
|
-
</span><span class="uncovered0"><a name="line242"></a>242 end
|
843
|
-
</span><span class="uncovered1"><a name="line243"></a>243 end
|
844
|
-
</span><span class="uncovered0"><a name="line244"></a>244
|
845
|
-
</span><span class="uncovered1"><a name="line245"></a>245 extend_heredocs if changed
|
846
|
-
</span><span class="uncovered0"><a name="line246"></a>246
|
847
|
-
</span><span class="uncovered1"><a name="line247"></a>247 # if there was any change, we have to recompute; we'll eventually
|
848
|
-
</span><span class="uncovered0"><a name="line248"></a>248 # reach a fixed point and stop there
|
849
|
-
</span><span class="uncovered1"><a name="line249"></a>249 precompute_coverage(comments_run_by_default) if changed
|
850
|
-
</span><span class="uncovered0"><a name="line250"></a>250 end
|
851
|
-
</span><span class="uncovered1"><a name="line251"></a>251
|
852
|
-
</span><span class="uncovered0"><a name="line252"></a>252 require 'strscan'
|
853
|
-
</span><span class="uncovered1"><a name="line253"></a>253 def extend_heredocs
|
854
|
-
</span><span class="uncovered0"><a name="line254"></a>254 i = 0
|
855
|
-
</span><span class="uncovered1"><a name="line255"></a>255 while i < @lines.size
|
856
|
-
</span><span class="uncovered0"><a name="line256"></a>256 unless is_code? i
|
857
|
-
</span><span class="uncovered1"><a name="line257"></a>257 i += 1
|
858
|
-
</span><span class="uncovered0"><a name="line258"></a>258 next
|
859
|
-
</span><span class="uncovered1"><a name="line259"></a>259 end
|
860
|
-
</span><span class="uncovered0"><a name="line260"></a>260 #FIXME: using a restrictive regexp so that only <<[A-Z_a-z]\w*
|
861
|
-
</span><span class="uncovered1"><a name="line261"></a>261 # matches when unquoted, so as to avoid problems with 1<<2
|
862
|
-
</span><span class="uncovered0"><a name="line262"></a>262 # (keep in mind that whereas puts <<2 is valid, puts 1<<2 is a
|
863
|
-
</span><span class="uncovered1"><a name="line263"></a>263 # parse error, but a = 1<<2 is of course fine)
|
864
|
-
</span><span class="uncovered0"><a name="line264"></a>264 scanner = StringScanner.new(@lines[i])
|
865
|
-
</span><span class="uncovered1"><a name="line265"></a>265 j = k = i
|
866
|
-
</span><span class="uncovered0"><a name="line266"></a>266 loop do
|
867
|
-
</span><span class="uncovered1"><a name="line267"></a>267 scanned_text = scanner.search_full(/<<(-?)(?:(['"`])((?:(?!\2).)+)\2|([A-Z_a-z]\w*))/,
|
868
|
-
</span><span class="uncovered0"><a name="line268"></a>268 true, true)
|
869
|
-
</span><span class="uncovered1"><a name="line269"></a>269 # k is the first line after the end delimiter for the last heredoc
|
870
|
-
</span><span class="uncovered0"><a name="line270"></a>270 # scanned so far
|
871
|
-
</span><span class="uncovered1"><a name="line271"></a>271 unless scanner.matched?
|
872
|
-
</span><span class="uncovered0"><a name="line272"></a>272 i = k
|
873
|
-
</span><span class="uncovered1"><a name="line273"></a>273 break
|
874
|
-
</span><span class="uncovered0"><a name="line274"></a>274 end
|
875
|
-
</span><span class="uncovered1"><a name="line275"></a>275 term = scanner[3] || scanner[4]
|
876
|
-
</span><span class="uncovered0"><a name="line276"></a>276 # try to ignore symbolic bitshifts like 1<<LSHIFT
|
877
|
-
</span><span class="uncovered1"><a name="line277"></a>277 ident_text = "<<#{scanner[1]}#{scanner[2]}#{term}#{scanner[2]}"
|
878
|
-
</span><span class="uncovered0"><a name="line278"></a>278 if scanned_text[/\d+\s*#{Regexp.escape(ident_text)}/]
|
879
|
-
</span><span class="uncovered1"><a name="line279"></a>279 # it was preceded by a number, ignore
|
880
|
-
</span><span class="uncovered0"><a name="line280"></a>280 i = k
|
881
|
-
</span><span class="uncovered1"><a name="line281"></a>281 break
|
882
|
-
</span><span class="uncovered0"><a name="line282"></a>282 end
|
883
|
-
</span><span class="uncovered1"><a name="line283"></a>283 must_mark = []
|
884
|
-
</span><span class="uncovered0"><a name="line284"></a>284 end_of_heredoc = (scanner[1] == "-") ?
|
885
|
-
</span><span class="uncovered1"><a name="line285"></a>285 /^\s*#{Regexp.escape(term)}$/ : /^#{Regexp.escape(term)}$/
|
886
|
-
</span><span class="uncovered0"><a name="line286"></a>286 loop do
|
887
|
-
</span><span class="uncovered1"><a name="line287"></a>287 break if j == @lines.size
|
888
|
-
</span><span class="uncovered0"><a name="line288"></a>288 must_mark << j
|
889
|
-
</span><span class="uncovered1"><a name="line289"></a>289 if end_of_heredoc =~ @lines[j]
|
890
|
-
</span><span class="uncovered0"><a name="line290"></a>290 must_mark.each do |n|
|
891
|
-
</span><span class="uncovered1"><a name="line291"></a>291 @heredoc_start[n] = i
|
892
|
-
</span><span class="uncovered0"><a name="line292"></a>292 end
|
893
|
-
</span><span class="uncovered1"><a name="line293"></a>293 if (must_mark + [i]).any?{|lineidx| @coverage[lineidx]}
|
894
|
-
</span><span class="uncovered0"><a name="line294"></a>294 @coverage[i] ||= :inferred
|
895
|
-
</span><span class="uncovered1"><a name="line295"></a>295 must_mark.each{|lineidx| @coverage[lineidx] ||= :inferred}
|
896
|
-
</span><span class="uncovered0"><a name="line296"></a>296 end
|
897
|
-
</span><span class="uncovered1"><a name="line297"></a>297 # move the "first line after heredocs" index
|
898
|
-
</span><span class="uncovered0"><a name="line298"></a>298 k = (j += 1)
|
899
|
-
</span><span class="uncovered1"><a name="line299"></a>299 break
|
900
|
-
</span><span class="uncovered0"><a name="line300"></a>300 end
|
901
|
-
</span><span class="uncovered1"><a name="line301"></a>301 j += 1
|
902
|
-
</span><span class="uncovered0"><a name="line302"></a>302 end
|
903
|
-
</span><span class="uncovered1"><a name="line303"></a>303 end
|
904
|
-
</span><span class="uncovered0"><a name="line304"></a>304
|
905
|
-
</span><span class="uncovered1"><a name="line305"></a>305 i += 1
|
906
|
-
</span><span class="uncovered0"><a name="line306"></a>306 end
|
907
|
-
</span><span class="uncovered1"><a name="line307"></a>307 end
|
908
|
-
</span><span class="uncovered0"><a name="line308"></a>308
|
909
|
-
</span><span class="uncovered1"><a name="line309"></a>309 def next_expr_marked?(lineno)
|
910
|
-
</span><span class="uncovered0"><a name="line310"></a>310 return false if lineno >= @lines.size
|
911
|
-
</span><span class="uncovered1"><a name="line311"></a>311 found = false
|
912
|
-
</span><span class="uncovered0"><a name="line312"></a>312 idx = (lineno+1).upto(@lines.size-1) do |i|
|
913
|
-
</span><span class="uncovered1"><a name="line313"></a>313 next unless is_code? i
|
914
|
-
</span><span class="uncovered0"><a name="line314"></a>314 found = true
|
915
|
-
</span><span class="uncovered1"><a name="line315"></a>315 break i
|
916
|
-
</span><span class="uncovered0"><a name="line316"></a>316 end
|
917
|
-
</span><span class="uncovered1"><a name="line317"></a>317 return false unless found
|
918
|
-
</span><span class="uncovered0"><a name="line318"></a>318 @coverage[idx]
|
919
|
-
</span><span class="uncovered1"><a name="line319"></a>319 end
|
920
|
-
</span><span class="uncovered0"><a name="line320"></a>320
|
921
|
-
</span><span class="uncovered1"><a name="line321"></a>321 def prev_expr_marked?(lineno)
|
922
|
-
</span><span class="uncovered0"><a name="line322"></a>322 return false if lineno <= 0
|
923
|
-
</span><span class="uncovered1"><a name="line323"></a>323 found = false
|
924
|
-
</span><span class="uncovered0"><a name="line324"></a>324 idx = (lineno-1).downto(0) do |i|
|
925
|
-
</span><span class="uncovered1"><a name="line325"></a>325 next unless is_code? i
|
926
|
-
</span><span class="uncovered0"><a name="line326"></a>326 found = true
|
927
|
-
</span><span class="uncovered1"><a name="line327"></a>327 break i
|
928
|
-
</span><span class="uncovered0"><a name="line328"></a>328 end
|
929
|
-
</span><span class="uncovered1"><a name="line329"></a>329 return false unless found
|
930
|
-
</span><span class="uncovered0"><a name="line330"></a>330 @coverage[idx]
|
931
|
-
</span><span class="uncovered1"><a name="line331"></a>331 end
|
932
|
-
</span><span class="uncovered0"><a name="line332"></a>332
|
933
|
-
</span><span class="uncovered1"><a name="line333"></a>333 def prev_expr_continued?(lineno)
|
934
|
-
</span><span class="uncovered0"><a name="line334"></a>334 return false if lineno <= 0
|
935
|
-
</span><span class="uncovered1"><a name="line335"></a>335 return false if lineno >= @lines.size
|
936
|
-
</span><span class="uncovered0"><a name="line336"></a>336 found = false
|
937
|
-
</span><span class="uncovered1"><a name="line337"></a>337 if @multiline_string_start[lineno] &&
|
938
|
-
</span><span class="uncovered0"><a name="line338"></a>338 @multiline_string_start[lineno] < lineno
|
939
|
-
</span><span class="uncovered1"><a name="line339"></a>339 return true
|
940
|
-
</span><span class="uncovered0"><a name="line340"></a>340 end
|
941
|
-
</span><span class="uncovered1"><a name="line341"></a>341 # find index of previous code line
|
942
|
-
</span><span class="uncovered0"><a name="line342"></a>342 idx = (lineno-1).downto(0) do |i|
|
943
|
-
</span><span class="uncovered1"><a name="line343"></a>343 if @heredoc_start[i]
|
944
|
-
</span><span class="uncovered0"><a name="line344"></a>344 found = true
|
945
|
-
</span><span class="uncovered1"><a name="line345"></a>345 break @heredoc_start[i]
|
946
|
-
</span><span class="uncovered0"><a name="line346"></a>346 end
|
947
|
-
</span><span class="uncovered1"><a name="line347"></a>347 next unless is_code? i
|
948
|
-
</span><span class="uncovered0"><a name="line348"></a>348 found = true
|
949
|
-
</span><span class="uncovered1"><a name="line349"></a>349 break i
|
950
|
-
</span><span class="uncovered0"><a name="line350"></a>350 end
|
951
|
-
</span><span class="uncovered1"><a name="line351"></a>351 return false unless found
|
952
|
-
</span><span class="uncovered0"><a name="line352"></a>352 #TODO: write a comprehensive list
|
953
|
-
</span><span class="uncovered1"><a name="line353"></a>353 if is_code?(lineno) && /^\s*((\)|\]|\})\s*)+(?:#.*)?$/.match(@lines[lineno])
|
954
|
-
</span><span class="uncovered0"><a name="line354"></a>354 return true
|
955
|
-
</span><span class="uncovered1"><a name="line355"></a>355 end
|
956
|
-
</span><span class="uncovered0"><a name="line356"></a>356 #FIXME: / matches regexps too
|
957
|
-
</span><span class="uncovered1"><a name="line357"></a>357 # the following regexp tries to reject #{interpolation}
|
958
|
-
</span><span class="uncovered0"><a name="line358"></a>358 r = /(,|\.|\+|-|\*|\/|<|>|%|&&|\|\||<<|\(|\[|\{|=|and|or|\\)\s*(?:#(?![{$@]).*)?$/.match @lines[idx]
|
959
|
-
</span><span class="uncovered1"><a name="line359"></a>359 # try to see if a multi-line expression with opening, closing delimiters
|
960
|
-
</span><span class="uncovered0"><a name="line360"></a>360 # started on that line
|
961
|
-
</span><span class="uncovered1"><a name="line361"></a>361 [%w!( )!].each do |opening_str, closing_str|
|
962
|
-
</span><span class="uncovered0"><a name="line362"></a>362 # conservative: only consider nesting levels opened in that line, not
|
963
|
-
</span><span class="uncovered1"><a name="line363"></a>363 # previous ones too.
|
964
|
-
</span><span class="uncovered0"><a name="line364"></a>364 # next regexp considers interpolation too
|
965
|
-
</span><span class="uncovered1"><a name="line365"></a>365 line = @lines[idx].gsub(/#(?![{$@]).*$/, "")
|
966
|
-
</span><span class="uncovered0"><a name="line366"></a>366 opened = line.scan(/#{Regexp.escape(opening_str)}/).size
|
967
|
-
</span><span class="uncovered1"><a name="line367"></a>367 closed = line.scan(/#{Regexp.escape(closing_str)}/).size
|
968
|
-
</span><span class="uncovered0"><a name="line368"></a>368 return true if opened - closed > 0
|
969
|
-
</span><span class="uncovered1"><a name="line369"></a>369 end
|
970
|
-
</span><span class="uncovered0"><a name="line370"></a>370 if /(do|\{)\s*\|[^|]*\|\s*(?:#.*)?$/.match @lines[idx]
|
971
|
-
</span><span class="uncovered1"><a name="line371"></a>371 return false
|
972
|
-
</span><span class="uncovered0"><a name="line372"></a>372 end
|
973
|
-
</span><span class="uncovered1"><a name="line373"></a>373
|
974
|
-
</span><span class="uncovered0"><a name="line374"></a>374 r
|
975
|
-
</span><span class="uncovered1"><a name="line375"></a>375 end
|
976
|
-
</span><span class="uncovered0"><a name="line376"></a>376 end
|
977
|
-
</span><span class="uncovered1"><a name="line377"></a>377
|
978
|
-
</span><span class="uncovered0"><a name="line378"></a>378
|
979
|
-
</span><span class="uncovered1"><a name="line379"></a>379 autoload :RCOV__, "rcov/lowlevel.rb"
|
980
|
-
</span><span class="uncovered0"><a name="line380"></a>380
|
981
|
-
</span><span class="uncovered1"><a name="line381"></a>381 class DifferentialAnalyzer
|
982
|
-
</span><span class="uncovered0"><a name="line382"></a>382 require 'thread'
|
983
|
-
</span><span class="uncovered1"><a name="line383"></a>383 @@mutex = Mutex.new
|
984
|
-
</span><span class="uncovered0"><a name="line384"></a>384
|
985
|
-
</span><span class="uncovered1"><a name="line385"></a>385 def initialize(install_hook_meth, remove_hook_meth, reset_meth)
|
986
|
-
</span><span class="uncovered0"><a name="line386"></a>386 @cache_state = :wait
|
987
|
-
</span><span class="uncovered1"><a name="line387"></a>387 @start_raw_data = data_default
|
988
|
-
</span><span class="uncovered0"><a name="line388"></a>388 @end_raw_data = data_default
|
989
|
-
</span><span class="uncovered1"><a name="line389"></a>389 @aggregated_data = data_default
|
990
|
-
</span><span class="uncovered0"><a name="line390"></a>390 @install_hook_meth = install_hook_meth
|
991
|
-
</span><span class="uncovered1"><a name="line391"></a>391 @remove_hook_meth= remove_hook_meth
|
992
|
-
</span><span class="uncovered0"><a name="line392"></a>392 @reset_meth= reset_meth
|
993
|
-
</span><span class="uncovered1"><a name="line393"></a>393 end
|
994
|
-
</span><span class="uncovered0"><a name="line394"></a>394
|
995
|
-
</span><span class="uncovered1"><a name="line395"></a>395 # Execute the code in the given block, monitoring it in order to gather
|
996
|
-
</span><span class="uncovered0"><a name="line396"></a>396 # information about which code was executed.
|
997
|
-
</span><span class="uncovered1"><a name="line397"></a>397 def run_hooked
|
998
|
-
</span><span class="uncovered0"><a name="line398"></a>398 install_hook
|
999
|
-
</span><span class="uncovered1"><a name="line399"></a>399 yield
|
1000
|
-
</span><span class="uncovered0"><a name="line400"></a>400 ensure
|
1001
|
-
</span><span class="uncovered1"><a name="line401"></a>401 remove_hook
|
1002
|
-
</span><span class="uncovered0"><a name="line402"></a>402 end
|
1003
|
-
</span><span class="uncovered1"><a name="line403"></a>403
|
1004
|
-
</span><span class="uncovered0"><a name="line404"></a>404 # Start monitoring execution to gather information. Such data will be
|
1005
|
-
</span><span class="uncovered1"><a name="line405"></a>405 # collected until #remove_hook is called.
|
1006
|
-
</span><span class="uncovered0"><a name="line406"></a>406 #
|
1007
|
-
</span><span class="uncovered1"><a name="line407"></a>407 # Use #run_hooked instead if possible.
|
1008
|
-
</span><span class="uncovered0"><a name="line408"></a>408 def install_hook
|
1009
|
-
</span><span class="marked1"><a name="line409"></a>409 @start_raw_data = raw_data_absolute
|
1010
|
-
</span><span class="uncovered0"><a name="line410"></a>410 Rcov::RCOV__.send(@install_hook_meth)
|
1011
|
-
</span><span class="marked1"><a name="line411"></a>411 @cache_state = :hooked
|
1012
|
-
</span><span class="marked0"><a name="line412"></a>412 @@mutex.synchronize{ self.class.hook_level += 1 }
|
1013
|
-
</span><span class="inferred1"><a name="line413"></a>413 end
|
1014
|
-
</span><span class="inferred0"><a name="line414"></a>414
|
1015
|
-
</span><span class="inferred1"><a name="line415"></a>415 # Stop collecting information.
|
1016
|
-
</span><span class="inferred0"><a name="line416"></a>416 # #remove_hook will also stop collecting info if it is run inside a
|
1017
|
-
</span><span class="inferred1"><a name="line417"></a>417 # #run_hooked block.
|
1018
|
-
</span><span class="marked0"><a name="line418"></a>418 def remove_hook
|
1019
|
-
</span><span class="marked1"><a name="line419"></a>419 @@mutex.synchronize do
|
1020
|
-
</span><span class="marked0"><a name="line420"></a>420 self.class.hook_level -= 1
|
1021
|
-
</span><span class="marked1"><a name="line421"></a>421 Rcov::RCOV__.send(@remove_hook_meth) if self.class.hook_level == 0
|
1022
|
-
</span><span class="inferred0"><a name="line422"></a>422 end
|
1023
|
-
</span><span class="uncovered1"><a name="line423"></a>423 @end_raw_data = raw_data_absolute
|
1024
|
-
</span><span class="uncovered0"><a name="line424"></a>424 @cache_state = :done
|
1025
|
-
</span><span class="uncovered1"><a name="line425"></a>425 # force computation of the stats for the traced code in this run;
|
1026
|
-
</span><span class="uncovered0"><a name="line426"></a>426 # we cannot simply let it be if self.class.hook_level == 0 because
|
1027
|
-
</span><span class="uncovered1"><a name="line427"></a>427 # some other analyzer could install a hook, causing the raw_data_absolute
|
1028
|
-
</span><span class="uncovered0"><a name="line428"></a>428 # to change again.
|
1029
|
-
</span><span class="uncovered1"><a name="line429"></a>429 # TODO: lazy computation of raw_data_relative, only when the hook gets
|
1030
|
-
</span><span class="uncovered0"><a name="line430"></a>430 # activated again.
|
1031
|
-
</span><span class="uncovered1"><a name="line431"></a>431 raw_data_relative
|
1032
|
-
</span><span class="uncovered0"><a name="line432"></a>432 end
|
1033
|
-
</span><span class="uncovered1"><a name="line433"></a>433
|
1034
|
-
</span><span class="uncovered0"><a name="line434"></a>434 # Remove the data collected so far. Further collection will start from
|
1035
|
-
</span><span class="uncovered1"><a name="line435"></a>435 # scratch.
|
1036
|
-
</span><span class="uncovered0"><a name="line436"></a>436 def reset
|
1037
|
-
</span><span class="uncovered1"><a name="line437"></a>437 @@mutex.synchronize do
|
1038
|
-
</span><span class="uncovered0"><a name="line438"></a>438 if self.class.hook_level == 0
|
1039
|
-
</span><span class="uncovered1"><a name="line439"></a>439 # Unfortunately there's no way to report this as covered with rcov:
|
1040
|
-
</span><span class="uncovered0"><a name="line440"></a>440 # if we run the tests under rcov self.class.hook_level will be >= 1 !
|
1041
|
-
</span><span class="uncovered1"><a name="line441"></a>441 # It is however executed when we run the tests normally.
|
1042
|
-
</span><span class="uncovered0"><a name="line442"></a>442 Rcov::RCOV__.send(@reset_meth)
|
1043
|
-
</span><span class="uncovered1"><a name="line443"></a>443 @start_raw_data = data_default
|
1044
|
-
</span><span class="uncovered0"><a name="line444"></a>444 @end_raw_data = data_default
|
1045
|
-
</span><span class="uncovered1"><a name="line445"></a>445 else
|
1046
|
-
</span><span class="uncovered0"><a name="line446"></a>446 @start_raw_data = @end_raw_data = raw_data_absolute
|
1047
|
-
</span><span class="uncovered1"><a name="line447"></a>447 end
|
1048
|
-
</span><span class="uncovered0"><a name="line448"></a>448 @raw_data_relative = data_default
|
1049
|
-
</span><span class="uncovered1"><a name="line449"></a>449 @aggregated_data = data_default
|
1050
|
-
</span><span class="uncovered0"><a name="line450"></a>450 end
|
1051
|
-
</span><span class="uncovered1"><a name="line451"></a>451 end
|
1052
|
-
</span><span class="uncovered0"><a name="line452"></a>452
|
1053
|
-
</span><span class="uncovered1"><a name="line453"></a>453 protected
|
1054
|
-
</span><span class="uncovered0"><a name="line454"></a>454
|
1055
|
-
</span><span class="uncovered1"><a name="line455"></a>455 def data_default
|
1056
|
-
</span><span class="uncovered0"><a name="line456"></a>456 raise "must be implemented by the subclass"
|
1057
|
-
</span><span class="uncovered1"><a name="line457"></a>457 end
|
1058
|
-
</span><span class="uncovered0"><a name="line458"></a>458
|
1059
|
-
</span><span class="uncovered1"><a name="line459"></a>459 def self.hook_level
|
1060
|
-
</span><span class="uncovered0"><a name="line460"></a>460 raise "must be implemented by the subclass"
|
1061
|
-
</span><span class="uncovered1"><a name="line461"></a>461 end
|
1062
|
-
</span><span class="uncovered0"><a name="line462"></a>462
|
1063
|
-
</span><span class="uncovered1"><a name="line463"></a>463 def raw_data_absolute
|
1064
|
-
</span><span class="uncovered0"><a name="line464"></a>464 raise "must be implemented by the subclass"
|
1065
|
-
</span><span class="uncovered1"><a name="line465"></a>465 end
|
1066
|
-
</span><span class="uncovered0"><a name="line466"></a>466
|
1067
|
-
</span><span class="uncovered1"><a name="line467"></a>467 def aggregate_data(aggregated_data, delta)
|
1068
|
-
</span><span class="uncovered0"><a name="line468"></a>468 raise "must be implemented by the subclass"
|
1069
|
-
</span><span class="uncovered1"><a name="line469"></a>469 end
|
1070
|
-
</span><span class="uncovered0"><a name="line470"></a>470
|
1071
|
-
</span><span class="uncovered1"><a name="line471"></a>471 def compute_raw_data_difference(first, last)
|
1072
|
-
</span><span class="uncovered0"><a name="line472"></a>472 raise "must be implemented by the subclass"
|
1073
|
-
</span><span class="uncovered1"><a name="line473"></a>473 end
|
1074
|
-
</span><span class="uncovered0"><a name="line474"></a>474
|
1075
|
-
</span><span class="uncovered1"><a name="line475"></a>475 private
|
1076
|
-
</span><span class="uncovered0"><a name="line476"></a>476 def raw_data_relative
|
1077
|
-
</span><span class="uncovered1"><a name="line477"></a>477 case @cache_state
|
1078
|
-
</span><span class="uncovered0"><a name="line478"></a>478 when :wait
|
1079
|
-
</span><span class="uncovered1"><a name="line479"></a>479 return @aggregated_data
|
1080
|
-
</span><span class="uncovered0"><a name="line480"></a>480 when :hooked
|
1081
|
-
</span><span class="uncovered1"><a name="line481"></a>481 new_start = raw_data_absolute
|
1082
|
-
</span><span class="uncovered0"><a name="line482"></a>482 new_diff = compute_raw_data_difference(@start_raw_data, new_start)
|
1083
|
-
</span><span class="uncovered1"><a name="line483"></a>483 @start_raw_data = new_start
|
1084
|
-
</span><span class="uncovered0"><a name="line484"></a>484 when :done
|
1085
|
-
</span><span class="uncovered1"><a name="line485"></a>485 @cache_state = :wait
|
1086
|
-
</span><span class="uncovered0"><a name="line486"></a>486 new_diff = compute_raw_data_difference(@start_raw_data,
|
1087
|
-
</span><span class="uncovered1"><a name="line487"></a>487 @end_raw_data)
|
1088
|
-
</span><span class="uncovered0"><a name="line488"></a>488 end
|
1089
|
-
</span><span class="uncovered1"><a name="line489"></a>489
|
1090
|
-
</span><span class="uncovered0"><a name="line490"></a>490 aggregate_data(@aggregated_data, new_diff)
|
1091
|
-
</span><span class="uncovered1"><a name="line491"></a>491
|
1092
|
-
</span><span class="uncovered0"><a name="line492"></a>492 @aggregated_data
|
1093
|
-
</span><span class="uncovered1"><a name="line493"></a>493 end
|
1094
|
-
</span><span class="uncovered0"><a name="line494"></a>494
|
1095
|
-
</span><span class="uncovered1"><a name="line495"></a>495 end
|
1096
|
-
</span><span class="uncovered0"><a name="line496"></a>496
|
1097
|
-
</span><span class="uncovered1"><a name="line497"></a>497 # A CodeCoverageAnalyzer is responsible for tracing code execution and
|
1098
|
-
</span><span class="uncovered0"><a name="line498"></a>498 # returning code coverage and execution count information.
|
1099
|
-
</span><span class="uncovered1"><a name="line499"></a>499 #
|
1100
|
-
</span><span class="uncovered0"><a name="line500"></a>500 # Note that you must <tt>require 'rcov'</tt> before the code you want to
|
1101
|
-
</span><span class="uncovered1"><a name="line501"></a>501 # analyze is parsed (i.e. before it gets loaded or required). You can do that
|
1102
|
-
</span><span class="uncovered0"><a name="line502"></a>502 # by either invoking ruby with the <tt>-rrcov</tt> command-line option or
|
1103
|
-
</span><span class="uncovered1"><a name="line503"></a>503 # just:
|
1104
|
-
</span><span class="uncovered0"><a name="line504"></a>504 # require 'rcov'
|
1105
|
-
</span><span class="uncovered1"><a name="line505"></a>505 # require 'mycode'
|
1106
|
-
</span><span class="uncovered0"><a name="line506"></a>506 # # ....
|
1107
|
-
</span><span class="uncovered1"><a name="line507"></a>507 #
|
1108
|
-
</span><span class="uncovered0"><a name="line508"></a>508 # == Example
|
1109
|
-
</span><span class="uncovered1"><a name="line509"></a>509 #
|
1110
|
-
</span><span class="uncovered0"><a name="line510"></a>510 # analyzer = Rcov::CodeCoverageAnalyzer.new
|
1111
|
-
</span><span class="uncovered1"><a name="line511"></a>511 # analyzer.run_hooked do
|
1112
|
-
</span><span class="uncovered0"><a name="line512"></a>512 # do_foo
|
1113
|
-
</span><span class="uncovered1"><a name="line513"></a>513 # # all the code executed as a result of this method call is traced
|
1114
|
-
</span><span class="uncovered0"><a name="line514"></a>514 # end
|
1115
|
-
</span><span class="uncovered1"><a name="line515"></a>515 # # ....
|
1116
|
-
</span><span class="uncovered0"><a name="line516"></a>516 #
|
1117
|
-
</span><span class="uncovered1"><a name="line517"></a>517 # analyzer.run_hooked do
|
1118
|
-
</span><span class="uncovered0"><a name="line518"></a>518 # do_bar
|
1119
|
-
</span><span class="uncovered1"><a name="line519"></a>519 # # the code coverage information generated in this run is aggregated
|
1120
|
-
</span><span class="uncovered0"><a name="line520"></a>520 # # to the previously recorded one
|
1121
|
-
</span><span class="uncovered1"><a name="line521"></a>521 # end
|
1122
|
-
</span><span class="uncovered0"><a name="line522"></a>522 #
|
1123
|
-
</span><span class="uncovered1"><a name="line523"></a>523 # analyzer.analyzed_files # => ["foo.rb", "bar.rb", ... ]
|
1124
|
-
</span><span class="uncovered0"><a name="line524"></a>524 # lines, marked_info, count_info = analyzer.data("foo.rb")
|
1125
|
-
</span><span class="uncovered1"><a name="line525"></a>525 #
|
1126
|
-
</span><span class="uncovered0"><a name="line526"></a>526 # In this example, two pieces of code are monitored, and the data generated in
|
1127
|
-
</span><span class="uncovered1"><a name="line527"></a>527 # both runs are aggregated. +lines+ is an array of strings representing the
|
1128
|
-
</span><span class="uncovered0"><a name="line528"></a>528 # source code of <tt>foo.rb</tt>. +marked_info+ is an array holding false,
|
1129
|
-
</span><span class="uncovered1"><a name="line529"></a>529 # true values indicating whether the corresponding lines of code were reported
|
1130
|
-
</span><span class="uncovered0"><a name="line530"></a>530 # as executed by Ruby. +count_info+ is an array of integers representing how
|
1131
|
-
</span><span class="uncovered1"><a name="line531"></a>531 # many times each line of code has been executed (more precisely, how many
|
1132
|
-
</span><span class="uncovered0"><a name="line532"></a>532 # events where reported by Ruby --- a single line might correspond to several
|
1133
|
-
</span><span class="uncovered1"><a name="line533"></a>533 # events, e.g. many method calls).
|
1134
|
-
</span><span class="uncovered0"><a name="line534"></a>534 #
|
1135
|
-
</span><span class="uncovered1"><a name="line535"></a>535 # You can have several CodeCoverageAnalyzer objects at a time, and it is
|
1136
|
-
</span><span class="uncovered0"><a name="line536"></a>536 # possible to nest the #run_hooked / #install_hook/#remove_hook blocks: each
|
1137
|
-
</span><span class="uncovered1"><a name="line537"></a>537 # analyzer will manage its data separately. Note however that no special
|
1138
|
-
</span><span class="uncovered0"><a name="line538"></a>538 # provision is taken to ignore code executed "inside" the CodeCoverageAnalyzer
|
1139
|
-
</span><span class="uncovered1"><a name="line539"></a>539 # class. At any rate this will not pose a problem since it's easy to ignore it
|
1140
|
-
</span><span class="uncovered0"><a name="line540"></a>540 # manually: just don't do
|
1141
|
-
</span><span class="uncovered1"><a name="line541"></a>541 # lines, coverage, counts = analyzer.data("/path/to/lib/rcov.rb")
|
1142
|
-
</span><span class="uncovered0"><a name="line542"></a>542 # if you're not interested in that information.
|
1143
|
-
</span><span class="uncovered1"><a name="line543"></a>543 class CodeCoverageAnalyzer < DifferentialAnalyzer
|
1144
|
-
</span><span class="uncovered0"><a name="line544"></a>544 @hook_level = 0
|
1145
|
-
</span><span class="inferred1"><a name="line545"></a>545 # defined this way instead of attr_accessor so that it's covered
|
1146
|
-
</span><span class="marked0"><a name="line546"></a>546 def self.hook_level # :nodoc:
|
1147
|
-
</span><span class="marked1"><a name="line547"></a>547 @hook_level
|
1148
|
-
</span><span class="marked0"><a name="line548"></a>548 end
|
1149
|
-
</span><span class="marked1"><a name="line549"></a>549 def self.hook_level=(x) # :nodoc:
|
1150
|
-
</span><span class="marked0"><a name="line550"></a>550 @hook_level = x
|
1151
|
-
</span><span class="marked1"><a name="line551"></a>551 end
|
1152
|
-
</span><span class="uncovered0"><a name="line552"></a>552
|
1153
|
-
</span><span class="uncovered1"><a name="line553"></a>553 def initialize
|
1154
|
-
</span><span class="uncovered0"><a name="line554"></a>554 @script_lines__ = SCRIPT_LINES__
|
1155
|
-
</span><span class="uncovered1"><a name="line555"></a>555 super(:install_coverage_hook, :remove_coverage_hook,
|
1156
|
-
</span><span class="uncovered0"><a name="line556"></a>556 :reset_coverage)
|
1157
|
-
</span><span class="uncovered1"><a name="line557"></a>557 end
|
1158
|
-
</span><span class="uncovered0"><a name="line558"></a>558
|
1159
|
-
</span><span class="uncovered1"><a name="line559"></a>559 # Return an array with the names of the files whose code was executed inside
|
1160
|
-
</span><span class="uncovered0"><a name="line560"></a>560 # the block given to #run_hooked or between #install_hook and #remove_hook.
|
1161
|
-
</span><span class="uncovered1"><a name="line561"></a>561 def analyzed_files
|
1162
|
-
</span><span class="uncovered0"><a name="line562"></a>562 update_script_lines__
|
1163
|
-
</span><span class="uncovered1"><a name="line563"></a>563 raw_data_relative.select do |file, lines|
|
1164
|
-
</span><span class="uncovered0"><a name="line564"></a>564 @script_lines__.has_key?(file)
|
1165
|
-
</span><span class="uncovered1"><a name="line565"></a>565 end.map{|fname,| fname}
|
1166
|
-
</span><span class="uncovered0"><a name="line566"></a>566 end
|
1167
|
-
</span><span class="uncovered1"><a name="line567"></a>567
|
1168
|
-
</span><span class="uncovered0"><a name="line568"></a>568 # Return the available data about the requested file, or nil if none of its
|
1169
|
-
</span><span class="uncovered1"><a name="line569"></a>569 # code was executed or it cannot be found.
|
1170
|
-
</span><span class="uncovered0"><a name="line570"></a>570 # The return value is an array with three elements:
|
1171
|
-
</span><span class="uncovered1"><a name="line571"></a>571 # lines, marked_info, count_info = analyzer.data("foo.rb")
|
1172
|
-
</span><span class="uncovered0"><a name="line572"></a>572 # +lines+ is an array of strings representing the
|
1173
|
-
</span><span class="uncovered1"><a name="line573"></a>573 # source code of <tt>foo.rb</tt>. +marked_info+ is an array holding false,
|
1174
|
-
</span><span class="uncovered0"><a name="line574"></a>574 # true values indicating whether the corresponding lines of code were reported
|
1175
|
-
</span><span class="uncovered1"><a name="line575"></a>575 # as executed by Ruby. +count_info+ is an array of integers representing how
|
1176
|
-
</span><span class="uncovered0"><a name="line576"></a>576 # many times each line of code has been executed (more precisely, how many
|
1177
|
-
</span><span class="uncovered1"><a name="line577"></a>577 # events where reported by Ruby --- a single line might correspond to several
|
1178
|
-
</span><span class="uncovered0"><a name="line578"></a>578 # events, e.g. many method calls).
|
1179
|
-
</span><span class="uncovered1"><a name="line579"></a>579 #
|
1180
|
-
</span><span class="uncovered0"><a name="line580"></a>580 # The returned data corresponds to the aggregation of all the statistics
|
1181
|
-
</span><span class="uncovered1"><a name="line581"></a>581 # collected in each #run_hooked or #install_hook/#remove_hook runs. You can
|
1182
|
-
</span><span class="uncovered0"><a name="line582"></a>582 # reset the data at any time with #reset to start from scratch.
|
1183
|
-
</span><span class="uncovered1"><a name="line583"></a>583 def data(filename)
|
1184
|
-
</span><span class="uncovered0"><a name="line584"></a>584 raw_data = raw_data_relative
|
1185
|
-
</span><span class="uncovered1"><a name="line585"></a>585 update_script_lines__
|
1186
|
-
</span><span class="uncovered0"><a name="line586"></a>586 unless @script_lines__.has_key?(filename) &&
|
1187
|
-
</span><span class="uncovered1"><a name="line587"></a>587 raw_data.has_key?(filename)
|
1188
|
-
</span><span class="uncovered0"><a name="line588"></a>588 return nil
|
1189
|
-
</span><span class="uncovered1"><a name="line589"></a>589 end
|
1190
|
-
</span><span class="uncovered0"><a name="line590"></a>590 refine_coverage_info(@script_lines__[filename], raw_data[filename])
|
1191
|
-
</span><span class="uncovered1"><a name="line591"></a>591 end
|
1192
|
-
</span><span class="uncovered0"><a name="line592"></a>592
|
1193
|
-
</span><span class="uncovered1"><a name="line593"></a>593 # Data for the first file matching the given regexp.
|
1194
|
-
</span><span class="uncovered0"><a name="line594"></a>594 # See #data.
|
1195
|
-
</span><span class="uncovered1"><a name="line595"></a>595 def data_matching(filename_re)
|
1196
|
-
</span><span class="uncovered0"><a name="line596"></a>596 raw_data = raw_data_relative
|
1197
|
-
</span><span class="uncovered1"><a name="line597"></a>597 update_script_lines__
|
1198
|
-
</span><span class="uncovered0"><a name="line598"></a>598
|
1199
|
-
</span><span class="uncovered1"><a name="line599"></a>599 match = raw_data.keys.sort.grep(filename_re).first
|
1200
|
-
</span><span class="uncovered0"><a name="line600"></a>600 return nil unless match
|
1201
|
-
</span><span class="uncovered1"><a name="line601"></a>601
|
1202
|
-
</span><span class="uncovered0"><a name="line602"></a>602 refine_coverage_info(@script_lines__[match], raw_data[match])
|
1203
|
-
</span><span class="uncovered1"><a name="line603"></a>603 end
|
1204
|
-
</span><span class="uncovered0"><a name="line604"></a>604
|
1205
|
-
</span><span class="uncovered1"><a name="line605"></a>605 # Execute the code in the given block, monitoring it in order to gather
|
1206
|
-
</span><span class="uncovered0"><a name="line606"></a>606 # information about which code was executed.
|
1207
|
-
</span><span class="uncovered1"><a name="line607"></a>607 def run_hooked; super end
|
1208
|
-
</span><span class="inferred0"><a name="line608"></a>608
|
1209
|
-
</span><span class="inferred1"><a name="line609"></a>609 # Start monitoring execution to gather code coverage and execution count
|
1210
|
-
</span><span class="inferred0"><a name="line610"></a>610 # information. Such data will be collected until #remove_hook is called.
|
1211
|
-
</span><span class="inferred1"><a name="line611"></a>611 #
|
1212
|
-
</span><span class="inferred0"><a name="line612"></a>612 # Use #run_hooked instead if possible.
|
1213
|
-
</span><span class="marked1"><a name="line613"></a>613 def install_hook; super end
|
1214
|
-
</span><span class="inferred0"><a name="line614"></a>614
|
1215
|
-
</span><span class="inferred1"><a name="line615"></a>615 # Stop collecting code coverage and execution count information.
|
1216
|
-
</span><span class="inferred0"><a name="line616"></a>616 # #remove_hook will also stop collecting info if it is run inside a
|
1217
|
-
</span><span class="inferred1"><a name="line617"></a>617 # #run_hooked block.
|
1218
|
-
</span><span class="marked0"><a name="line618"></a>618 def remove_hook; super end
|
1219
|
-
</span><span class="uncovered1"><a name="line619"></a>619
|
1220
|
-
</span><span class="uncovered0"><a name="line620"></a>620 # Remove the data collected so far. The coverage and execution count
|
1221
|
-
</span><span class="uncovered1"><a name="line621"></a>621 # "history" will be erased, and further collection will start from scratch:
|
1222
|
-
</span><span class="uncovered0"><a name="line622"></a>622 # no code is considered executed, and therefore all execution counts are 0.
|
1223
|
-
</span><span class="uncovered1"><a name="line623"></a>623 # Right after #reset, #analyzed_files will return an empty array, and
|
1224
|
-
</span><span class="uncovered0"><a name="line624"></a>624 # #data(filename) will return nil.
|
1225
|
-
</span><span class="uncovered1"><a name="line625"></a>625 def reset; super end
|
1226
|
-
</span><span class="uncovered0"><a name="line626"></a>626
|
1227
|
-
</span><span class="uncovered1"><a name="line627"></a>627 def dump_coverage_info(formatters) # :nodoc:
|
1228
|
-
</span><span class="uncovered0"><a name="line628"></a>628 update_script_lines__
|
1229
|
-
</span><span class="uncovered1"><a name="line629"></a>629 raw_data_relative.each do |file, lines|
|
1230
|
-
</span><span class="uncovered0"><a name="line630"></a>630 next if @script_lines__.has_key?(file) == false
|
1231
|
-
</span><span class="uncovered1"><a name="line631"></a>631 lines = @script_lines__[file]
|
1232
|
-
</span><span class="uncovered0"><a name="line632"></a>632 raw_coverage_array = raw_data_relative[file]
|
1233
|
-
</span><span class="uncovered1"><a name="line633"></a>633
|
1234
|
-
</span><span class="uncovered0"><a name="line634"></a>634 line_info, marked_info,
|
1235
|
-
</span><span class="uncovered1"><a name="line635"></a>635 count_info = refine_coverage_info(lines, raw_coverage_array)
|
1236
|
-
</span><span class="uncovered0"><a name="line636"></a>636 formatters.each do |formatter|
|
1237
|
-
</span><span class="uncovered1"><a name="line637"></a>637 formatter.add_file(file, line_info, marked_info, count_info)
|
1238
|
-
</span><span class="uncovered0"><a name="line638"></a>638 end
|
1239
|
-
</span><span class="uncovered1"><a name="line639"></a>639 end
|
1240
|
-
</span><span class="uncovered0"><a name="line640"></a>640 formatters.each{|formatter| formatter.execute}
|
1241
|
-
</span><span class="uncovered1"><a name="line641"></a>641 end
|
1242
|
-
</span><span class="uncovered0"><a name="line642"></a>642
|
1243
|
-
</span><span class="uncovered1"><a name="line643"></a>643 private
|
1244
|
-
</span><span class="uncovered0"><a name="line644"></a>644
|
1245
|
-
</span><span class="uncovered1"><a name="line645"></a>645 def data_default; {} end
|
1246
|
-
</span><span class="uncovered0"><a name="line646"></a>646
|
1247
|
-
</span><span class="uncovered1"><a name="line647"></a>647 def raw_data_absolute
|
1248
|
-
</span><span class="uncovered0"><a name="line648"></a>648 Rcov::RCOV__.generate_coverage_info
|
1249
|
-
</span><span class="uncovered1"><a name="line649"></a>649 end
|
1250
|
-
</span><span class="uncovered0"><a name="line650"></a>650
|
1251
|
-
</span><span class="uncovered1"><a name="line651"></a>651 def aggregate_data(aggregated_data, delta)
|
1252
|
-
</span><span class="uncovered0"><a name="line652"></a>652 delta.each_pair do |file, cov_arr|
|
1253
|
-
</span><span class="uncovered1"><a name="line653"></a>653 dest = (aggregated_data[file] ||= Array.new(cov_arr.size, 0))
|
1254
|
-
</span><span class="uncovered0"><a name="line654"></a>654 cov_arr.each_with_index{|x,i| dest[i] += x}
|
1255
|
-
</span><span class="uncovered1"><a name="line655"></a>655 end
|
1256
|
-
</span><span class="uncovered0"><a name="line656"></a>656 end
|
1257
|
-
</span><span class="uncovered1"><a name="line657"></a>657
|
1258
|
-
</span><span class="uncovered0"><a name="line658"></a>658 def compute_raw_data_difference(first, last)
|
1259
|
-
</span><span class="uncovered1"><a name="line659"></a>659 difference = {}
|
1260
|
-
</span><span class="uncovered0"><a name="line660"></a>660 last.each_pair do |fname, cov_arr|
|
1261
|
-
</span><span class="uncovered1"><a name="line661"></a>661 unless first.has_key?(fname)
|
1262
|
-
</span><span class="uncovered0"><a name="line662"></a>662 difference[fname] = cov_arr.clone
|
1263
|
-
</span><span class="uncovered1"><a name="line663"></a>663 else
|
1264
|
-
</span><span class="uncovered0"><a name="line664"></a>664 orig_arr = first[fname]
|
1265
|
-
</span><span class="uncovered1"><a name="line665"></a>665 diff_arr = Array.new(cov_arr.size, 0)
|
1266
|
-
</span><span class="uncovered0"><a name="line666"></a>666 changed = false
|
1267
|
-
</span><span class="uncovered1"><a name="line667"></a>667 cov_arr.each_with_index do |x, i|
|
1268
|
-
</span><span class="uncovered0"><a name="line668"></a>668 diff_arr[i] = diff = (x || 0) - (orig_arr[i] || 0)
|
1269
|
-
</span><span class="uncovered1"><a name="line669"></a>669 changed = true if diff != 0
|
1270
|
-
</span><span class="uncovered0"><a name="line670"></a>670 end
|
1271
|
-
</span><span class="uncovered1"><a name="line671"></a>671 difference[fname] = diff_arr if changed
|
1272
|
-
</span><span class="uncovered0"><a name="line672"></a>672 end
|
1273
|
-
</span><span class="uncovered1"><a name="line673"></a>673 end
|
1274
|
-
</span><span class="uncovered0"><a name="line674"></a>674 difference
|
1275
|
-
</span><span class="uncovered1"><a name="line675"></a>675 end
|
1276
|
-
</span><span class="uncovered0"><a name="line676"></a>676
|
1277
|
-
</span><span class="uncovered1"><a name="line677"></a>677
|
1278
|
-
</span><span class="uncovered0"><a name="line678"></a>678 def refine_coverage_info(lines, covers)
|
1279
|
-
</span><span class="uncovered1"><a name="line679"></a>679 marked_info = []
|
1280
|
-
</span><span class="uncovered0"><a name="line680"></a>680 count_info = []
|
1281
|
-
</span><span class="uncovered1"><a name="line681"></a>681 lines.size.times do |i|
|
1282
|
-
</span><span class="uncovered0"><a name="line682"></a>682 c = covers[i]
|
1283
|
-
</span><span class="uncovered1"><a name="line683"></a>683 marked_info << ((c && c > 0) ? true : false)
|
1284
|
-
</span><span class="uncovered0"><a name="line684"></a>684 count_info << (c || 0)
|
1285
|
-
</span><span class="uncovered1"><a name="line685"></a>685 end
|
1286
|
-
</span><span class="uncovered0"><a name="line686"></a>686
|
1287
|
-
</span><span class="uncovered1"><a name="line687"></a>687 script_lines_workaround(lines, marked_info, count_info)
|
1288
|
-
</span><span class="uncovered0"><a name="line688"></a>688 end
|
1289
|
-
</span><span class="uncovered1"><a name="line689"></a>689
|
1290
|
-
</span><span class="uncovered0"><a name="line690"></a>690 # Try to detect repeated data, based on observed repetitions in line_info:
|
1291
|
-
</span><span class="uncovered1"><a name="line691"></a>691 # this is a workaround for SCRIPT_LINES__[filename] including as many copies
|
1292
|
-
</span><span class="uncovered0"><a name="line692"></a>692 # of the file as the number of times it was parsed.
|
1293
|
-
</span><span class="uncovered1"><a name="line693"></a>693 def script_lines_workaround(line_info, coverage_info, count_info)
|
1294
|
-
</span><span class="uncovered0"><a name="line694"></a>694 is_repeated = lambda do |div|
|
1295
|
-
</span><span class="uncovered1"><a name="line695"></a>695 n = line_info.size / div
|
1296
|
-
</span><span class="uncovered0"><a name="line696"></a>696 break false unless line_info.size % div == 0 && n > 1
|
1297
|
-
</span><span class="uncovered1"><a name="line697"></a>697 different = false
|
1298
|
-
</span><span class="uncovered0"><a name="line698"></a>698 n.times do |i|
|
1299
|
-
</span><span class="uncovered1"><a name="line699"></a>699 if (0...div).map{|j| line_info[i+j*n]}.uniq.size != 1
|
1300
|
-
</span><span class="uncovered0"><a name="line700"></a>700 different = true
|
1301
|
-
</span><span class="uncovered1"><a name="line701"></a>701 break
|
1302
|
-
</span><span class="uncovered0"><a name="line702"></a>702 end
|
1303
|
-
</span><span class="uncovered1"><a name="line703"></a>703 end
|
1304
|
-
</span><span class="uncovered0"><a name="line704"></a>704
|
1305
|
-
</span><span class="uncovered1"><a name="line705"></a>705 ! different
|
1306
|
-
</span><span class="uncovered0"><a name="line706"></a>706 end
|
1307
|
-
</span><span class="uncovered1"><a name="line707"></a>707
|
1308
|
-
</span><span class="uncovered0"><a name="line708"></a>708 factors = braindead_factorize(line_info.size)
|
1309
|
-
</span><span class="uncovered1"><a name="line709"></a>709 factors.each do |n|
|
1310
|
-
</span><span class="uncovered0"><a name="line710"></a>710 if is_repeated[n]
|
1311
|
-
</span><span class="uncovered1"><a name="line711"></a>711 line_info = line_info[0, line_info.size / n]
|
1312
|
-
</span><span class="uncovered0"><a name="line712"></a>712 coverage_info = coverage_info[0, coverage_info.size / n]
|
1313
|
-
</span><span class="uncovered1"><a name="line713"></a>713 count_info = count_info[0, count_info.size / n]
|
1314
|
-
</span><span class="uncovered0"><a name="line714"></a>714 end
|
1315
|
-
</span><span class="uncovered1"><a name="line715"></a>715 end if factors.size > 1 # don't even try if it's prime
|
1316
|
-
</span><span class="uncovered0"><a name="line716"></a>716
|
1317
|
-
</span><span class="uncovered1"><a name="line717"></a>717 [line_info, coverage_info, count_info]
|
1318
|
-
</span><span class="uncovered0"><a name="line718"></a>718 end
|
1319
|
-
</span><span class="uncovered1"><a name="line719"></a>719
|
1320
|
-
</span><span class="uncovered0"><a name="line720"></a>720 def braindead_factorize(num)
|
1321
|
-
</span><span class="uncovered1"><a name="line721"></a>721 return [0] if num == 0
|
1322
|
-
</span><span class="uncovered0"><a name="line722"></a>722 return [-1] + braindead_factorize(-num) if num < 0
|
1323
|
-
</span><span class="uncovered1"><a name="line723"></a>723 factors = []
|
1324
|
-
</span><span class="uncovered0"><a name="line724"></a>724 while num % 2 == 0
|
1325
|
-
</span><span class="uncovered1"><a name="line725"></a>725 factors << 2
|
1326
|
-
</span><span class="uncovered0"><a name="line726"></a>726 num /= 2
|
1327
|
-
</span><span class="uncovered1"><a name="line727"></a>727 end
|
1328
|
-
</span><span class="uncovered0"><a name="line728"></a>728 size = num
|
1329
|
-
</span><span class="uncovered1"><a name="line729"></a>729 n = 3
|
1330
|
-
</span><span class="uncovered0"><a name="line730"></a>730 max = Math.sqrt(num)
|
1331
|
-
</span><span class="uncovered1"><a name="line731"></a>731 while n <= max && n <= size
|
1332
|
-
</span><span class="uncovered0"><a name="line732"></a>732 while size % n == 0
|
1333
|
-
</span><span class="uncovered1"><a name="line733"></a>733 size /= n
|
1334
|
-
</span><span class="uncovered0"><a name="line734"></a>734 factors << n
|
1335
|
-
</span><span class="uncovered1"><a name="line735"></a>735 end
|
1336
|
-
</span><span class="uncovered0"><a name="line736"></a>736 n += 2
|
1337
|
-
</span><span class="uncovered1"><a name="line737"></a>737 end
|
1338
|
-
</span><span class="uncovered0"><a name="line738"></a>738 factors << size if size != 1
|
1339
|
-
</span><span class="uncovered1"><a name="line739"></a>739 factors
|
1340
|
-
</span><span class="uncovered0"><a name="line740"></a>740 end
|
1341
|
-
</span><span class="uncovered1"><a name="line741"></a>741
|
1342
|
-
</span><span class="uncovered0"><a name="line742"></a>742 def update_script_lines__
|
1343
|
-
</span><span class="uncovered1"><a name="line743"></a>743 @script_lines__ = @script_lines__.merge(SCRIPT_LINES__)
|
1344
|
-
</span><span class="uncovered0"><a name="line744"></a>744 end
|
1345
|
-
</span><span class="uncovered1"><a name="line745"></a>745
|
1346
|
-
</span><span class="uncovered0"><a name="line746"></a>746 public
|
1347
|
-
</span><span class="uncovered1"><a name="line747"></a>747 def marshal_dump # :nodoc:
|
1348
|
-
</span><span class="uncovered0"><a name="line748"></a>748 # @script_lines__ is updated just before serialization so as to avoid
|
1349
|
-
</span><span class="uncovered1"><a name="line749"></a>749 # missing files in SCRIPT_LINES__
|
1350
|
-
</span><span class="uncovered0"><a name="line750"></a>750 ivs = {}
|
1351
|
-
</span><span class="uncovered1"><a name="line751"></a>751 update_script_lines__
|
1352
|
-
</span><span class="uncovered0"><a name="line752"></a>752 instance_variables.each{|iv| ivs[iv] = instance_variable_get(iv)}
|
1353
|
-
</span><span class="uncovered1"><a name="line753"></a>753 ivs
|
1354
|
-
</span><span class="uncovered0"><a name="line754"></a>754 end
|
1355
|
-
</span><span class="uncovered1"><a name="line755"></a>755
|
1356
|
-
</span><span class="uncovered0"><a name="line756"></a>756 def marshal_load(ivs) # :nodoc:
|
1357
|
-
</span><span class="uncovered1"><a name="line757"></a>757 ivs.each_pair{|iv, val| instance_variable_set(iv, val)}
|
1358
|
-
</span><span class="uncovered0"><a name="line758"></a>758 end
|
1359
|
-
</span><span class="uncovered1"><a name="line759"></a>759
|
1360
|
-
</span><span class="uncovered0"><a name="line760"></a>760 end # CodeCoverageAnalyzer
|
1361
|
-
</span><span class="uncovered1"><a name="line761"></a>761
|
1362
|
-
</span><span class="uncovered0"><a name="line762"></a>762 # A CallSiteAnalyzer can be used to obtain information about:
|
1363
|
-
</span><span class="uncovered1"><a name="line763"></a>763 # * where a method is defined ("+defsite+")
|
1364
|
-
</span><span class="uncovered0"><a name="line764"></a>764 # * where a method was called from ("+callsite+")
|
1365
|
-
</span><span class="uncovered1"><a name="line765"></a>765 #
|
1366
|
-
</span><span class="uncovered0"><a name="line766"></a>766 # == Example
|
1367
|
-
</span><span class="uncovered1"><a name="line767"></a>767 # <tt>example.rb</tt>:
|
1368
|
-
</span><span class="uncovered0"><a name="line768"></a>768 # class X
|
1369
|
-
</span><span class="uncovered1"><a name="line769"></a>769 # def f1; f2 end
|
1370
|
-
</span><span class="uncovered0"><a name="line770"></a>770 # def f2; 1 + 1 end
|
1371
|
-
</span><span class="uncovered1"><a name="line771"></a>771 # def f3; f1 end
|
1372
|
-
</span><span class="uncovered0"><a name="line772"></a>772 # end
|
1373
|
-
</span><span class="uncovered1"><a name="line773"></a>773 #
|
1374
|
-
</span><span class="uncovered0"><a name="line774"></a>774 # analyzer = Rcov::CallSiteAnalyzer.new
|
1375
|
-
</span><span class="uncovered1"><a name="line775"></a>775 # x = X.new
|
1376
|
-
</span><span class="uncovered0"><a name="line776"></a>776 # analyzer.run_hooked do
|
1377
|
-
</span><span class="uncovered1"><a name="line777"></a>777 # x.f1
|
1378
|
-
</span><span class="uncovered0"><a name="line778"></a>778 # end
|
1379
|
-
</span><span class="uncovered1"><a name="line779"></a>779 # # ....
|
1380
|
-
</span><span class="uncovered0"><a name="line780"></a>780 #
|
1381
|
-
</span><span class="uncovered1"><a name="line781"></a>781 # analyzer.run_hooked do
|
1382
|
-
</span><span class="uncovered0"><a name="line782"></a>782 # x.f3
|
1383
|
-
</span><span class="uncovered1"><a name="line783"></a>783 # # the information generated in this run is aggregated
|
1384
|
-
</span><span class="uncovered0"><a name="line784"></a>784 # # to the previously recorded one
|
1385
|
-
</span><span class="uncovered1"><a name="line785"></a>785 # end
|
1386
|
-
</span><span class="uncovered0"><a name="line786"></a>786 #
|
1387
|
-
</span><span class="uncovered1"><a name="line787"></a>787 # analyzer.analyzed_classes # => ["X", ... ]
|
1388
|
-
</span><span class="uncovered0"><a name="line788"></a>788 # analyzer.methods_for_class("X") # => ["f1", "f2", "f3"]
|
1389
|
-
</span><span class="uncovered1"><a name="line789"></a>789 # analyzer.defsite("X#f1") # => DefSite object
|
1390
|
-
</span><span class="uncovered0"><a name="line790"></a>790 # analyzer.callsites("X#f2") # => hash with CallSite => count
|
1391
|
-
</span><span class="uncovered1"><a name="line791"></a>791 # # associations
|
1392
|
-
</span><span class="uncovered0"><a name="line792"></a>792 # defsite = analyzer.defsite("X#f1")
|
1393
|
-
</span><span class="uncovered1"><a name="line793"></a>793 # defsite.file # => "example.rb"
|
1394
|
-
</span><span class="uncovered0"><a name="line794"></a>794 # defsite.line # => 2
|
1395
|
-
</span><span class="uncovered1"><a name="line795"></a>795 #
|
1396
|
-
</span><span class="uncovered0"><a name="line796"></a>796 # You can have several CallSiteAnalyzer objects at a time, and it is
|
1397
|
-
</span><span class="uncovered1"><a name="line797"></a>797 # possible to nest the #run_hooked / #install_hook/#remove_hook blocks: each
|
1398
|
-
</span><span class="uncovered0"><a name="line798"></a>798 # analyzer will manage its data separately. Note however that no special
|
1399
|
-
</span><span class="uncovered1"><a name="line799"></a>799 # provision is taken to ignore code executed "inside" the CallSiteAnalyzer
|
1400
|
-
</span><span class="uncovered0"><a name="line800"></a>800 # class.
|
1401
|
-
</span><span class="uncovered1"><a name="line801"></a>801 #
|
1402
|
-
</span><span class="uncovered0"><a name="line802"></a>802 # +defsite+ information is only available for methods that were called under
|
1403
|
-
</span><span class="uncovered1"><a name="line803"></a>803 # the inspection of the CallSiteAnalyzer, i.o.w. you will only have +defsite+
|
1404
|
-
</span><span class="uncovered0"><a name="line804"></a>804 # information for those methods for which callsite information is
|
1405
|
-
</span><span class="uncovered1"><a name="line805"></a>805 # available.
|
1406
|
-
</span><span class="uncovered0"><a name="line806"></a>806 class CallSiteAnalyzer < DifferentialAnalyzer
|
1407
|
-
</span><span class="uncovered1"><a name="line807"></a>807 # A method definition site.
|
1408
|
-
</span><span class="uncovered0"><a name="line808"></a>808 class DefSite < Struct.new(:file, :line)
|
1409
|
-
</span><span class="uncovered1"><a name="line809"></a>809 end
|
1410
|
-
</span><span class="uncovered0"><a name="line810"></a>810
|
1411
|
-
</span><span class="uncovered1"><a name="line811"></a>811 # Object representing a method call site.
|
1412
|
-
</span><span class="uncovered0"><a name="line812"></a>812 # It corresponds to a part of the callstack starting from the context that
|
1413
|
-
</span><span class="uncovered1"><a name="line813"></a>813 # called the method.
|
1414
|
-
</span><span class="uncovered0"><a name="line814"></a>814 class CallSite < Struct.new(:backtrace)
|
1415
|
-
</span><span class="uncovered1"><a name="line815"></a>815 # The depth of a CallSite is the number of stack frames
|
1416
|
-
</span><span class="uncovered0"><a name="line816"></a>816 # whose information is included in the CallSite object.
|
1417
|
-
</span><span class="uncovered1"><a name="line817"></a>817 def depth
|
1418
|
-
</span><span class="uncovered0"><a name="line818"></a>818 backtrace.size
|
1419
|
-
</span><span class="uncovered1"><a name="line819"></a>819 end
|
1420
|
-
</span><span class="uncovered0"><a name="line820"></a>820
|
1421
|
-
</span><span class="uncovered1"><a name="line821"></a>821 # File where the method call originated.
|
1422
|
-
</span><span class="uncovered0"><a name="line822"></a>822 # Might return +nil+ or "" if it is not meaningful (C extensions, etc).
|
1423
|
-
</span><span class="uncovered1"><a name="line823"></a>823 def file(level = 0)
|
1424
|
-
</span><span class="uncovered0"><a name="line824"></a>824 stack_frame = backtrace[level]
|
1425
|
-
</span><span class="uncovered1"><a name="line825"></a>825 stack_frame ? stack_frame[2] : nil
|
1426
|
-
</span><span class="uncovered0"><a name="line826"></a>826 end
|
1427
|
-
</span><span class="uncovered1"><a name="line827"></a>827
|
1428
|
-
</span><span class="uncovered0"><a name="line828"></a>828 # Line where the method call originated.
|
1429
|
-
</span><span class="uncovered1"><a name="line829"></a>829 # Might return +nil+ or 0 if it is not meaningful (C extensions, etc).
|
1430
|
-
</span><span class="uncovered0"><a name="line830"></a>830 def line(level = 0)
|
1431
|
-
</span><span class="uncovered1"><a name="line831"></a>831 stack_frame = backtrace[level]
|
1432
|
-
</span><span class="uncovered0"><a name="line832"></a>832 stack_frame ? stack_frame[3] : nil
|
1433
|
-
</span><span class="uncovered1"><a name="line833"></a>833 end
|
1434
|
-
</span><span class="uncovered0"><a name="line834"></a>834
|
1435
|
-
</span><span class="uncovered1"><a name="line835"></a>835 # Name of the method where the call originated.
|
1436
|
-
</span><span class="uncovered0"><a name="line836"></a>836 # Returns +nil+ if the call originated in +toplevel+.
|
1437
|
-
</span><span class="uncovered1"><a name="line837"></a>837 # Might return +nil+ if it could not be determined.
|
1438
|
-
</span><span class="uncovered0"><a name="line838"></a>838 def calling_method(level = 0)
|
1439
|
-
</span><span class="uncovered1"><a name="line839"></a>839 stack_frame = backtrace[level]
|
1440
|
-
</span><span class="uncovered0"><a name="line840"></a>840 stack_frame ? stack_frame[1] : nil
|
1441
|
-
</span><span class="uncovered1"><a name="line841"></a>841 end
|
1442
|
-
</span><span class="uncovered0"><a name="line842"></a>842
|
1443
|
-
</span><span class="uncovered1"><a name="line843"></a>843 # Name of the class holding the method where the call originated.
|
1444
|
-
</span><span class="uncovered0"><a name="line844"></a>844 # Might return +nil+ if it could not be determined.
|
1445
|
-
</span><span class="uncovered1"><a name="line845"></a>845 def calling_class(level = 0)
|
1446
|
-
</span><span class="uncovered0"><a name="line846"></a>846 stack_frame = backtrace[level]
|
1447
|
-
</span><span class="uncovered1"><a name="line847"></a>847 stack_frame ? stack_frame[0] : nil
|
1448
|
-
</span><span class="uncovered0"><a name="line848"></a>848 end
|
1449
|
-
</span><span class="uncovered1"><a name="line849"></a>849 end
|
1450
|
-
</span><span class="uncovered0"><a name="line850"></a>850
|
1451
|
-
</span><span class="uncovered1"><a name="line851"></a>851 @hook_level = 0
|
1452
|
-
</span><span class="uncovered0"><a name="line852"></a>852 # defined this way instead of attr_accessor so that it's covered
|
1453
|
-
</span><span class="uncovered1"><a name="line853"></a>853 def self.hook_level # :nodoc:
|
1454
|
-
</span><span class="uncovered0"><a name="line854"></a>854 @hook_level
|
1455
|
-
</span><span class="uncovered1"><a name="line855"></a>855 end
|
1456
|
-
</span><span class="uncovered0"><a name="line856"></a>856 def self.hook_level=(x) # :nodoc:
|
1457
|
-
</span><span class="uncovered1"><a name="line857"></a>857 @hook_level = x
|
1458
|
-
</span><span class="uncovered0"><a name="line858"></a>858 end
|
1459
|
-
</span><span class="uncovered1"><a name="line859"></a>859
|
1460
|
-
</span><span class="uncovered0"><a name="line860"></a>860 def initialize
|
1461
|
-
</span><span class="uncovered1"><a name="line861"></a>861 super(:install_callsite_hook, :remove_callsite_hook,
|
1462
|
-
</span><span class="uncovered0"><a name="line862"></a>862 :reset_callsite)
|
1463
|
-
</span><span class="uncovered1"><a name="line863"></a>863 end
|
1464
|
-
</span><span class="uncovered0"><a name="line864"></a>864
|
1465
|
-
</span><span class="uncovered1"><a name="line865"></a>865 # Classes whose methods have been called.
|
1466
|
-
</span><span class="uncovered0"><a name="line866"></a>866 # Returns an array of strings describing the classes (just klass.to_s for
|
1467
|
-
</span><span class="uncovered1"><a name="line867"></a>867 # each of them). Singleton classes are rendered as:
|
1468
|
-
</span><span class="uncovered0"><a name="line868"></a>868 # #<Class:MyNamespace::MyClass>
|
1469
|
-
</span><span class="uncovered1"><a name="line869"></a>869 def analyzed_classes
|
1470
|
-
</span><span class="uncovered0"><a name="line870"></a>870 raw_data_relative.first.keys.map{|klass, meth| klass}.uniq.sort
|
1471
|
-
</span><span class="uncovered1"><a name="line871"></a>871 end
|
1472
|
-
</span><span class="uncovered0"><a name="line872"></a>872
|
1473
|
-
</span><span class="uncovered1"><a name="line873"></a>873 # Methods that were called for the given class. See #analyzed_classes for
|
1474
|
-
</span><span class="uncovered0"><a name="line874"></a>874 # the notation used for singleton classes.
|
1475
|
-
</span><span class="uncovered1"><a name="line875"></a>875 # Returns an array of strings or +nil+
|
1476
|
-
</span><span class="uncovered0"><a name="line876"></a>876 def methods_for_class(classname)
|
1477
|
-
</span><span class="uncovered1"><a name="line877"></a>877 a = raw_data_relative.first.keys.select{|kl,_| kl == classname}.map{|_,meth| meth}.sort
|
1478
|
-
</span><span class="uncovered0"><a name="line878"></a>878 a.empty? ? nil : a
|
1479
|
-
</span><span class="uncovered1"><a name="line879"></a>879 end
|
1480
|
-
</span><span class="uncovered0"><a name="line880"></a>880 alias_method :analyzed_methods, :methods_for_class
|
1481
|
-
</span><span class="uncovered1"><a name="line881"></a>881
|
1482
|
-
</span><span class="uncovered0"><a name="line882"></a>882 # Returns a hash with <tt>CallSite => call count</tt> associations or +nil+
|
1483
|
-
</span><span class="uncovered1"><a name="line883"></a>883 # Can be called in two ways:
|
1484
|
-
</span><span class="uncovered0"><a name="line884"></a>884 # analyzer.callsites("Foo#f1") # instance method
|
1485
|
-
</span><span class="uncovered1"><a name="line885"></a>885 # analyzer.callsites("Foo.g1") # singleton method of the class
|
1486
|
-
</span><span class="uncovered0"><a name="line886"></a>886 # or
|
1487
|
-
</span><span class="uncovered1"><a name="line887"></a>887 # analyzer.callsites("Foo", "f1")
|
1488
|
-
</span><span class="uncovered0"><a name="line888"></a>888 # analyzer.callsites("#<class:Foo>", "g1")
|
1489
|
-
</span><span class="uncovered1"><a name="line889"></a>889 def callsites(classname_or_fullname, methodname = nil)
|
1490
|
-
</span><span class="uncovered0"><a name="line890"></a>890 rawsites = raw_data_relative.first[expand_name(classname_or_fullname, methodname)]
|
1491
|
-
</span><span class="uncovered1"><a name="line891"></a>891 return nil unless rawsites
|
1492
|
-
</span><span class="uncovered0"><a name="line892"></a>892 ret = {}
|
1493
|
-
</span><span class="uncovered1"><a name="line893"></a>893 # could be a job for inject but it's slow and I don't mind the extra loc
|
1494
|
-
</span><span class="uncovered0"><a name="line894"></a>894 rawsites.each_pair do |backtrace, count|
|
1495
|
-
</span><span class="uncovered1"><a name="line895"></a>895 ret[CallSite.new(backtrace)] = count
|
1496
|
-
</span><span class="uncovered0"><a name="line896"></a>896 end
|
1497
|
-
</span><span class="uncovered1"><a name="line897"></a>897 ret
|
1498
|
-
</span><span class="uncovered0"><a name="line898"></a>898 end
|
1499
|
-
</span><span class="uncovered1"><a name="line899"></a>899
|
1500
|
-
</span><span class="uncovered0"><a name="line900"></a>900 # Returns a DefSite object corresponding to the given method
|
1501
|
-
</span><span class="uncovered1"><a name="line901"></a>901 # Can be called in two ways:
|
1502
|
-
</span><span class="uncovered0"><a name="line902"></a>902 # analyzer.defsite("Foo#f1") # instance method
|
1503
|
-
</span><span class="uncovered1"><a name="line903"></a>903 # analyzer.defsite("Foo.g1") # singleton method of the class
|
1504
|
-
</span><span class="uncovered0"><a name="line904"></a>904 # or
|
1505
|
-
</span><span class="uncovered1"><a name="line905"></a>905 # analyzer.defsite("Foo", "f1")
|
1506
|
-
</span><span class="uncovered0"><a name="line906"></a>906 # analyzer.defsite("#<class:Foo>", "g1")
|
1507
|
-
</span><span class="uncovered1"><a name="line907"></a>907 def defsite(classname_or_fullname, methodname = nil)
|
1508
|
-
</span><span class="uncovered0"><a name="line908"></a>908 file, line = raw_data_relative[1][expand_name(classname_or_fullname, methodname)]
|
1509
|
-
</span><span class="uncovered1"><a name="line909"></a>909 return nil unless file && line
|
1510
|
-
</span><span class="uncovered0"><a name="line910"></a>910 DefSite.new(file, line)
|
1511
|
-
</span><span class="uncovered1"><a name="line911"></a>911 end
|
1512
|
-
</span><span class="uncovered0"><a name="line912"></a>912
|
1513
|
-
</span><span class="uncovered1"><a name="line913"></a>913 private
|
1514
|
-
</span><span class="uncovered0"><a name="line914"></a>914
|
1515
|
-
</span><span class="uncovered1"><a name="line915"></a>915 def expand_name(classname_or_fullname, methodname = nil)
|
1516
|
-
</span><span class="uncovered0"><a name="line916"></a>916 if methodname.nil?
|
1517
|
-
</span><span class="uncovered1"><a name="line917"></a>917 case classname_or_fullname
|
1518
|
-
</span><span class="uncovered0"><a name="line918"></a>918 when /(.*)#(.*)/: classname, methodname = $1, $2
|
1519
|
-
</span><span class="uncovered1"><a name="line919"></a>919 when /(.*)\.(.*)/: classname, methodname = "#<Class:#{$1}>", $2
|
1520
|
-
</span><span class="uncovered0"><a name="line920"></a>920 else
|
1521
|
-
</span><span class="uncovered1"><a name="line921"></a>921 raise ArgumentError, "Incorrect method name"
|
1522
|
-
</span><span class="uncovered0"><a name="line922"></a>922 end
|
1523
|
-
</span><span class="uncovered1"><a name="line923"></a>923
|
1524
|
-
</span><span class="uncovered0"><a name="line924"></a>924 return [classname, methodname]
|
1525
|
-
</span><span class="uncovered1"><a name="line925"></a>925 end
|
1526
|
-
</span><span class="uncovered0"><a name="line926"></a>926
|
1527
|
-
</span><span class="uncovered1"><a name="line927"></a>927 [classname_or_fullname, methodname]
|
1528
|
-
</span><span class="uncovered0"><a name="line928"></a>928 end
|
1529
|
-
</span><span class="uncovered1"><a name="line929"></a>929
|
1530
|
-
</span><span class="uncovered0"><a name="line930"></a>930 def data_default; [{}, {}] end
|
1531
|
-
</span><span class="uncovered1"><a name="line931"></a>931
|
1532
|
-
</span><span class="uncovered0"><a name="line932"></a>932 def raw_data_absolute
|
1533
|
-
</span><span class="uncovered1"><a name="line933"></a>933 raw, method_def_site = RCOV__.generate_callsite_info
|
1534
|
-
</span><span class="uncovered0"><a name="line934"></a>934 ret1 = {}
|
1535
|
-
</span><span class="uncovered1"><a name="line935"></a>935 ret2 = {}
|
1536
|
-
</span><span class="uncovered0"><a name="line936"></a>936 raw.each_pair do |(klass, method), hash|
|
1537
|
-
</span><span class="uncovered1"><a name="line937"></a>937 begin
|
1538
|
-
</span><span class="uncovered0"><a name="line938"></a>938 key = [klass.to_s, method.to_s]
|
1539
|
-
</span><span class="uncovered1"><a name="line939"></a>939 ret1[key] = hash.clone #Marshal.load(Marshal.dump(hash))
|
1540
|
-
</span><span class="uncovered0"><a name="line940"></a>940 ret2[key] = method_def_site[[klass, method]]
|
1541
|
-
</span><span class="uncovered1"><a name="line941"></a>941 #rescue Exception
|
1542
|
-
</span><span class="uncovered0"><a name="line942"></a>942 end
|
1543
|
-
</span><span class="uncovered1"><a name="line943"></a>943 end
|
1544
|
-
</span><span class="uncovered0"><a name="line944"></a>944
|
1545
|
-
</span><span class="uncovered1"><a name="line945"></a>945 [ret1, ret2]
|
1546
|
-
</span><span class="uncovered0"><a name="line946"></a>946 end
|
1547
|
-
</span><span class="uncovered1"><a name="line947"></a>947
|
1548
|
-
</span><span class="uncovered0"><a name="line948"></a>948 def aggregate_data(aggregated_data, delta)
|
1549
|
-
</span><span class="uncovered1"><a name="line949"></a>949 callsites1, defsites1 = aggregated_data
|
1550
|
-
</span><span class="uncovered0"><a name="line950"></a>950 callsites2, defsites2 = delta
|
1551
|
-
</span><span class="uncovered1"><a name="line951"></a>951
|
1552
|
-
</span><span class="uncovered0"><a name="line952"></a>952 callsites2.each_pair do |(klass, method), hash|
|
1553
|
-
</span><span class="uncovered1"><a name="line953"></a>953 dest_hash = (callsites1[[klass, method]] ||= {})
|
1554
|
-
</span><span class="uncovered0"><a name="line954"></a>954 hash.each_pair do |callsite, count|
|
1555
|
-
</span><span class="uncovered1"><a name="line955"></a>955 dest_hash[callsite] ||= 0
|
1556
|
-
</span><span class="uncovered0"><a name="line956"></a>956 dest_hash[callsite] += count
|
1557
|
-
</span><span class="uncovered1"><a name="line957"></a>957 end
|
1558
|
-
</span><span class="uncovered0"><a name="line958"></a>958 end
|
1559
|
-
</span><span class="uncovered1"><a name="line959"></a>959
|
1560
|
-
</span><span class="uncovered0"><a name="line960"></a>960 defsites1.update(defsites2)
|
1561
|
-
</span><span class="uncovered1"><a name="line961"></a>961 end
|
1562
|
-
</span><span class="uncovered0"><a name="line962"></a>962
|
1563
|
-
</span><span class="uncovered1"><a name="line963"></a>963 def compute_raw_data_difference(first, last)
|
1564
|
-
</span><span class="uncovered0"><a name="line964"></a>964 difference = {}
|
1565
|
-
</span><span class="uncovered1"><a name="line965"></a>965 default = Hash.new(0)
|
1566
|
-
</span><span class="uncovered0"><a name="line966"></a>966
|
1567
|
-
</span><span class="uncovered1"><a name="line967"></a>967 callsites1, defsites1 = *first
|
1568
|
-
</span><span class="uncovered0"><a name="line968"></a>968 callsites2, defsites2 = *last
|
1569
|
-
</span><span class="uncovered1"><a name="line969"></a>969
|
1570
|
-
</span><span class="uncovered0"><a name="line970"></a>970 callsites2.each_pair do |(klass, method), hash|
|
1571
|
-
</span><span class="uncovered1"><a name="line971"></a>971 old_hash = callsites1[[klass, method]] || default
|
1572
|
-
</span><span class="uncovered0"><a name="line972"></a>972 hash.each_pair do |callsite, count|
|
1573
|
-
</span><span class="uncovered1"><a name="line973"></a>973 diff = hash[callsite] - (old_hash[callsite] || 0)
|
1574
|
-
</span><span class="uncovered0"><a name="line974"></a>974 if diff > 0
|
1575
|
-
</span><span class="uncovered1"><a name="line975"></a>975 difference[[klass, method]] ||= {}
|
1576
|
-
</span><span class="uncovered0"><a name="line976"></a>976 difference[[klass, method]][callsite] = diff
|
1577
|
-
</span><span class="uncovered1"><a name="line977"></a>977 end
|
1578
|
-
</span><span class="uncovered0"><a name="line978"></a>978 end
|
1579
|
-
</span><span class="uncovered1"><a name="line979"></a>979 end
|
1580
|
-
</span><span class="uncovered0"><a name="line980"></a>980
|
1581
|
-
</span><span class="uncovered1"><a name="line981"></a>981 [difference, defsites1.update(defsites2)]
|
1582
|
-
</span><span class="uncovered0"><a name="line982"></a>982 end
|
1583
|
-
</span><span class="uncovered1"><a name="line983"></a>983
|
1584
|
-
</span><span class="uncovered0"><a name="line984"></a>984 end
|
1585
|
-
</span><span class="uncovered1"><a name="line985"></a>985
|
1586
|
-
</span><span class="uncovered0"><a name="line986"></a>986 end # Rcov
|
1587
|
-
</span><span class="inferred1"><a name="line987"></a>987
|
1588
|
-
</span><span class="inferred0"><a name="line988"></a>988 # vi: set sw=2:
|
1589
|
-
</span></pre><hr/>
|
1590
|
-
<p>Generated using the <a href='http://eigenclass.org/hiki.rb?rcov'>rcov code coverage analysis tool for Ruby</a>
|
1591
|
-
version 0.8.1.2.</p>
|
1592
|
-
<p><a href='http://validator.w3.org/check/referer'><img src='http://www.w3.org/Icons/valid-xhtml10' height='31' alt='Valid XHTML 1.0!' width='88'/>
|
1593
|
-
</a>
|
1594
|
-
<a href='http://jigsaw.w3.org/css-validator/check/referer'><img src='http://jigsaw.w3.org/css-validator/images/vcss' alt='Valid CSS!' style='border:0;width:88px;height:31px'/>
|
1595
|
-
</a>
|
1596
|
-
</p>
|
1597
|
-
</body>
|
1598
|
-
</html>
|