rubycritic 0.0.5 → 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 (135) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +593 -0
  3. data/.travis.yml +11 -0
  4. data/CHANGELOG.md +45 -0
  5. data/CONTRIBUTING.md +67 -15
  6. data/README.md +105 -14
  7. data/Rakefile +9 -6
  8. data/bin/rubycritic +3 -1
  9. data/lib/rubycritic/analysers/attributes.rb +21 -0
  10. data/lib/rubycritic/analysers/churn.rb +21 -0
  11. data/lib/rubycritic/analysers/complexity.rb +22 -0
  12. data/lib/rubycritic/analysers/helpers/ast_node.rb +69 -0
  13. data/lib/rubycritic/analysers/{config.reek → helpers/config.reek} +8 -0
  14. data/lib/rubycritic/analysers/helpers/flay.rb +13 -0
  15. data/lib/rubycritic/analysers/helpers/flog.rb +17 -0
  16. data/lib/rubycritic/analysers/helpers/methods_counter.rb +25 -0
  17. data/lib/rubycritic/analysers/helpers/modules_locator.rb +43 -0
  18. data/lib/rubycritic/analysers/helpers/parser.rb +12 -0
  19. data/lib/rubycritic/analysers/helpers/reek.rb +17 -0
  20. data/lib/rubycritic/analysers/smells/flay.rb +68 -0
  21. data/lib/rubycritic/analysers/smells/flog.rb +62 -0
  22. data/lib/rubycritic/analysers/smells/reek.rb +44 -0
  23. data/lib/rubycritic/analysers_runner.rb +21 -10
  24. data/lib/rubycritic/cli/application.rb +24 -0
  25. data/lib/rubycritic/cli/options.rb +79 -0
  26. data/lib/rubycritic/commands/ci.rb +26 -0
  27. data/lib/rubycritic/commands/default.rb +28 -0
  28. data/lib/rubycritic/commands/help.rb +13 -0
  29. data/lib/rubycritic/commands/version.rb +11 -0
  30. data/lib/rubycritic/configuration.rb +33 -0
  31. data/lib/rubycritic/core/analysed_module.rb +66 -0
  32. data/lib/rubycritic/{location.rb → core/location.rb} +17 -2
  33. data/lib/rubycritic/core/rating.rb +30 -0
  34. data/lib/rubycritic/{smell.rb → core/smell.rb} +22 -13
  35. data/lib/rubycritic/generators/html/assets/javascripts/application.js +104 -0
  36. data/lib/rubycritic/generators/html/assets/javascripts/highcharts.src-4.0.1.js +17672 -0
  37. data/lib/rubycritic/generators/html/assets/javascripts/jquery.floatThead-v1.2.7.js +754 -0
  38. data/lib/rubycritic/generators/html/assets/javascripts/jquery.scrollTo-1.4.11.js +186 -0
  39. data/lib/rubycritic/generators/html/assets/javascripts/jquery.tablesorter.js +2089 -0
  40. data/lib/rubycritic/generators/html/assets/javascripts/jquery.timeago-v1.4.1.js +214 -0
  41. data/lib/rubycritic/generators/html/assets/stylesheets/application.css +303 -0
  42. data/lib/rubycritic/{report_generators → generators/html}/assets/stylesheets/prettify.custom_theme.css +1 -4
  43. data/lib/rubycritic/generators/html/base.rb +52 -0
  44. data/lib/rubycritic/generators/html/code_file.rb +40 -0
  45. data/lib/rubycritic/generators/html/code_index.rb +26 -0
  46. data/lib/rubycritic/generators/html/line.rb +37 -0
  47. data/lib/rubycritic/generators/html/overview.rb +27 -0
  48. data/lib/rubycritic/generators/html/smells_index.rb +38 -0
  49. data/lib/rubycritic/generators/html/templates/code_file.html.erb +38 -0
  50. data/lib/rubycritic/generators/html/templates/code_index.html.erb +30 -0
  51. data/lib/rubycritic/generators/html/templates/layouts/application.html.erb +34 -0
  52. data/lib/rubycritic/generators/html/templates/overview.html.erb +5 -0
  53. data/lib/rubycritic/generators/html/templates/smells_index.html.erb +26 -0
  54. data/lib/rubycritic/{report_generators → generators/html}/templates/smelly_line.html.erb +1 -1
  55. data/lib/rubycritic/generators/html/turbulence.rb +17 -0
  56. data/lib/rubycritic/generators/html/view_helpers.rb +43 -0
  57. data/lib/rubycritic/generators/html_report.rb +66 -0
  58. data/lib/rubycritic/generators/json/simple.rb +30 -0
  59. data/lib/rubycritic/generators/json_report.rb +23 -0
  60. data/lib/rubycritic/reporter.rb +20 -0
  61. data/lib/rubycritic/revision_comparator.rb +27 -29
  62. data/lib/rubycritic/serializer.rb +32 -0
  63. data/lib/rubycritic/smells_status_setter.rb +7 -16
  64. data/lib/rubycritic/source_control_systems/base.rb +37 -0
  65. data/lib/rubycritic/source_control_systems/double.rb +18 -0
  66. data/lib/rubycritic/source_control_systems/git.rb +41 -37
  67. data/lib/rubycritic/source_control_systems/mercurial.rb +29 -0
  68. data/lib/rubycritic/source_locator.rb +25 -13
  69. data/lib/rubycritic/version.rb +1 -1
  70. data/lib/rubycritic.rb +17 -22
  71. data/rubycritic.gemspec +10 -7
  72. data/test/analysers_test_helper.rb +3 -0
  73. data/test/lib/rubycritic/analysers/churn_test.rb +33 -0
  74. data/test/lib/rubycritic/analysers/complexity_test.rb +16 -0
  75. data/test/lib/rubycritic/analysers/helpers/methods_counter_test.rb +29 -0
  76. data/test/lib/rubycritic/analysers/helpers/modules_locator_test.rb +53 -0
  77. data/test/lib/rubycritic/analysers/smells/flay_test.rb +39 -0
  78. data/test/lib/rubycritic/analysers/smells/flog_test.rb +26 -0
  79. data/test/lib/rubycritic/analysers/smells/reek_test.rb +33 -0
  80. data/test/lib/rubycritic/configuration_test.rb +29 -0
  81. data/test/lib/rubycritic/core/analysed_module_test.rb +88 -0
  82. data/test/lib/rubycritic/{location_test.rb → core/location_test.rb} +8 -4
  83. data/test/lib/rubycritic/core/smell_test.rb +72 -0
  84. data/test/lib/rubycritic/{smells_array_test.rb → core/smells_array_test.rb} +1 -1
  85. data/test/lib/rubycritic/report_generators/turbulence_test.rb +17 -0
  86. data/test/lib/rubycritic/report_generators/view_helpers_test.rb +83 -0
  87. data/test/lib/rubycritic/smells_status_setter_test.rb +5 -5
  88. data/test/lib/rubycritic/source_control_systems/base_test.rb +29 -0
  89. data/test/lib/rubycritic/source_control_systems/double_test.rb +11 -0
  90. data/test/lib/rubycritic/source_control_systems/git_test.rb +13 -0
  91. data/test/lib/rubycritic/source_control_systems/interfaces/basic.rb +7 -0
  92. data/test/lib/rubycritic/source_control_systems/interfaces/time_travel.rb +7 -0
  93. data/test/lib/rubycritic/source_control_systems/mercurial_test.rb +11 -0
  94. data/test/lib/rubycritic/source_locator_test.rb +42 -18
  95. data/test/lib/rubycritic/version_test.rb +1 -0
  96. data/test/samples/empty.rb +0 -0
  97. data/test/samples/flay/smelly.rb +8 -0
  98. data/test/samples/flay/smelly2.rb +8 -0
  99. data/test/samples/flog/complex.rb +11 -0
  100. data/test/samples/flog/smelly.rb +7 -2
  101. data/test/samples/location/file0_symlink.rb +0 -0
  102. data/test/samples/methods_count.rb +7 -0
  103. data/test/samples/module_names.rb +18 -0
  104. data/test/samples/reek/not_smelly.rb +31 -3
  105. data/test/samples/unparsable.rb +1 -0
  106. data/test/test_helper.rb +39 -0
  107. metadata +178 -53
  108. data/SPEC.md +0 -58
  109. data/lib/rubycritic/analysers/flog.rb +0 -20
  110. data/lib/rubycritic/analysers/reek.rb +0 -15
  111. data/lib/rubycritic/cli.rb +0 -25
  112. data/lib/rubycritic/report_generators/assets/javascripts/application.js +0 -25
  113. data/lib/rubycritic/report_generators/assets/stylesheets/application.css +0 -26
  114. data/lib/rubycritic/report_generators/base_generator.rb +0 -42
  115. data/lib/rubycritic/report_generators/file_generator.rb +0 -42
  116. data/lib/rubycritic/report_generators/index_generator.rb +0 -28
  117. data/lib/rubycritic/report_generators/line_generator.rb +0 -27
  118. data/lib/rubycritic/report_generators/reporter.rb +0 -45
  119. data/lib/rubycritic/report_generators/templates/file.html.erb +0 -3
  120. data/lib/rubycritic/report_generators/templates/index.html.erb +0 -14
  121. data/lib/rubycritic/report_generators/templates/layouts/application.html.erb +0 -19
  122. data/lib/rubycritic/report_generators/view_helpers.rb +0 -26
  123. data/lib/rubycritic/smell_adapters/flog.rb +0 -41
  124. data/lib/rubycritic/smell_adapters/reek.rb +0 -35
  125. data/lib/rubycritic/smells_aggregator.rb +0 -29
  126. data/lib/rubycritic/smelly_pathnames_serializer.rb +0 -34
  127. data/lib/rubycritic/source_control_systems/source_control_system.rb +0 -42
  128. data/test/lib/rubycritic/metric_adapters/flog_adapter_test.rb +0 -25
  129. data/test/lib/rubycritic/metric_adapters/reek_adapter_test.rb +0 -34
  130. data/test/lib/rubycritic/smell_test.rb +0 -71
  131. data/test/lib/rubycritic/smells_aggregator_test.rb +0 -47
  132. data/test/lib/rubycritic/source_control_systems/source_control_system_test.rb +0 -26
  133. /data/lib/rubycritic/{report_generators → generators/html}/assets/javascripts/jquery-2.1.0.js +0 -0
  134. /data/lib/rubycritic/{report_generators/assets/javascripts/prettify.js → generators/html/assets/javascripts/prettify-4-Mar-2013.js} +0 -0
  135. /data/lib/rubycritic/{report_generators → generators/html}/templates/line.html.erb +0 -0
@@ -0,0 +1,44 @@
1
+ require "rubycritic/analysers/helpers/reek"
2
+ require "rubycritic/core/smell"
3
+
4
+ module Rubycritic
5
+ module Analyser
6
+
7
+ class ReekSmells
8
+ def initialize(analysed_modules)
9
+ @analysed_modules = analysed_modules
10
+ end
11
+
12
+ def run
13
+ @analysed_modules.each do |analysed_module|
14
+ add_smells_to(analysed_module)
15
+ end
16
+ end
17
+
18
+ private
19
+
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
+ end
24
+ end
25
+
26
+ def create_smell(smell)
27
+ Smell.new(
28
+ :locations => smell_locations(smell.source, smell.lines),
29
+ :context => smell.context,
30
+ :message => smell.message,
31
+ :type => smell.smell_type,
32
+ :cost => 0
33
+ )
34
+ end
35
+
36
+ def smell_locations(file_path, file_lines)
37
+ file_lines.uniq.map do |file_line|
38
+ Location.new(file_path, file_line)
39
+ end.sort
40
+ end
41
+ end
42
+
43
+ end
44
+ end
@@ -1,25 +1,36 @@
1
- require "rubycritic/analysers/reek"
2
- require "rubycritic/smell_adapters/reek"
1
+ require "rubycritic/source_locator"
2
+ require "rubycritic/core/analysed_module"
3
+ require "rubycritic/analysers/smells/flay"
4
+ require "rubycritic/analysers/smells/flog"
5
+ require "rubycritic/analysers/smells/reek"
6
+ require "rubycritic/analysers/complexity"
7
+ require "rubycritic/analysers/churn"
8
+ require "rubycritic/analysers/attributes"
3
9
 
4
10
  module Rubycritic
5
11
 
6
12
  class AnalysersRunner
7
- ANALYSERS = ["Reek"]
13
+ ANALYSERS = [
14
+ Analyser::FlaySmells,
15
+ Analyser::FlogSmells,
16
+ Analyser::ReekSmells,
17
+ Analyser::Complexity,
18
+ Analyser::Attributes,
19
+ Analyser::Churn
20
+ ]
8
21
 
9
22
  def initialize(paths)
10
23
  @paths = paths
11
24
  end
12
25
 
13
26
  def run
14
- smell_adapters
27
+ ANALYSERS.each { |analyser| analyser.new(analysed_modules).run }
28
+ analysed_modules
15
29
  end
16
30
 
17
- private
18
-
19
- def smell_adapters
20
- ANALYSERS.map do |analyser_name|
21
- analyser = Object.const_get("Rubycritic::Analyser::#{analyser_name}").new(@paths)
22
- Object.const_get("Rubycritic::SmellAdapter::#{analyser_name}").new(analyser)
31
+ def analysed_modules
32
+ @analysed_modules ||= SourceLocator.new(@paths).pathnames.map do |pathname|
33
+ AnalysedModule.new(:pathname => pathname)
23
34
  end
24
35
  end
25
36
  end
@@ -0,0 +1,24 @@
1
+ require "rubycritic"
2
+ require "rubycritic/cli/options"
3
+
4
+ module Rubycritic
5
+ module Cli
6
+ class Application
7
+ STATUS_SUCCESS = 0
8
+ STATUS_ERROR = 1
9
+
10
+ def initialize(argv)
11
+ @options = Options.new(argv)
12
+ end
13
+
14
+ def execute
15
+ parsed_options = @options.parse
16
+ ::Rubycritic.create(parsed_options).execute
17
+ STATUS_SUCCESS
18
+ rescue OptionParser::InvalidOption => error
19
+ $stderr.puts "Error: #{error}"
20
+ STATUS_ERROR
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,79 @@
1
+ require "optparse"
2
+
3
+ module Rubycritic
4
+ module Cli
5
+ class Options
6
+ def initialize(argv)
7
+ @argv = argv
8
+ @parser = OptionParser.new
9
+ end
10
+
11
+ # rubocop:disable Metrics/MethodLength
12
+ def parse
13
+ @parser.new do |opts|
14
+ opts.banner = "Usage: rubycritic [options] [paths]"
15
+
16
+ opts.on("-p", "--path [PATH]", "Set path where report will be saved (tmp/rubycritic by default)") do |path|
17
+ @root = path
18
+ end
19
+
20
+ opts.on(
21
+ "-f", "--format [FORMAT]",
22
+ [:html, :json],
23
+ "Report smells in the given format:",
24
+ " html (default)",
25
+ " json"
26
+ ) do |format|
27
+ @format = format
28
+ end
29
+
30
+ opts.on("-m", "--mode-ci", "Use CI mode (faster, but only analyses last commit)") do
31
+ @mode = :ci
32
+ end
33
+
34
+ opts.on("--deduplicate-symlinks", "De-duplicate symlinks based on their final target") do
35
+ @deduplicate_symlinks = true
36
+ end
37
+
38
+ opts.on("--suppress-ratings", "Suppress letter ratings") do
39
+ @suppress_ratings = true
40
+ end
41
+
42
+ opts.on_tail("-v", "--version", "Show gem's version") do
43
+ @mode = :version
44
+ end
45
+
46
+ opts.on_tail("-h", "--help", "Show this message") do
47
+ @mode = :help
48
+ end
49
+ end.parse!(@argv)
50
+ self
51
+ end
52
+
53
+ def help_text
54
+ @parser.help
55
+ end
56
+
57
+ def to_h
58
+ {
59
+ :mode => @mode,
60
+ :root => @root,
61
+ :format => @format,
62
+ :deduplicate_symlinks => @deduplicate_symlinks,
63
+ :paths => paths,
64
+ :suppress_ratings => @suppress_ratings
65
+ }
66
+ end
67
+
68
+ private
69
+
70
+ def paths
71
+ if @argv.empty?
72
+ ["."]
73
+ else
74
+ @argv
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,26 @@
1
+ require "rubycritic/source_control_systems/base"
2
+ require "rubycritic/analysers_runner"
3
+ require "rubycritic/reporter"
4
+
5
+ module Rubycritic
6
+ module Command
7
+ class Ci
8
+ def initialize(paths)
9
+ @paths = paths
10
+ Config.source_control_system = SourceControlSystem::Base.create
11
+ end
12
+
13
+ def execute
14
+ report(critique)
15
+ end
16
+
17
+ def critique
18
+ AnalysersRunner.new(@paths).run
19
+ end
20
+
21
+ def report(analysed_modules)
22
+ Reporter.generate_report(analysed_modules)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ require "rubycritic/source_control_systems/base"
2
+ require "rubycritic/analysers_runner"
3
+ require "rubycritic/revision_comparator"
4
+ require "rubycritic/reporter"
5
+
6
+ module Rubycritic
7
+ module Command
8
+ class Default
9
+ def initialize(paths)
10
+ @paths = paths
11
+ Config.source_control_system = SourceControlSystem::Base.create
12
+ end
13
+
14
+ def execute
15
+ report(critique)
16
+ end
17
+
18
+ def critique
19
+ analysed_modules = AnalysersRunner.new(@paths).run
20
+ RevisionComparator.new(@paths).set_statuses(analysed_modules)
21
+ end
22
+
23
+ def report(analysed_modules)
24
+ Reporter.generate_report(analysed_modules)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ module Rubycritic
2
+ module Command
3
+ class Help
4
+ def initialize(help_text)
5
+ @help_text = help_text
6
+ end
7
+
8
+ def execute
9
+ puts @help_text
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require "rubycritic/version"
2
+
3
+ module Rubycritic
4
+ module Command
5
+ class Version
6
+ def execute
7
+ puts "RubyCritic #{VERSION}"
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ module Rubycritic
2
+ class Configuration
3
+ attr_reader :root
4
+ attr_accessor :source_control_system, :mode, :format, :deduplicate_symlinks,
5
+ :suppress_ratings
6
+
7
+ def set(options)
8
+ self.mode = options[:mode] || :default
9
+ self.root = options[:root] || "tmp/rubycritic"
10
+ self.format = options[:format] || :html
11
+ self.deduplicate_symlinks = options[:deduplicate_symlinks] || false
12
+ self.suppress_ratings = options[:suppress_ratings] || false
13
+ end
14
+
15
+ def root=(path)
16
+ @root = File.expand_path(path)
17
+ end
18
+ end
19
+
20
+ module Config
21
+ def self.configuration
22
+ @configuration ||= Configuration.new
23
+ end
24
+
25
+ def self.set(options = {})
26
+ configuration.set(options)
27
+ end
28
+
29
+ def self.method_missing(method, *args, &block)
30
+ configuration.public_send(method, *args, &block)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,66 @@
1
+ require "virtus"
2
+ require "rubycritic/core/rating"
3
+
4
+ module Rubycritic
5
+
6
+ class AnalysedModule
7
+ include Virtus.model
8
+
9
+ attribute :name
10
+ attribute :pathname
11
+ attribute :smells, Array, :default => []
12
+ attribute :churn
13
+ attribute :committed_at
14
+ attribute :complexity
15
+ attribute :duplication, Integer, :default => 0
16
+ attribute :methods_count
17
+
18
+ def path
19
+ @path ||= pathname.to_s
20
+ end
21
+
22
+ def cost
23
+ @cost ||= smells.map(&:cost).inject(0, :+) + (complexity / 25)
24
+ end
25
+
26
+ def rating
27
+ @rating ||= Rating.from_cost(cost)
28
+ end
29
+
30
+ def complexity_per_method
31
+ if methods_count == 0
32
+ "N/A"
33
+ else
34
+ complexity.fdiv(methods_count).round(1)
35
+ end
36
+ end
37
+
38
+ def smells?
39
+ !smells.empty?
40
+ end
41
+
42
+ def smells_at_location(location)
43
+ smells.select { |smell| smell.at_location?(location) }
44
+ end
45
+
46
+ def to_h
47
+ {
48
+ :name => name,
49
+ :path => path,
50
+ :smells => smells,
51
+ :churn => churn,
52
+ :committed_at => committed_at,
53
+ :complexity => complexity,
54
+ :duplication => duplication,
55
+ :methods_count => methods_count,
56
+ :cost => cost,
57
+ :rating => rating
58
+ }
59
+ end
60
+
61
+ def to_json(*a)
62
+ to_h.to_json(*a)
63
+ end
64
+ end
65
+
66
+ end
@@ -7,15 +7,30 @@ module Rubycritic
7
7
 
8
8
  def initialize(path, line)
9
9
  @pathname = Pathname.new(path)
10
- @line = line
10
+ @line = line.to_i
11
+ end
12
+
13
+ def file_name
14
+ @pathname.basename.sub_ext("").to_s
11
15
  end
12
16
 
13
17
  def to_s
14
18
  "#{pathname}:#{line}"
15
19
  end
16
20
 
21
+ def to_h
22
+ {
23
+ :path => pathname.to_s,
24
+ :line => line
25
+ }
26
+ end
27
+
28
+ def to_json(*a)
29
+ to_h.to_json(*a)
30
+ end
31
+
17
32
  def ==(other)
18
- self.class == other.class && state == other.state
33
+ state == other.state
19
34
  end
20
35
 
21
36
  def <=>(other)
@@ -0,0 +1,30 @@
1
+ module Rubycritic
2
+
3
+ class Rating
4
+ def self.from_cost(cost)
5
+ if cost <= 2 then new("A")
6
+ elsif cost <= 4 then new("B")
7
+ elsif cost <= 8 then new("C")
8
+ elsif cost <= 16 then new("D")
9
+ else new("F")
10
+ end
11
+ end
12
+
13
+ def initialize(letter)
14
+ @letter = letter
15
+ end
16
+
17
+ def to_s
18
+ @letter
19
+ end
20
+
21
+ def to_h
22
+ @letter
23
+ end
24
+
25
+ def to_json(*a)
26
+ to_h.to_json(*a)
27
+ end
28
+ end
29
+
30
+ end
@@ -1,5 +1,5 @@
1
1
  require "virtus"
2
- require "rubycritic/location"
2
+ require "rubycritic/core/location"
3
3
 
4
4
  module Rubycritic
5
5
 
@@ -7,37 +7,46 @@ module Rubycritic
7
7
  include Virtus.model
8
8
 
9
9
  attribute :context
10
+ attribute :cost
10
11
  attribute :locations
11
12
  attribute :message
12
13
  attribute :score
13
- attribute :type
14
14
  attribute :status
15
+ attribute :type
15
16
 
16
- def pathnames
17
- @pathnames ||= locations.map(&:pathname).uniq
18
- end
19
-
20
- def located_in?(other_location)
17
+ def at_location?(other_location)
21
18
  locations.any? { |location| location == other_location }
22
19
  end
23
20
 
24
- def has_multiple_locations?
21
+ def multiple_locations?
25
22
  locations.length > 1
26
23
  end
27
24
 
28
25
  def ==(other)
29
- self.class == other.class && state == other.state
26
+ state == other.state
30
27
  end
31
28
  alias_method :eql?, :==
32
29
 
33
- def <=>(other)
34
- locations <=> other.locations
35
- end
36
-
37
30
  def to_s
38
31
  "(#{type}) #{context} #{message}"
39
32
  end
40
33
 
34
+ def to_h
35
+ {
36
+ :context => context,
37
+ :cost => cost,
38
+ :locations => locations,
39
+ :message => message,
40
+ :score => score,
41
+ :status => status,
42
+ :type => type
43
+ }
44
+ end
45
+
46
+ def to_json(*a)
47
+ to_h.to_json(*a)
48
+ end
49
+
41
50
  def hash
42
51
  state.hash
43
52
  end
@@ -0,0 +1,104 @@
1
+ prettyPrint();
2
+
3
+ emphasizeLineFromFragment();
4
+
5
+ function emphasizeLineFromFragment() {
6
+ emphasizeLine(window.location.hash)
7
+ }
8
+
9
+ $(".js-file-code").on("click", ".js-smell-location", emphasizeLineFromHref);
10
+
11
+ function emphasizeLineFromHref(event) {
12
+ if (hrefTargetIsOnCurrentPage(this) && !event.ctrlKey) {
13
+ $(".js-file-code li").removeClass("highlight");
14
+ var lineId = "#" + this.href.split("#")[1];
15
+ emphasizeLine(lineId);
16
+ return false;
17
+ }
18
+ }
19
+
20
+ function hrefTargetIsOnCurrentPage(aTag) {
21
+ return (window.location.pathname === aTag.pathname);
22
+ }
23
+
24
+ function emphasizeLine(lineReference) {
25
+ scrollToTarget(lineReference);
26
+ highlightLine(lineReference);
27
+ }
28
+
29
+ function scrollToTarget(lineReference) {
30
+ $.scrollTo(lineReference, {
31
+ duration: 300,
32
+ easing: "linear",
33
+ onAfter: function() {
34
+ window.location.hash = lineReference;
35
+ }
36
+ });
37
+ }
38
+
39
+ function highlightLine(lineReference) {
40
+ $(lineReference).addClass("highlight");
41
+ }
42
+
43
+ $("#js-toggle-smells").on("click", toggleSmells);
44
+
45
+ function toggleSmells() {
46
+ $(".js-smells").toggle();
47
+ }
48
+
49
+ $("#js-index-table")
50
+ .tablesorter({ // Sort the table
51
+ sortList: [[0,0]] // on the first column, in ascending order
52
+ })
53
+ .floatThead(); // Make table headers stick to the top when scrolling
54
+
55
+ $(".js-timeago").timeago();
56
+
57
+ $("#js-chart-container").highcharts({
58
+ chart: {
59
+ type: "scatter",
60
+ zoomType: "xy"
61
+ },
62
+ title: {
63
+ text: "Churn vs Complexity"
64
+ },
65
+ xAxis: {
66
+ title: {
67
+ enabled: true,
68
+ text: "Churn"
69
+ },
70
+ floor: 0,
71
+ startOnTick: true,
72
+ endOnTick: true
73
+ },
74
+ yAxis: {
75
+ title: {
76
+ text: "Complexity"
77
+ },
78
+ floor: 0,
79
+ startOnTick: true,
80
+ endOnTick: true
81
+ },
82
+ plotOptions: {
83
+ scatter: {
84
+ marker: {
85
+ radius: 5,
86
+ states: {
87
+ hover: {
88
+ enabled: true,
89
+ lineColor: "rgb(100,100,100)"
90
+ }
91
+ }
92
+ },
93
+ tooltip: {
94
+ headerFormat: "<b>{point.key}</b><br>",
95
+ pointFormat: "Committed {point.x} times, with Flog score of {point.y}"
96
+ }
97
+ }
98
+ },
99
+ series: [{
100
+ showInLegend: false,
101
+ color: "steelblue",
102
+ data: turbulenceData
103
+ }]
104
+ });