flog 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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