flog 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,82 +1,84 @@
1
- require 'test/test_helper'
1
+ require 'minitest/autorun'
2
2
  require 'flog'
3
- require 'sexp_processor'
4
-
5
- class Flog
6
- attr_writer :total_score
7
- end
8
3
 
9
4
  class TestFlog < MiniTest::Unit::TestCase
10
5
  def setup
11
6
  @flog = Flog.new
12
7
  end
13
8
 
14
- # def test_sanity
15
- # # FIX: make this easy to pass in to Flog.new
16
- # ARGV.push("-a")
17
- # opts = Flog.parse_options
18
- # ARGV.clear
19
- # @flog.flog __FILE__
20
- #
21
- # test_methods = self.class.instance_methods(false).sort.map { |m|
22
- # "#{self.class}##{m}"
23
- # }
24
- #
25
- # expected_calls = ["Flog#none"] + test_methods + ["main#none"]
26
- #
27
- # assert_in_delta 1.0, @flog.multiplier, 0.001
28
- # assert_equal expected_calls, @flog.calls.keys.sort
29
- # assert_equal 1, @flog.mass.size
30
- # assert_operator @flog.mass[__FILE__], :>, 100
31
- # assert_equal [], @flog.class_stack
32
- # assert_equal [], @flog.method_stack
33
- #
34
- # # FIX: this sucks, but it is a start.
35
- # out = StringIO.new
36
- # @flog.report out
37
- # out = out.string
38
- #
39
- # assert_match(/[\d\.]+: flog total/, out)
40
- # assert_match(/[\d\.]+: flog.method average/, out)
41
- #
42
- # test_methods.each do |m|
43
- # assert_match(/[\d\.]+: #{m}/, out)
44
- # end
45
- # end
46
-
47
- def test_class_expand_dirs_to_files
9
+ def test_add_to_score
10
+ assert_empty @flog.calls
11
+ @flog.class_stack << "MyKlass"
12
+ @flog.method_stack << "mymethod"
13
+ @flog.add_to_score "blah", 42
14
+
15
+ expected = {"MyKlass#mymethod" => {"blah" => 42.0}}
16
+ assert_equal expected, @flog.calls
17
+
18
+ @flog.add_to_score "blah", 2
19
+
20
+ expected["MyKlass#mymethod"]["blah"] = 44.0
21
+ assert_equal expected, @flog.calls
22
+ end
23
+
24
+ def test_average
25
+ test_process_and
26
+
27
+ assert_equal 1.0, @flog.average
28
+ end
29
+
30
+ def test_cls_expand_dirs_to_files
48
31
  expected = %w(lib/flog.rb lib/flog_task.rb lib/gauntlet_flog.rb)
49
32
  assert_equal expected, Flog.expand_dirs_to_files('lib')
50
33
  expected = %w(Rakefile)
51
34
  assert_equal expected, Flog.expand_dirs_to_files('Rakefile')
52
35
  end
53
36
 
54
- def test_class_parse_options
55
- d = Flog.default_options
56
- assert_equal d, Flog.parse_options
57
-
58
- options = {
59
- "-a" => :all,
60
- "-b" => :blame,
61
- "-c" => :continue,
62
- "-d" => :details,
63
- "-g" => :group,
64
- "-m" => :methods,
65
- "-q" => :quiet,
66
- "-s" => :score,
67
- "-v" => :verbose,
68
- }
69
-
70
- options.each do |arg, opt|
71
- ARGV.replace [arg]
72
- assert_equal d.merge(opt => true), Flog.parse_options
37
+ def test_cls_parse_options
38
+ # defaults
39
+ opts = Flog.parse_options
40
+ assert_equal true, opts[:quiet]
41
+ assert_equal false, opts[:continue]
42
+
43
+ {
44
+ "-a" => :all,
45
+ "--all" => :all,
46
+ "-b" => :blame,
47
+ "--blame" => :blame,
48
+ "-c" => :continue,
49
+ "--continue" => :continue,
50
+ "-d" => :details,
51
+ "--details" => :details,
52
+ "-g" => :group,
53
+ "--group" => :group,
54
+ "-m" => :methods,
55
+ "--methods-only" => :methods,
56
+ "-q" => :quiet,
57
+ "--quiet" => :quiet,
58
+ "-s" => :score,
59
+ "--score" => :score,
60
+ "-v" => :verbose,
61
+ "--verbose" => :verbose,
62
+ }.each do |key, val|
63
+ assert_equal true, Flog.parse_options(key)[val]
73
64
  end
65
+ end
74
66
 
75
- old_load_path = $:.dup
76
- ARGV.replace ["-Iblah1,blah2"]
77
- assert_equal d, Flog.parse_options
78
- assert_equal old_load_path + %w(blah1 blah2), $:
67
+ def test_cls_parse_options_path
68
+ old_path = $:.dup
69
+ Flog.parse_options("-Ia,b,c")
70
+ assert_equal old_path + %w(a b c), $:
79
71
 
72
+ Flog.parse_options(["-I", "d,e,f"])
73
+ assert_equal old_path + %w(a b c d e f), $:
74
+
75
+ Flog.parse_options(["-I", "g", "-Ih"])
76
+ assert_equal old_path + %w(a b c d e f g h), $:
77
+ ensure
78
+ $:.replace old_path
79
+ end
80
+
81
+ def test_cls_parse_options_help
80
82
  def Flog.exit
81
83
  raise "happy"
82
84
  end
@@ -84,50 +86,46 @@ class TestFlog < MiniTest::Unit::TestCase
84
86
  ex = nil
85
87
  o, e = capture_io do
86
88
  ex = assert_raises RuntimeError do
87
- ARGV.replace ["-h"]
88
- Flog.parse_options
89
+ Flog.parse_options "-h"
89
90
  end
90
91
  end
92
+
91
93
  assert_equal "happy", ex.message
92
94
  assert_match(/methods-only/, o)
93
95
  assert_equal "", e
94
- ensure
95
- ARGV.clear
96
96
  end
97
97
 
98
- def test_add_to_score
99
- assert_empty @flog.calls
100
- @flog.class_stack << "MyKlass"
101
- @flog.method_stack << "mymethod"
102
- @flog.add_to_score "blah", 42
98
+ def test_flog
99
+ old_stdin = $stdin
100
+ $stdin = StringIO.new "2 + 3"
101
+ $stdin.rewind
103
102
 
104
- expected = {"MyKlass#mymethod"=>{"blah"=>42.0}}
105
- assert_equal expected, @flog.calls
103
+ @flog.flog "-"
106
104
 
107
- @flog.add_to_score "blah", 2
105
+ exp = { "main#none" => { :+ => 1.0, :lit_fixnum => 0.6 } }
106
+ assert_equal exp, @flog.calls
108
107
 
109
- expected["MyKlass#mymethod"]["blah"] = 44.0
110
- assert_equal expected, @flog.calls
108
+ assert_equal 1.6, @flog.total unless @flog.option[:methods]
109
+ assert_equal 4, @flog.mass["-"]
110
+ ensure
111
+ $stdin = old_stdin
111
112
  end
112
113
 
113
- # def test_analyze_list
114
- # raise NotImplementedError, 'Need to write test_analyze_list'
115
- # end
114
+ def test_flog_erb
115
+ old_stdin = $stdin
116
+ $stdin = StringIO.new "2 + <%= blah %>"
117
+ $stdin.rewind
116
118
 
117
- def test_average
118
- assert_equal 0, Flog.new.average
119
- # TODO: non-zero... but do total/totals first
120
- end
119
+ o, e = capture_io do
120
+ @flog.flog "-"
121
+ end
121
122
 
122
- def test_calls
123
- expected = {}
124
- assert_equal expected, Flog.new.calls
123
+ assert_equal "", o
124
+ assert_match(/stupid lemmings/, e)
125
+ ensure
126
+ $stdin = old_stdin
125
127
  end
126
128
 
127
- # def test_flog
128
- # raise NotImplementedError, 'Need to write test_flog'
129
- # end
130
-
131
129
  def test_in_klass
132
130
  assert_empty @flog.class_stack
133
131
 
@@ -141,60 +139,120 @@ class TestFlog < MiniTest::Unit::TestCase
141
139
  def test_in_method
142
140
  assert_empty @flog.method_stack
143
141
 
144
- @flog.in_method "xxx" do
142
+ @flog.in_method "xxx", "file.rb", 42 do
145
143
  assert_equal ["xxx"], @flog.method_stack
146
144
  end
147
145
 
148
146
  assert_empty @flog.method_stack
147
+
148
+ expected = {"main#xxx" => "file.rb:42"}
149
+ assert_equal expected, @flog.method_locations
150
+ end
151
+
152
+ def test_klass_name
153
+ assert_equal :main, @flog.klass_name
154
+
155
+ @flog.class_stack << "whatevs"
156
+ assert_equal "whatevs", @flog.klass_name
157
+ end
158
+
159
+ def test_klass_name_sexp
160
+ @flog.in_klass s(:colon2, s(:const, :X), :Y) do
161
+ assert_equal "X::Y", @flog.klass_name
162
+ end
163
+
164
+ @flog.in_klass s(:colon3, :Y) do
165
+ assert_equal "Y", @flog.klass_name
166
+ end
167
+ end
168
+
169
+ def test_method_name
170
+ assert_equal :none, @flog.method_name
171
+
172
+ @flog.method_stack << "whatevs"
173
+ assert_equal "#whatevs", @flog.method_name
174
+ end
175
+
176
+ def test_method_name_cls
177
+ assert_equal :none, @flog.method_name
178
+
179
+ @flog.method_stack << "::whatevs"
180
+ assert_equal "::whatevs", @flog.method_name
181
+ end
182
+
183
+ def test_output_details
184
+ test_flog
185
+
186
+ o = StringIO.new
187
+ @flog.output_details o
188
+
189
+ assert_equal "\n 1.6: main#none\n", o.string
190
+ end
191
+
192
+ def test_output_details_group
193
+ @flog.option[:group] = true
194
+
195
+ test_flog
196
+
197
+ o = StringIO.new
198
+ @flog.output_details o
199
+
200
+ expected = "\n 1.6: main total\n 1.6: main#none\n"
201
+
202
+ assert_equal expected, o.string
149
203
  end
150
204
 
151
- # def test_increment_total_score_by
152
- # raise NotImplementedError, 'Need to write test_increment_total_score_by'
153
- # end
154
- #
155
- # def test_klass_name
156
- # raise NotImplementedError, 'Need to write test_klass_name'
157
- # end
158
- #
159
- # def test_mass
160
- # raise NotImplementedError, 'Need to write test_mass'
161
- # end
162
- #
163
- # def test_method_name
164
- # raise NotImplementedError, 'Need to write test_method_name'
165
- # end
166
- #
167
- # def test_method_stack
168
- # raise NotImplementedError, 'Need to write test_method_stack'
169
- # end
170
- #
171
- # def test_multiplier
172
- # raise NotImplementedError, 'Need to write test_multiplier'
173
- # end
174
- #
175
- # def test_multiplier_equals
176
- # raise NotImplementedError, 'Need to write test_multiplier_equals'
177
- # end
178
- #
179
- # def test_options
180
- # raise NotImplementedError, 'Need to write test_options'
181
- # end
182
- #
183
- # def test_output_details
184
- # raise NotImplementedError, 'Need to write test_output_details'
185
- # end
186
- #
187
- # def test_output_method_details
188
- # raise NotImplementedError, 'Need to write test_output_method_details'
189
- # end
190
- #
191
- # def test_output_summary
192
- # raise NotImplementedError, 'Need to write test_output_summary'
193
- # end
194
- #
195
- # def test_parse_tree
196
- # raise NotImplementedError, 'Need to write test_parse_tree'
197
- # end
205
+ def test_output_method_details
206
+ test_flog
207
+
208
+ @flog.totals["main#something"] = 42.0
209
+
210
+ o = StringIO.new
211
+ n = @flog.output_method_details o, "main#none", @flog.calls["main#none"]
212
+
213
+ expected = " 1.6: main#none\n"
214
+
215
+ assert_equal expected, o.string
216
+ assert_equal 1.6, n
217
+ end
218
+
219
+ def test_output_method_details_methods
220
+ @flog.option[:methods] = true
221
+
222
+ test_flog
223
+
224
+ @flog.totals["main#something"] = 42.0
225
+
226
+ o = StringIO.new
227
+ n = @flog.output_method_details o, "main#none", @flog.calls["main#none"]
228
+
229
+ assert_equal "", o.string
230
+ assert_equal 0, n
231
+ end
232
+
233
+ def test_output_method_details_detailed
234
+ @flog.option[:details] = true
235
+
236
+ test_flog
237
+
238
+ @flog.totals["main#something"] = 42.0
239
+
240
+ o = StringIO.new
241
+ n = @flog.output_method_details o, "main#none", @flog.calls["main#none"]
242
+
243
+ expected = " 1.6: main#none
244
+ 1.0: +
245
+ 0.6: lit_fixnum
246
+
247
+ "
248
+
249
+ assert_equal expected, o.string
250
+ assert_equal 1.6, n
251
+ end
252
+
253
+ # def test_process_until_empty
254
+ # flunk "no"
255
+ # end
198
256
 
199
257
  def test_penalize_by
200
258
  assert_equal 1, @flog.multiplier
@@ -204,1283 +262,274 @@ class TestFlog < MiniTest::Unit::TestCase
204
262
  assert_equal 1, @flog.multiplier
205
263
  end
206
264
 
207
- # def test_record_method_score
208
- # raise NotImplementedError, 'Need to write test_record_method_score'
209
- # end
210
- #
211
- # def test_report
212
- # raise NotImplementedError, 'Need to write test_report'
213
- # end
214
- #
215
- # def test_reset
216
- # raise NotImplementedError, 'Need to write test_reset'
217
- # end
265
+ def test_process_alias
266
+ sexp = s(:alias, s(:lit, :a), s(:lit, :b))
267
+
268
+ util_process sexp, 2.0, :alias => 2.0
269
+ end
270
+
271
+ def test_process_and
272
+ sexp = s(:and, s(:lit, :a), s(:lit, :b))
273
+
274
+ util_process sexp, 1.0, :branch => 1.0
275
+ end
276
+
277
+ def test_process_attrasgn
278
+ sexp = s(:attrasgn,
279
+ s(:call, nil, :a, s(:arglist)),
280
+ :[]=,
281
+ s(:arglist,
282
+ s(:splat,
283
+ s(:call, nil, :b, s(:arglist))),
284
+ s(:call, nil, :c, s(:arglist))))
285
+
286
+ util_process(sexp, 3.162,
287
+ :c => 1.0, :b => 1.0, :a => 1.0, :assignment => 1.0)
288
+ end
289
+
290
+ # def test_process_attrset
291
+ # sexp = s(:attrset, :@writer)
292
+ #
293
+ # util_process(sexp, 3.162,
294
+ # :c => 1.0, :b => 1.0, :a => 1.0, :assignment => 1.0)
295
+ #
296
+ # flunk "Not yet"
297
+ # end
298
+
299
+ def test_process_block
300
+ sexp = s(:block, s(:and, s(:lit, :a), s(:lit, :b)))
301
+
302
+ util_process sexp, 1.1, :branch => 1.1 # 10% penalty over process_and
303
+ end
304
+
305
+ def test_process_block_pass
306
+ sexp = s(:call, nil, :a,
307
+ s(:arglist,
308
+ s(:block_pass,
309
+ s(:call, nil, :b, s(:arglist)))))
310
+
311
+ util_process(sexp, 9.4,
312
+ :a => 1.0,
313
+ :block_pass => 1.2,
314
+ :b => 1.2,
315
+ :to_proc_normal => 6.0)
316
+ end
317
+
318
+ def test_process_call
319
+ sexp = s(:call, nil, :a, s(:arglist))
320
+ util_process sexp, 1.0, :a => 1.0
321
+ end
322
+
323
+ def test_process_case
324
+ case :a
325
+ when :a
326
+ 42
327
+ end
328
+
329
+
330
+ sexp = s(:case,
331
+ s(:lit, :a),
332
+ s(:when, s(:array, s(:lit, :a)), s(:nil)),
333
+ nil)
334
+
335
+ util_process sexp, 2.1, :branch => 2.1
336
+ end
337
+
338
+ def test_process_class
339
+ @klass = "X::Y"
340
+
341
+ sexp = s(:class,
342
+ s(:colon2, s(:const, :X), :Y), nil,
343
+ s(:scope, s(:lit, 42)))
344
+
345
+ util_process sexp, 0.25, :lit_fixnum => 0.25
346
+ end
347
+
348
+ # TODO:
349
+ # 392: alias :process_or :process_and
350
+ # 475: alias :process_iasgn :process_dasgn_curr
351
+ # 476: alias :process_lasgn :process_dasgn_curr
352
+ # 501: alias :process_rescue :process_else
353
+ # 502: alias :process_when :process_else
354
+ # 597: alias :process_until :process_while
355
+
356
+
357
+ # def test_process_dasgn_curr
358
+ # flunk "Not yet"
359
+ # end
360
+
361
+ def test_process_defn
362
+ @meth = "#x"
363
+
364
+ sexp = s(:defn, :x,
365
+ s(:args, :y),
366
+ s(:scope,
367
+ s(:block,
368
+ s(:lit, 42))))
369
+
370
+ util_process sexp, 0.275, :lit_fixnum => 0.275
371
+ end
372
+
373
+ def test_process_defs
374
+ @meth = "::x" # HACK, I don't like this
375
+
376
+ sexp = s(:defs, s(:self), :x,
377
+ s(:args, :y),
378
+ s(:scope,
379
+ s(:block,
380
+ s(:lit, 42))))
381
+
382
+ util_process sexp, 0.275, :lit_fixnum => 0.275
383
+ end
384
+
385
+ # FIX: huh? over-refactored?
386
+ # def test_process_else
387
+ # flunk "Not yet"
388
+ # end
389
+
390
+ def test_process_if
391
+ sexp = s(:if,
392
+ s(:call, nil, :b, s(:arglist)), # outside block, not penalized
393
+ s(:call, nil, :a, s(:arglist)), nil)
394
+
395
+ util_process sexp, 2.326, :branch => 1.0, :b => 1.0, :a => 1.1
396
+ end
397
+
398
+ def test_process_iter
399
+ sexp = s(:iter,
400
+ s(:call, nil, :loop, s(:arglist)), nil,
401
+ s(:if, s(:true), s(:break), nil))
402
+
403
+ util_process sexp, 2.326, :loop => 1.0, :branch => 2.1
404
+ end
405
+
406
+ def test_process_lit
407
+ sexp = s(:lit, :y)
408
+ util_process sexp, 0.0
409
+ end
410
+
411
+ def test_process_lit_int
412
+ sexp = s(:lit, 42)
413
+ util_process sexp, 0.25, :lit_fixnum => 0.25
414
+ end
415
+
416
+ def test_process_lit_float # and other lits
417
+ sexp = s(:lit, 3.1415) # TODO: consider penalizing floats if not in cdecl
418
+ util_process sexp, 0.0
419
+ end
420
+
421
+ def test_process_lit_bad
422
+ assert_raises RuntimeError do
423
+ @flog.process s(:lit, Object.new)
424
+ end
425
+ end
426
+
427
+ def test_process_masgn
428
+ sexp = s(:masgn,
429
+ s(:array, s(:lasgn, :a), s(:lasgn, :b)),
430
+ s(:to_ary, s(:call, nil, :c, s(:arglist))))
431
+
432
+ util_process sexp, 3.162, :c => 1.0, :assignment => 3.0
433
+ end
434
+
435
+ def test_process_module
436
+ @klass = "X::Y"
437
+
438
+ sexp = s(:module,
439
+ s(:colon2, s(:const, :X), :Y),
440
+ s(:scope, s(:lit, 42)))
441
+
442
+ util_process sexp, 0.25, :lit_fixnum => 0.25
443
+ end
444
+
445
+ def test_process_sclass
446
+ sexp = s(:sclass, s(:self), s(:scope, s(:lit, 42)))
447
+ util_process sexp, 5.375, :sclass => 5.0, :lit_fixnum => 0.375
448
+ end
449
+
450
+ def test_process_super
451
+ sexp = s(:super)
452
+ util_process sexp, 1.0, :super => 1.0
453
+
454
+ sexp = s(:super, s(:lit, 42))
455
+ util_process sexp, 1.25, :super => 1.0, :lit_fixnum => 0.25
456
+ end
457
+
458
+ def test_process_super
459
+ sexp = s(:super)
460
+ util_process sexp, 1.00, :super => 1.0
461
+
462
+ sexp = s(:super, s(:lit, 42))
463
+ util_process sexp, 1.25, :super => 1.0, :lit_fixnum => 0.25
464
+ end
465
+
466
+ def test_process_while
467
+ sexp = s(:while,
468
+ s(:call, nil, :a, s(:arglist)),
469
+ s(:call, nil, :b, s(:arglist)),
470
+ true)
471
+
472
+ util_process sexp, 2.417, :branch => 1.0, :a => 1.1, :b => 1.1
473
+ end
474
+
475
+ def test_process_yield
476
+ sexp = s(:yield)
477
+ util_process sexp, 1.00, :yield => 1.0
478
+
479
+ sexp = s(:yield, s(:lit, 4))
480
+ util_process sexp, 1.25, :yield => 1.0, :lit_fixnum => 0.25
481
+
482
+ sexp = s(:yield, s(:lit, 42), s(:lit, 24))
483
+ util_process sexp, 1.50, :yield => 1.0, :lit_fixnum => 0.50
484
+ end
485
+
486
+ def test_report
487
+ test_flog
488
+
489
+ o = StringIO.new
490
+ @flog.report o
491
+
492
+ expected = " 1.6: flog total
493
+ 1.6: flog/method average
494
+
495
+ 1.6: main#none
496
+ "
497
+
498
+ assert_equal expected, o.string
499
+ end
500
+
501
+ def test_report_all
502
+ @flog.option[:all] = true
503
+
504
+ test_report
505
+ # FIX: add thresholded output
506
+ end
218
507
 
219
508
  def test_score_method
220
- expected = 3.742
221
- assert_in_delta expected, @flog.score_method(:assignment => 1,
222
- :branch => 2,
223
- :other => 3)
509
+ assert_equal 3.0, @flog.score_method(:blah => 3.0)
510
+ assert_equal 4.0, @flog.score_method(:assignment => 4.0)
511
+ assert_equal 2.0, @flog.score_method(:branch => 2.0)
512
+ assert_equal 5.0, @flog.score_method(:blah => 3.0, # distance formula
513
+ :branch => 4.0)
224
514
  end
225
515
 
226
- # def test_summarize_method
227
- # raise NotImplementedError, 'Need to write test_summarize_method'
228
- # end
229
- #
230
- # def test_total
231
- # raise NotImplementedError, 'Need to write test_total'
232
- # end
233
- #
234
- # def test_totals
235
- # raise NotImplementedError, 'Need to write test_totals'
236
- # end
237
- end
516
+ def test_total
517
+ @flog.add_to_score "blah", 2
518
+ assert_equal 2.0, @flog.total
519
+ end
520
+
521
+ def util_process sexp, score = -1, hash = {}
522
+ setup
523
+ @flog.process sexp
238
524
 
239
- # Number of errors detected: 64
240
-
241
- # describe Flog do
242
- # before :each do
243
- # @options = { }
244
- # @flog = Flog.new(@options)
245
- # end
246
- #
247
- # # describe 'when initializing' do
248
- # # it 'should not reference the parse tree' do
249
- # # ParseTree.expects(:new).never
250
- # # Flog.new(@options)
251
- # # end
252
- # # end
253
- #
254
- # describe 'after initializing' do
255
- # it 'should have options set' do
256
- # @flog.options.must_equal @options
257
- # end
258
- #
259
- # it 'should return an SexpProcessor' do
260
- # @flog.must_be_kind_of(SexpProcessor)
261
- # end
262
- #
263
- # it 'should be initialized like all SexpProcessors' do
264
- # # less than ideal means of insuring the Flog instance was initialized properly, imo -RB
265
- # @flog.context.must_equal []
266
- # end
267
- #
268
- # it 'should have no current class' do
269
- # @flog.klass_name.must_equal :main
270
- # end
271
- #
272
- # it 'should have no current method' do
273
- # @flog.method_name.must_equal :none
274
- # end
275
- #
276
- # it 'should not have any calls yet' do
277
- # @flog.calls.must_equal({})
278
- # end
279
- #
280
- # it 'should have a means of accessing its parse tree' do
281
- # @flog.must_respond_to(:parse_tree)
282
- # end
283
- #
284
- # it 'should not have any totals yet' do
285
- # @flog.totals.must_equal({})
286
- # end
287
- #
288
- # it 'should have a 0 total score' do
289
- # @flog.total.must_equal 0.0
290
- # end
291
- #
292
- # it 'should have a multiplier of 1' do
293
- # @flog.multiplier.must_equal 1.0
294
- # end
295
- #
296
- # currently "should have 'auto shift type' set to true" do
297
- # @flog.auto_shift_type.must_equal true
298
- # end
299
- #
300
- # currently "should have 'require empty' set to false" do
301
- # @flog.require_empty.must_equal false
302
- # end
303
- # end
304
- #
305
- # describe 'options' do
306
- # it 'should return the current options settings' do
307
- # @flog.must_respond_to(:options)
308
- # end
309
- # end
310
- #
311
- # describe 'when accessing the parse tree' do
312
- # before :each do
313
- # @parse_tree = stub('parse tree')
314
- # end
315
- #
316
- # describe 'for the first time' do
317
- # it 'should create a new ParseTree' do
318
- # RubyParser.expects(:new)
319
- # @flog.parse_tree
320
- # end
321
- #
322
- # # HACK: most tarded spec ever
323
- # # it 'should return a ParseTree instance' do
324
- # # ParseTree.stubs(:new).returns(@parse_tree)
325
- # # @flog.parse_tree.must_equal @parse_tree
326
- # # end
327
- # end
328
- #
329
- # # HACK Jesus... this is useless.
330
- # # describe 'after the parse tree has been initialized' do
331
- # # it 'should not attempt to create a new ParseTree instance' do
332
- # # @flog.parse_tree
333
- # # ParseTree.expects(:new).never
334
- # # @flog.parse_tree
335
- # # end
336
- # #
337
- # # it 'should return a ParseTree instance' do
338
- # # ParseTree.stubs(:new).returns(@parse_tree)
339
- # # @flog.parse_tree
340
- # # @flog.parse_tree.must_equal @parse_tree
341
- # # end
342
- # # end
343
- # end
344
- #
345
- # describe "when flogging a list of files" do
346
- # describe 'when no files are specified' do
347
- # currently 'should not raise an exception' do
348
- # lambda { @flog.flog_files }.wont_raise_error
349
- # end
350
- #
351
- # it 'should never call flog_file' do
352
- # def @flog.flog_file(*args); raise "no"; end
353
- # @flog.flog_files
354
- # end
355
- # end
356
- #
357
- # # HACK
358
- # # describe 'when files are specified' do
359
- # # before :each do
360
- # # @files = [1, 2, 3, 4]
361
- # # @flog.stubs(:flog_file)
362
- # # end
363
- # #
364
- # # it 'should do a flog for each individual file' do
365
- # # @flog.expects(:flog_file).times(@files.size)
366
- # # @flog.flog_files(@files)
367
- # # end
368
- # #
369
- # # it 'should provide the filename when flogging a file' do
370
- # # @files.each do |file|
371
- # # @flog.expects(:flog_file).with(file)
372
- # # end
373
- # # @flog.flog_files(@files)
374
- # # end
375
- # # end
376
- #
377
- # describe 'when flogging a single file' do
378
- # before :each do
379
- # @flog.stubs(:flog)
380
- # end
381
- #
382
- # describe 'when the filename is "-"' do
383
- # before :each do
384
- # @stdin = $stdin # HERE: working through the fact that zenspider is using $stdin in the middle of the system
385
- # $stdin = stub('stdin', :read => 'data')
386
- # end
387
- #
388
- # after :each do
389
- # $stdin = @stdin
390
- # end
391
- #
392
- # # describe 'when reporting blame information' do
393
- # # before :each do
394
- # # @flog = Flog.new(:blame => true)
395
- # # @flog.stubs(:flog)
396
- # # end
397
- # #
398
- # # it 'should fail' do
399
- # # lambda { @flog.flog_file('-') }.must_raise(RuntimeError)
400
- # # end
401
- # # end
402
- #
403
- # # HACK: need to figure out how to do nested setup w/o inherited tests
404
- # # it 'should not raise an exception' do
405
- # # lambda { @flog.flog_file('-') }.wont_raise_error
406
- # # end
407
- #
408
- # # HACK: need to figure out how to do nested setup w/o inherited tests
409
- # # it 'should read the data from stdin' do
410
- # # $stdin.expects(:read).returns('data')
411
- # # @flog.flog_file('-')
412
- # # end
413
- #
414
- # # it 'should flog the read data' do
415
- # # @flog.expects(:flog).with('data', '-')
416
- # # @flog.flog_file('-')
417
- # # end
418
- #
419
- # describe 'when the verbose flag is on' do
420
- # before :each do
421
- # @flog = Flog.new(:verbose => true)
422
- # end
423
- #
424
- # # it 'should note which file is being flogged' do
425
- # # @flog.expects(:warn)
426
- # # @flog.flog_file('-')
427
- # # end
428
- # end
429
- #
430
- # describe 'when the verbose flag is off' do
431
- # before :each do
432
- # @flog = Flog.new({})
433
- # end
434
- #
435
- # it 'should not note which file is being flogged' do
436
- # def @flog.warn(*args); raise "no"; end
437
- # @flog.flog_file('-')
438
- # end
439
- # end
440
- # end
441
- #
442
- # describe 'when the filename points to a directory' do
443
- # before :each do
444
- # def @flog.flog_directory(*args); end
445
- # @file = File.dirname(__FILE__)
446
- # end
447
- #
448
- # it 'should expand the files under the directory' do
449
- # @flog.expects(:flog_directory)
450
- # @flog.flog_file(@file)
451
- # end
452
- #
453
- # it 'should not read data from stdin' do
454
- # def $stdin.read(*args); raise "no"; end
455
- # @flog.flog_file(@file)
456
- # end
457
- #
458
- # it 'should not flog any data' do
459
- # def @flog.flog(*args); raise "no"; end
460
- # @flog.flog_file(@file)
461
- # end
462
- # end
463
- #
464
- # describe 'when the filename points to a non-existant file' do
465
- # before :each do
466
- # @file = '/adfasdfasfas/fasdfaf-#{rand(1000000).to_s}'
467
- # end
468
- #
469
- # it 'should raise an exception' do
470
- # lambda { @flog.flog_file(@file) }.must_raise(Errno::ENOENT)
471
- # end
472
- # end
473
- #
474
- # # describe 'when the filename points to an existing file' do
475
- # # before :each do
476
- # # @file = __FILE__
477
- # # File.stubs(:read).returns('data')
478
- # # end
479
- # #
480
- # # it 'should read the contents of the file' do
481
- # # File.expects(:read).with(@file).returns('data')
482
- # # @flog.flog_file(@file)
483
- # # end
484
- # #
485
- # # it 'should flog the contents of the file' do
486
- # # @flog.expects(:flog).with('data', @file)
487
- # # @flog.flog_file(@file)
488
- # # end
489
- # #
490
- # # describe 'when the verbose flag is on' do
491
- # # before :each do
492
- # # @flog = Flog.new(:verbose => true)
493
- # # end
494
- # #
495
- # # it 'should note which file is being flogged' do
496
- # # @flog.expects(:warn)
497
- # # @flog.flog_file(@file)
498
- # # end
499
- # # end
500
- # #
501
- # # describe 'when the verbose flag is off' do
502
- # # before :each do
503
- # # @flog = Flog.new({})
504
- # # end
505
- # #
506
- # # it 'should not note which file is being flogged' do
507
- # # def @flog.warn(*args); raise "no"; end
508
- # # @flog.flog_file(@file)
509
- # # end
510
- # # end
511
- # # end
512
- # end
513
- # end
514
- #
515
- # # describe 'when flogging a directory' do
516
- # # before :each do
517
- # # @files = ['a.rb', '/foo/b.rb', '/foo/bar/c.rb', '/foo/bar/baz/d.rb']
518
- # # @dir = File.dirname(__FILE__)
519
- # # Dir.stubs(:[]).returns(@files)
520
- # # end
521
- # #
522
- # # it 'should get the list of ruby files under the directory' do
523
- # # @flog.stubs(:flog_file)
524
- # # Dir.expects(:[]).returns(@files)
525
- # # @flog.flog_directory(@dir)
526
- # # end
527
- # #
528
- # # it "should call flog_file once for each file in the directory" do
529
- # # @files.each {|f| @flog.expects(:flog_file).with(f) }
530
- # # @flog.flog_directory(@dir)
531
- # # end
532
- # # end
533
- #
534
- # describe 'when flogging a Ruby string' do
535
- # it 'should require both a Ruby string and a filename' do
536
- # lambda { @flog.flog('string') }.must_raise(ArgumentError)
537
- # end
538
- #
539
- # describe 'when reporting blame information' do
540
- # before :each do
541
- # @flog = Flog.new(:blame => true)
542
- # end
543
- #
544
- # it 'should gather blame information for the file' do
545
- # @flog.expects(:collect_blame).with('filename')
546
- # @flog.flog('string', 'filename')
547
- # end
548
- # end
549
- #
550
- # describe 'when not reporting blame information' do
551
- # it 'should not gather blame information for the file' do
552
- # def @flog.collect_blame(*args); raise "no"; end
553
- # @flog.flog('string', 'filename')
554
- # end
555
- # end
556
- #
557
- # describe 'when the string has a syntax error' do
558
- # before :each do
559
- # def @flog.warn(*args); end
560
- # def @flog.process_parse_tree(*args); raise SyntaxError, "<% foo %>"; end
561
- # end
562
- #
563
- # describe 'when the string has erb snippets' do
564
- # currently 'should warn about skipping' do
565
- # @flog.expects(:warn)
566
- # @flog.flog('string', 'filename')
567
- # end
568
- #
569
- # it 'should not raise an exception' do
570
- # lambda { @flog.flog('string', 'filename') }.wont_raise_error
571
- # end
572
- #
573
- # it 'should not process the failing code' do
574
- # def @flog.process(*args); raise "no"; end
575
- # @flog.flog('string', 'filename')
576
- # end
577
- # end
578
- #
579
- # describe 'when the string has no erb snippets' do
580
- # before :each do
581
- # def @flog.process_parse_tree(*args); raise SyntaxError; end
582
- # end
583
- #
584
- # it 'should raise a SyntaxError exception' do
585
- # # TODO: what the fuck?!? how does this test ANYTHING?
586
- # # it checks that #flog calls #process_parse_tree?? AND?!?!
587
- # lambda { @flog.flog('string', 'filename') }.must_raise(SyntaxError)
588
- # end
589
- #
590
- # it 'should not process the failing code' do
591
- # def @flog.process(*args); raise "no"; end
592
- # lambda { @flog.flog('string', 'filename') }
593
- # end
594
- # end
595
- # end
596
- #
597
- # describe 'when the string contains valid Ruby' do
598
- # before :each do
599
- # @flog.stubs(:process_parse_tree)
600
- # end
601
- #
602
- # it 'should process the parse tree for the string' do
603
- # @flog.expects(:process_parse_tree)
604
- # @flog.flog('string', 'filename')
605
- # end
606
- #
607
- # it 'should provide the string and the filename to the parse tree processor' do
608
- # @flog.expects(:process_parse_tree).with('string', 'filename')
609
- # @flog.flog('string', 'filename')
610
- # end
611
- # end
612
- # end
613
- #
614
- # # describe 'when processing a ruby parse tree' do
615
- # # before :each do
616
- # # @flog.stubs(:process)
617
- # # @sexp = stub('s-expressions')
618
- # # @parse_tree = stub('parse tree', :parse_tree_for_string => @sexp)
619
- # # ParseTree.stubs(:new).returns(@parse_tree)
620
- # # end
621
- # #
622
- # # it 'should require both a ruby string and a filename' do
623
- # # lambda { @flog.process_parse_tree('string') }.must_raise(ArgumentError)
624
- # # end
625
- # #
626
- # # it 'should compute the parse tree for the ruby string' do
627
- # # Sexp.stubs(:from_array).returns(['1', '2'])
628
- # # @parse_tree.expects(:parse_tree_for_string).returns(@sexp)
629
- # # @flog.process_parse_tree('string', 'file')
630
- # # end
631
- # #
632
- # # it 'should use both the ruby string and the filename when computing the parse tree' do
633
- # # Sexp.stubs(:from_array).returns(['1', '2'])
634
- # # @parse_tree.expects(:parse_tree_for_string).with('string', 'file').returns(@sexp)
635
- # # @flog.process_parse_tree('string', 'file')
636
- # # end
637
- # #
638
- # # describe 'if the ruby string is valid' do
639
- # # before :each do
640
- # # $pt = @parse_tree = stub('parse tree', :parse_tree_for_string => @sexp)
641
- # # def @flog.process; end
642
- # # def @flog.parse_tree; return $pt; end
643
- # # end
644
- # #
645
- # # it 'should convert the parse tree into a list of S-expressions' do
646
- # # Sexp.expects(:from_array).with(@sexp).returns(['1', '2'])
647
- # # @flog.process_parse_tree('string', 'file')
648
- # # end
649
- # #
650
- # # it 'should process the list of S-expressions' do
651
- # # @flog.expects(:process)
652
- # # @flog.process_parse_tree('string', 'file')
653
- # # end
654
- # #
655
- # # it 'should start processing at the first S-expression' do
656
- # # Sexp.stubs(:from_array).returns(['1', '2'])
657
- # # @flog.expects(:process).with('1')
658
- # # @flog.process_parse_tree('string', 'file')
659
- # # end
660
- # # end
661
- # #
662
- # # describe 'if the ruby string is invalid' do
663
- # # before :each do
664
- # # $parse_tree = stub('parse tree')
665
- # # def @flog.parse_tree; return $parse_tree; end
666
- # # def $parse_tree.parse_tree_for_string(*args); raise SyntaxError; end
667
- # # end
668
- # #
669
- # # it 'should fail' do
670
- # # lambda { @flog.process_parse_tree('string', 'file') }.must_raise(SyntaxError)
671
- # # end
672
- # #
673
- # # it 'should not attempt to process the parse tree' do
674
- # # def @flog.process(*args); raise "no"; end
675
- # # lambda { @flog.process_parse_tree('string', 'file') }
676
- # # end
677
- # # end
678
- # # end
679
- #
680
- # describe 'when collecting blame information from a file' do
681
- # it 'should require a filename' do
682
- # lambda { @flog.collect_blame }.must_raise(ArgumentError)
683
- # end
684
- #
685
- # it 'should not fail when given a filename' do
686
- # @flog.collect_blame('filename')
687
- # end
688
- #
689
- # # TODO: talk to Rick and see what he was planning for
690
- # # this... otherwise I'm thinking it should be ripped out
691
- #
692
- # # it 'should have more specs'
693
- # end
694
- #
695
- # describe 'multiplier' do
696
- # it 'should be possible to determine the current value of the multiplier' do
697
- # @flog.must_respond_to(:multiplier)
698
- # end
699
- #
700
- # currently 'should be possible to set the current value of the multiplier' do
701
- # @flog.multiplier = 10
702
- # @flog.multiplier.must_equal 10
703
- # end
704
- # end
705
- #
706
- # describe 'class_stack' do
707
- # it 'should be possible to determine the current value of the class stack' do
708
- # @flog.must_respond_to(:class_stack)
709
- # end
710
- #
711
- # currently 'should be possible to set the current value of the class stack' do
712
- # @flog.class_stack << 'name'
713
- # @flog.class_stack.must_equal [ 'name' ]
714
- # end
715
- # end
716
- #
717
- # describe 'method_stack' do
718
- # it 'should be possible to determine the current value of the method stack' do
719
- # @flog.must_respond_to(:method_stack)
720
- # end
721
- #
722
- # currently 'should be possible to set the current value of the method stack' do
723
- # @flog.method_stack << 'name'
724
- # @flog.method_stack.must_equal [ 'name' ]
725
- # end
726
- # end
727
- #
728
- # describe 'when adding to the current flog score' do
729
- # before :each do
730
- # @flog.multiplier = 1
731
- # def @flog.klass_name; return 'foo'; end
732
- # def @flog.method_name; return 'bar'; end
733
- # @flog.calls['foo#bar'] = { :alias => 0 }
734
- # end
735
- #
736
- # it 'should require an operation name' do
737
- # lambda { @flog.add_to_score() }.must_raise(ArgumentError)
738
- # end
739
- #
740
- # it 'should update the score for the current class, method, and operation' do
741
- # @flog.add_to_score(:alias)
742
- # @flog.calls['foo#bar'][:alias].wont_equal 0
743
- # end
744
- #
745
- # it 'should use the multiplier when updating the current call score' do
746
- # @flog.multiplier = 10
747
- # @flog.add_to_score(:alias)
748
- # @flog.calls['foo#bar'][:alias].must_equal 10*Flog::OTHER_SCORES[:alias]
749
- # end
750
- # end
751
- #
752
- # describe 'when computing the average per-call flog score' do
753
- # it 'should not allow arguments' do
754
- # lambda { @flog.average('foo') }.must_raise(ArgumentError)
755
- # end
756
- #
757
- # it 'should return the total flog score divided by the number of calls' do
758
- # def @flog.total; return 100; end
759
- # def @flog.calls; return :bar => {}, :foo => {} ; end
760
- # @flog.average.must_be_close_to 50.0
761
- # end
762
- # end
763
- #
764
- # describe 'when recursively analyzing the complexity of code' do
765
- # it 'should require a complexity modifier value' do
766
- # lambda { @flog.penalize_by }.must_raise(ArgumentError)
767
- # end
768
- #
769
- # it 'should require a block, for code to recursively analyze' do
770
- # lambda { @flog.penalize_by(42) }.must_raise(LocalJumpError)
771
- # end
772
- #
773
- # it 'should recursively analyze the provided code block' do
774
- # @flog.penalize_by(42) do
775
- # @foo = true
776
- # end
777
- #
778
- # @foo.must_equal true
779
- # end
780
- #
781
- # it 'should update the complexity multiplier when recursing' do
782
- # @flog.multiplier = 1
783
- # @flog.penalize_by(42) do
784
- # @flog.multiplier.must_equal 43
785
- # end
786
- # end
787
- #
788
- # it 'when it is done it should restore the complexity multiplier to its original value' do
789
- # @flog.multiplier = 1
790
- # @flog.penalize_by(42) do
791
- # end
792
- # @flog.multiplier.must_equal 1
793
- # end
794
- # end
795
- #
796
- # describe 'when computing complexity of all remaining opcodes' do
797
- # it 'should require a list of opcodes' do
798
- # lambda { @flog.analyze_list }.must_raise(ArgumentError)
799
- # end
800
- #
801
- # # HACK: nope. this is just poorly written.
802
- # # it 'should process each opcode' do
803
- # # @opcodes = [ :foo, :bar, :baz ]
804
- # # @opcodes.each do |opcode|
805
- # # @flog.expects(:process).with(opcode)
806
- # # end
807
- # #
808
- # # @flog.analyze_list @opcodes
809
- # # end
810
- # end
811
- #
812
- # describe 'when recording the current class being analyzed' do
813
- # it 'should require a class name' do
814
- # lambda { @flog.in_klass }.must_raise(ArgumentError)
815
- # end
816
- #
817
- # it 'should require a block during which the class name is in effect' do
818
- # lambda { @flog.in_klass('name') }.must_raise(LocalJumpError)
819
- # end
820
- #
821
- # it 'should recursively analyze the provided code block' do
822
- # @flog.in_klass 'name' do
823
- # @foo = true
824
- # end
825
- #
826
- # @foo.must_equal true
827
- # end
828
- #
829
- # it 'should update the class stack when recursing' do
830
- # @flog.class_stack.clear
831
- # @flog.in_klass 'name' do
832
- # @flog.class_stack.must_equal ['name']
833
- # end
834
- # end
835
- #
836
- # it 'when it is done it should restore the class stack to its original value' do
837
- # @flog.class_stack.clear
838
- # @flog.in_klass 'name' do
839
- # end
840
- # @flog.class_stack.must_equal []
841
- # end
842
- # end
843
- #
844
- # describe 'when looking up the name of the class currently under analysis' do
845
- # it 'should not take any arguments' do
846
- # lambda { @flog.klass_name('foo') }.must_raise(ArgumentError)
847
- # end
848
- #
849
- # it 'should return the most recent class entered' do
850
- # @flog.class_stack << :foo << :bar << :baz
851
- # @flog.klass_name.must_equal :foo
852
- # end
853
- #
854
- # it 'should return the default class if no classes entered' do
855
- # @flog.class_stack.clear
856
- # @flog.klass_name.must_equal :main
857
- # end
858
- # end
859
- #
860
- # describe 'when recording the current method being analyzed' do
861
- # it 'should require a method name' do
862
- # lambda { @flog.in_method }.must_raise(ArgumentError)
863
- # end
864
- #
865
- # it 'should require a block during which the class name is in effect' do
866
- # lambda { @flog.in_method('name') }.must_raise(LocalJumpError)
867
- # end
868
- #
869
- # it 'should recursively analyze the provided code block' do
870
- # @flog.in_method 'name' do
871
- # @foo = true
872
- # end
873
- #
874
- # @foo.must_equal true
875
- # end
876
- #
877
- # it 'should update the class stack when recursing' do
878
- # @flog.method_stack.clear
879
- # @flog.in_method 'name' do
880
- # @flog.method_stack.must_equal ['name']
881
- # end
882
- # end
883
- #
884
- # it 'when it is done it should restore the class stack to its original value' do
885
- # @flog.method_stack.clear
886
- # @flog.in_method 'name' do
887
- # end
888
- # @flog.method_stack.must_equal []
889
- # end
890
- # end
891
- #
892
- # describe 'when looking up the name of the method currently under analysis' do
893
- # it 'should not take any arguments' do
894
- # lambda { @flog.method_name('foo') }.must_raise(ArgumentError)
895
- # end
896
- #
897
- # it 'should return the most recent method entered' do
898
- # @flog.method_stack << :foo << :bar << :baz
899
- # @flog.method_name.must_equal :foo
900
- # end
901
- #
902
- # it 'should return the default method if no methods entered' do
903
- # @flog.method_stack.clear
904
- # @flog.method_name.must_equal :none
905
- # end
906
- # end
907
- #
908
- # describe 'when resetting state' do
909
- # it 'should not take any arguments' do
910
- # lambda { @flog.reset('foo') }.must_raise(ArgumentError)
911
- # end
912
- #
913
- # it 'should clear any recorded totals data' do
914
- # @flog.totals['foo'] = 'bar'
915
- # @flog.reset
916
- # @flog.totals.must_equal({})
917
- # end
918
- #
919
- # it 'should clear the total score' do
920
- # # the only way I know to do this is to force the total score to be computed for actual code, then reset it
921
- # @flog.flog_files(fixture_files('/simple/simple.rb'))
922
- # @flog.reset
923
- # @flog.total.must_equal 0
924
- # end
925
- #
926
- # it 'should set the multiplier to 1.0' do
927
- # @flog.multiplier = 20.0
928
- # @flog.reset
929
- # @flog.multiplier.must_equal 1.0
930
- # end
931
- #
932
- # it 'should set clear any calls data' do
933
- # @flog.calls['foobar'] = 'yoda'
934
- # @flog.reset
935
- # @flog.calls.must_equal({})
936
- # end
937
- #
938
- # it 'should ensure that new recorded calls will get 0 counts without explicit initialization' do
939
- # @flog.reset
940
- # @flog.calls['foobar']['baz'] += 20
941
- # @flog.calls['foobar']['baz'].must_equal 20
942
- # end
943
- # end
944
- #
945
- # describe 'when retrieving the total score' do
946
- # it 'should take no arguments' do
947
- # lambda { @flog.total('foo') }.must_raise(ArgumentError)
948
- # end
949
- #
950
- # it 'should return 0 if nothing has been analyzed' do
951
- # @flog.total.must_equal 0
952
- # end
953
- #
954
- # it 'should compute totals data when called the first time' do
955
- # @flog.expects(:totals)
956
- # @flog.total
957
- # end
958
- #
959
- # it 'should not recompute totals data when called after the first time' do
960
- # @flog.total
961
- # def @flog.totals(*args); raise "no"; end
962
- # @flog.total
963
- # end
964
- #
965
- # it 'should return the score from the analysis once files have been analyzed' do
966
- # @flog.flog_files(fixture_files('/simple/simple.rb'))
967
- # @flog.total.wont_equal 0
968
- # end
969
- # end
970
- #
971
- # describe 'when computing a score for a method' do
972
- # it 'should require a hash of call tallies' do
973
- # lambda { @flog.score_method }.must_raise(ArgumentError)
974
- # end
975
- #
976
- # it 'should return a score of 0 if no tallies are provided' do
977
- # @flog.score_method({}).must_equal 0.0
978
- # end
979
- #
980
- # it 'should compute the sqrt of summed squares for assignments, branches, and other tallies' do
981
- # @flog.score_method({
982
- # :assignment => 7,
983
- # :branch => 23,
984
- # :crap => 37
985
- # }).must_be_close_to Math.sqrt(7*7 + 23*23 + 37*37)
986
- # end
987
- # end
988
- #
989
- # describe 'when recording a total for a method' do
990
- # # guess what, @totals and @calls could be refactored to be first-class objects
991
- # it 'should require a method and a score' do
992
- # lambda { @flog.record_method_score('foo') }.must_raise(ArgumentError)
993
- # end
994
- #
995
- # it 'should set the total score for the provided method' do
996
- # @flog.record_method_score('foo', 20)
997
- # @flog.totals['foo'].must_equal 20
998
- # end
999
- # end
1000
- #
1001
- # describe 'when updating the total flog score' do
1002
- # it 'should require an amount to update by' do
1003
- # lambda { @flog.increment_total_score_by }.must_raise(ArgumentError)
1004
- # end
1005
- #
1006
- # it 'should update the total flog score' do
1007
- # @flog.total_score = 0
1008
- # @flog.increment_total_score_by 42
1009
- # @flog.total.must_equal 42
1010
- # end
1011
- # end
1012
- #
1013
- # describe 'when compiling summaries for a method' do
1014
- # before :each do
1015
- # @tally = { :foo => 0.0 }
1016
- # @method = 'foo'
1017
- # $score = @score = 42.0
1018
- #
1019
- # @flog.total_score = 0
1020
- #
1021
- # def @flog.score_method(*args); return $score; end
1022
- # def @flog.record_method_score(*args); end
1023
- # def @flog.increment_total_score_by(*args); end
1024
- # end
1025
- #
1026
- # it 'should require a method name and a tally' do
1027
- # lambda { @flog.summarize_method('foo') }.must_raise(ArgumentError)
1028
- # end
1029
- #
1030
- # it 'should compute a score for the method, based on the tally' do
1031
- # @flog.expects(:score_method).with(@tally)
1032
- # @flog.summarize_method(@method, @tally)
1033
- # end
1034
- #
1035
- # it 'should record the score for the method' do
1036
- # @flog.expects(:record_method_score).with(@method, @score)
1037
- # @flog.summarize_method(@method, @tally)
1038
- # end
1039
- #
1040
- # it 'should update the overall flog score' do
1041
- # @flog.expects(:increment_total_score_by).with(@score)
1042
- # @flog.summarize_method(@method, @tally)
1043
- # end
1044
- #
1045
- # # HACK: I don't see how these ever worked if the above passes... *shrug*
1046
- # # describe 'ignoring non-method code and given a non-method tally' do
1047
- # # it 'should not compute a score for the tally' do
1048
- # # def @flog.score_method(*args); raise "no"; end
1049
- # # @flog.summarize_method(@method, @tally)
1050
- # # end
1051
- # #
1052
- # # it 'should not record a score based on the tally' do
1053
- # # def @flog.record_method_score(*args); raise "no"; end
1054
- # # @flog.summarize_method(@method, @tally)
1055
- # # end
1056
- # #
1057
- # # it 'should not update the overall flog score' do
1058
- # # def @flog.increment_total_score_by(*args); raise "no"; end
1059
- # # @flog.summarize_method(@method, @tally)
1060
- # # end
1061
- # # end
1062
- # end
1063
- #
1064
- # describe 'when requesting totals' do
1065
- # it 'should not accept any arguments' do
1066
- # lambda { @flog.totals('foo') }.must_raise(ArgumentError)
1067
- # end
1068
- #
1069
- # describe 'when called the first time' do
1070
- # # it 'should access calls data' do
1071
- # # @flog.expects(:calls).returns({})
1072
- # # @flog.totals
1073
- # # end
1074
- #
1075
- # # it "will compile a summary for each method from the method's tally" do
1076
- # # $calls = @calls = { :foo => 1.0, :bar => 2.0, :baz => 3.0 }
1077
- # # def @flog.calls; return $calls; end
1078
- # #
1079
- # # @calls.each do |meth, tally|
1080
- # # @flog.expects(:summarize_method).with(meth, tally)
1081
- # # end
1082
- # #
1083
- # # @flog.totals
1084
- # # end
1085
- #
1086
- # it 'should return the totals data' do
1087
- # @flog.totals.must_equal({})
1088
- # end
1089
- # end
1090
- #
1091
- # describe 'when called after the first time' do
1092
- # before :each do
1093
- # @flog.totals
1094
- # end
1095
- #
1096
- # it 'should not access calls data' do
1097
- # def @flog.calls(*args); raise "no"; end
1098
- # @flog.totals
1099
- # end
1100
- #
1101
- # it 'should not compile method summaries' do
1102
- # def @flog.summarize_method(*args); raise "no"; end
1103
- # @flog.totals
1104
- # end
1105
- #
1106
- # it 'should return the totals data' do
1107
- # @flog.totals.must_equal({})
1108
- # end
1109
- # end
1110
- # end
1111
- #
1112
- # describe 'when producing a report summary' do
1113
- # before :each do
1114
- # @handle = stub('io handle)', :puts => nil)
1115
- # @total_score = 42.0
1116
- # @average_score = 1.0
1117
- # def @flog.total; return 42.0; end
1118
- # def @flog.average; return 1.0; end
1119
- # end
1120
- #
1121
- # it 'should require an io handle' do
1122
- # lambda { @flog.output_summary }.must_raise(ArgumentError)
1123
- # end
1124
- #
1125
- # it 'computes the total flog score' do
1126
- # # HACK @flog.expects(:total).returns 42.0
1127
- # @flog.output_summary(@handle)
1128
- # end
1129
- #
1130
- # it 'computes the average flog score' do
1131
- # # HACK @flog.expects(:average).returns 1.0
1132
- # @flog.output_summary(@handle)
1133
- # end
1134
- #
1135
- # it 'outputs the total flog score to the handle' do
1136
- # @handle.expects(:puts).with do |string|
1137
- # string =~ Regexp.new(Regexp.escape("%.1f" % @total_score))
1138
- # end
1139
- # @flog.output_summary(@handle)
1140
- # end
1141
- #
1142
- # it 'outputs the average flog score to the handle' do
1143
- # @handle.expects(:puts).with do |string|
1144
- # string =~ Regexp.new(Regexp.escape("%.1f" % @average_score))
1145
- # end
1146
- # @flog.output_summary(@handle)
1147
- # end
1148
- # end
1149
- #
1150
- # describe 'when producing a detailed call summary report' do
1151
- # before :each do
1152
- # @handle = stub('io handle)', :puts => nil)
1153
- # $calls = @calls = { :foo => {}, :bar => {}, :baz => {} }
1154
- # $totals = @totals = { :foo => 1, :bar => 2, :baz => 3 }
1155
- #
1156
- # def @flog.calls; return $calls; end
1157
- # def @flog.totals; return $totals; end
1158
- # def @flog.output_method_details(*args); return 5; end
1159
- # end
1160
- #
1161
- # it 'should require an i/o handle' do
1162
- # lambda { @flog.output_details }.must_raise(ArgumentError)
1163
- # end
1164
- #
1165
- # it 'should allow a threshold on the amount of detail to report' do
1166
- # lambda { @flog.output_details(@handle, 300) }.wont_raise_error(ArgumentError)
1167
- # end
1168
- #
1169
- # # it 'retrieves the set of total statistics' do
1170
- # # @flog.expects(:totals).returns(@totals)
1171
- # # @flog.output_details(@handle)
1172
- # # end
1173
- #
1174
- # # it 'retrieves the set of call statistics' do
1175
- # # @flog.expects(:calls).returns({})
1176
- # # @flog.output_details(@handle)
1177
- # # end
1178
- #
1179
- # # it 'should output a method summary for each located method' do
1180
- # # @calls.each do |meth, list|
1181
- # # @flog.expects(:output_method_details).with(@handle, meth, list).returns(5)
1182
- # # end
1183
- # # @flog.output_details(@handle)
1184
- # # end
1185
- # #
1186
- # # describe 'if a threshold is provided' do
1187
- # # it 'should only output details for methods until the threshold is reached' do
1188
- # # @flog.expects(:output_method_details).with(@handle, :baz, {}).returns(5)
1189
- # # @flog.expects(:output_method_details).with(@handle, :bar, {}).returns(5)
1190
- # # # HACK @flog.expects(:output_method_details).with(@handle, :foo, {}).never
1191
- # # @flog.output_details(@handle, 10)
1192
- # # end
1193
- # # end
1194
- #
1195
- # # describe 'if no threshold is provided' do
1196
- # # it 'should output details for all methods' do
1197
- # # @calls.each do |class_method, call_list|
1198
- # # @flog.expects(:output_method_details).with(@handle, class_method, call_list).returns(5)
1199
- # # end
1200
- # # @flog.output_details(@handle)
1201
- # # end
1202
- # # end
1203
- # end
1204
- #
1205
- # describe 'when reporting the details for a specific method' do
1206
- # before :each do
1207
- # @handle = stub('i/o handle', :puts => nil)
1208
- # $totals = { 'foo#foo' => 42.0, 'foo#none' => 12.0 }
1209
- # @data = { :assign => 10, :branch => 5, :case => 3 }
1210
- # def @flog.totals; return $totals; end
1211
- # end
1212
- #
1213
- # it 'should require an i/o handle, a method name, and method details' do
1214
- # lambda { @flog.output_method_details('foo', 'bar') }.must_raise(ArgumentError)
1215
- # end
1216
- #
1217
- # describe 'and ignoring non-method code' do
1218
- # before :each do
1219
- # @flog = Flog.new(:methods => true)
1220
- # def @flog.totals; return $totals; end
1221
- # end
1222
- #
1223
- # describe 'and given non-method data to summarize' do
1224
- # it 'should not generate any output on the i/o handle' do
1225
- # def @handle.puts(*args); raise "no"; end
1226
- # @flog.output_method_details(@handle, 'foo#none', @data)
1227
- # end
1228
- #
1229
- # it 'should return 0' do
1230
- # @flog.output_method_details(@handle, 'foo#none', @data).must_equal 0.0
1231
- # end
1232
- # end
1233
- #
1234
- # describe 'and given method data to summarize' do
1235
- # it 'should return the total complexity for the method' do
1236
- # @flog.output_method_details(@handle, 'foo#foo', @data).must_equal 42.0
1237
- # end
1238
- #
1239
- # it 'should output the overall total for the method' do
1240
- # @handle.expects(:puts).with do |string|
1241
- # string =~ Regexp.new(Regexp.escape("%.1f" % 42.0))
1242
- # end
1243
- # @flog.output_method_details(@handle, 'foo#foo', @data)
1244
- # end
1245
- #
1246
- # it 'should output call details for each call for the method' do
1247
- # @data.each do |call, count|
1248
- # @handle.expects(:puts).with do |string|
1249
- # string =~ Regexp.new(Regexp.escape("%6.1f: %s" % [ count, call ]))
1250
- # end
1251
- # end
1252
- # @flog.output_method_details(@handle, 'foo#foo', @data)
1253
- # end
1254
- # end
1255
- # end
1256
- #
1257
- # describe 'and not excluding non-method code' do
1258
- # it 'should return the total complexity for the method' do
1259
- # @flog.output_method_details(@handle, 'foo#foo', @data).must_equal 42.0
1260
- # end
1261
- #
1262
- # it 'should output the overall total for the method' do
1263
- # @handle.expects(:puts).with do |string|
1264
- # string =~ Regexp.new(Regexp.escape("%.1f" % 42.0))
1265
- # end
1266
- # @flog.output_method_details(@handle, 'foo#foo', @data)
1267
- # end
1268
- #
1269
- # it 'should output call details for each call for the method' do
1270
- # @data.each do |call, count|
1271
- # @handle.expects(:puts).with do |string|
1272
- # string =~ Regexp.new(Regexp.escape("%6.1f: %s" % [ count, call ]))
1273
- # end
1274
- # end
1275
- # @flog.output_method_details(@handle, 'foo#foo', @data)
1276
- # end
1277
- # end
1278
- # end
1279
- #
1280
- # describe 'when generating a report' do
1281
- # before :each do
1282
- # @flog.stubs(:output_summary)
1283
- # @handle = stub('io handle)', :puts => nil)
1284
- # end
1285
- #
1286
- # # it 'allows specifying an i/o handle' do
1287
- # # lambda { @flog.report @handle }.wont_raise_error(ArgumentError)
1288
- # # end
1289
- # #
1290
- # # it 'allows running the report without a specified i/o handle' do
1291
- # # lambda { @flog.report }.wont_raise_error(ArgumentError)
1292
- # # end
1293
- #
1294
- # # describe 'and no i/o handle is specified' do
1295
- # # it 'defaults the io handle to stdout' do
1296
- # # @flog.expects(:output_summary).with($stdout)
1297
- # # @flog.report
1298
- # # end
1299
- # # end
1300
- #
1301
- # describe 'and producing a summary report' do
1302
- # before :each do
1303
- # @flog = Flog.new(:score => true)
1304
- # @flog.stubs(:output_summary)
1305
- # end
1306
- #
1307
- # it 'produces an output summary on the i/o handle' do
1308
- # @flog.expects(:output_summary).with(@handle)
1309
- # @flog.report(@handle)
1310
- # end
1311
- #
1312
- # it 'does not output a detailed report' do
1313
- # def @flog.output_details(*args); raise "no"; end
1314
- # @flog.report(@handle)
1315
- # end
1316
- #
1317
- # it 'should reset statistics when finished' do
1318
- # @flog.expects(:reset)
1319
- # @flog.report(@handle)
1320
- # end
1321
- # end
1322
- #
1323
- # describe 'and producing a full report' do
1324
- # before :each do
1325
- # @flog.stubs(:output_summary)
1326
- # @flog.stubs(:output_details)
1327
- # end
1328
- #
1329
- # it 'produces an output summary on the i/o handle' do
1330
- # @flog.expects(:output_summary).with(@handle)
1331
- # @flog.report(@handle)
1332
- # end
1333
- #
1334
- # it 'should generate a detailed report of method complexity on the i/o handle' do
1335
- # @flog.expects(:output_details).with {|handle, max| handle == @handle }
1336
- # @flog.report(@handle)
1337
- # end
1338
- #
1339
- # describe 'when flogging all methods in the system' do
1340
- # before :each do
1341
- # @flog = Flog.new(:all => true)
1342
- # @flog.stubs(:output_summary)
1343
- # @flog.stubs(:output_details)
1344
- # end
1345
- #
1346
- # it 'should not limit the detailed report' do
1347
- # @flog.expects(:output_details).with(@handle)
1348
- # @flog.report(@handle)
1349
- # end
1350
- # end
1351
- #
1352
- # describe 'when flogging only the most expensive methods in the system' do
1353
- # it 'should limit the detailed report to the Flog threshold' do
1354
- # def @flog.total; return 3.45; end
1355
- # @flog.expects(:output_details).with(@handle, 3.45 * 0.60)
1356
- # @flog.report(@handle)
1357
- # end
1358
- # end
1359
- #
1360
- # it 'should reset statistics when finished' do
1361
- # @flog.expects(:reset)
1362
- # @flog.report(@handle)
1363
- # end
1364
- # end
1365
- # end
1366
- # end
1367
-
1368
- ############################################################
1369
- # TODO after driver code is covered
1370
-
1371
- # def test_process_alias
1372
- # raise NotImplementedError, 'Need to write test_process_alias'
1373
- # end
1374
- #
1375
- # def test_process_and
1376
- # raise NotImplementedError, 'Need to write test_process_and'
1377
- # end
1378
- #
1379
- # def test_process_attrasgn
1380
- # raise NotImplementedError, 'Need to write test_process_attrasgn'
1381
- # end
1382
- #
1383
- # def test_process_attrset
1384
- # raise NotImplementedError, 'Need to write test_process_attrset'
1385
- # end
1386
- #
1387
- # def test_process_block
1388
- # raise NotImplementedError, 'Need to write test_process_block'
1389
- # end
1390
- #
1391
- # def test_process_block_pass
1392
- # raise NotImplementedError, 'Need to write test_process_block_pass'
1393
- # end
1394
- #
1395
- # def test_process_call
1396
- # raise NotImplementedError, 'Need to write test_process_call'
1397
- # end
1398
- #
1399
- # def test_process_case
1400
- # raise NotImplementedError, 'Need to write test_process_case'
1401
- # end
1402
- #
1403
- # def test_process_class
1404
- # raise NotImplementedError, 'Need to write test_process_class'
1405
- # end
1406
- #
1407
- # def test_process_dasgn_curr
1408
- # raise NotImplementedError, 'Need to write test_process_dasgn_curr'
1409
- # end
1410
- #
1411
- # def test_process_defn
1412
- # raise NotImplementedError, 'Need to write test_process_defn'
1413
- # end
1414
- #
1415
- # def test_process_defs
1416
- # raise NotImplementedError, 'Need to write test_process_defs'
1417
- # end
1418
- #
1419
- # def test_process_else
1420
- # raise NotImplementedError, 'Need to write test_process_else'
1421
- # end
1422
- #
1423
- # def test_process_iasgn
1424
- # raise NotImplementedError, 'Need to write test_process_iasgn'
1425
- # end
1426
- #
1427
- # def test_process_if
1428
- # raise NotImplementedError, 'Need to write test_process_if'
1429
- # end
1430
- #
1431
- # def test_process_iter
1432
- # raise NotImplementedError, 'Need to write test_process_iter'
1433
- # end
1434
- #
1435
- # def test_process_lasgn
1436
- # raise NotImplementedError, 'Need to write test_process_lasgn'
1437
- # end
1438
- #
1439
- # def test_process_lit
1440
- # raise NotImplementedError, 'Need to write test_process_lit'
1441
- # end
1442
- #
1443
- # def test_process_masgn
1444
- # raise NotImplementedError, 'Need to write test_process_masgn'
1445
- # end
1446
- #
1447
- # def test_process_module
1448
- # raise NotImplementedError, 'Need to write test_process_module'
1449
- # end
1450
- #
1451
- # def test_process_or
1452
- # raise NotImplementedError, 'Need to write test_process_or'
1453
- # end
1454
- #
1455
- # def test_process_parse_tree
1456
- # raise NotImplementedError, 'Need to write test_process_parse_tree'
1457
- # end
1458
- #
1459
- # def test_process_rescue
1460
- # raise NotImplementedError, 'Need to write test_process_rescue'
1461
- # end
1462
- #
1463
- # def test_process_sclass
1464
- # raise NotImplementedError, 'Need to write test_process_sclass'
1465
- # end
1466
- #
1467
- # def test_process_super
1468
- # raise NotImplementedError, 'Need to write test_process_super'
1469
- # end
1470
- #
1471
- # def test_process_until
1472
- # raise NotImplementedError, 'Need to write test_process_until'
1473
- # end
1474
- #
1475
- # def test_process_when
1476
- # raise NotImplementedError, 'Need to write test_process_when'
1477
- # end
1478
- #
1479
- # def test_process_while
1480
- # raise NotImplementedError, 'Need to write test_process_while'
1481
- # end
1482
- #
1483
- # def test_process_yield
1484
- # raise NotImplementedError, 'Need to write test_process_yield'
1485
- # end
1486
- #
525
+ @klass ||= "main"
526
+ @meth ||= "#none"
527
+
528
+ unless score != -1 && hash.empty? then
529
+ exp = {"#{@klass}#{@meth}" => hash}
530
+ assert_equal exp, @flog.calls
531
+ end
532
+
533
+ assert_in_delta score, @flog.total
534
+ end
535
+ end