fukuzatsu 0.9.13 → 0.9.14

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 33b9be43725bfc69fd427bc78857cb173db66586
4
- data.tar.gz: 93eb38e086bcf10b4e38cccc9cec53e3a10bcd7b
3
+ metadata.gz: 2f84b5108ad126a90f2320712aa5c5ec01690969
4
+ data.tar.gz: 7b5d7114da4f187368fef32eaa46949c664cf41b
5
5
  SHA512:
6
- metadata.gz: 0f42bf703830a6e88d468b0fc64c96f3de69c9b69a79557ebe59c6a0913b3858ed68c498685daddcdf454df3bbf1fa622a042b7632e568b09602dec6828299d6
7
- data.tar.gz: 38fa1c7d5ecbd1be0725af017d162f58ef23f5c0b2cbd43014ac224461b56ead7df38dc08c596549e4b83c33782afa300a61dddf71bce645118f8bc27a246522
6
+ metadata.gz: 18a5e3e5352b534f2e9c1cd1de89c7dfa674e4281c58b36b4c5c973fa1f0d89bfd7bc14b8ad96e5ad3b676095ec50fb08330fe9182a55ef4ce70e0f7a1b43050
7
+ data.tar.gz: fdf63925b5cf99805c394674c7214a65f0f6c00a7ece731be10ccdbe06f295fea7ba768ef88ed7eda28764bd29f84aaa55d298816828e3e3724be6913b48e6fd
data/.gitignore CHANGED
@@ -22,3 +22,4 @@ tmp
22
22
  mkmf.log
23
23
  .console_history
24
24
  *.swp
25
+ coverage
data/Gemfile CHANGED
@@ -1,4 +1,2 @@
1
1
  source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in fukuzatsu.gemspec
4
2
  gemspec
data/fukuzatsu.gemspec CHANGED
@@ -22,10 +22,11 @@ Gem::Specification.new do |spec|
22
22
  spec.add_dependency "poro_plus"
23
23
  spec.add_dependency "haml"
24
24
  spec.add_dependency "parser"
25
+ spec.add_dependency "thor"
25
26
 
26
27
  spec.add_development_dependency "bundler", "~> 1.6"
27
28
  spec.add_development_dependency "rake"
28
29
  spec.add_development_dependency "rspec"
29
- spec.add_development_dependency "thor"
30
+ spec.add_development_dependency "simplecov"
30
31
 
31
32
  end
@@ -50,13 +50,13 @@ class Analyzer
50
50
  end
51
51
 
52
52
  def methods_from(node, methods=[])
53
- if node.type == :def || node.type == :defs
53
+ if node.type == :def || node.type == :defs || node.type == :class
54
54
  name = node.loc.name
55
55
  expression = node.loc.expression
56
56
  methods << ParsedMethod.new(
57
57
  name: content[name.begin_pos..name.end_pos - 1],
58
58
  content: content[expression.begin_pos..expression.end_pos - 1],
59
- type: node.type == :defs ? :class : :instance
59
+ type: [:defs, :class].include?(node.type) ? :class : :instance
60
60
  )
61
61
  end
62
62
  node.children.each do |child|
data/lib/fukuzatsu/cli.rb CHANGED
@@ -13,36 +13,31 @@ module Fukuzatsu
13
13
  method_option :threshold, :type => :numeric, :default => 0, :aliases => "-t"
14
14
 
15
15
  def check(path="./")
16
-
17
- file_summary = []
18
- file_complexities = []
19
- last_file = {}
20
-
21
- file_list(path).each do |path_to_file|
22
- file = ParsedFile.new(path_to_file: path_to_file)
23
- parser = formatter(options).new(file)
24
- parser.export
25
- file_summary << {
26
- results_file: "#{parser.output_path}/#{parser.filename}",
27
- path_to_file: path_to_file,
28
- class_name: "#{file.class_name}",
29
- complexity: file.complexity
30
- }
31
- file_complexities << file.complexity
32
- end
33
-
34
- last_file = handle_index(file_summary) if options['format'] == 'html'
35
- report(last_file[:results_file], file_summary.map{|s| s[:results_file]})
36
- handle_complexity(options, file_complexities.sort.last, options['threshold'])
37
-
16
+ file_list(path).each{ |path_to_file| parse(path_to_file) }
17
+ handle_index(summaries)
18
+ report
38
19
  end
39
20
 
40
21
  default_task :check
41
22
 
23
+ attr_accessor :summaries, :last_file
24
+
42
25
  private
43
26
 
44
- def formatter(options)
45
- formatter = case options['format']
27
+ def complexities
28
+ summaries.to_a.map{|s| s[:complexity]}
29
+ end
30
+
31
+ def file_list(start_file)
32
+ if File.directory?(start_file)
33
+ return Dir.glob(File.join(start_file, "**", "*")).select{|n| n =~ /\.rb$/}
34
+ else
35
+ return [start_file]
36
+ end
37
+ end
38
+
39
+ def formatter
40
+ case options['format']
46
41
  when 'html'
47
42
  Formatters::Html
48
43
  when 'csv'
@@ -53,30 +48,37 @@ module Fukuzatsu
53
48
  end
54
49
 
55
50
  def handle_index(file_summary)
51
+ return unless options['format'] == 'html'
56
52
  index = Formatters::HtmlIndex.new(file_summary)
53
+ self.last_file = "#{index.output_path}/#{index.filename}"
57
54
  index.export
58
- {results_file: "#{index.output_path}/#{index.filename}"}
59
55
  end
60
56
 
61
- def report(last_file, file_list)
62
- return if options['format'] == "text"
63
- puts "Results written to:"
64
- puts last_file.present? && "#{last_file}" || file_list.join("\r\n")
57
+ def parse(path_to_file, options={})
58
+ file = ParsedFile.new(path_to_file: path_to_file)
59
+ parser = formatter.new(file)
60
+ parser.export
61
+ self.summaries ||= []
62
+ self.summaries << file.summary.merge(results_file: parser.path_to_results)
63
+ end
64
+
65
+ def report
66
+ unless options['format'] == "text"
67
+ puts "Results written to:"
68
+ puts last_file.present? && "#{last_file}" || results_files.join("\r\n")
69
+ end
70
+ report_complexity
65
71
  end
66
72
 
67
- def handle_complexity(options, highest_complexity, threshold)
73
+ def report_complexity
68
74
  return if options['threshold'].to_i == 0
69
- return if highest_complexity <= options['threshold']
70
- puts "Maximum complexity is #{highest_complexity}, which is greater than the threshold of #{options['threshold']}."
75
+ return if complexities.max.to_i <= options['threshold']
76
+ puts "Maximum complexity of #{complexities.max} exceeds #{options['threshold']} threshold!"
71
77
  exit 1
72
78
  end
73
79
 
74
- def file_list(start_file)
75
- if File.directory?(start_file)
76
- return Dir.glob(File.join(start_file, "**", "*")).select{|n| n =~ /\.rb$/}
77
- else
78
- return [start_file]
79
- end
80
+ def results_files
81
+ summaries.map{|s| s[:results_file]}
80
82
  end
81
83
 
82
84
  end
@@ -28,6 +28,10 @@ module Formatters
28
28
  output_path
29
29
  end
30
30
 
31
+ def path_to_results
32
+ "#{output_path}/#{filename}"
33
+ end
34
+
31
35
  def filename
32
36
  self.file.path_to_file.split('/')[-1] + file_extension
33
37
  end
@@ -38,7 +42,7 @@ module Formatters
38
42
 
39
43
  def export
40
44
  begin
41
- outfile = File.open("#{output_path}/#{filename}", 'w')
45
+ outfile = File.open("#{path_to_results}", 'w')
42
46
  outfile.write(content)
43
47
  rescue Exception => e
44
48
  puts "Unable to write output: #{e} #{e.backtrace}"
@@ -3,7 +3,7 @@ class ParsedFile
3
3
  include PoroPlus
4
4
  include Ephemeral::Base
5
5
 
6
- attr_accessor :path_to_file, :class_name
6
+ attr_accessor :complexity, :path_to_file, :class_name, :path_to_results
7
7
 
8
8
  def class_name
9
9
  @class_name ||= analyzer.extract_class_name
@@ -14,7 +14,7 @@ class ParsedFile
14
14
  end
15
15
 
16
16
  def analyzer
17
- Analyzer.new(content)
17
+ @analyzer ||= Analyzer.new(content)
18
18
  end
19
19
 
20
20
  def complexity
@@ -25,4 +25,13 @@ class ParsedFile
25
25
  @methods ||= analyzer.extract_methods
26
26
  end
27
27
 
28
+ def summary
29
+ {
30
+ results_file: self.path_to_results,
31
+ path_to_file: self.path_to_file,
32
+ class_name: self.class_name,
33
+ complexity: complexity
34
+ }
35
+ end
36
+
28
37
  end
@@ -1,17 +1,19 @@
1
- require 'parser/current'
2
-
3
1
  class ParsedMethod
4
2
 
5
3
  include PoroPlus
6
4
 
7
- attr_accessor :name, :content, :type
5
+ attr_accessor :name, :content, :type, :complexity
8
6
 
9
7
  def complexity
10
- @complexity ||= Analyzer.new(content).complexity
8
+ @complexity ||= analyzer.complexity
11
9
  end
12
10
 
13
11
  def prefix
14
- self.type == :class ? "." : "#"
12
+ self.type.to_s == 'class' ? "." : "#"
13
+ end
14
+
15
+ def analyzer
16
+ Analyzer.new(self.content)
15
17
  end
16
18
 
17
19
  end
@@ -1,3 +1,3 @@
1
1
  module Fukuzatsu
2
- VERSION = "0.9.13"
2
+ VERSION = "0.9.14"
3
3
  end
@@ -36,24 +36,68 @@ describe Analyzer do
36
36
  end
37
37
  end
38
38
 
39
- context "program_1" do
39
+ describe "#complexity" do
40
+ context "program_1" do
40
41
 
41
- let(:analyzer) { Analyzer.new(content_1) }
42
+ let(:analyzer) { Analyzer.new(content_1) }
43
+
44
+ it "matches the manual calculation of complexity of 4" do
45
+ expect(analyzer.complexity).to eq(4)
46
+ end
42
47
 
43
- it "matches the manual calculation of complexity of 4" do
44
- expect(analyzer.complexity).to eq(4)
45
48
  end
46
49
 
47
- end
50
+ context "program_2" do
48
51
 
49
- context "program_2" do
52
+ let(:analyzer) { Analyzer.new(content_2) }
50
53
 
51
- let(:analyzer) { Analyzer.new(content_2) }
54
+ it "matches the manual calculation of complexity of 5" do
55
+ expect(analyzer.complexity).to eq(5)
56
+ end
52
57
 
53
- it "matches the manual calculation of complexity of 5" do
54
- expect(analyzer.complexity).to eq(5)
55
58
  end
56
-
59
+ end
60
+
61
+ describe "extract_methods" do
62
+ # Note: should implicitly trust private method #methods_from
63
+ context "from a file with a single method" do
64
+ let(:analyzer) { Analyzer.new(File.read("spec/fixtures/single_method.rb")) }
65
+ it "should return a single method" do
66
+ expect(analyzer.extract_methods.count).to eq 1
67
+ end
68
+ it "should extract the method name" do
69
+ expect(analyzer.extract_methods[0].name).to eq "read_poem"
70
+ end
71
+ it "should extract the method content" do
72
+ expect(analyzer.extract_methods[0].content).to eq 'def read_poem
73
+ return "I meant to find her when I came/Death had the same design"
74
+ end'
75
+ end
76
+ it "should set type to :instance" do
77
+ expect(analyzer.extract_methods[0].type).to eq :instance
78
+ end
79
+ end
80
+ context "from a file with multiple methods" do
81
+ let(:analyzer) { Analyzer.new(File.read("spec/fixtures/multiple_methods.rb")) }
82
+ it "should return multiple methods" do
83
+ expect(analyzer.extract_methods.map { |m| m.name }).to eq ["bake_treats", "lower_from_window"]
84
+ end
85
+ end
86
+ context "from a file with nested methods" do
87
+ let(:analyzer) { Analyzer.new(File.read("spec/fixtures/nested_methods.rb")) }
88
+ it "should return the root method, and its child" do
89
+ expect(analyzer.extract_methods.map { |m| m.name }).to eq ["grow_flowers", "water_earth"]
90
+ end
91
+ end
92
+ context "from a file with a class" do
93
+ let(:analyzer) { Analyzer.new(File.read("spec/fixtures/single_class.rb")) }
94
+ it "should return the class and its methods" do
95
+ expect(analyzer.extract_methods.map { |m| m.name }).to eq ["Gown", "initialize", "color"]
96
+ end
97
+ it "should set the type of class to :class" do
98
+ expect(analyzer.extract_methods[0].type).to eq :class
99
+ end
100
+ end
57
101
  end
58
102
 
59
103
  end
data/spec/cli_spec.rb ADDED
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Fukuzatsu::CLI" do
4
+
5
+ let(:cli) { Fukuzatsu::CLI.new([
6
+ path: "foo/bar.rb",
7
+ format: 'text'
8
+ ]
9
+ )}
10
+
11
+ let(:summary_1) {
12
+ {
13
+ results_file: "doc/fukuzatsu/file_1.rb.htm",
14
+ path_to_file: "file_1.rb",
15
+ class_name: "File_1",
16
+ complexity: 13
17
+ }
18
+ }
19
+
20
+ let(:summary_2) {
21
+ {
22
+ results_file: "doc/fukuzatsu/file_2.rb.htm",
23
+ path_to_file: "file_2.rb",
24
+ class_name: "File_2",
25
+ complexity: 11
26
+ }
27
+ }
28
+
29
+ before do
30
+ allow(cli).to receive(:summaries) { [summary_1, summary_2] }
31
+ end
32
+
33
+ describe "#complexities" do
34
+ it "extracts complexities from its file summaries" do
35
+ expect(cli.send(:complexities)).to eq([13,11])
36
+ end
37
+ end
38
+
39
+ describe "#formatter" do
40
+ it "returns a csv formatter" do
41
+ allow(cli).to receive(:options) { {'format' => 'csv'} }
42
+ expect(cli.send(:formatter)).to eq Formatters::Csv
43
+ end
44
+ it "returns an html formatter" do
45
+ allow(cli).to receive(:options) { {'format' => 'html'} }
46
+ expect(cli.send(:formatter)).to eq Formatters::Html
47
+ end
48
+ it "returns a text formatter" do
49
+ allow(cli).to receive(:options) { {'format' => 'text'} }
50
+ expect(cli.send(:formatter)).to eq Formatters::Text
51
+ end
52
+ end
53
+
54
+ describe "#report" do
55
+ it "does not report if format is text" do
56
+ allow(cli).to receive(:options) { {'format' => 'text'} }
57
+ expect(cli.send(:report)).to be_nil
58
+ end
59
+ end
60
+
61
+ describe "#report_complexity" do
62
+ it "does not report if threshold is not set" do
63
+ expect(cli.send(:report_complexity)).to be_nil
64
+ end
65
+
66
+ it "does not report if threshold is respected" do
67
+ allow(cli).to receive(:options) { {'threshold' => 15} }
68
+ allow(cli).to receive(:complexities) { [0,13,11] }
69
+ expect(cli.send(:report_complexity)).to be_nil
70
+
71
+ end
72
+ end
73
+
74
+ describe "#results_files" do
75
+ it "extracts results files from its file summaries" do
76
+ expect(cli.send(:results_files)).to eq(
77
+ [
78
+ "doc/fukuzatsu/file_1.rb.htm",
79
+ "doc/fukuzatsu/file_2.rb.htm"
80
+ ]
81
+ )
82
+ end
83
+ end
84
+
85
+ end
@@ -0,0 +1,7 @@
1
+ def bake_treats
2
+ return :a_basket_of_cookies
3
+ end
4
+
5
+ def lower_from_window(window)
6
+ window.insert(bake_treats)
7
+ end
@@ -0,0 +1,8 @@
1
+ def grow_flowers(seed, water, earth)
2
+ def water_earth(water, earth)
3
+ earth.insert(water)
4
+ end
5
+
6
+ earth.insert.seed
7
+ 50.times(water_earth(water, earth))
8
+ end
@@ -0,0 +1,9 @@
1
+ class Gown
2
+ def initialize
3
+ @color = "White"
4
+ end
5
+
6
+ def color
7
+ return @color
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ def read_poem
2
+ return "I meant to find her when I came/Death had the same design"
3
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Formatters::Base" do
4
+
5
+ class Formatters::Sample; include Formatters::Base; end
6
+
7
+ let (:parsed_file) { ParsedFile.new(class_name: "Foo", path_to_file: "lib/foo.rb") }
8
+ let (:formatter) { Formatters::Sample.new(parsed_file) }
9
+
10
+ before do
11
+ allow(formatter).to receive(:header) { "class,method,complexity" }
12
+ allow(formatter).to receive(:rows) { "Foo,#initialize,24" }
13
+ allow(formatter).to receive(:footer) { "TOTAL,,24" }
14
+ end
15
+
16
+ describe "#columns" do
17
+ it "returns default columns" do
18
+ expect(formatter.columns).to eq(["class", "method", "complexity"])
19
+ end
20
+ end
21
+
22
+ describe "#content" do
23
+ it "returns expected content" do
24
+ expect(formatter.content).to eq "class,method,complexity\r\nFoo,#initialize,24\r\nTOTAL,,24"
25
+ end
26
+ end
27
+
28
+ describe "#filename" do
29
+ it "builds a filename" do
30
+ allow(formatter).to receive(:file_extension) { '.doc' }
31
+ expect(formatter.filename).to eq "foo.rb.doc"
32
+ end
33
+ end
34
+
35
+ describe "#output_path" do
36
+ it "builds a path" do
37
+ allow(FileUtils).to receive(:mkpath)
38
+ expect(formatter.output_path).to eq "doc/fukuzatsu/lib"
39
+ end
40
+ end
41
+
42
+ describe "#path_to_results" do
43
+ it "builds a path" do
44
+ allow(formatter).to receive(:file_extension) { '.doc' }
45
+ allow(formatter).to receive(:output_path) { 'doc/fukuzatsu/lib' }
46
+ expect(formatter.path_to_results).to eq "doc/fukuzatsu/lib/foo.rb.doc"
47
+ end
48
+ end
49
+
50
+ describe "#root_path" do
51
+ it "returns the expected path" do
52
+ expect(formatter.root_path).to eq "doc/fukuzatsu"
53
+ end
54
+ end
55
+
56
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Formatters::Csv" do
4
+
5
+ let (:parsed_file) { ParsedFile.new(class_name: "Foo") }
6
+ let (:method_1) { ParsedMethod.new(
7
+ name: "initialize",
8
+ complexity: 13,
9
+ type: "instance"
10
+ )
11
+ }
12
+ let (:method_2) { ParsedMethod.new(
13
+ name: "report",
14
+ complexity: 11,
15
+ type: "instance"
16
+ )
17
+ }
18
+ let (:formatter) { Formatters::Csv.new(parsed_file) }
19
+
20
+ describe "#header" do
21
+ it "returns a comma-separated header" do
22
+ expect(formatter.header).to eq "class,method,complexity"
23
+ end
24
+ end
25
+
26
+ describe "#rows" do
27
+ it "returns comma-separated rows" do
28
+ allow(parsed_file).to receive(:methods) { [method_1, method_2] }
29
+ expect(formatter.rows).to eq(
30
+ "Foo,#initialize,13\r\nFoo,#report,11"
31
+ )
32
+ end
33
+ end
34
+
35
+ describe "#file_extension" do
36
+ it "returns the proper extension" do
37
+ expect(formatter.file_extension).to eq ".csv"
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Formatters::HtmlIndex" do
4
+
5
+ let(:file_summary) {
6
+ [
7
+ {
8
+ results_file: "doc/fukuzatsu/file_1.rb.htm",
9
+ path_to_file: "file_1.rb",
10
+ class_name: "File_1",
11
+ complexity: 13
12
+ },
13
+ {
14
+ results_file: "doc/fukuzatsu/file_2.rb.htm",
15
+ path_to_file: "file_2.rb",
16
+ class_name: "File_2",
17
+ complexity: 11
18
+ }
19
+ ]
20
+ }
21
+
22
+ let (:formatter) { Formatters::HtmlIndex.new(file_summary) }
23
+
24
+ describe "#initialize" do
25
+ it "initializes with a file summary" do
26
+ expect(formatter.file_summary).to eq file_summary
27
+ end
28
+ end
29
+
30
+ describe "#filename" do
31
+ it "returns the expected filename" do
32
+ expect(formatter.filename).to eq "index.htm"
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Formatters::Text" do
4
+
5
+ let (:parsed_file) { ParsedFile.new(class_name: "Foo", complexity: 11) }
6
+ let (:method_1) { ParsedMethod.new(
7
+ name: "initialize",
8
+ complexity: 13,
9
+ type: "instance"
10
+ )
11
+ }
12
+ let (:method_2) { ParsedMethod.new(
13
+ name: "report",
14
+ complexity: 11,
15
+ type: "instance"
16
+ )
17
+ }
18
+ let (:formatter) { Formatters::Html.new(parsed_file) }
19
+
20
+ before do
21
+ allow(parsed_file).to receive(:methods) { [method_1, method_2] }
22
+ end
23
+
24
+ describe "#header" do
25
+ it "returns an HTML-formatted header" do
26
+ expect(formatter.header).to eq(
27
+ "<th>Class</th>\r\n<th>Method</th>\r\n<th>Complexity</th>"
28
+ )
29
+ end
30
+ end
31
+
32
+ describe "#rows" do
33
+ it "returns HTML-formatted rows" do
34
+ expected = "<tr class='even'>\r\n <td>Foo</td>\r\n <td>#initialize</td>\r\n <td>13</td>\r\n</tr>\r\n"
35
+ expected << "<tr class='odd'>\r\n <td>Foo</td>\r\n <td>#report</td>\r\n <td>11</td>\r\n</tr>"
36
+ allow(parsed_file).to receive(:methods) { [method_1, method_2] }
37
+ expect(formatter.rows).to eq(expected)
38
+ end
39
+ end
40
+
41
+ describe "#file_extension" do
42
+ it "returns the proper extension" do
43
+ expect(formatter.file_extension).to eq ".htm"
44
+ end
45
+ end
46
+
47
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Formatters::Text" do
4
+
5
+ let (:parsed_file) { ParsedFile.new(class_name: "Foo", complexity: 11) }
6
+ let (:method_1) { ParsedMethod.new(
7
+ name: "initialize",
8
+ complexity: 13,
9
+ type: "instance"
10
+ )
11
+ }
12
+ let (:method_2) { ParsedMethod.new(
13
+ name: "report",
14
+ complexity: 11,
15
+ type: "instance"
16
+ )
17
+ }
18
+ let (:formatter) { Formatters::Text.new(parsed_file) }
19
+
20
+ describe "#header" do
21
+ it "returns a tab-separated header" do
22
+ expect(formatter.header).to eq "Foo\t\t11"
23
+ end
24
+ end
25
+
26
+ describe "#rows" do
27
+ it "returns tab-separated rows" do
28
+ allow(parsed_file).to receive(:methods) { [method_1, method_2] }
29
+ expect(formatter.rows).to eq(
30
+ ["Foo\t#initialize\t13", "Foo\t#report\t11"]
31
+ )
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe ParsedFile do
4
+
5
+ let(:parsed_file) { ParsedFile.new(path_to_file: "bar/foo.rb") }
6
+ let(:analyzer) { Analyzer.new("class Foo; end") }
7
+
8
+ describe "#class_name" do
9
+ before do
10
+ allow(parsed_file).to receive(:analyzer) { analyzer }
11
+ end
12
+ it "retrieves class name from analyzer" do
13
+ expect(parsed_file.class_name).to eq "Foo"
14
+ end
15
+ end
16
+
17
+ describe "#content" do
18
+ it "reads from file" do
19
+ allow(File).to receive(:open).with("bar/foo.rb", "r") {
20
+ instance_double("File", read: "whatever")
21
+ }
22
+ expect(parsed_file.content).to eq("whatever")
23
+ end
24
+ end
25
+
26
+ describe "#analyzer" do
27
+ it "instantiates an Analyzer instance with content" do
28
+ allow(parsed_file).to receive("content") { "stuff" }
29
+ expect(parsed_file.analyzer.class.name).to eq "Analyzer"
30
+ end
31
+ end
32
+
33
+ describe "#complexity" do
34
+ before do
35
+ allow(parsed_file).to receive(:analyzer) { analyzer }
36
+ end
37
+ it "retrieves complexity score from analyzer" do
38
+ allow(analyzer).to receive(:complexity) { 13 }
39
+ expect(parsed_file.complexity).to eq 13
40
+ end
41
+ end
42
+
43
+ describe "methods" do
44
+ before do
45
+ allow(parsed_file).to receive(:analyzer) { analyzer }
46
+ end
47
+ it "retrieves methods from analyzer" do
48
+ allow(analyzer).to receive(:extract_methods) { [:talk, :walk] }
49
+ expect(parsed_file.methods).to eq([:talk, :walk])
50
+ end
51
+ end
52
+
53
+ describe "summary" do
54
+ it "builds a hash" do
55
+ allow(parsed_file).to receive(:path_to_results) { "doc/fukuzatsu/foo.rb.htm" }
56
+ allow(parsed_file).to receive(:path_to_file) { "foo.rb.htm" }
57
+ allow(parsed_file).to receive(:class_name) { "Foo" }
58
+ allow(parsed_file).to receive(:complexity) { 11 }
59
+ expect(parsed_file.summary[:results_file]).to eq "doc/fukuzatsu/foo.rb.htm"
60
+ expect(parsed_file.summary[:path_to_file]).to eq "foo.rb.htm"
61
+ expect(parsed_file.summary[:class_name]).to eq "Foo"
62
+ expect(parsed_file.summary[:complexity]).to eq 11
63
+ end
64
+ end
65
+
66
+
67
+ end
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe ParsedMethod do
4
+
5
+ let(:parsed_method) { ParsedMethod.new }
6
+ let(:analyzer) { Analyzer.new("class Foo; end") }
7
+
8
+ describe "#complexity" do
9
+ it "retrieves complexity from its analyzer" do
10
+ allow(parsed_method).to receive(:analyzer) { analyzer }
11
+ allow(analyzer).to receive(:complexity) { 23 }
12
+ expect(parsed_method.complexity).to eq 23
13
+ end
14
+ end
15
+
16
+ describe "#analyzer" do
17
+ it "instantiates an Analyzer instance with content" do
18
+ allow(parsed_method).to receive("content") { "stuff" }
19
+ expect(parsed_method.analyzer.class.name).to eq "Analyzer"
20
+ end
21
+ end
22
+
23
+ describe "#prefix" do
24
+ it "returns '.' if its type is class" do
25
+ allow(parsed_method).to receive("type") { "class" }
26
+ expect(parsed_method.prefix).to eq "."
27
+ end
28
+ it "returns '#' if its type is instance" do
29
+ allow(parsed_method).to receive("type") { "instance" }
30
+ expect(parsed_method.prefix).to eq "#"
31
+ end
32
+ end
33
+
34
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,7 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.start
4
+
1
5
  require 'rubygems'
2
6
  require 'rspec'
3
7
  require 'fukuzatsu'
data/tags ADDED
@@ -0,0 +1,92 @@
1
+ !_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
2
+ !_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
3
+ !_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
4
+ !_TAG_PROGRAM_NAME Exuberant Ctags //
5
+ !_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
6
+ !_TAG_PROGRAM_VERSION 5.8 //
7
+ Analyzer lib/fukuzatsu/analyzer.rb /^class Analyzer$/;" c
8
+ Base lib/fukuzatsu/formatters/base.rb /^ module Base$/;" m class:Formatters
9
+ Breathalizer spec/fixtures/program_3.rb /^class Breathalizer$/;" c
10
+ CLI lib/fukuzatsu/cli.rb /^ class CLI < Thor$/;" c class:Fukuzatsu
11
+ Csv lib/fukuzatsu/formatters/csv.rb /^ class Csv$/;" c class:Formatters
12
+ Extracted spec/fixtures/eg_mod_class_2.rb /^module Extracted$/;" m
13
+ Foo spec/fixtures/eg_class.rb /^class Foo$/;" c
14
+ Foo spec/fixtures/eg_mod_class.rb /^class Foo::Bar$/;" c
15
+ Formatters lib/fukuzatsu/formatters/base.rb /^module Formatters$/;" m
16
+ Formatters lib/fukuzatsu/formatters/csv.rb /^module Formatters$/;" m
17
+ Formatters lib/fukuzatsu/formatters/html.rb /^module Formatters$/;" m
18
+ Formatters lib/fukuzatsu/formatters/html_index.rb /^module Formatters$/;" m
19
+ Formatters lib/fukuzatsu/formatters/text.rb /^module Formatters$/;" m
20
+ Fukuzatsu lib/fukuzatsu.rb /^module Fukuzatsu$/;" m
21
+ Fukuzatsu lib/fukuzatsu/cli.rb /^module Fukuzatsu$/;" m
22
+ Fukuzatsu lib/fukuzatsu/version.rb /^module Fukuzatsu$/;" m
23
+ Html lib/fukuzatsu/formatters/html.rb /^ class Html$/;" c class:Formatters
24
+ HtmlIndex lib/fukuzatsu/formatters/html_index.rb /^ class HtmlIndex$/;" c class:Formatters
25
+ ParsedFile lib/fukuzatsu/parsed_file.rb /^class ParsedFile$/;" c
26
+ ParsedMethod lib/fukuzatsu/parsed_method.rb /^class ParsedMethod$/;" c
27
+ Something spec/fixtures/eg_module.rb /^module Something$/;" m
28
+ Text lib/fukuzatsu/formatters/text.rb /^ class Text$/;" c class:Formatters
29
+ Thing spec/fixtures/eg_mod_class_2.rb /^ class Thing$/;" c class:Extracted
30
+ analyzer lib/fukuzatsu/parsed_file.rb /^ def analyzer$/;" f class:ParsedFile
31
+ check lib/fukuzatsu/cli.rb /^ def check(path=".\/")$/;" f class:Fukuzatsu.CLI
32
+ class_name lib/fukuzatsu/parsed_file.rb /^ def class_name$/;" f class:ParsedFile
33
+ columns lib/fukuzatsu/formatters/base.rb /^ def columns$/;" f class:Formatters.Base
34
+ complexity lib/fukuzatsu/analyzer.rb /^ def complexity$/;" f class:Analyzer
35
+ complexity lib/fukuzatsu/parsed_file.rb /^ def complexity$/;" f class:ParsedFile
36
+ complexity lib/fukuzatsu/parsed_method.rb /^ def complexity$/;" f class:ParsedMethod
37
+ complexity spec/fixtures/program_3.rb /^ def complexity$/;" f class:Breathalizer
38
+ content lib/fukuzatsu/formatters/base.rb /^ def content$/;" f class:Formatters.Base
39
+ content lib/fukuzatsu/formatters/html.rb /^ def content$/;" f class:Formatters.Html
40
+ content lib/fukuzatsu/formatters/html_index.rb /^ def content$/;" f class:Formatters.HtmlIndex
41
+ content lib/fukuzatsu/parsed_file.rb /^ def content$/;" f class:ParsedFile
42
+ export lib/fukuzatsu/formatters/base.rb /^ def export$/;" f class:Formatters.Base
43
+ export lib/fukuzatsu/formatters/text.rb /^ def export$/;" f class:Formatters.Text
44
+ extend_graph lib/fukuzatsu/analyzer.rb /^ def extend_graph$/;" f class:Analyzer
45
+ extract_class_name lib/fukuzatsu/analyzer.rb /^ def extract_class_name$/;" f class:Analyzer
46
+ extract_methods lib/fukuzatsu/analyzer.rb /^ def extract_methods$/;" f class:Analyzer
47
+ file_contents spec/fixtures/program_3.rb /^ def file_contents$/;" f class:Breathalizer
48
+ file_extension lib/fukuzatsu/formatters/base.rb /^ def file_extension$/;" f class:Formatters.Base
49
+ file_extension lib/fukuzatsu/formatters/csv.rb /^ def file_extension$/;" f class:Formatters.Csv.rows
50
+ file_extension lib/fukuzatsu/formatters/html.rb /^ def file_extension$/;" f class:Formatters.Html.rows
51
+ file_list lib/fukuzatsu/cli.rb /^ def file_list(start_file)$/;" f class:Fukuzatsu
52
+ filename lib/fukuzatsu/formatters/base.rb /^ def filename$/;" f class:Formatters.Base
53
+ filename lib/fukuzatsu/formatters/html_index.rb /^ def filename$/;" f class:Formatters.HtmlIndex
54
+ find_class lib/fukuzatsu/analyzer.rb /^ def find_class(node)$/;" f class:Analyzer
55
+ footer lib/fukuzatsu/formatters/csv.rb /^ def footer$/;" f class:Formatters.Csv.rows
56
+ footer lib/fukuzatsu/formatters/html.rb /^ def footer$/;" f class:Formatters.Html.rows
57
+ footer lib/fukuzatsu/formatters/text.rb /^ def footer$/;" f class:Formatters.Text
58
+ formatter lib/fukuzatsu/cli.rb /^ def formatter(options)$/;" f class:Fukuzatsu.CLI
59
+ handle_complexity lib/fukuzatsu/cli.rb /^ def handle_complexity(options, highest_complexity, threshold)$/;" f class:Fukuzatsu
60
+ handle_index lib/fukuzatsu/cli.rb /^ def handle_index(file_summary)$/;" f class:Fukuzatsu
61
+ header lib/fukuzatsu/formatters/csv.rb /^ def header$/;" f class:Formatters.Csv
62
+ header lib/fukuzatsu/formatters/html.rb /^ def header$/;" f class:Formatters.Html
63
+ header lib/fukuzatsu/formatters/text.rb /^ def header$/;" f class:Formatters.Text
64
+ included lib/fukuzatsu/formatters/base.rb /^ def self.included(klass)$/;" F class:Formatters.Base
65
+ initialize lib/fukuzatsu/analyzer.rb /^ def initialize(content)$/;" f class:Analyzer
66
+ initialize lib/fukuzatsu/formatters/base.rb /^ def initialize(file)$/;" f class:Formatters.Base
67
+ initialize lib/fukuzatsu/formatters/html_index.rb /^ def initialize(file_summary)$/;" f class:Formatters.HtmlIndex
68
+ initialize spec/fixtures/program_3.rb /^ def initialize(path_to_file)$/;" f class:Breathalizer
69
+ methods lib/fukuzatsu/parsed_file.rb /^ def methods$/;" f class:ParsedFile
70
+ methods_from lib/fukuzatsu/analyzer.rb /^ def methods_from(node, methods=[])$/;" f class:Analyzer
71
+ output_path lib/fukuzatsu/formatters/base.rb /^ def output_path$/;" f class:Formatters.Base
72
+ output_path lib/fukuzatsu/formatters/html_index.rb /^ def output_path$/;" f class:Formatters.HtmlIndex
73
+ output_template lib/fukuzatsu/formatters/html.rb /^ def output_template$/;" f class:Formatters.Html
74
+ output_template lib/fukuzatsu/formatters/html_index.rb /^ def output_template$/;" f class:Formatters.HtmlIndex
75
+ parent_node? lib/fukuzatsu/analyzer.rb /^ def parent_node?(node)$/;" f class:Analyzer
76
+ parse spec/fixtures/program_3.rb /^ def self.parse!(path_to_file)$/;" F class:Breathalizer
77
+ parse! lib/fukuzatsu/analyzer.rb /^ def parse!$/;" f class:Analyzer
78
+ parse! spec/fixtures/program_3.rb /^ def parse!$/;" f class:Breathalizer
79
+ parsed lib/fukuzatsu/analyzer.rb /^ def parsed$/;" f class:Analyzer
80
+ parsed spec/fixtures/program_3.rb /^ def parsed$/;" f class:Breathalizer
81
+ prefix lib/fukuzatsu/parsed_method.rb /^ def prefix$/;" f class:ParsedMethod
82
+ report lib/fukuzatsu/cli.rb /^ def report(last_file, file_list)$/;" f class:Fukuzatsu
83
+ root_path lib/fukuzatsu/formatters/base.rb /^ def root_path$/;" f class:Formatters.Base
84
+ rows lib/fukuzatsu/formatters/csv.rb /^ def rows$/;" f class:Formatters.Csv
85
+ rows lib/fukuzatsu/formatters/html.rb /^ def rows$/;" f class:Formatters.Html
86
+ rows lib/fukuzatsu/formatters/text.rb /^ def rows$/;" f class:Formatters.Text
87
+ say_hello spec/fixtures/eg_class.rb /^ def say_hello$/;" f class:Foo
88
+ spaghetti spec/fixtures/program_1.rb /^def spaghetti$/;" f
89
+ text_at lib/fukuzatsu/analyzer.rb /^ def text_at(start_pos, end_pos)$/;" f class:Analyzer
90
+ toppings spec/fixtures/program_2.rb /^def toppings$/;" f
91
+ traverse lib/fukuzatsu/analyzer.rb /^ def traverse(node, accumulator=[], extract_methods=false)$/;" f class:Analyzer
92
+ traverse spec/fixtures/program_3.rb /^ def traverse(node)#, accumulator=[])$/;" f class:Breathalizer
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fukuzatsu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.13
4
+ version: 0.9.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bantik
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-05 00:00:00.000000000 Z
11
+ date: 2014-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ephemeral
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: thor
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: bundler
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -109,7 +123,7 @@ dependencies:
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
- name: thor
126
+ name: simplecov
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
@@ -156,15 +170,28 @@ files:
156
170
  - lib/fukuzatsu/parsed_method.rb
157
171
  - lib/fukuzatsu/version.rb
158
172
  - spec/analyzer_spec.rb
173
+ - spec/cli_spec.rb
159
174
  - spec/fixtures/eg_class.rb
160
175
  - spec/fixtures/eg_mod_class.rb
161
176
  - spec/fixtures/eg_mod_class_2.rb
162
177
  - spec/fixtures/eg_module.rb
178
+ - spec/fixtures/multiple_methods.rb
179
+ - spec/fixtures/nested_methods.rb
163
180
  - spec/fixtures/program_1.rb
164
181
  - spec/fixtures/program_2.rb
165
182
  - spec/fixtures/program_3.rb
166
183
  - spec/fixtures/program_4.rb
184
+ - spec/fixtures/single_class.rb
185
+ - spec/fixtures/single_method.rb
186
+ - spec/formatters/base_spec.rb
187
+ - spec/formatters/csv_spec.rb
188
+ - spec/formatters/html_index_spec.rb
189
+ - spec/formatters/html_spec.rb
190
+ - spec/formatters/text_spec.rb
191
+ - spec/parsed_file_spec.rb
192
+ - spec/parsed_method_spec.rb
167
193
  - spec/spec_helper.rb
194
+ - tags
168
195
  homepage: https://gitlab.com/coraline/fukuzatsu/tree/master
169
196
  licenses:
170
197
  - MIT
@@ -191,12 +218,24 @@ specification_version: 4
191
218
  summary: A simple code complexity analyzer.
192
219
  test_files:
193
220
  - spec/analyzer_spec.rb
221
+ - spec/cli_spec.rb
194
222
  - spec/fixtures/eg_class.rb
195
223
  - spec/fixtures/eg_mod_class.rb
196
224
  - spec/fixtures/eg_mod_class_2.rb
197
225
  - spec/fixtures/eg_module.rb
226
+ - spec/fixtures/multiple_methods.rb
227
+ - spec/fixtures/nested_methods.rb
198
228
  - spec/fixtures/program_1.rb
199
229
  - spec/fixtures/program_2.rb
200
230
  - spec/fixtures/program_3.rb
201
231
  - spec/fixtures/program_4.rb
232
+ - spec/fixtures/single_class.rb
233
+ - spec/fixtures/single_method.rb
234
+ - spec/formatters/base_spec.rb
235
+ - spec/formatters/csv_spec.rb
236
+ - spec/formatters/html_index_spec.rb
237
+ - spec/formatters/html_spec.rb
238
+ - spec/formatters/text_spec.rb
239
+ - spec/parsed_file_spec.rb
240
+ - spec/parsed_method_spec.rb
202
241
  - spec/spec_helper.rb