rubycritic 1.0.2 → 1.1.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 (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/lib/rubycritic/analysers/attributes.rb +21 -0
  4. data/lib/rubycritic/analysers/churn.rb +5 -5
  5. data/lib/rubycritic/analysers/complexity.rb +6 -6
  6. data/lib/rubycritic/analysers/helpers/ast_node.rb +73 -0
  7. data/lib/rubycritic/analysers/{adapters → helpers}/config.reek +0 -0
  8. data/lib/rubycritic/analysers/{adapters → helpers}/flay.rb +0 -0
  9. data/lib/rubycritic/analysers/{adapters → helpers}/flog.rb +0 -0
  10. data/lib/rubycritic/analysers/helpers/methods_counter.rb +28 -0
  11. data/lib/rubycritic/analysers/helpers/modules_locator.rb +46 -0
  12. data/lib/rubycritic/analysers/{adapters → helpers}/reek.rb +0 -0
  13. data/lib/rubycritic/analysers/smells/flay.rb +9 -9
  14. data/lib/rubycritic/analysers/smells/flog.rb +8 -8
  15. data/lib/rubycritic/analysers/smells/reek.rb +8 -8
  16. data/lib/rubycritic/analysers_runner.rb +6 -6
  17. data/lib/rubycritic/cli.rb +2 -2
  18. data/lib/rubycritic/core/{analysed_file.rb → analysed_module.rb} +4 -7
  19. data/lib/rubycritic/modules_initializer.rb +14 -0
  20. data/lib/rubycritic/orchestrator.rb +5 -5
  21. data/lib/rubycritic/report_generators/code_file.rb +4 -4
  22. data/lib/rubycritic/report_generators/code_index.rb +2 -2
  23. data/lib/rubycritic/report_generators/overview.rb +2 -2
  24. data/lib/rubycritic/report_generators/smells_index.rb +13 -2
  25. data/lib/rubycritic/report_generators/templates/code_file.html.erb +10 -10
  26. data/lib/rubycritic/report_generators/templates/code_index.html.erb +7 -7
  27. data/lib/rubycritic/report_generators/templates/smells_index.html.erb +1 -1
  28. data/lib/rubycritic/report_generators/turbulence.rb +5 -5
  29. data/lib/rubycritic/report_generators/view_helpers.rb +4 -4
  30. data/lib/rubycritic/reporters/main.rb +7 -8
  31. data/lib/rubycritic/reporters/mini.rb +3 -3
  32. data/lib/rubycritic/revision_comparator.rb +12 -10
  33. data/lib/rubycritic/source_locator.rb +1 -1
  34. data/lib/rubycritic/version.rb +1 -1
  35. data/rubycritic.gemspec +3 -4
  36. data/test/analysers_test_helper.rb +1 -1
  37. data/test/lib/rubycritic/analysers/churn_test.rb +9 -9
  38. data/test/lib/rubycritic/analysers/complexity_test.rb +5 -5
  39. data/test/lib/rubycritic/analysers/helpers/methods_counter_test.rb +29 -0
  40. data/test/lib/rubycritic/analysers/helpers/modules_locator_test.rb +53 -0
  41. data/test/lib/rubycritic/analysers/smells/flay_test.rb +10 -12
  42. data/test/lib/rubycritic/analysers/smells/flog_test.rb +7 -7
  43. data/test/lib/rubycritic/analysers/smells/reek_test.rb +10 -10
  44. data/test/lib/rubycritic/core/analysed_module_test.rb +88 -0
  45. data/test/lib/rubycritic/report_generators/turbulence_test.rb +4 -4
  46. data/test/lib/rubycritic/report_generators/view_helpers_test.rb +10 -23
  47. data/test/lib/rubycritic/smells_status_setter_test.rb +1 -1
  48. data/test/lib/rubycritic/source_locator_test.rb +6 -6
  49. data/test/samples/{stats/empty_example.rb → empty.rb} +0 -0
  50. data/test/samples/{stats/example.rb → methods_count.rb} +0 -0
  51. data/test/samples/module_names.rb +18 -0
  52. data/test/samples/unparsable.rb +1 -0
  53. metadata +30 -23
  54. data/lib/rubycritic/analysers/adapters/ast_node.rb +0 -35
  55. data/lib/rubycritic/analysers/stats.rb +0 -34
  56. data/lib/rubycritic/files_initializer.rb +0 -15
  57. data/test/lib/rubycritic/analysers/stats_test.rb +0 -30
  58. data/test/lib/rubycritic/core/analysed_file_test.rb +0 -86
  59. data/test/samples/stats/unparsable_example.rb +0 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b0accaa8040e2dc7aee137d0f73cce04c35e59f4
4
- data.tar.gz: 589f325af9afba9ce66dedccd501b6f32451490c
3
+ metadata.gz: e19fa08f433cdb1ef0d4f49096ffa2de1e8a7132
4
+ data.tar.gz: 0eb7f2ce702010efc38a3d14d5044ba9dcccfe70
5
5
  SHA512:
6
- metadata.gz: 1e94e46ee87cea62b1248c1eaa6735aa6b0c6437bfba024ce1a2bdbd53c32983a292eeaed11df5747ec920d5c3fdbff25718e3359bcc4453a0a0d192e85ae77a
7
- data.tar.gz: bfcba2f0bed83fad8bacb44775c7fd10684efbfd981a05ff589f3317c7d7c1440cce82278657ecfcdc06e20cb706a8c160738b40708f0bc52c4fc07aa05b74d8
6
+ metadata.gz: ae8600a942a9c784bb4c7c4c3caba9d649430c9f346ce5e8576c92fef8e5a0e933ee3200b96f44deee10f9bef3b9cca99094949ea7c5f36a21baba36d839c0c3
7
+ data.tar.gz: 285e582072b09076129b9519349aa4e2d941cee174c31688b730674ac689f030d5f2df5ee232185b3f9456b96aee2a481f25676d4ced89c669f5f0e4b651f17c
data/CHANGELOG.md ADDED
@@ -0,0 +1,15 @@
1
+ # 1.1.0 / 2014-07-27
2
+
3
+ * [FEATURE] Display name of the first module found in a file instead of the file's name
4
+
5
+ # 1.0.2 / 2014-07-23
6
+
7
+ * [BUGFIX] Fix issue #8 - Solve a dependency error by requiring at least ruby2ruby 2.1.1
8
+
9
+ # 1.0.1 / 2014-07-22
10
+
11
+ * [BUGFIX] Fix issue #6 - Rescue `Parser::SyntaxError` when a file is unparsable
12
+
13
+ # 1.0.0 / 2014-07-13
14
+
15
+ * Official Release
@@ -0,0 +1,21 @@
1
+ require "rubycritic/analysers/helpers/methods_counter"
2
+ require "rubycritic/analysers/helpers/modules_locator"
3
+
4
+ module Rubycritic
5
+ module Analyser
6
+
7
+ class Attributes
8
+ def initialize(analysed_modules)
9
+ @analysed_modules = analysed_modules
10
+ end
11
+
12
+ def run
13
+ @analysed_modules.each do |analysed_module|
14
+ analysed_module.methods_count = MethodsCounter.new(analysed_module).count
15
+ analysed_module.name = ModulesLocator.new(analysed_module).first_name
16
+ end
17
+ end
18
+ end
19
+
20
+ end
21
+ end
@@ -2,15 +2,15 @@ module Rubycritic
2
2
  module Analyser
3
3
 
4
4
  class Churn
5
- def initialize(analysed_files, source_control_system)
6
- @analysed_files = analysed_files
5
+ def initialize(analysed_modules, source_control_system)
6
+ @analysed_modules = analysed_modules
7
7
  @source_control_system = source_control_system
8
8
  end
9
9
 
10
10
  def run
11
- @analysed_files.each do |analysed_file|
12
- analysed_file.churn = @source_control_system.revisions_count(analysed_file.path)
13
- analysed_file.committed_at = @source_control_system.date_of_last_commit(analysed_file.path)
11
+ @analysed_modules.each do |analysed_module|
12
+ analysed_module.churn = @source_control_system.revisions_count(analysed_module.path)
13
+ analysed_module.committed_at = @source_control_system.date_of_last_commit(analysed_module.path)
14
14
  end
15
15
  end
16
16
  end
@@ -1,19 +1,19 @@
1
- require "rubycritic/analysers/adapters/flog"
1
+ require "rubycritic/analysers/helpers/flog"
2
2
 
3
3
  module Rubycritic
4
4
  module Analyser
5
5
 
6
6
  class Complexity
7
- def initialize(analysed_files)
7
+ def initialize(analysed_modules)
8
8
  @flog = Flog.new
9
- @analysed_files = analysed_files
9
+ @analysed_modules = analysed_modules
10
10
  end
11
11
 
12
12
  def run
13
- @analysed_files.each do |analysed_file|
13
+ @analysed_modules.each do |analysed_module|
14
14
  @flog.reset
15
- @flog.flog(analysed_file.path)
16
- analysed_file.complexity = @flog.total_score.round
15
+ @flog.flog(analysed_module.path)
16
+ analysed_module.complexity = @flog.total_score.round
17
17
  end
18
18
  end
19
19
  end
@@ -0,0 +1,73 @@
1
+ module Parser
2
+ module AST
3
+
4
+ class Node
5
+ MODULE_TYPES = [:module, :class]
6
+
7
+ def count_nodes_of_type(*types)
8
+ count = 0
9
+ recursive_children do |child|
10
+ count += 1 if types.include?(child.type)
11
+ end
12
+ count
13
+ end
14
+
15
+ def recursive_children
16
+ children.each do |child|
17
+ next unless child.is_a?(Parser::AST::Node)
18
+ yield child
19
+ child.recursive_children { |grand_child| yield grand_child }
20
+ end
21
+ end
22
+
23
+ def get_module_names
24
+ children_modules = children
25
+ .select { |child| child.is_a?(Parser::AST::Node) }
26
+ .flat_map { |child| child.get_module_names }
27
+
28
+ if MODULE_TYPES.include?(self.type)
29
+ if children_modules.empty?
30
+ [module_name]
31
+ else
32
+ children_modules.map do |children_module|
33
+ "#{module_name}::#{children_module}"
34
+ end
35
+ end
36
+ elsif children_modules.empty?
37
+ []
38
+ else
39
+ children_modules
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def module_name
46
+ name_segments = []
47
+ current_node = children[0]
48
+ while(current_node) do
49
+ name_segments.unshift(current_node.children[1])
50
+ current_node = current_node.children[0]
51
+ end
52
+ name_segments.join("::")
53
+ end
54
+ end
55
+
56
+ end
57
+ end
58
+
59
+ module Rubycritic
60
+ module AST
61
+
62
+ class EmptyNode
63
+ def count_nodes_of_type(*types)
64
+ 0
65
+ end
66
+
67
+ def get_module_names
68
+ []
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,28 @@
1
+ require "parser/current"
2
+ require "rubycritic/analysers/helpers/ast_node"
3
+
4
+ module Rubycritic
5
+
6
+ class MethodsCounter
7
+ def initialize(analysed_module)
8
+ @analysed_module = analysed_module
9
+ end
10
+
11
+ def count
12
+ node.count_nodes_of_type(:def, :defs)
13
+ end
14
+
15
+ private
16
+
17
+ def node
18
+ Parser::CurrentRuby.parse(content) || AST::EmptyNode.new
19
+ rescue Parser::SyntaxError => error
20
+ AST::EmptyNode.new
21
+ end
22
+
23
+ def content
24
+ File.read(@analysed_module.path)
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,46 @@
1
+ require "parser/current"
2
+ require "rubycritic/analysers/helpers/ast_node"
3
+
4
+ module Rubycritic
5
+
6
+ class ModulesLocator
7
+ def initialize(analysed_module)
8
+ @analysed_module = analysed_module
9
+ end
10
+
11
+ def first_name
12
+ names.first
13
+ end
14
+
15
+ def names
16
+ return name_from_path if @analysed_module.methods_count == 0
17
+ names = node.get_module_names
18
+ if names.empty?
19
+ name_from_path
20
+ else
21
+ names
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def node
28
+ Parser::CurrentRuby.parse(content) || AST::EmptyNode.new
29
+ rescue Parser::SyntaxError => error
30
+ AST::EmptyNode.new
31
+ end
32
+
33
+ def content
34
+ File.read(@analysed_module.path)
35
+ end
36
+
37
+ def name_from_path
38
+ [file_name.split("_").map(&:capitalize).join]
39
+ end
40
+
41
+ def file_name
42
+ @analysed_module.pathname.basename.sub_ext("").to_s
43
+ end
44
+ end
45
+
46
+ end
@@ -1,34 +1,34 @@
1
- require "rubycritic/analysers/adapters/flay"
1
+ require "rubycritic/analysers/helpers/flay"
2
2
  require "rubycritic/core/smell"
3
3
 
4
4
  module Rubycritic
5
5
  module Analyser
6
6
 
7
7
  class FlaySmells
8
- def initialize(analysed_files)
9
- @analysed_files = paths_to_analysed_files(analysed_files)
10
- @flay = Flay.new(@analysed_files.keys)
8
+ def initialize(analysed_modules)
9
+ @analysed_modules = paths_to_analysed_modules(analysed_modules)
10
+ @flay = Flay.new(@analysed_modules.keys)
11
11
  end
12
12
 
13
13
  def run
14
14
  @flay.hashes.each do |structural_hash, nodes|
15
15
  smell = create_smell(structural_hash, nodes)
16
16
  nodes.map(&:file).uniq.each do |file|
17
- @analysed_files[file].smells << smell
17
+ @analysed_modules[file].smells << smell
18
18
  end
19
19
 
20
20
  nodes.each do |node|
21
- @analysed_files[node.file].duplication += node.mass
21
+ @analysed_modules[node.file].duplication += node.mass
22
22
  end
23
23
  end
24
24
  end
25
25
 
26
26
  private
27
27
 
28
- def paths_to_analysed_files(analysed_files)
28
+ def paths_to_analysed_modules(analysed_modules)
29
29
  paths = {}
30
- analysed_files.each do |analysed_file|
31
- paths[analysed_file.path] = analysed_file
30
+ analysed_modules.each do |analysed_module|
31
+ paths[analysed_module.path] = analysed_module
32
32
  end
33
33
  paths
34
34
  end
@@ -1,4 +1,4 @@
1
- require "rubycritic/analysers/adapters/flog"
1
+ require "rubycritic/analysers/helpers/flog"
2
2
  require "rubycritic/core/smell"
3
3
 
4
4
  module Rubycritic
@@ -8,26 +8,26 @@ module Rubycritic
8
8
  HIGH_COMPLEXITY_SCORE_THRESHOLD = 25
9
9
  VERY_HIGH_COMPLEXITY_SCORE_THRESHOLD = 60
10
10
 
11
- def initialize(analysed_files)
11
+ def initialize(analysed_modules)
12
12
  @flog = Flog.new
13
- @analysed_files = analysed_files
13
+ @analysed_modules = analysed_modules
14
14
  end
15
15
 
16
16
  def run
17
- @analysed_files.each do |analysed_file|
18
- add_smells_to(analysed_file)
17
+ @analysed_modules.each do |analysed_module|
18
+ add_smells_to(analysed_module)
19
19
  end
20
20
  end
21
21
 
22
22
  private
23
23
 
24
- def add_smells_to(analysed_file)
24
+ def add_smells_to(analysed_module)
25
25
  @flog.reset
26
- @flog.flog(analysed_file.path)
26
+ @flog.flog(analysed_module.path)
27
27
  @flog.each_by_score do |class_method, original_score|
28
28
  score = original_score.round
29
29
  if score >= HIGH_COMPLEXITY_SCORE_THRESHOLD
30
- analysed_file.smells << create_smell(class_method, score)
30
+ analysed_module.smells << create_smell(class_method, score)
31
31
  end
32
32
  end
33
33
  end
@@ -1,25 +1,25 @@
1
- require "rubycritic/analysers/adapters/reek"
1
+ require "rubycritic/analysers/helpers/reek"
2
2
  require "rubycritic/core/smell"
3
3
 
4
4
  module Rubycritic
5
5
  module Analyser
6
6
 
7
7
  class ReekSmells
8
- def initialize(analysed_files)
9
- @analysed_files = analysed_files
8
+ def initialize(analysed_modules)
9
+ @analysed_modules = analysed_modules
10
10
  end
11
11
 
12
12
  def run
13
- @analysed_files.each do |analysed_file|
14
- add_smells_to(analysed_file)
13
+ @analysed_modules.each do |analysed_module|
14
+ add_smells_to(analysed_module)
15
15
  end
16
16
  end
17
17
 
18
18
  private
19
19
 
20
- def add_smells_to(analysed_file)
21
- Reek.new(analysed_file.path).smells.each do |smell|
22
- analysed_file.smells << create_smell(smell)
20
+ def add_smells_to(analysed_module)
21
+ Reek.new(analysed_module.path).smells.each do |smell|
22
+ analysed_module.smells << create_smell(smell)
23
23
  end
24
24
  end
25
25
 
@@ -3,7 +3,7 @@ require "rubycritic/analysers/smells/flog"
3
3
  require "rubycritic/analysers/smells/reek"
4
4
  require "rubycritic/analysers/complexity"
5
5
  require "rubycritic/analysers/churn"
6
- require "rubycritic/analysers/stats"
6
+ require "rubycritic/analysers/attributes"
7
7
 
8
8
  module Rubycritic
9
9
 
@@ -13,19 +13,19 @@ module Rubycritic
13
13
  Analyser::FlogSmells,
14
14
  Analyser::ReekSmells,
15
15
  Analyser::Complexity,
16
- Analyser::Stats
16
+ Analyser::Attributes
17
17
  ]
18
18
 
19
- def initialize(analysed_files, source_control_system)
20
- @analysed_files = analysed_files
19
+ def initialize(analysed_modules, source_control_system)
20
+ @analysed_modules = analysed_modules
21
21
  @source_control_system = source_control_system
22
22
  end
23
23
 
24
24
  def run
25
25
  ANALYSERS.each do |analyser|
26
- analyser.new(@analysed_files).run
26
+ analyser.new(@analysed_modules).run
27
27
  end
28
- Analyser::Churn.new(@analysed_files, @source_control_system).run
28
+ Analyser::Churn.new(@analysed_modules, @source_control_system).run
29
29
  end
30
30
  end
31
31
 
@@ -34,8 +34,8 @@ module Rubycritic
34
34
  end.parse!(@argv)
35
35
 
36
36
  if @main_command
37
- analysed_files = Orchestrator.new.critique(@argv)
38
- report_location = Reporter::Main.new(analysed_files).generate_report
37
+ analysed_modules = Orchestrator.new.critique(@argv)
38
+ report_location = Reporter::Main.new(analysed_modules).generate_report
39
39
  puts "New critique at #{report_location}"
40
40
  end
41
41
 
@@ -3,21 +3,18 @@ require "rubycritic/core/rating"
3
3
 
4
4
  module Rubycritic
5
5
 
6
- class AnalysedFile
6
+ class AnalysedModule
7
7
  include Virtus.model
8
8
 
9
+ attribute :name
9
10
  attribute :pathname
10
- attribute :smells
11
+ attribute :smells, Array, :default => []
11
12
  attribute :churn
12
13
  attribute :committed_at
13
14
  attribute :complexity
14
- attribute :duplication
15
+ attribute :duplication, Integer, :default => 0
15
16
  attribute :methods_count
16
17
 
17
- def name
18
- @name ||= pathname.basename.sub_ext("").to_s
19
- end
20
-
21
18
  def path
22
19
  @path ||= pathname.to_s
23
20
  end