hooligan495-rcov 0.8.1.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,471 @@
1
+ require File.dirname(__FILE__) + '/test_helper'
2
+
3
+ class TestFileStatistics < Test::Unit::TestCase
4
+ def test_trailing_end_is_inferred
5
+ verify_everything_marked "trailing end", <<-EOF
6
+ 1 class X
7
+ 1 def foo
8
+ 2 "foo"
9
+ 0 end
10
+ 0 end
11
+ EOF
12
+ verify_everything_marked "trailing end with comments", <<-EOF
13
+ 1 class X
14
+ 1 def foo
15
+ 2 "foo"
16
+ 0 end
17
+ 0 # foo bar
18
+ 0 =begin
19
+ 0 ....
20
+ 0 =end
21
+ 0 end
22
+ EOF
23
+ end
24
+
25
+ def test_begin_ensure_else_case_are_inferred
26
+ verify_everything_marked "begin ensure else case", <<-EOF
27
+ 0 begin
28
+ # bleh
29
+ 2 puts a
30
+ 0 begin
31
+ 2 raise "foo"
32
+ 0 rescue Exception => e
33
+ 2 puts b
34
+ 0 ensure
35
+ 2 puts c
36
+ 0 end
37
+ 2 if a()
38
+ 1 b
39
+ 0 else
40
+ 1 c
41
+ 0 end
42
+ 0 case
43
+ 2 when bar =~ /foo/
44
+ 1 puts "bar"
45
+ 0 else
46
+ 1 puts "baz"
47
+ 0 end
48
+ 0 end
49
+ EOF
50
+ end
51
+
52
+ def test_rescue_is_inferred
53
+ verify_everything_marked "rescue", <<-EOF
54
+ 0 begin
55
+ 1 foo
56
+ 0 rescue
57
+ 1 puts "bar"
58
+ 0 end
59
+ EOF
60
+ end
61
+
62
+ def test_code_metrics_are_computed_correctly
63
+ lines, coverage, counts = code_info_from_string <<-EOF
64
+ 1 a = 1
65
+ 0 # this is a comment
66
+ 1 if bar
67
+ 0 b = 2
68
+ 0 end
69
+ 0 =begin
70
+ 0 this too
71
+ 0 bleh
72
+ 0 =end
73
+ 0 puts <<EOF
74
+ 0 bleh
75
+ 0 EOF
76
+ 3 c.times{ i += 1}
77
+ EOF
78
+ sf = Rcov::FileStatistics.new("metrics", lines, counts)
79
+ assert_in_delta(0.307, sf.total_coverage, 0.01)
80
+ assert_in_delta(0.375, sf.code_coverage, 0.01)
81
+ assert_equal(8, sf.num_code_lines)
82
+ assert_equal(13, sf.num_lines)
83
+ assert_equal([true, :inferred, true, false, false, false, false, false,
84
+ false, false, false, false, true], sf.coverage.to_a)
85
+ end
86
+
87
+ def test_merge
88
+ lines, coverage, counts = code_info_from_string <<-EOF
89
+ 1 a = 1
90
+ 1 if bar
91
+ 0 b = 2
92
+ 0 end
93
+ 1 puts <<EOF
94
+ 0 bleh
95
+ 0 EOF
96
+ 3 c.times{ i += 1}
97
+ EOF
98
+ sf = Rcov::FileStatistics.new("merge", lines, counts)
99
+ lines, coverage, counts = code_info_from_string <<-EOF
100
+ 1 a = 1
101
+ 1 if bar
102
+ 1 b = 2
103
+ 0 end
104
+ 1 puts <<EOF
105
+ 0 bleh
106
+ 0 EOF
107
+ 10 c.times{ i += 1}
108
+ EOF
109
+ sf2 = Rcov::FileStatistics.new("merge", lines, counts)
110
+ expected = [true, true, true, :inferred, true, :inferred, :inferred, true]
111
+ assert_equal(expected, sf2.coverage.to_a)
112
+ sf.merge(sf2.lines, sf2.coverage, sf2.counts)
113
+ assert_equal(expected, sf.coverage.to_a)
114
+ assert_equal([2, 2, 1, 0, 2, 0, 0, 13], sf.counts)
115
+ end
116
+
117
+ def test_last_comment_block_is_marked
118
+ verify_everything_marked "last comment block", <<-EOF
119
+ 1 a = 1
120
+ 1 b = 1
121
+ 0 # foo
122
+ 0 # bar baz
123
+ EOF
124
+ verify_everything_marked "last comment block, =begin/=end", <<-EOF
125
+ 1 a = 1
126
+ 2 b = 1
127
+ 0 # fooo
128
+ 0 =begin
129
+ 0 bar baz
130
+ 0 =end
131
+ EOF
132
+ verify_everything_marked "last comment block, __END__", <<-EOF
133
+ 1 a = 1
134
+ 2 b = 1
135
+ 0 # fooo
136
+ 0 =begin
137
+ 0 bar baz
138
+ 0 =end
139
+ __END__
140
+ EOF
141
+ end
142
+
143
+ def test_heredocs_basic
144
+ verify_everything_marked "heredocs-basic.rb", <<-EOF
145
+ 1 puts 1 + 1
146
+ 1 puts <<HEREDOC
147
+ 0 first line of the heredoc
148
+ 0 not marked
149
+ 0 but should be
150
+ 0 HEREDOC
151
+ 1 puts 1
152
+ EOF
153
+ verify_everything_marked "squote", <<-EOF
154
+ 1 puts <<'HEREDOC'
155
+ 0 first line of the heredoc
156
+ 0 HEREDOC
157
+ EOF
158
+ verify_everything_marked "dquote", <<-EOF
159
+ 1 puts <<"HEREDOC"
160
+ 0 first line of the heredoc
161
+ 0 HEREDOC
162
+ EOF
163
+ verify_everything_marked "xquote", <<-EOF
164
+ 1 puts <<`HEREDOC`
165
+ 0 first line of the heredoc
166
+ 0 HEREDOC
167
+ EOF
168
+ verify_everything_marked "stuff-after-heredoc", <<-EOF
169
+ 1 full_message = build_message(msg, <<EOT, object1, object2)
170
+ 0 <?> and <?> do not contain the same elements
171
+ 0 EOT
172
+ EOF
173
+ end
174
+
175
+ def test_heredocs_multiple
176
+ verify_everything_marked "multiple-unquoted", <<-EOF
177
+ 1 puts <<HEREDOC, <<HERE2
178
+ 0 first line of the heredoc
179
+ 0 HEREDOC
180
+ 0 second heredoc
181
+ 0 HERE2
182
+ EOF
183
+ verify_everything_marked "multiple-quoted", <<-EOF
184
+ 1 puts <<'HEREDOC', <<`HERE2`, <<"HERE3"
185
+ 0 first line of the heredoc
186
+ 0 HEREDOC
187
+ 0 second heredoc
188
+ 0 HERE2
189
+ 0 dsfdsfffd
190
+ 0 HERE3
191
+ EOF
192
+ verify_everything_marked "same-identifier", <<-EOF
193
+ 1 puts <<H, <<H
194
+ 0 foo
195
+ 0 H
196
+ 0 bar
197
+ 0 H
198
+ EOF
199
+ verify_everything_marked "stuff-after-heredoc", <<-EOF
200
+ 1 full_message = build_message(msg, <<EOT, object1, object2, <<EOT)
201
+ 0 <?> and <?> do not contain the same elements
202
+ 0 EOT
203
+ 0 <?> and <?> are foo bar baz
204
+ 0 EOT
205
+ EOF
206
+ end
207
+ def test_ignore_non_heredocs
208
+ verify_marked_exactly "bitshift-numeric", [0], <<-EOF
209
+ 1 puts 1<<2
210
+ 0 return if foo
211
+ 0 do_stuff()
212
+ 0 2
213
+ EOF
214
+ verify_marked_exactly "bitshift-symbolic", [0], <<-EOF
215
+ 1 puts 1<<LSHIFT
216
+ 0 return if bar
217
+ 0 do_stuff()
218
+ 0 LSHIFT
219
+ EOF
220
+ verify_marked_exactly "bitshift-symbolic-multi", 0..3, <<-EOF
221
+ 1 puts <<EOF, 1<<LSHIFT
222
+ 0 random text
223
+ 0 EOF
224
+ 1 return if bar
225
+ 0 puts "foo"
226
+ 0 LSHIFT
227
+ EOF
228
+ verify_marked_exactly "bitshift-symshift-evil", 0..2, <<-EOF
229
+ 1 foo = 1
230
+ 1 puts foo<<CONS
231
+ 1 return if bar
232
+ 0 foo + baz
233
+ EOF
234
+ end
235
+
236
+ def test_heredocs_with_interpolation_alone_in_method
237
+ verify_everything_marked "lonely heredocs with interpolation", <<-'EOS'
238
+ 1 def to_s
239
+ 0 <<-EOF
240
+ 1 #{name}
241
+ 0 #{street}
242
+ 0 #{city}, #{state}
243
+ 0 #{zip}
244
+ 0 EOF
245
+ 0 end
246
+ EOS
247
+ end
248
+
249
+ def test_handle_multiline_expressions
250
+ verify_everything_marked "expression", <<-EOF
251
+ 1 puts 1, 2.
252
+ 0 abs +
253
+ 0 1 -
254
+ 0 1 *
255
+ 0 1 /
256
+ 0 1, 1 <
257
+ 0 2, 3 >
258
+ 0 4 %
259
+ 0 3 &&
260
+ 0 true ||
261
+ 0 foo <<
262
+ 0 bar(
263
+ 0 baz[
264
+ 0 {
265
+ 0 1,2}] =
266
+ 0 1 )
267
+ EOF
268
+ verify_everything_marked "boolean expression", <<-EOF
269
+ 1 x = (foo and
270
+ 0 bar) or
271
+ 0 baz
272
+ EOF
273
+ verify_marked_exactly "code blocks", [0, 3, 6], <<-EOF
274
+ 1 x = foo do # stuff
275
+ 0 baz
276
+ 0 end
277
+ 1 bar do |x|
278
+ 0 baz
279
+ 0 end
280
+ 1 bar {|a, b| # bleh | +1
281
+ 0 baz
282
+ 0 }
283
+ EOF
284
+ verify_everything_marked "escaped linebreaks", <<-EOF
285
+ 1 def t2
286
+ 0 puts \\
287
+ 1 "foo"
288
+ 0 end
289
+ 0 end
290
+ EOF
291
+ end
292
+
293
+ def test_handle_multiline_blocks_first_not_marked
294
+ verify_everything_marked "multiline block first not marked", <<-'EOF'
295
+ 1 blah = Array.new
296
+ 1 10.times do
297
+ 0 blah << lambda do |f|
298
+ 1 puts "I should say #{f}!"
299
+ 0 end
300
+ 0 end
301
+ EOF
302
+ end
303
+
304
+ def test_handle_multiline_blocks_last_line_not_marked
305
+ verify_everything_marked "multiline block last not marked", <<-'EOF'
306
+ 1 blee = [1, 2, 3]
307
+ 0 blee.map! do |e|
308
+ 1 [e, e]
309
+ 0 end.flatten!
310
+ 1 p blee
311
+ EOF
312
+ end
313
+
314
+ def test_handle_multiline_data_with_trailing_stuff_on_last_line
315
+ verify_everything_marked "multiline data hash", <<-'EOF'
316
+ 1 @review = Review.new({
317
+ 0 :product_id => params[:id],
318
+ 0 :user => current_user
319
+ 0 }.merge(params[:review])) #red
320
+ 1 @review.save
321
+ EOF
322
+ end
323
+
324
+ def test_handle_multiline_expression_1st_line_ends_in_block_header
325
+ # excerpt taken from mongrel/handlers.rb
326
+ verify_everything_marked "multiline with block starting on 1st", <<-EOF
327
+ 1 uris = listener.classifier.handler_map
328
+ 0 results << table("handlers", uris.map {|uri,handlers|
329
+ 1 [uri,
330
+ 0 "<pre>" +
331
+ 1 handlers.map {|h| h.class.to_s }.join("\n") +
332
+ 0 "</pre>"
333
+ 0 ]
334
+ 1 })
335
+ EOF
336
+ end
337
+
338
+ def test_handle_multiple_block_end_delimiters_in_empty_line
339
+ verify_everything_marked "multiline with }) delimiter, forward", <<-EOF
340
+ 1 assert(@c.config == {
341
+ 0 'host' => 'myhost.tld',
342
+ 0 'port' => 1234
343
+ 0 })
344
+ EOF
345
+ verify_everything_marked "multiline with }) delimiter, backwards", <<-EOF
346
+ 0 assert(@c.config == {
347
+ 0 'host' => 'myhost.tld',
348
+ 0 'port' => 1234
349
+ 1 })
350
+ EOF
351
+ end
352
+
353
+ STRING_DELIMITER_PAIRS = [
354
+ %w-%{ }-, %w-%q{ }-, %w-%Q{ }-, %w{%[ ]}, %w{%q[ ]},
355
+ %w{%( )}, %w{%Q( )}, %w{%Q[ ]}, %w{%q! !}, %w{%! !},
356
+ ]
357
+
358
+ def test_multiline_strings_basic
359
+ STRING_DELIMITER_PAIRS.each do |s_delim, e_delim|
360
+ verify_everything_marked "multiline strings, basic #{s_delim}", <<-EOF
361
+ 1 PATTERN_TEXT = #{s_delim}
362
+ 0 NUMBERS = 'one|two|three|four|five'
363
+ 0 ON_OFF = 'on|off'
364
+ 0 #{e_delim}
365
+ EOF
366
+ end
367
+ STRING_DELIMITER_PAIRS.each do |s_delim, e_delim|
368
+ verify_marked_exactly "multiline strings, escaped #{s_delim}", [0], <<-EOF
369
+ 1 PATTERN_TEXT = #{s_delim} foooo bar baz \\#{e_delim} baz #{e_delim}
370
+ 0 NUMBERS = 'one|two|three|four|five'
371
+ 0 ON_OFF = 'on|off'
372
+ EOF
373
+
374
+ verify_marked_exactly "multiline strings, #{s_delim}, interpolation",
375
+ [0], <<-EOF
376
+ 1 PATTERN_TEXT = #{s_delim} \#{#{s_delim} foo #{e_delim}} \\#{e_delim} baz #{e_delim}
377
+ 0 NUMBERS = 'one|two|three|four|five'
378
+ 0 ON_OFF = 'on|off'
379
+ EOF
380
+ end
381
+ end
382
+
383
+ def test_multiline_strings_escaped_delimiter
384
+ STRING_DELIMITER_PAIRS.each do |s_delim, e_delim|
385
+ verify_everything_marked "multiline, escaped #{s_delim}", <<-EOF
386
+ 1 PATTERN_TEXT = #{s_delim} foo \\#{e_delim}
387
+ 0 NUMBERS = 'one|two|three|four|five'
388
+ 0 ON_OFF = 'on|off'
389
+ 0 #{e_delim}
390
+ EOF
391
+ end
392
+ end
393
+
394
+ def test_handle_multiline_expressions_with_heredocs
395
+ verify_everything_marked "multiline and heredocs", <<-EOF
396
+ 1 puts <<EOF +
397
+ 0 testing
398
+ 0 one two three
399
+ 0 EOF
400
+ 0 somevar
401
+ EOF
402
+ end
403
+
404
+ def test_begin_end_comment_blocks
405
+ verify_everything_marked "=begin/=end", <<-EOF
406
+ 1 x = foo
407
+ 0 =begin
408
+ 0 return if bar(x)
409
+ 0 =end
410
+ 1 y = 1
411
+ EOF
412
+ end
413
+
414
+ def test_is_code_p
415
+ verify_is_code "basic", [true] + [false] * 5 + [true], <<-EOF
416
+ 1 x = foo
417
+ 0 =begin
418
+ 0 return if bar
419
+ 0 =end
420
+ 0 # foo
421
+ 0 # bar
422
+ 1 y = 1
423
+ EOF
424
+ end
425
+
426
+ def test_is_code_p_tricky_heredocs
427
+ verify_is_code "tricky heredocs", [true] * 4, <<-EOF
428
+ 2 x = foo <<EOF and return
429
+ 0 =begin
430
+ 0 EOF
431
+ 0 z = x + 1
432
+ EOF
433
+ end
434
+
435
+ def verify_is_code(testname, is_code_arr, str)
436
+ lines, coverage, counts = code_info_from_string str
437
+
438
+ sf = Rcov::FileStatistics.new(testname, lines, counts)
439
+ is_code_arr.each_with_index do |val,i|
440
+ assert_equal(val, sf.is_code?(i),
441
+ "Unable to detect =begin comments properly: #{lines[i].inspect}")
442
+ end
443
+ end
444
+
445
+ def verify_marked_exactly(testname, marked_indices, str)
446
+ lines, coverage, counts = code_info_from_string(str)
447
+
448
+ sf = Rcov::FileStatistics.new(testname, lines, counts)
449
+ lines.size.times do |i|
450
+ if marked_indices.include? i
451
+ assert(sf.coverage[i], "Test #{testname}; " +
452
+ "line should have been marked: #{lines[i].inspect}.")
453
+ else
454
+ assert(!sf.coverage[i], "Test #{testname}; " +
455
+ "line should not have been marked: #{lines[i].inspect}.")
456
+ end
457
+ end
458
+ end
459
+
460
+ def verify_everything_marked(testname, str)
461
+ verify_marked_exactly(testname, (0...str.size).to_a, str)
462
+ end
463
+
464
+
465
+ def code_info_from_string(str)
466
+ str = str.gsub(/^\s*/,"")
467
+ [ str.map{|line| line.sub(/^\d+ /, "") },
468
+ str.map{|line| line[/^\d+/].to_i > 0},
469
+ str.map{|line| line[/^\d+/].to_i } ]
470
+ end
471
+ end