analdiffist 0.3.0 → 0.4.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.
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