analdiffist 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ - if there are uncommitted changes, should they be analyzed?
2
+ - diffing engine needs help
3
+ - add -v and --version switches
4
+ - different grouping options (added/removed and by class/module/context)
5
+
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.0
1
+ 0.4.0
@@ -1,6 +1,5 @@
1
1
  module AnalDiffist
2
2
  require 'analdiffist/target_finder'
3
- require 'analdiffist/reek_metrics'
4
3
  require 'analdiffist/reek_parser'
5
4
  require 'analdiffist/flog_parser'
6
5
  require 'analdiffist/diff_set'
@@ -49,7 +48,7 @@ module AnalDiffist
49
48
  end
50
49
 
51
50
  def get_refs_to_diff current_branch, start_ref, end_ref
52
- [ start_ref || "origin/master", end_ref || current_branch]
51
+ [ start_ref || `git merge-base HEAD origin/master`, end_ref || current_branch]
53
52
  end
54
53
 
55
54
  def analyze_ref ref_name
@@ -6,25 +6,48 @@ module AnalDiffist
6
6
  end
7
7
 
8
8
  def added_problems
9
- compare(@after, @before)
9
+ differences.select {|difference| difference.score > 0 }
10
10
  end
11
11
 
12
12
  def removed_problems
13
- compare(@before, @after)
13
+ differences.select {|difference| difference.score < 0 }
14
14
  end
15
15
 
16
16
  private
17
- def compare(a,b)
18
- #TODO: move this comparison into the class?
19
- a.map do |problem|
20
- matching_problem = b.detect {|problem2| [problem.type, problem.context] == [problem2.type, problem2.context] }
17
+ def differences
18
+ @differences ||= calculate_differences
19
+ end
20
+
21
+ def calculate_differences
22
+ diffs = []
23
+ before_by_context = @before.group_by {|b| [b.type, b.context]}
24
+ after_by_context = @after.group_by {|b| [b.type, b.context]}
25
+ all_contexts = (before_by_context.keys + after_by_context.keys).uniq
21
26
 
22
- problem.diff(matching_problem)
27
+ all_contexts.each do |context|
23
28
 
24
- end.reject {|x| x.nil?}
29
+ before = before_by_context[context] || []
30
+ after = after_by_context[context] || []
31
+
32
+ diffs.concat(calculate_diffs_for_a_context(before, after))
33
+ end
34
+ diffs.reject(&:nil?)
25
35
  end
26
- end
27
36
 
28
- class ScoreDiffSet
37
+ def calculate_diffs_for_a_context before, after
38
+ diffs = []
39
+ while before.any? || after.any? do
40
+ diff = get_diff(before.pop, after.pop)
41
+ diffs << diff unless diff.nil?
42
+ end
43
+ diffs
44
+ end
45
+
46
+ def get_diff before, after
47
+ return after.diff(before) unless after.nil?
48
+ diff = before.diff(after)
49
+ return nil if diff.nil?
50
+ InvertedDiff.new(diff)
51
+ end
29
52
  end
30
53
  end
@@ -7,7 +7,8 @@ module AnalDiffist
7
7
  end
8
8
 
9
9
  def problems
10
- f = Flog.new
10
+ f = Flog.new :continue => true
11
+
11
12
  f.flog(@paths)
12
13
  problems = []
13
14
  f.each_by_score{|class_method, score, ignore_for_now| problems << FlogProblem.new(class_method, score, @flog_threshold)}
@@ -29,10 +30,12 @@ module AnalDiffist
29
30
  end
30
31
 
31
32
  def diff other
32
- return nil if score < @flog_threshold
33
- return FlogDiff.new(@context, 0, score) if other.nil?
34
-
35
- return nil if other.score >= score
33
+ if other.nil?
34
+ return nil if score < @flog_threshold
35
+ return FlogDiff.new(@context, 0, score)
36
+ end
37
+ return nil if other.score == score
38
+ return nil if score < @flog_threshold && other.score < @flog_threshold
36
39
  FlogDiff.new(@context, other.score, score)
37
40
  end
38
41
 
@@ -53,9 +56,36 @@ module AnalDiffist
53
56
  (@current_score - @previous_score).round(1)
54
57
  end
55
58
 
59
+ def invert!
60
+ score = 0 - (score || 0)
61
+ self
62
+ end
63
+
56
64
  def description(mode = :added)
57
- indicator = (mode == :added) ? "+" : "-"
65
+ indicator = (mode == :added) ? "+" : ""
58
66
  "Flog: #{@current_score.round(1)} (#{indicator}#{(@current_score - @previous_score).round(1)})"
59
67
  end
60
68
  end
69
+
70
+ class InvertedDiff
71
+ def initialize inner
72
+ @inner = inner
73
+ end
74
+
75
+ def context
76
+ @inner.context
77
+ end
78
+
79
+ def score
80
+ 0-@inner.score
81
+ end
82
+
83
+ def type
84
+ @inner.type
85
+ end
86
+
87
+ def description(mode = :added)
88
+ @inner.description(mode)
89
+ end
90
+ end
61
91
  end
@@ -4,8 +4,17 @@ module AnalDiffist
4
4
  attr_accessor :problems
5
5
 
6
6
  def initialize(paths)
7
- examiner = Reek::Examiner.new(paths)
8
- @problems = examiner.smells.map {|smell| ReekProblem.new(smell)}
7
+ @examiner = Reek::Examiner.new(paths)
8
+ @problems = get_problems
9
+ end
10
+
11
+ def get_problems
12
+ unfiltered = @examiner.smells.map {|smell| ReekProblem.new(smell)}
13
+ filter_reek_problems(unfiltered)
14
+ end
15
+
16
+ def filter_reek_problems(reek_problems)
17
+ reek_problems
9
18
  end
10
19
 
11
20
  def diff(previous)
@@ -29,10 +38,12 @@ module AnalDiffist
29
38
  def diff other
30
39
  self if other.nil?
31
40
  end
41
+
32
42
  def score
33
43
  2
34
44
  end
35
- def description mode = :added
45
+
46
+ def description(mode = :added)
36
47
  "Reek: #{type}"
37
48
  end
38
49
  end
@@ -22,7 +22,10 @@ module AnalDiffist
22
22
  diff = DiffSet.new(before.problems, after.problems)
23
23
 
24
24
  @reporter.report(diff, before.name, after.name)
25
+ end
25
26
 
27
+ def puts_problems problems
28
+ puts problems.map {|p| "#{p.context} - #{p.description}"}.join("\n")
26
29
  end
27
30
 
28
31
  private
@@ -2,13 +2,29 @@ module AnalDiffist
2
2
  class StdOutReporter
3
3
  def report diff, from_rev, to_rev
4
4
  puts "\n\nAnaldifference between revisions: \n #{from_rev}\n #{to_rev}"
5
- puts "\nAdded:\n"
6
- puts describe(diff.added_problems, :added).join("\n")
7
- puts "\nRemoved:\n"
8
- puts describe(diff.removed_problems, :removed).join("\n")
5
+ sum = sum_scores(diff.added_problems + diff.removed_problems)
6
+ direction = ["Same", "Worse", "Better"][sum<=>0]
7
+
8
+ puts "Overall: #{'+' if sum > 0}#{sum} (#{direction})"
9
+
10
+ describe_problems(diff.added_problems, 'Worse', :added)
11
+ describe_problems(diff.removed_problems, 'Better', :removed)
12
+
9
13
  puts "\n\n"
10
14
  end
11
15
 
16
+ def sum_scores diffs
17
+ sum = 0.0
18
+ diffs.each {|p| sum += p.score}
19
+ sum.round(1)
20
+ end
21
+
22
+ def describe_problems problems, title, mode
23
+ sum = sum_scores(problems)
24
+ puts "\n#{title} (#{problems.length} : #{sum})\n"
25
+ puts describe(problems, mode).join("\n")
26
+ end
27
+
12
28
  def describe(problems, mode)
13
29
  results = []
14
30
  by_type = problems.group_by do |prob|
@@ -1,83 +1,88 @@
1
1
  require 'spec_helper'
2
2
 
3
+ RSpec::Matchers.define :have_a_single_problem do |type, context|
4
+ match do |problems|
5
+ problems.length.should == 1
6
+ problems.first.type.should == type
7
+ problems.first.context.should == context
8
+ end
9
+ end
10
+
3
11
  describe 'diffing two files' do
4
12
  context 'single problem added' do
5
- before do
6
- @diff = AnalDiffist::DiffSet.new([], [test_problem('foo', 'bar')])
7
- end
8
- it 'should find a new reek' do
9
- added_problems = @diff.added_problems
10
- added_problems.length.should == 1
11
- added_problems.first.type.should == 'foo'
12
- added_problems.first.context == 'bar'
13
- end
14
- it 'should not have any removed reeks' do
15
- @diff.removed_problems.should == []
16
- end
13
+ subject{AnalDiffist::DiffSet.new([], [test_problem('foo', 'bar')])}
14
+
15
+ its(:removed_problems) {should == []}
16
+ its(:added_problems) {should have_a_single_problem 'foo', 'bar'}
17
17
  end
18
18
 
19
19
  context 'single problem removed' do
20
- before do
21
- @diff = AnalDiffist::DiffSet.new( [test_problem('foo', 'bar')], [])
22
- end
23
- it 'should find a removed reek' do
24
- removed_problems = @diff.removed_problems
25
- removed_problems.length.should == 1
26
- removed_problems.first.type.should == 'foo'
27
- removed_problems.first.context == 'bar'
28
- end
29
- it 'should not have any added reeks' do
30
- @diff.added_problems.should == []
31
- end
20
+ subject { AnalDiffist::DiffSet.new( [test_problem('foo', 'bar')], [])}
21
+
22
+ its(:removed_problems) {should have_a_single_problem 'foo', 'bar' }
23
+ its(:added_problems) {should == []}
32
24
  end
33
25
 
34
26
  context 'one removed, one added, one remains' do
35
- before do
27
+ subject do
36
28
  before = [test_problem('foo', 'bar'), test_problem('removed', 'removed')]
37
29
  after = [test_problem('foo', 'bar'), test_problem('added', 'added')]
38
- @diff = AnalDiffist::DiffSet.new(before, after)
30
+ AnalDiffist::DiffSet.new(before, after)
39
31
  end
40
32
 
41
- it 'should find a removed reek' do
42
- removed_problems = @diff.removed_problems
43
- removed_problems.length.should == 1
44
- removed_problems.first.type.should == 'removed'
45
- removed_problems.first.context == 'removed'
33
+ its(:removed_problems) {should have_a_single_problem 'removed', 'removed'}
34
+ its(:added_problems) {should have_a_single_problem 'added', 'added'}
35
+ end
36
+
37
+ context 'reeks are grouped by context and type' do
38
+ context 'two reeks with same context and type, then one is removed' do
39
+ subject do
40
+ before = [test_problem('same-type', 'bar'), test_problem('same-type', 'bar')]
41
+ after = [test_problem('same-type', 'bar')]
42
+ AnalDiffist::DiffSet.new(before, after)
43
+ end
44
+
45
+ its(:removed_problems) {should have_a_single_problem 'same-type', 'bar'}
46
+ its(:added_problems) {should == []}
46
47
  end
47
48
 
48
- it 'should find an added problem' do
49
- added_problems = @diff.added_problems
50
- added_problems.length.should == 1
51
- added_problems.first.type.should == 'added'
52
- added_problems.first.context == 'added'
49
+ context 'two reeks with same context and different type, then one is removed' do
50
+ subject do
51
+ before = [test_problem('other-type', 'bar')]
52
+ after = [test_problem('same-type', 'bar')]
53
+ AnalDiffist::DiffSet.new(before, after)
54
+ end
55
+
56
+ its(:removed_problems) {should have_a_single_problem 'other-type', 'bar'}
57
+ its(:added_problems) {should have_a_single_problem 'same-type', 'bar'}
53
58
  end
54
59
  end
55
60
 
56
61
  context 'when scores change' do
57
- before do
62
+ subject do
58
63
  before = [AnalDiffist::FlogProblem.new('bar', 17.1)]
59
64
  after = [AnalDiffist::FlogProblem.new('bar', 18.5)]
60
- @diff = AnalDiffist::DiffSet.new(before, after)
65
+ AnalDiffist::DiffSet.new(before, after).added_problems
61
66
  end
67
+ specify {subject.should have(1).item}
68
+ specify {subject.first.score.should == 1.4 }
69
+ end
62
70
 
63
- it 'should identify as added' do
64
- added_problems = @diff.added_problems
65
- added_problems.length.should == 1
66
- added_problems.first.score.round(1).should == 1.4
71
+ context 'removing a flog' do
72
+ subject do
73
+ before = [AnalDiffist::FlogProblem.new('bar', 18.1)]
74
+ after = [AnalDiffist::FlogProblem.new('bar', 8.5)]
75
+ AnalDiffist::DiffSet.new(before, after)
67
76
  end
77
+ specify {subject.added_problems.should have(0).problems}
78
+ specify {subject.removed_problems.should have(1).item}
79
+ specify {subject.removed_problems.first.score.should == -9.6 }
68
80
  end
69
81
 
70
82
  def test_problem type, context, score = 1
71
83
  smell = double("fake problem")
72
84
  smell.stub(:subclass) {type}
73
- smell.stub(:location) {context}
85
+ smell.stub(:location) { {"context" => context} }
74
86
  return AnalDiffist::ReekProblem.new(smell)
75
-
76
- double('fake problem').tap do |p|
77
- p.stub(:type) {type}
78
- p.stub(:context) {context}
79
- p.stub(:score) {score}
80
- p.stub(:diff) {p}
81
- end
82
87
  end
83
88
  end
@@ -7,5 +7,4 @@ require 'anal_diffist'
7
7
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
8
8
 
9
9
  RSpec.configure do |config|
10
-
11
10
  end
data/todo ADDED
@@ -0,0 +1,5 @@
1
+ - if there are uncommitted changes, should they be analyzed?
2
+ - diffing engine needs help
3
+ - add -v and --version switches
4
+ - different grouping options (added/removed and by class/module/context)
5
+
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: analdiffist
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.3.0
5
+ version: 0.4.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Adam Pearson
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2011-04-08 00:00:00 -07:00
14
+ date: 2011-07-06 00:00:00 -07:00
15
15
  default_executable: analdiffist
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -89,6 +89,7 @@ extensions: []
89
89
  extra_rdoc_files:
90
90
  - LICENSE.txt
91
91
  - README.md
92
+ - TODO
92
93
  files:
93
94
  - .document
94
95
  - .rspec
@@ -103,7 +104,6 @@ files:
103
104
  - lib/anal_diffist.rb
104
105
  - lib/analdiffist/diff_set.rb
105
106
  - lib/analdiffist/flog_parser.rb
106
- - lib/analdiffist/reek_metrics.rb
107
107
  - lib/analdiffist/reek_parser.rb
108
108
  - lib/analdiffist/standard_diffist.rb
109
109
  - lib/analdiffist/std_out_reporter.rb
@@ -113,12 +113,13 @@ files:
113
113
  - spec/fixtures/smelly_file.rb
114
114
  - spec/lib/analdiffist/diff_set_spec.rb
115
115
  - spec/lib/analdiffist/flog_parser_spec.rb
116
- - spec/lib/analdiffist/reek_metrics_spec.rb
117
116
  - spec/lib/analdiffist/reek_parser_spec.rb
118
117
  - spec/lib/analdiffist/standard_diffist_spec.rb
119
118
  - spec/lib/analdiffist/std_out_reporter_spec.rb
120
119
  - spec/lib/analdiffist/target_finder_spec.rb
121
120
  - spec/spec_helper.rb
121
+ - todo
122
+ - TODO
122
123
  has_rdoc: true
123
124
  homepage: http://github.com/radamant/analdiffist
124
125
  licenses:
@@ -133,7 +134,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
133
134
  requirements:
134
135
  - - ">="
135
136
  - !ruby/object:Gem::Version
136
- hash: -1146240536421962276
137
+ hash: -915699214738148394
137
138
  segments:
138
139
  - 0
139
140
  version: "0"
@@ -155,7 +156,6 @@ test_files:
155
156
  - spec/fixtures/smelly_file.rb
156
157
  - spec/lib/analdiffist/diff_set_spec.rb
157
158
  - spec/lib/analdiffist/flog_parser_spec.rb
158
- - spec/lib/analdiffist/reek_metrics_spec.rb
159
159
  - spec/lib/analdiffist/reek_parser_spec.rb
160
160
  - spec/lib/analdiffist/standard_diffist_spec.rb
161
161
  - spec/lib/analdiffist/std_out_reporter_spec.rb
@@ -1,4 +0,0 @@
1
- module AnalDiffist
2
- class ReekMetrics
3
- end
4
- end
@@ -1,5 +0,0 @@
1
- require 'spec_helper'
2
-
3
-
4
- describe AnalDiffist::ReekMetrics do
5
- end