analdiffist 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -4,8 +4,8 @@ gem "reek"
4
4
  gem "flog"
5
5
 
6
6
  group :development do
7
- gem "rspec", "~> 2.3.0"
7
+ gem "rspec", "~> 2.5.0"
8
8
  gem "bundler", "~> 1.0.0"
9
9
  gem "jeweler", "~> 1.5.2"
10
- gem "rcov", ">= 0"
10
+ gem "autotest"
11
11
  end
data/Gemfile.lock CHANGED
@@ -1,6 +1,9 @@
1
1
  GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
+ ZenTest (4.5.0)
5
+ autotest (4.4.6)
6
+ ZenTest (>= 4.4.1)
4
7
  diff-lcs (1.1.2)
5
8
  flog (2.5.1)
6
9
  ruby_parser (~> 2.0)
@@ -11,19 +14,18 @@ GEM
11
14
  git (>= 1.2.5)
12
15
  rake
13
16
  rake (0.8.7)
14
- rcov (0.9.9)
15
17
  reek (1.2.8)
16
18
  ruby2ruby (~> 1.2)
17
19
  ruby_parser (~> 2.0)
18
20
  sexp_processor (~> 3.0)
19
- rspec (2.3.0)
20
- rspec-core (~> 2.3.0)
21
- rspec-expectations (~> 2.3.0)
22
- rspec-mocks (~> 2.3.0)
23
- rspec-core (2.3.1)
24
- rspec-expectations (2.3.0)
21
+ rspec (2.5.0)
22
+ rspec-core (~> 2.5.0)
23
+ rspec-expectations (~> 2.5.0)
24
+ rspec-mocks (~> 2.5.0)
25
+ rspec-core (2.5.1)
26
+ rspec-expectations (2.5.0)
25
27
  diff-lcs (~> 1.1.2)
26
- rspec-mocks (2.3.0)
28
+ rspec-mocks (2.5.0)
27
29
  ruby2ruby (1.2.5)
28
30
  ruby_parser (~> 2.0)
29
31
  sexp_processor (~> 3.0)
@@ -35,9 +37,9 @@ PLATFORMS
35
37
  ruby
36
38
 
37
39
  DEPENDENCIES
40
+ autotest
38
41
  bundler (~> 1.0.0)
39
42
  flog
40
43
  jeweler (~> 1.5.2)
41
- rcov
42
44
  reek
43
- rspec (~> 2.3.0)
45
+ rspec (~> 2.5.0)
data/README.md CHANGED
@@ -2,6 +2,7 @@ analdiffist
2
2
  ============
3
3
 
4
4
  A professional twice over: an analyst and a diffist.
5
+ [http://www.youtube.com/watch?v=UrIpPqcln6Y](http://www.youtube.com/watch?v=UrIpPqcln6Y)
5
6
 
6
7
  analdiffist uses [flog](http://ruby.sadi.st/Flog.html) and [reek](https://github.com/kevinrutherford/reek/wiki) to analyze ruby code.
7
8
  Given two git refs (for example *master* and *feature-branch*), it will show you any differences in code metrics introduced between the refs.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.2.0
data/analdiffist.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{analdiffist}
8
- s.version = "0.1.1"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Adam Pearson", "Dave Foley"]
12
- s.date = %q{2011-03-09}
12
+ s.date = %q{2011-04-08}
13
13
  s.default_executable = %q{analdiffist}
14
14
  s.description = %q{A tool for comparing the complexity and code smells between two git revisions}
15
15
  s.email = %q{davidmfoley@gmail.com}
@@ -29,6 +29,22 @@ Gem::Specification.new do |s|
29
29
  "VERSION",
30
30
  "analdiffist.gemspec",
31
31
  "bin/analdiffist",
32
+ "lib/anal_diffist.rb",
33
+ "lib/analdiffist/diff_set.rb",
34
+ "lib/analdiffist/flog_parser.rb",
35
+ "lib/analdiffist/reek_metrics.rb",
36
+ "lib/analdiffist/reek_parser.rb",
37
+ "lib/analdiffist/standard_diffist.rb",
38
+ "lib/analdiffist/target_finder.rb",
39
+ "lib/analdiffist/text_based_diffist.rb",
40
+ "spec/fixtures/other_smelly_file.rb",
41
+ "spec/fixtures/smelly_file.rb",
42
+ "spec/lib/analdiffist/diff_set_spec.rb",
43
+ "spec/lib/analdiffist/flog_parser_spec.rb",
44
+ "spec/lib/analdiffist/reek_metrics_spec.rb",
45
+ "spec/lib/analdiffist/reek_parser_spec.rb",
46
+ "spec/lib/analdiffist/standard_diffist_spec.rb",
47
+ "spec/lib/analdiffist/target_finder_spec.rb",
32
48
  "spec/spec_helper.rb"
33
49
  ]
34
50
  s.homepage = %q{http://github.com/radamant/analdiffist}
@@ -37,6 +53,14 @@ Gem::Specification.new do |s|
37
53
  s.rubygems_version = %q{1.5.2}
38
54
  s.summary = %q{A professional twice over: an analyst and a diffist.}
39
55
  s.test_files = [
56
+ "spec/fixtures/other_smelly_file.rb",
57
+ "spec/fixtures/smelly_file.rb",
58
+ "spec/lib/analdiffist/diff_set_spec.rb",
59
+ "spec/lib/analdiffist/flog_parser_spec.rb",
60
+ "spec/lib/analdiffist/reek_metrics_spec.rb",
61
+ "spec/lib/analdiffist/reek_parser_spec.rb",
62
+ "spec/lib/analdiffist/standard_diffist_spec.rb",
63
+ "spec/lib/analdiffist/target_finder_spec.rb",
40
64
  "spec/spec_helper.rb"
41
65
  ]
42
66
 
@@ -46,25 +70,25 @@ Gem::Specification.new do |s|
46
70
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
71
  s.add_runtime_dependency(%q<reek>, [">= 0"])
48
72
  s.add_runtime_dependency(%q<flog>, [">= 0"])
49
- s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
73
+ s.add_development_dependency(%q<rspec>, ["~> 2.5.0"])
50
74
  s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
51
75
  s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
52
- s.add_development_dependency(%q<rcov>, [">= 0"])
76
+ s.add_development_dependency(%q<autotest>, [">= 0"])
53
77
  else
54
78
  s.add_dependency(%q<reek>, [">= 0"])
55
79
  s.add_dependency(%q<flog>, [">= 0"])
56
- s.add_dependency(%q<rspec>, ["~> 2.3.0"])
80
+ s.add_dependency(%q<rspec>, ["~> 2.5.0"])
57
81
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
58
82
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
59
- s.add_dependency(%q<rcov>, [">= 0"])
83
+ s.add_dependency(%q<autotest>, [">= 0"])
60
84
  end
61
85
  else
62
86
  s.add_dependency(%q<reek>, [">= 0"])
63
87
  s.add_dependency(%q<flog>, [">= 0"])
64
- s.add_dependency(%q<rspec>, ["~> 2.3.0"])
88
+ s.add_dependency(%q<rspec>, ["~> 2.5.0"])
65
89
  s.add_dependency(%q<bundler>, ["~> 1.0.0"])
66
90
  s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
67
- s.add_dependency(%q<rcov>, [">= 0"])
91
+ s.add_dependency(%q<autotest>, [">= 0"])
68
92
  end
69
93
  end
70
94
 
data/bin/analdiffist CHANGED
@@ -1,94 +1,7 @@
1
1
  #! /usr/bin/env ruby
2
2
 
3
- require 'tmpdir'
3
+ require 'anal_diffist'
4
4
 
5
- def main
6
- current_branch = get_current_branch
7
- puts "current branch: #{current_branch}"
8
- stashed = try_to_stash
9
-
10
- ref = get_refs_to_diff current_branch
11
-
12
- file_1 = analyze_ref(ref[0])
13
- file_2 = analyze_ref(ref[1])
14
-
15
- begin
16
- echo_exec "git checkout #{current_branch}" if current_branch != ref[1]
17
- rescue Exception
18
- end
19
-
20
- if stashed
21
- echo "unstashing"
22
- echo_exec "git stash apply"
23
- end
24
-
25
- diff file_1, file_2
26
- end
27
-
28
- def get_current_branch
29
- current_branch_raw = echo_exec "git branch --no-color"
30
- lines = current_branch_raw.split("\n")
31
- current_branch_line = lines.detect{|x| x[0] == '*'}
32
- current_branch = current_branch_line.split(' ')[1]
33
- end
34
-
35
- def get_refs_to_diff current_branch
36
- [ ARGV[0] || "origin/master", ARGV[1] || current_branch]
37
- end
38
-
39
- def analyze_ref ref_name
40
- file = get_file_name ref_name
41
- begin
42
- echo_exec "git checkout #{ref_name}"
43
- do_analytics file, ref_name
44
- rescue Exception
45
- end
46
-
47
- file
48
- end
49
-
50
- def get_file_name ref_name
51
-
52
- File.join(Dir.tmpdir, "#{ref_name.gsub('/', '_')}-analytics.txt")
53
- end
54
-
55
- def do_analytics dest_filename, ref_name
56
- puts 'writing analytics to ' + dest_filename
57
- reek_result = `reek -q app lib`
58
- flog_result = `flog -g app lib`
59
- File.open(dest_filename, 'w') do |f|
60
- f.write"--- Analytics for #{ref_name} ---\n\n"
61
-
62
- f.write"\n\n--- FLOG ---\n\n"
63
- f.write clean_up_flog(flog_result)
64
-
65
- f.write"\n\n--- REEK ---\n\n"
66
- f.write reek_result
67
- end
68
- end
69
-
70
- def clean_up_flog(flog_result)
71
- flog_result.gsub(/:[0-9]+$/, '')
72
- end
73
-
74
- def echo s
75
- puts s
76
- end
77
-
78
- def echo_exec command
79
- puts command
80
- result = `#{command}`
81
- puts result
82
- result
83
- end
84
-
85
- def try_to_stash
86
- result = echo_exec "git stash"
87
- !(result =~ /No local changes to save/)
88
- end
89
-
90
- def diff f1, f2
91
- echo_exec "git diff --color=always -U0 -- '#{f1}' '#{f2}'"
92
- end
93
-
94
- main
5
+ start_ref = ARGV[0]
6
+ end_ref = ARGV[1]
7
+ AnalDiffist::Anal.new.run(start_ref, end_ref)
@@ -0,0 +1,79 @@
1
+ module AnalDiffist
2
+ require 'analdiffist/target_finder'
3
+ require 'analdiffist/reek_metrics'
4
+ require 'analdiffist/reek_parser'
5
+ require 'analdiffist/flog_parser'
6
+ require 'analdiffist/diff_set'
7
+ require 'analdiffist/text_based_diffist'
8
+ require 'analdiffist/standard_diffist'
9
+
10
+ class Diffist
11
+ end
12
+
13
+ require 'tmpdir'
14
+ class Anal < Diffist
15
+ def initialize
16
+ @diffist = AnalDiffist::StandardDiffist.new
17
+ end
18
+
19
+ def run(start_ref, end_ref)
20
+ current_branch = get_current_branch
21
+ stashed = try_to_stash
22
+
23
+ ref = get_refs_to_diff current_branch, start_ref, end_ref
24
+ puts "\nAnaldiffizing: #{ref.join(" -> ")}"
25
+ analyze_ref(ref[0])
26
+ analyze_ref(ref[1])
27
+
28
+ begin
29
+ if current_branch != ref[1]
30
+ puts " checking out original revision: #{current_branch}"
31
+ checkout_revision current_branch
32
+ end
33
+ rescue Exception
34
+ end
35
+
36
+ if stashed
37
+ puts "unstashing"
38
+ `git stash apply`
39
+ end
40
+
41
+ @diffist.report_results
42
+ end
43
+
44
+ def get_current_branch
45
+ current_branch_raw = `git branch --no-color`
46
+ lines = current_branch_raw.split("\n")
47
+ current_branch_line = lines.detect{|x| x[0] == '*'}
48
+ current_branch = current_branch_line.split(' ')[1]
49
+ end
50
+
51
+ def get_refs_to_diff current_branch, start_ref, end_ref
52
+ [ start_ref || "origin/master", end_ref || current_branch]
53
+ end
54
+
55
+ def analyze_ref ref_name
56
+ begin
57
+ checkout_revision ref_name
58
+ puts " analyzing revision: #{ref_name}"
59
+ @diffist.do_analytics ref_name
60
+ rescue Exception
61
+ puts "Error in analyze_ref: " + $!.to_s
62
+ end
63
+
64
+ end
65
+
66
+ def checkout_revision ref_name
67
+ puts " checking out revision: #{ref_name}"
68
+ `git checkout -q #{ref_name}`
69
+ end
70
+
71
+ def try_to_stash
72
+ result = `git stash`
73
+ stashed = !(result =~ /No local changes to save/)
74
+ puts "stashed local uncommitted changes" if stashed
75
+ stashed
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,30 @@
1
+ module AnalDiffist
2
+ class DiffSet
3
+ def initialize before, after
4
+ @before = before
5
+ @after = after
6
+ end
7
+
8
+ def added_problems
9
+ compare(@after, @before)
10
+ end
11
+
12
+ def removed_problems
13
+ compare(@before, @after)
14
+ end
15
+
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] }
21
+
22
+ problem.diff(matching_problem)
23
+
24
+ end.reject {|x| x.nil?}
25
+ end
26
+ end
27
+
28
+ class ScoreDiffSet
29
+ end
30
+ end
@@ -0,0 +1,55 @@
1
+ require 'flog'
2
+ module AnalDiffist
3
+ class FlogParser
4
+ def initialize paths, threshold = 10.0
5
+ @paths = paths
6
+ @flog_threshold = threshold
7
+ end
8
+
9
+ def problems
10
+ f = Flog.new
11
+ f.flog(@paths)
12
+ problems = []
13
+ f.each_by_score{|class_method, score, ignore_for_now| problems << FlogProblem.new(class_method, score)}
14
+ problems.select {|p| p.score >= @flog_threshold}
15
+ end
16
+ end
17
+
18
+ class FlogProblem
19
+ attr_accessor :context, :score
20
+ def initialize class_method, score
21
+ @context = class_method || '(none)'
22
+ @score = score
23
+ end
24
+
25
+ def type
26
+ 'flog score'
27
+ end
28
+
29
+ def diff other
30
+ return self if other.nil?
31
+ return nil if other.score >= score
32
+ FlogDiff.new(@context, other.score, score)
33
+ end
34
+
35
+ def description
36
+ "Flog score: #{score}"
37
+ end
38
+ end
39
+ class FlogDiff
40
+ attr_accessor :context, :score
41
+ def initialize context, previous_score, current_score
42
+ @context = context
43
+ @current_score = current_score
44
+ @previous_score = previous_score
45
+ end
46
+
47
+ def score
48
+ (@current_score - @previous_score).round(1)
49
+ end
50
+
51
+ def description
52
+ "Flog: #{@current_score.round(1)} (+#{(@current_score - @previous_score).round(1)})"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,4 @@
1
+ module AnalDiffist
2
+ class ReekMetrics
3
+ end
4
+ end
@@ -0,0 +1,39 @@
1
+ require 'reek'
2
+ module AnalDiffist
3
+ class ReekParser
4
+ attr_accessor :problems
5
+
6
+ def initialize(paths)
7
+ examiner = Reek::Examiner.new(paths)
8
+ @problems = examiner.smells.map {|smell| ReekProblem.new(smell)}
9
+ end
10
+
11
+ def diff(previous)
12
+ AnalDiffist::DiffSet.new(previous.problems, self.problems)
13
+ end
14
+ end
15
+
16
+ class ReekProblem
17
+ def initialize smell
18
+ @smell = smell
19
+ end
20
+
21
+ def type
22
+ @smell.subclass.to_s || ''
23
+ end
24
+
25
+ def context
26
+ @smell.location["context"]
27
+ end
28
+
29
+ def diff other
30
+ self if other.nil?
31
+ end
32
+ def score
33
+ 1
34
+ end
35
+ def description
36
+ "Reek: #{type}"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,64 @@
1
+ module AnalDiffist
2
+ class StandardDiffist
3
+ def initialize options = {}
4
+ @targets = options[:targets] || AnalDiffist::TargetFinder.new
5
+ @reporter = options[:reporter] || AnalDiffist::StdOutReporter.new
6
+ @parsers = options[:parsers] || [FlogParser, ReekParser]
7
+
8
+ @revisions = []
9
+ end
10
+
11
+ def do_analytics name
12
+ #puts 'analyzing ' + name
13
+ #puts @revisions.inspect
14
+ @revisions << ProblemSet.new(name, @parsers, @targets)
15
+ #puts @revisions.inspect
16
+ end
17
+
18
+ def report_results
19
+ #puts @revisions.inspect
20
+ before = @revisions[0]
21
+ after = @revisions[1]
22
+ diff = DiffSet.new(before.problems, after.problems)
23
+
24
+ @reporter.report(diff, before.name, after.name)
25
+
26
+ end
27
+
28
+ private
29
+
30
+ class ProblemSet
31
+ attr_accessor :problems, :name
32
+ def initialize name, parsers, targets
33
+ @name = name
34
+ @problems = []
35
+ parsers.each do |parser|
36
+ parser_instance = parser.new(targets.targets)
37
+ problems = parser_instance.problems
38
+ @problems += (problems || [])
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ class StdOutReporter
45
+ def report diff, from_rev, to_rev
46
+ puts "\n\nAnaldifference between revisions: \n #{from_rev}\n #{to_rev}"
47
+ puts "\nAdded:\n"
48
+ puts describe(diff.added_problems)
49
+ puts "\nRemoved:\n"
50
+ puts describe(diff.removed_problems)
51
+ puts "\n\n"
52
+ end
53
+
54
+ def describe(problems)
55
+ by_context = problems.group_by {|prob| prob.context}
56
+ results = []
57
+ by_context.keys.sort.each do |k|
58
+ results << " #{k}"
59
+ results << by_context[k].map {|p| " #{p.description}"}.join("\n")
60
+ end.collect
61
+ results.join("\n")
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,17 @@
1
+ module AnalDiffist
2
+ class TargetFinder
3
+ def initialize
4
+ end
5
+ def targets
6
+ @targets = []
7
+ @targets << "lib" if Dir.exists?("lib")
8
+ @targets << "app" if Dir.exists?("app")
9
+ @targets
10
+ end
11
+
12
+ def to_s
13
+ targets.join(' ')
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+
2
+ module AnalDiffist
3
+ class TextBasedDiffist
4
+ def initialize
5
+ @targets = AnalDiffist::TargetFinder.new
6
+ @files = []
7
+ end
8
+ def report_results
9
+ puts 'results:'
10
+ diff @files[0], @files[1]
11
+ end
12
+
13
+ def do_analytics ref_name
14
+ dest_filename = get_file_name ref_name
15
+
16
+ puts
17
+ puts 'collecting reek'
18
+ reek_result = `reek -q #{@targets}`
19
+ puts 'collecting flog'
20
+ flog_result = `flog -g #{@targets}`
21
+ File.open(dest_filename, 'w') do |f|
22
+ puts 'writing analytics to ' + dest_filename
23
+ f.write"--- Analytics for #{ref_name} ---\n\n"
24
+
25
+ f.write"\n\n--- FLOG ---\n\n"
26
+ f.write clean_up_flog(flog_result)
27
+
28
+ f.write"\n\n--- REEK ---\n\n"
29
+ f.write reek_result
30
+ end
31
+
32
+ @files << dest_filename
33
+ end
34
+
35
+ def get_file_name ref_name
36
+ File.join(Dir.tmpdir, "#{ref_name.gsub('/', '_')}-analytics.txt")
37
+ end
38
+
39
+ def clean_up_flog(flog_result)
40
+ flog_result.gsub(/:[0-9]+$/, '')
41
+ end
42
+ def diff f1, f2
43
+ puts `git diff --color=always -U0 -- '#{f1}' '#{f2}'`
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ class SmellyFile
2
+ def self.class_variable
3
+ @@class_variable = 42
4
+ end
5
+
6
+ def duplication
7
+ if some_method
8
+ some_method
9
+ end
10
+
11
+ some_method
12
+ end
13
+
14
+ def some_method
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ class SmellyFile
2
+ def self.class_variable
3
+ @@class_variable = 42
4
+ end
5
+
6
+ def duplication
7
+ if some_method
8
+ some_method
9
+ end
10
+
11
+ some_method
12
+ end
13
+
14
+ def some_method
15
+ end
16
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'diffing two files' do
4
+ 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
17
+ end
18
+
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
32
+ end
33
+
34
+ context 'one removed, one added, one remains' do
35
+ before do
36
+ before = [test_problem('foo', 'bar'), test_problem('removed', 'removed')]
37
+ after = [test_problem('foo', 'bar'), test_problem('added', 'added')]
38
+ @diff = AnalDiffist::DiffSet.new(before, after)
39
+ end
40
+
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'
46
+ end
47
+
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'
53
+ end
54
+ end
55
+
56
+ context 'when scores change' do
57
+ before do
58
+ before = [AnalDiffist::FlogProblem.new('bar', 7.1)]
59
+ after = [AnalDiffist::FlogProblem.new('bar', 8.5)]
60
+ @diff = AnalDiffist::DiffSet.new(before, after)
61
+ end
62
+
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
67
+ end
68
+ end
69
+
70
+ def test_problem type, context, score = 1
71
+ smell = double("fake problem")
72
+ smell.stub(:subclass) {type}
73
+ smell.stub(:location) {context}
74
+ 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
+ end
83
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe AnalDiffist::FlogParser do
4
+ context 'analyzing a class' do
5
+ before do
6
+ file_parser = get_parser_for('smelly_file.rb')
7
+ @problems = file_parser.problems
8
+ end
9
+ def get_parser_for(fixture_file)
10
+ file_name = File.join(File.dirname(__FILE__), '../../fixtures/', fixture_file)
11
+ AnalDiffist::FlogParser.new(file_name, 1.0)
12
+ end
13
+ it 'should have an entry for the test method with a non zero score' do
14
+ duplication = @problems.detect {|p| p.context == 'SmellyFile#duplication'}
15
+ duplication.score.should > 0
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe AnalDiffist::ReekMetrics do
5
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe AnalDiffist::ReekParser do
4
+ context 'a smelly file' do
5
+ before do
6
+ smelly_file_parser = get_parser_for('smelly_file.rb')
7
+ @problems = smelly_file_parser.problems
8
+ end
9
+
10
+ it 'has a duplication warning for the duplication method' do
11
+ smells = get_smells_for('SmellyFile#duplication')
12
+ smells[0].type.should == 'DuplicateMethodCall'
13
+ end
14
+
15
+ it 'should have some results' do
16
+ @problems.length.should > 0
17
+ end
18
+
19
+ it 'creates a diff' do
20
+ smelly_file_parser = get_parser_for('smelly_file.rb')
21
+ other_smelly_file_parser = get_parser_for('other_smelly_file.rb')
22
+ diff = smelly_file_parser.diff(other_smelly_file_parser)
23
+ diff.should be
24
+ end
25
+
26
+ def get_smells_for context
27
+ @problems.select {|reek| reek.context == context}
28
+ end
29
+ end
30
+
31
+ def get_parser_for(fixture_file)
32
+ file_name = File.join(File.dirname(__FILE__), '../../fixtures/', fixture_file)
33
+ AnalDiffist::ReekParser.new([file_name])
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe AnalDiffist::StandardDiffist do
4
+ class FakeParser
5
+ def problems
6
+ []
7
+ end
8
+ end
9
+
10
+ it 'should work' do
11
+ @diffist = AnalDiffist::StandardDiffist.new :parsers => [FakeParser]
12
+ @diffist.do_analytics('foo')
13
+ @diffist.do_analytics('bar')
14
+ end
15
+
16
+ it 'should work!' do
17
+ @diffist = AnalDiffist::StandardDiffist.new
18
+ @diffist.do_analytics('foo')
19
+ @diffist.do_analytics('bar')
20
+ end
21
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe AnalDiffist::TargetFinder do
4
+ describe "#targets" do
5
+
6
+ before { Dir.stub(:exists?){false} }
7
+
8
+ subject { AnalDiffist::TargetFinder.new.targets }
9
+
10
+ context 'when ./lib exists' do
11
+ before { Dir.stub(:exists?).with('lib'){true} }
12
+ it{should include("lib")}
13
+ end
14
+
15
+ context 'when ./app exists' do
16
+ before { Dir.stub(:exists?).with('app'){true} }
17
+ it{should include("app")}
18
+ end
19
+
20
+ end
21
+
22
+ describe "#to_s" do
23
+ subject do
24
+ atf = AnalDiffist::TargetFinder.new.tap do |t|
25
+ t.stub(:targets){['analyst', 'therapist']}
26
+ end
27
+ atf.to_s
28
+ end
29
+
30
+ it{ should == "analyst therapist"}
31
+ end
32
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
  require 'rspec'
4
- require 'analdiffist'
5
-
4
+ require 'anal_diffist'
6
5
  # Requires supporting files with custom matchers and macros, etc,
7
6
  # in ./support/ and its subdirectories.
8
7
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: analdiffist
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.1
5
+ version: 0.2.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-03-09 00:00:00 -08:00
14
+ date: 2011-04-08 00:00:00 -07:00
15
15
  default_executable: analdiffist
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirements:
44
44
  - - ~>
45
45
  - !ruby/object:Gem::Version
46
- version: 2.3.0
46
+ version: 2.5.0
47
47
  type: :development
48
48
  prerelease: false
49
49
  version_requirements: *id003
@@ -70,7 +70,7 @@ dependencies:
70
70
  prerelease: false
71
71
  version_requirements: *id005
72
72
  - !ruby/object:Gem::Dependency
73
- name: rcov
73
+ name: autotest
74
74
  requirement: &id006 !ruby/object:Gem::Requirement
75
75
  none: false
76
76
  requirements:
@@ -100,6 +100,22 @@ files:
100
100
  - VERSION
101
101
  - analdiffist.gemspec
102
102
  - bin/analdiffist
103
+ - lib/anal_diffist.rb
104
+ - lib/analdiffist/diff_set.rb
105
+ - lib/analdiffist/flog_parser.rb
106
+ - lib/analdiffist/reek_metrics.rb
107
+ - lib/analdiffist/reek_parser.rb
108
+ - lib/analdiffist/standard_diffist.rb
109
+ - lib/analdiffist/target_finder.rb
110
+ - lib/analdiffist/text_based_diffist.rb
111
+ - spec/fixtures/other_smelly_file.rb
112
+ - spec/fixtures/smelly_file.rb
113
+ - spec/lib/analdiffist/diff_set_spec.rb
114
+ - spec/lib/analdiffist/flog_parser_spec.rb
115
+ - spec/lib/analdiffist/reek_metrics_spec.rb
116
+ - spec/lib/analdiffist/reek_parser_spec.rb
117
+ - spec/lib/analdiffist/standard_diffist_spec.rb
118
+ - spec/lib/analdiffist/target_finder_spec.rb
103
119
  - spec/spec_helper.rb
104
120
  has_rdoc: true
105
121
  homepage: http://github.com/radamant/analdiffist
@@ -115,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
131
  requirements:
116
132
  - - ">="
117
133
  - !ruby/object:Gem::Version
118
- hash: 2617333102341510059
134
+ hash: -4153762444283860543
119
135
  segments:
120
136
  - 0
121
137
  version: "0"
@@ -133,4 +149,12 @@ signing_key:
133
149
  specification_version: 3
134
150
  summary: "A professional twice over: an analyst and a diffist."
135
151
  test_files:
152
+ - spec/fixtures/other_smelly_file.rb
153
+ - spec/fixtures/smelly_file.rb
154
+ - spec/lib/analdiffist/diff_set_spec.rb
155
+ - spec/lib/analdiffist/flog_parser_spec.rb
156
+ - spec/lib/analdiffist/reek_metrics_spec.rb
157
+ - spec/lib/analdiffist/reek_parser_spec.rb
158
+ - spec/lib/analdiffist/standard_diffist_spec.rb
159
+ - spec/lib/analdiffist/target_finder_spec.rb
136
160
  - spec/spec_helper.rb