rubycritic 1.3.0 → 1.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.
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,3 +1,7 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
1
5
  .group:after {
2
6
  content: '';
3
7
  display: table;
@@ -6,10 +10,42 @@
6
10
 
7
11
  html {
8
12
  overflow-y: scroll;
13
+ font-family: "Droid Sans", Arial, "Helvetica Neue", Helvetica, sans-serif;
14
+ font-size: 1em;
15
+ }
16
+
17
+ html, body {
18
+ margin: 0;
19
+ padding: 0;
20
+ }
21
+
22
+ a {
23
+ color: #00adc4;
24
+ text-decoration: none;
25
+ }
26
+
27
+ a:hover {
28
+ border-bottom: 1px solid;
29
+ }
30
+
31
+ a:visited {
32
+ color: #4E6072;
33
+ }
34
+
35
+ .container {
36
+ width: 100%;
37
+ max-width: 80em;
38
+ margin: 0 auto;
9
39
  }
10
40
 
11
41
  .project-header {
12
- padding: 20px 0 20px 60px;
42
+ padding: 1em 0 1em 0;
43
+ margin-bottom: 2em;
44
+ background-color: #F2F1EE;
45
+ }
46
+
47
+ .project-header .container {
48
+ padding: 0 2rem;
13
49
  }
14
50
 
15
51
  .logo {
@@ -17,21 +53,23 @@ html {
17
53
  margin: 0;
18
54
  }
19
55
 
20
- .logo-link {
56
+ a.logo-link {
21
57
  color: black;
22
- text-decoration: none;
23
58
  }
24
59
 
25
60
  .project-nav {
26
61
  float: left;
27
- margin-left: 100px;
62
+ margin-left: 4rem;
28
63
  line-height: 2.5em;
29
64
  }
30
65
 
31
- .project-nav-item {
32
- color: black;
33
- margin-right: 40px;
34
- text-decoration: none;
66
+ a.project-nav-item {
67
+ color: #323333;
68
+ margin-right: 3rem;
69
+ }
70
+
71
+ a.project-nav-item:hover {
72
+ border-bottom: 1px solid;
35
73
  }
36
74
 
37
75
  .chart-container {
@@ -42,7 +80,6 @@ html {
42
80
  .index-table {
43
81
  width: 100%;
44
82
  border-collapse: collapse;
45
- table-layout: fixed;
46
83
  }
47
84
 
48
85
  .index-table th {
@@ -54,6 +91,18 @@ html {
54
91
  background-color: white;
55
92
  }
56
93
 
94
+ .floatThead-container {
95
+ box-shadow: 0 3px 4px -2px rgb(224, 223, 223);
96
+ }
97
+
98
+ .index-table tr:nth-child(odd) {
99
+ background-color: #f9f9f9;
100
+ }
101
+
102
+ .index-table tr:hover {
103
+ background-color: #e9fafc;
104
+ }
105
+
57
106
  .index-table .circle {
58
107
  width: 28px;
59
108
  height: 28px;
@@ -64,27 +113,28 @@ html {
64
113
  line-height: 28px;
65
114
  }
66
115
 
67
- .sortable-table .headerSortUp,
68
- .sortable-table .headerSortDown {
69
- border: 1px solid silver;
70
- border-bottom: 0;
116
+ .tablesorter-headerAsc .tablesorter-header-inner:after,
117
+ .tablesorter-headerDesc .tablesorter-header-inner:after {
118
+ position: absolute;
71
119
  }
72
120
 
73
- .sortable-table th:hover {
74
- background-color: #ECECEC;
75
- cursor: pointer;
121
+ .tablesorter-headerAsc .tablesorter-header-inner:after {
122
+ content: '\00A0\2191';
123
+ }
124
+ .tablesorter-headerDesc .tablesorter-header-inner:after {
125
+ content: '\00A0\2193';
76
126
  }
77
127
 
78
- .index-table td {
79
- padding: 12px 10px;
128
+ .sortable-table th:focus {
129
+ outline: none;
80
130
  }
81
131
 
82
- .index-table .first-cell {
83
- padding-left: 60px;
132
+ .sortable-table th:hover {
133
+ cursor: pointer;
84
134
  }
85
135
 
86
- .index-table .last-cell {
87
- padding-right: 60px;
136
+ .index-table td, .index-table th {
137
+ padding: 1rem 2rem;
88
138
  }
89
139
 
90
140
  .index-table .numeric-cell {
@@ -138,7 +188,7 @@ html {
138
188
 
139
189
  .file-header {
140
190
  position: relative;
141
- padding: 0 0 10px 60px;
191
+ padding: 0 0 10px 2rem;
142
192
  border-bottom: 1px solid silver;
143
193
  }
144
194
 
@@ -175,7 +225,7 @@ html {
175
225
 
176
226
  .file-name {
177
227
  float: left;
178
- margin: 0 0 0 20px;
228
+ margin: 0;
179
229
  line-height: 50px;
180
230
  font-weight: normal;
181
231
  }
@@ -189,7 +239,6 @@ html {
189
239
 
190
240
  .file-stats {
191
241
  clear: both;
192
- margin-left: 68px;
193
242
  width: 300px;
194
243
  }
195
244
 
@@ -201,6 +250,18 @@ html {
201
250
  white-space: nowrap;
202
251
  }
203
252
 
253
+ .file-header.rated .file-stats {
254
+ margin-left: 68px;
255
+ }
256
+
257
+ .file-header.rated .file-name {
258
+ margin-left: 20px;
259
+ }
260
+
261
+ .file-header.unrated .rating {
262
+ display: none;
263
+ }
264
+
204
265
  .smells-toggle-button {
205
266
  position: absolute;
206
267
  right: 64px;
@@ -214,6 +275,7 @@ html {
214
275
  }
215
276
 
216
277
  .smells {
278
+ font-family: "Droid Sans", Arial, "Helvetica Neue", Helvetica, sans-serif;
217
279
  margin: 2px 0 22px 0;
218
280
  padding-left: 0;
219
281
  border: 1px solid #000;
@@ -0,0 +1,52 @@
1
+ require "erb"
2
+ require "pathname"
3
+ require "rubycritic/generators/html/view_helpers"
4
+
5
+ module Rubycritic
6
+ module Generator
7
+ module Html
8
+
9
+ class Base
10
+ def self.erb_template(template_path)
11
+ ERB.new(File.read(File.join(TEMPLATES_DIR, template_path)))
12
+ end
13
+
14
+ TEMPLATES_DIR = File.expand_path("../templates", __FILE__)
15
+ LAYOUT_TEMPLATE = erb_template(File.join("layouts", "application.html.erb"))
16
+
17
+ include ViewHelpers
18
+
19
+ def file_href
20
+ "file://#{file_pathname}"
21
+ end
22
+
23
+ def file_pathname
24
+ File.join(file_directory, file_name)
25
+ end
26
+
27
+ def file_directory
28
+ @file_directory ||= root_directory
29
+ end
30
+
31
+ def file_name
32
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
33
+ end
34
+
35
+ def render
36
+ raise NotImplementedError.new("The #{self.class} class must implement the #{__method__} method.")
37
+ end
38
+
39
+ private
40
+
41
+ def root_directory
42
+ @root_directory ||= Pathname.new(Config.root)
43
+ end
44
+
45
+ def get_binding
46
+ binding
47
+ end
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,40 @@
1
+ require "rubycritic/generators/html/base"
2
+ require "rubycritic/generators/html/line"
3
+
4
+ module Rubycritic
5
+ module Generator
6
+ module Html
7
+
8
+ class CodeFile < Base
9
+ LINE_NUMBER_OFFSET = 1
10
+ TEMPLATE = erb_template("code_file.html.erb")
11
+
12
+ def initialize(analysed_module)
13
+ @analysed_module = analysed_module
14
+ @pathname = @analysed_module.pathname
15
+ end
16
+
17
+ def file_directory
18
+ @file_directory ||= root_directory + @pathname.dirname
19
+ end
20
+
21
+ def file_name
22
+ @pathname.basename.sub_ext(".html")
23
+ end
24
+
25
+ def render
26
+ file_code = ""
27
+ File.readlines(@pathname).each.with_index(LINE_NUMBER_OFFSET) do |line_text, line_number|
28
+ location = Location.new(@pathname, line_number)
29
+ line_smells = @analysed_module.smells_at_location(location)
30
+ file_code << Line.new(file_directory, line_text, line_smells).render
31
+ end
32
+
33
+ file_body = TEMPLATE.result(get_binding { file_code })
34
+ LAYOUT_TEMPLATE.result(get_binding { file_body })
35
+ end
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,26 @@
1
+ require "rubycritic/generators/html/base"
2
+
3
+ module Rubycritic
4
+ module Generator
5
+ module Html
6
+
7
+ class CodeIndex < Base
8
+ TEMPLATE = erb_template("code_index.html.erb")
9
+
10
+ def initialize(analysed_modules)
11
+ @analysed_modules = analysed_modules
12
+ end
13
+
14
+ def file_name
15
+ "code_index.html"
16
+ end
17
+
18
+ def render
19
+ index_body = TEMPLATE.result(get_binding)
20
+ LAYOUT_TEMPLATE.result(get_binding { index_body })
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,37 @@
1
+ require "cgi"
2
+ require "rubycritic/generators/html/base"
3
+
4
+ module Rubycritic
5
+ module Generator
6
+ module Html
7
+
8
+ class Line < Base
9
+ NORMAL_TEMPLATE = erb_template("line.html.erb")
10
+ SMELLY_TEMPLATE = erb_template("smelly_line.html.erb")
11
+
12
+ attr_reader :file_directory
13
+
14
+ def initialize(file_directory, text, smells)
15
+ @file_directory = file_directory
16
+ @text = CGI.escapeHTML(text.chomp)
17
+ @smells = smells
18
+ end
19
+
20
+ def render
21
+ template.result(binding).delete("\n") + "\n"
22
+ end
23
+
24
+ private
25
+
26
+ def template
27
+ if @smells.empty?
28
+ NORMAL_TEMPLATE
29
+ else
30
+ SMELLY_TEMPLATE
31
+ end
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ require "rubycritic/generators/html/base"
2
+ require "rubycritic/generators/html/turbulence"
3
+
4
+ module Rubycritic
5
+ module Generator
6
+ module Html
7
+
8
+ class Overview < Base
9
+ TEMPLATE = erb_template("overview.html.erb")
10
+
11
+ def initialize(analysed_modules)
12
+ @turbulence_data = Turbulence.data(analysed_modules)
13
+ end
14
+
15
+ def file_name
16
+ "overview.html"
17
+ end
18
+
19
+ def render
20
+ index_body = TEMPLATE.result(get_binding)
21
+ LAYOUT_TEMPLATE.result(get_binding { index_body })
22
+ end
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ require "rubycritic/generators/html/base"
2
+
3
+ module Rubycritic
4
+ module Generator
5
+ module Html
6
+
7
+ class SmellsIndex < Base
8
+ TEMPLATE = erb_template("smells_index.html.erb")
9
+
10
+ def initialize(analysed_modules)
11
+ @smells = analysed_modules.flat_map(&:smells).uniq
12
+ @analysed_module_names = analysed_module_names(analysed_modules)
13
+ @show_status = (Config.mode == :default)
14
+ end
15
+
16
+ def file_name
17
+ "smells_index.html"
18
+ end
19
+
20
+ def render
21
+ index_body = TEMPLATE.result(get_binding)
22
+ LAYOUT_TEMPLATE.result(get_binding { index_body })
23
+ end
24
+
25
+ private
26
+
27
+ def analysed_module_names(analysed_modules)
28
+ names = {}
29
+ analysed_modules.each do |analysed_module|
30
+ names[analysed_module.pathname] = analysed_module.name
31
+ end
32
+ names
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,7 @@
1
- <div class="file-header group">
2
- <span class="rating-<%= @analysed_module.rating.to_s.downcase %> circled-text circle "><%= @analysed_module.rating %></span>
1
+ <div class="file-header group <%= Config.suppress_ratings ? 'unrated' : 'rated' %>">
2
+ <span class="rating rating-<%= @analysed_module.rating.to_s.downcase %> circled-text circle">
3
+ <%= @analysed_module.rating %>
4
+ </span>
3
5
  <h2 class="file-name"><%= @analysed_module.name %></h2>
4
6
 
5
7
  <span class="file-committed-at">