fukuzatsu 0.9.13 → 0.9.14

Sign up to get free protection for your applications and to get access to all the features.
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