rubycritic 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/CONTRIBUTING.md +2 -1
  4. data/README.md +1 -0
  5. data/lib/rubycritic/cli/options.rb +17 -1
  6. data/lib/rubycritic/commands/ci.rb +2 -3
  7. data/lib/rubycritic/commands/default.rb +2 -3
  8. data/lib/rubycritic/configuration.rb +4 -1
  9. data/lib/rubycritic/core/analysed_module.rb +19 -0
  10. data/lib/rubycritic/core/location.rb +11 -0
  11. data/lib/rubycritic/core/rating.rb +8 -0
  12. data/lib/rubycritic/core/smell.rb +16 -0
  13. data/lib/rubycritic/{report_generators → generators/html}/assets/javascripts/application.js +0 -0
  14. data/lib/rubycritic/{report_generators → generators/html}/assets/javascripts/highcharts.src-4.0.1.js +0 -0
  15. data/lib/rubycritic/{report_generators → generators/html}/assets/javascripts/jquery-2.1.0.js +0 -0
  16. data/lib/rubycritic/{report_generators → generators/html}/assets/javascripts/jquery.floatThead-v1.2.7.js +0 -0
  17. data/lib/rubycritic/{report_generators → generators/html}/assets/javascripts/jquery.scrollTo-1.4.11.js +0 -0
  18. data/lib/rubycritic/generators/html/assets/javascripts/jquery.tablesorter.js +2089 -0
  19. data/lib/rubycritic/{report_generators → generators/html}/assets/javascripts/jquery.timeago-v1.4.1.js +0 -0
  20. data/lib/rubycritic/{report_generators → generators/html}/assets/javascripts/prettify-4-Mar-2013.js +0 -0
  21. data/lib/rubycritic/{report_generators → generators/html}/assets/stylesheets/application.css +87 -25
  22. data/lib/rubycritic/{report_generators → generators/html}/assets/stylesheets/prettify.custom_theme.css +0 -0
  23. data/lib/rubycritic/generators/html/base.rb +52 -0
  24. data/lib/rubycritic/generators/html/code_file.rb +40 -0
  25. data/lib/rubycritic/generators/html/code_index.rb +26 -0
  26. data/lib/rubycritic/generators/html/line.rb +37 -0
  27. data/lib/rubycritic/generators/html/overview.rb +27 -0
  28. data/lib/rubycritic/generators/html/smells_index.rb +38 -0
  29. data/lib/rubycritic/{report_generators → generators/html}/templates/code_file.html.erb +4 -2
  30. data/lib/rubycritic/{report_generators → generators/html}/templates/code_index.html.erb +8 -4
  31. data/lib/rubycritic/{report_generators → generators/html}/templates/layouts/application.html.erb +12 -8
  32. data/lib/rubycritic/{report_generators → generators/html}/templates/line.html.erb +0 -0
  33. data/lib/rubycritic/{report_generators → generators/html}/templates/overview.html.erb +0 -0
  34. data/lib/rubycritic/{report_generators → generators/html}/templates/smells_index.html.erb +4 -4
  35. data/lib/rubycritic/{report_generators → generators/html}/templates/smelly_line.html.erb +0 -0
  36. data/lib/rubycritic/{report_generators → generators/html}/turbulence.rb +0 -0
  37. data/lib/rubycritic/{report_generators → generators/html}/view_helpers.rb +0 -0
  38. data/lib/rubycritic/generators/html_report.rb +66 -0
  39. data/lib/rubycritic/generators/json/simple.rb +30 -0
  40. data/lib/rubycritic/generators/json_report.rb +23 -0
  41. data/lib/rubycritic/reporter.rb +20 -0
  42. data/lib/rubycritic/version.rb +1 -1
  43. data/test/lib/rubycritic/analysers/churn_test.rb +12 -13
  44. data/test/lib/rubycritic/analysers/complexity_test.rb +9 -5
  45. data/test/lib/rubycritic/analysers/smells/flay_test.rb +27 -20
  46. data/test/lib/rubycritic/analysers/smells/flog_test.rb +17 -15
  47. data/test/lib/rubycritic/analysers/smells/reek_test.rb +2 -2
  48. data/test/lib/rubycritic/report_generators/turbulence_test.rb +1 -1
  49. data/test/lib/rubycritic/report_generators/view_helpers_test.rb +1 -1
  50. data/test/lib/rubycritic/source_control_systems/base_test.rb +2 -2
  51. data/test/lib/rubycritic/source_locator_test.rb +1 -1
  52. data/test/samples/flay/smelly.rb +0 -9
  53. data/test/samples/flay/smelly2.rb +8 -0
  54. metadata +33 -31
  55. data/lib/rubycritic/report_generators/assets/javascripts/jquery.tablesorter-2.0.js +0 -1031
  56. data/lib/rubycritic/report_generators/base.rb +0 -50
  57. data/lib/rubycritic/report_generators/code_file.rb +0 -38
  58. data/lib/rubycritic/report_generators/code_index.rb +0 -24
  59. data/lib/rubycritic/report_generators/current_code_file.rb +0 -17
  60. data/lib/rubycritic/report_generators/line.rb +0 -31
  61. data/lib/rubycritic/report_generators/overview.rb +0 -25
  62. data/lib/rubycritic/report_generators/smells_index.rb +0 -36
  63. data/lib/rubycritic/reporters/base.rb +0 -24
  64. data/lib/rubycritic/reporters/main.rb +0 -51
  65. data/lib/rubycritic/reporters/mini.rb +0 -30
@@ -1,25 +1,29 @@
1
1
  <table id="js-index-table" class="index-table sortable-table">
2
2
  <thead>
3
3
  <tr>
4
- <th class="first-cell">Name</th>
4
+ <th>Name</th>
5
5
  <th class="numeric-cell" title="Number of times a file has changed">Churn</th>
6
6
  <th class="numeric-cell" title="Overall amount of code in a file">Complexity</th>
7
7
  <th class="numeric-cell" title="Amount of code that is similar to other code">Duplication</th>
8
8
  <th class="numeric-cell">Smells</th>
9
- <th class="centered-cell last-cell">Rating</th>
9
+ <% unless Config.suppress_ratings %>
10
+ <th class="centered-cell">Rating</th>
11
+ <% end %>
10
12
  </tr>
11
13
  </thead>
12
14
  <tbody>
13
15
  <% @analysed_modules.each do |analysed_module| %>
14
16
  <tr>
15
- <td class="first-cell">
17
+ <td>
16
18
  <a href="<%= file_path(analysed_module.pathname.sub_ext('.html')) %>"><%= analysed_module.name %></a>
17
19
  </td>
18
20
  <td class="numeric-cell"><%= analysed_module.churn %></td>
19
21
  <td class="numeric-cell"><%= analysed_module.complexity %></td>
20
22
  <td class="numeric-cell"><%= analysed_module.duplication %></td>
21
23
  <td class="numeric-cell"><%= analysed_module.smells.length %></td>
22
- <td class="centered-cell last-cell"><span class="rating-<%= analysed_module.rating.to_s.downcase %> circled-text circle"><%= analysed_module.rating %></span></td>
24
+ <% unless Config.suppress_ratings %>
25
+ <td class="centered-cell"><span class="rating-<%= analysed_module.rating.to_s.downcase %> circled-text circle"><%= analysed_module.rating %></span></td>
26
+ <% end %>
23
27
  </tr>
24
28
  <% end %>
25
29
  </tbody>
@@ -10,16 +10,20 @@
10
10
  </head>
11
11
  <body>
12
12
  <header class="project-header group">
13
- <h1 class="logo"><a href="<%= file_path('overview.html') %>" class="logo-link">RubyCritic</a></h1>
14
- <nav class="project-nav">
15
- <a href="<%= file_path('overview.html') %>" class="project-nav-item">Overview</a>
16
- <a href="<%= file_path('code_index.html') %>" class="project-nav-item">Code</a>
17
- <a href="<%= file_path('smells_index.html') %>" class="project-nav-item">Smells</a>
18
- </nav>
13
+ <div class="container">
14
+ <h1 class="logo"><a href="<%= file_path('overview.html') %>" class="logo-link">RubyCritic</a></h1>
15
+ <nav class="project-nav">
16
+ <a href="<%= file_path('overview.html') %>" class="project-nav-item">Overview</a>
17
+ <a href="<%= file_path('code_index.html') %>" class="project-nav-item">Code</a>
18
+ <a href="<%= file_path('smells_index.html') %>" class="project-nav-item">Smells</a>
19
+ </nav>
20
+ </div>
19
21
  </header>
20
- <%= yield %>
22
+ <div class="container">
23
+ <%= yield %>
24
+ </div>
21
25
  <%= javascript_tag(:'jquery-2.1.0') %>
22
- <%= javascript_tag(:'jquery.tablesorter-2.0') %>
26
+ <%= javascript_tag(:'jquery.tablesorter') %>
23
27
  <%= javascript_tag(:'jquery.floatThead-v1.2.7') %>
24
28
  <%= javascript_tag(:'jquery.timeago-v1.4.1') %>
25
29
  <%= javascript_tag(:'highcharts.src-4.0.1') %>
@@ -1,24 +1,24 @@
1
1
  <table id="js-index-table" class="smells-index-table index-table sortable-table">
2
2
  <thead>
3
3
  <tr>
4
- <th class="first-cell">Smell</th>
4
+ <th>Smell</th>
5
5
  <th>Locations</th>
6
6
  <% if @show_status %>
7
- <th class="centered-cell last-cell" title="Code smells introduced recently are marked as new. There's still time before they are committed!">Status</th>
7
+ <th class="centered-cell" title="Code smells introduced recently are marked as new. There's still time before they are committed!">Status</th>
8
8
  <% end %>
9
9
  </tr>
10
10
  </thead>
11
11
  <tbody>
12
12
  <% @smells.each do |smell| %>
13
13
  <tr>
14
- <td class="first-cell"><%= smell.type %></td>
14
+ <td><%= smell.type %></td>
15
15
  <td>
16
16
  <% smell.locations.each do |location| %>
17
17
  <a href="<%= smell_location_path(location) %>"><%= @analysed_module_names[location.pathname] %></a>
18
18
  <% end %>
19
19
  </td>
20
20
  <% if @show_status %>
21
- <td class="centered-cell last-cell"><span class="status-<%= smell.status %> circled-text circle"><%= smell.status %></span></td>
21
+ <td class="centered-cell"><span class="status-<%= smell.status %> circled-text circle"><%= smell.status %></span></td>
22
22
  <% end %>
23
23
  </tr>
24
24
  <% end %>
@@ -0,0 +1,66 @@
1
+ require "fileutils"
2
+ require "rubycritic/generators/html/overview"
3
+ require "rubycritic/generators/html/smells_index"
4
+ require "rubycritic/generators/html/code_index"
5
+ require "rubycritic/generators/html/code_file"
6
+
7
+ module Rubycritic
8
+ module Generator
9
+
10
+ class HtmlReport
11
+ ASSETS_DIR = File.expand_path("../html/assets", __FILE__)
12
+
13
+ def initialize(analysed_modules)
14
+ @analysed_modules = analysed_modules
15
+ end
16
+
17
+ def generate_report
18
+ create_directories_and_files
19
+ copy_assets_to_report_directory
20
+ puts "New critique at #{report_location}"
21
+ end
22
+
23
+ private
24
+
25
+ def create_directories_and_files
26
+ Array(generators).each do |generator|
27
+ FileUtils.mkdir_p(generator.file_directory)
28
+ File.open(generator.file_pathname, "w+") do |file|
29
+ file.write(generator.render)
30
+ end
31
+ end
32
+ end
33
+
34
+ def generators
35
+ [overview_generator, code_index_generator, smells_index_generator] + file_generators
36
+ end
37
+
38
+ def overview_generator
39
+ @overview_generator ||= Html::Overview.new(@analysed_modules)
40
+ end
41
+
42
+ def code_index_generator
43
+ Html::CodeIndex.new(@analysed_modules)
44
+ end
45
+
46
+ def smells_index_generator
47
+ Html::SmellsIndex.new(@analysed_modules)
48
+ end
49
+
50
+ def file_generators
51
+ @analysed_modules.map do |analysed_module|
52
+ Html::CodeFile.new(analysed_module)
53
+ end
54
+ end
55
+
56
+ def copy_assets_to_report_directory
57
+ FileUtils.cp_r(ASSETS_DIR, Config.root)
58
+ end
59
+
60
+ def report_location
61
+ overview_generator.file_href
62
+ end
63
+ end
64
+
65
+ end
66
+ end
@@ -0,0 +1,30 @@
1
+ require "json"
2
+
3
+ module Rubycritic
4
+ module Generator
5
+ module Json
6
+
7
+ class Simple
8
+ def initialize(analysed_modules)
9
+ @analysed_modules = analysed_modules
10
+ end
11
+
12
+ def render
13
+ JSON.dump(data)
14
+ end
15
+
16
+ def data
17
+ {
18
+ :metadata => {
19
+ :rubycritic => {
20
+ :version => Rubycritic::VERSION
21
+ }
22
+ },
23
+ :analysed_modules => @analysed_modules
24
+ }
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ require "rubycritic/generators/json/simple"
2
+
3
+ module Rubycritic
4
+ module Generator
5
+
6
+ class JsonReport
7
+ def initialize(analysed_modules)
8
+ @analysed_modules = analysed_modules
9
+ end
10
+
11
+ def generate_report
12
+ print generator.render
13
+ end
14
+
15
+ private
16
+
17
+ def generator
18
+ Json::Simple.new(@analysed_modules)
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module Rubycritic
2
+
3
+ module Reporter
4
+ def self.generate_report(analysed_modules)
5
+ report_generator_class.new(analysed_modules).generate_report
6
+ end
7
+
8
+ def self.report_generator_class
9
+ case Config.format
10
+ when :json
11
+ require "rubycritic/generators/json_report"
12
+ Generator::JsonReport
13
+ else
14
+ require "rubycritic/generators/html_report"
15
+ Generator::HtmlReport
16
+ end
17
+ end
18
+ end
19
+
20
+ end
@@ -1,3 +1,3 @@
1
1
  module Rubycritic
2
- VERSION = "1.3.0"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -3,22 +3,21 @@ require "rubycritic/analysers/churn"
3
3
  require "rubycritic/source_control_systems/base"
4
4
 
5
5
  describe Rubycritic::Analyser::Churn do
6
- before do
7
- @analysed_modules = [AnalysedModuleDouble.new(:path => "path_to_some_file.rb")]
8
- analyser = Rubycritic::Analyser::Churn.new(@analysed_modules)
9
- analyser.source_control_system = SourceControlSystemDouble.new
10
- analyser.run
11
- end
6
+ context "when analysing a file" do
7
+ before do
8
+ @analysed_module = AnalysedModuleDouble.new(:path => "path_to_some_file.rb")
9
+ analysed_modules = [@analysed_module]
10
+ analyser = Rubycritic::Analyser::Churn.new(analysed_modules)
11
+ analyser.source_control_system = SourceControlSystemDouble.new
12
+ analyser.run
13
+ end
12
14
 
13
- it "calculates the churn of each file and adds it to analysed_modules" do
14
- @analysed_modules.each do |analysed_module|
15
- analysed_module.churn.must_equal 1
15
+ it "calculates its churn" do
16
+ @analysed_module.churn.must_equal 1
16
17
  end
17
- end
18
18
 
19
- it "calculates the date of the last commit of each file and adds it to analysed_modules" do
20
- @analysed_modules.each do |analysed_module|
21
- analysed_module.committed_at.must_equal "2013-10-09 12:52:49 +0100"
19
+ it "determines the date of its last commit" do
20
+ @analysed_module.committed_at.must_equal "2013-10-09 12:52:49 +0100"
22
21
  end
23
22
  end
24
23
  end
@@ -2,11 +2,15 @@ require "analysers_test_helper"
2
2
  require "rubycritic/analysers/complexity"
3
3
 
4
4
  describe Rubycritic::Analyser::Complexity do
5
- it "calculates the complexity of each file and adds it to analysed_modules" do
6
- analysed_modules = [AnalysedModuleDouble.new(:path => "test/samples/flog/complex.rb")]
7
- Rubycritic::Analyser::Complexity.new(analysed_modules).run
8
- analysed_modules.each do |analysed_module|
9
- analysed_module.complexity.must_be_kind_of Numeric
5
+ context "when analysing a file" do
6
+ before do
7
+ @analysed_module = AnalysedModuleDouble.new(:path => "test/samples/flog/complex.rb", :smells => [])
8
+ analysed_modules = [@analysed_module]
9
+ Rubycritic::Analyser::Complexity.new(analysed_modules).run
10
+ end
11
+
12
+ it "calculates its complexity" do
13
+ @analysed_module.complexity.must_be :>, 0
10
14
  end
11
15
  end
12
16
  end
@@ -4,29 +4,36 @@ require "rubycritic/core/analysed_module"
4
4
  require "pathname"
5
5
 
6
6
  describe Rubycritic::Analyser::FlaySmells do
7
- before do
8
- @analysed_module = Rubycritic::AnalysedModule.new(
9
- :pathname => Pathname.new("test/samples/flay/smelly.rb")
10
- )
11
- analysed_modules = [@analysed_module]
12
- Rubycritic::Analyser::FlaySmells.new(analysed_modules).run
13
- end
7
+ context "when analysing a bunch of files with duplicate code" do
8
+ before do
9
+ @analysed_modules = [
10
+ Rubycritic::AnalysedModule.new(:pathname => Pathname.new("test/samples/flay/smelly.rb")),
11
+ Rubycritic::AnalysedModule.new(:pathname => Pathname.new("test/samples/flay/smelly2.rb"))
12
+ ]
13
+ Rubycritic::Analyser::FlaySmells.new(@analysed_modules).run
14
+ end
14
15
 
15
- it "detects smells and adds them to analysed_modules" do
16
- @analysed_module.smells.length.must_equal 1
17
- end
16
+ it "detects its smells" do
17
+ @analysed_modules.first.smells?.must_equal true
18
+ end
18
19
 
19
- it "creates smells with messages" do
20
- smell = @analysed_module.smells.first
21
- smell.message.must_be_instance_of String
22
- end
20
+ it "creates smells with messages" do
21
+ smell = @analysed_modules.first.smells.first
22
+ smell.message.must_be_instance_of String
23
+ end
23
24
 
24
- it "creates smells with scores" do
25
- smell = @analysed_module.smells.first
26
- smell.score.must_be_kind_of Numeric
27
- end
25
+ it "creates smells with scores" do
26
+ smell = @analysed_modules.first.smells.first
27
+ smell.score.must_be_kind_of Numeric
28
+ end
29
+
30
+ it "creates smells with more than one location" do
31
+ smell = @analysed_modules.first.smells.first
32
+ smell.multiple_locations?.must_equal true
33
+ end
28
34
 
29
- it "calculates the mass of duplicate code and adds it to analysed_modules" do
30
- @analysed_module.duplication.must_be(:>, 0)
35
+ it "calculates the mass of duplicate code" do
36
+ @analysed_modules.first.duplication.must_be(:>, 0)
37
+ end
31
38
  end
32
39
  end
@@ -2,23 +2,25 @@ require "analysers_test_helper"
2
2
  require "rubycritic/analysers/smells/flog"
3
3
 
4
4
  describe Rubycritic::Analyser::FlogSmells do
5
- before do
6
- @analysed_module = AnalysedModuleDouble.new(:path => "test/samples/flog/smelly.rb", :smells => [])
7
- analysed_modules = [@analysed_module]
8
- Rubycritic::Analyser::FlogSmells.new(analysed_modules).run
9
- end
5
+ context "when analysing a complex file" do
6
+ before do
7
+ @analysed_module = AnalysedModuleDouble.new(:path => "test/samples/flog/smelly.rb", :smells => [])
8
+ analysed_modules = [@analysed_module]
9
+ Rubycritic::Analyser::FlogSmells.new(analysed_modules).run
10
+ end
10
11
 
11
- it "detects smells and adds them to analysed_modules" do
12
- @analysed_module.smells.length.must_equal 1
13
- end
12
+ it "detects its smells" do
13
+ @analysed_module.smells.length.must_equal 1
14
+ end
14
15
 
15
- it "creates smells with messages" do
16
- smell = @analysed_module.smells.first
17
- smell.message.must_be_instance_of String
18
- end
16
+ it "creates smells with messages" do
17
+ smell = @analysed_module.smells.first
18
+ smell.message.must_be_instance_of String
19
+ end
19
20
 
20
- it "creates smells with scores" do
21
- smell = @analysed_module.smells.first
22
- smell.score.must_be_kind_of Numeric
21
+ it "creates smells with scores" do
22
+ smell = @analysed_module.smells.first
23
+ smell.score.must_be :>, 0
24
+ end
23
25
  end
24
26
  end
@@ -9,7 +9,7 @@ describe Rubycritic::Analyser::ReekSmells do
9
9
  Rubycritic::Analyser::ReekSmells.new(analysed_modules).run
10
10
  end
11
11
 
12
- it "detects smells and adds them to analysed_modules" do
12
+ it "detects its smells" do
13
13
  @analysed_module.smells.length.must_equal 1
14
14
  end
15
15
 
@@ -26,7 +26,7 @@ describe Rubycritic::Analyser::ReekSmells do
26
26
  Rubycritic::Analyser::ReekSmells.new(analysed_modules).run
27
27
  end
28
28
 
29
- it "does not detect smells and does not add them to analysed files" do
29
+ it "does not detect those smells" do
30
30
  @analysed_module.smells.must_be_empty
31
31
  end
32
32
  end
@@ -1,5 +1,5 @@
1
1
  require "test_helper"
2
- require "rubycritic/report_generators/turbulence"
2
+ require "rubycritic/generators/html/turbulence"
3
3
 
4
4
  describe Rubycritic::Turbulence do
5
5
  describe "::data" do
@@ -1,5 +1,5 @@
1
1
  require "test_helper"
2
- require "rubycritic/report_generators/view_helpers"
2
+ require "rubycritic/generators/html/view_helpers"
3
3
  require "pathname"
4
4
 
5
5
  describe Rubycritic::ViewHelpers do