count_von_count 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +39 -0
- data/README.md +48 -0
- data/Rakefile +5 -0
- data/bin/count_von_count +3 -0
- data/count_von_count.gemspec +29 -0
- data/lib/count_von_count/cli.rb +44 -0
- data/lib/count_von_count/counter.rb +60 -0
- data/lib/count_von_count/formatter.rb +84 -0
- data/lib/count_von_count/stat.rb +115 -0
- data/lib/count_von_count/version.rb +3 -0
- data/lib/count_von_count.rb +40 -0
- data/spec/counter_spec.rb +57 -0
- data/spec/fixture/app/controllers/test_controller.rb +7 -0
- data/spec/fixture/app/models/foo.rb +2 -0
- data/spec/fixture/app/models/test.rb +11 -0
- data/spec/fixture/js/test.js +12 -0
- data/spec/fixture/test.rb +26 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/stat_spec.rb +72 -0
- metadata +164 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5331c0ef8cfb1d8c62ff892e0b7550a28feb0ceb
|
4
|
+
data.tar.gz: 4c92fe24c97ab6968d43543720680a0367ae0f34
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bf51c9b84c749649c8efa7ca0b54c66ca990ebaa43f9662d166c1dedc8c47a7aafc9bb4992f27a969e52b57102f48c1189d23a8b39a01228ab8a3c8a7fc701da
|
7
|
+
data.tar.gz: 5517603051d82ae5ee683daf60910bcf9cecd4aaf4c10ede3045fc5cae7755a56aca681bbe5bce678c5f0c579fb64355bba2311135097a573a8d3ee5e012f79e
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
count_von_count (0.0.1)
|
5
|
+
terminal-table
|
6
|
+
thor
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
coderay (1.1.0)
|
12
|
+
docile (1.1.5)
|
13
|
+
method_source (0.8.2)
|
14
|
+
multi_json (1.10.1)
|
15
|
+
pry (0.10.1)
|
16
|
+
coderay (~> 1.1.0)
|
17
|
+
method_source (~> 0.8.1)
|
18
|
+
slop (~> 3.4)
|
19
|
+
rake (10.4.2)
|
20
|
+
rs (35)
|
21
|
+
simplecov (0.9.1)
|
22
|
+
docile (~> 1.1.0)
|
23
|
+
multi_json (~> 1.0)
|
24
|
+
simplecov-html (~> 0.8.0)
|
25
|
+
simplecov-html (0.8.0)
|
26
|
+
slop (3.6.0)
|
27
|
+
terminal-table (1.4.5)
|
28
|
+
thor (0.19.1)
|
29
|
+
|
30
|
+
PLATFORMS
|
31
|
+
ruby
|
32
|
+
|
33
|
+
DEPENDENCIES
|
34
|
+
bundler (~> 1.6)
|
35
|
+
count_von_count!
|
36
|
+
pry
|
37
|
+
rake
|
38
|
+
rs
|
39
|
+
simplecov
|
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#Count Von Count
|
2
|
+
|
3
|
+
![The Count](http://img2.wikia.nocookie.net/__cb20060205225316/muppet/images/3/3c/CT-p0001-ST.jpg)
|
4
|
+
|
5
|
+
1! 2! 3! Ah Ah Ah
|
6
|
+
|
7
|
+
Count your lines of code and love it
|
8
|
+
|
9
|
+
## What it is
|
10
|
+
`rake stats` and other similiar line counters are rails specific, this counts lines based on a given glob
|
11
|
+
and support proper counting for ruby, js, and coffee
|
12
|
+
|
13
|
+
It supports mutliple output formats including json and yaml.
|
14
|
+
|
15
|
+
### To Install
|
16
|
+
```
|
17
|
+
gem install count_von_count
|
18
|
+
```
|
19
|
+
|
20
|
+
Or Gemfile, or whatever
|
21
|
+
|
22
|
+
### Docs
|
23
|
+
|
24
|
+
```Bash
|
25
|
+
count_von_count count /path/to/dir
|
26
|
+
#or
|
27
|
+
cd /path/to/dir
|
28
|
+
count_von_count
|
29
|
+
```
|
30
|
+
|
31
|
+
#### Options
|
32
|
+
By default, when you point to a project, it will count all the code in default set of directories:
|
33
|
+
|
34
|
+
- app/\*\*/\*.rb
|
35
|
+
- lib/\*\*/\*.rb
|
36
|
+
|
37
|
+
And tests in:
|
38
|
+
|
39
|
+
- spec/\*\*/\*\_spec.rb
|
40
|
+
|
41
|
+
If you don't want to include these paths, you can pass `--no_default` and add a list of custom paths
|
42
|
+
using `-c` for code paths and `-t` for test paths. These paths are given relative to the project
|
43
|
+
directory.
|
44
|
+
|
45
|
+
If you want to output in a different format other than text, pass `-f {yaml,json}` to get what you want.
|
46
|
+
|
47
|
+
If you want to write the files out to a directory (instead of stdout), pass `-o` with a path and
|
48
|
+
it will end up in a file called results.txt (or whatever format you choose)
|
data/Rakefile
ADDED
data/bin/count_von_count
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'count_von_count/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "count_von_count"
|
7
|
+
s.version = CountVonCount::VERSION
|
8
|
+
s.authors = ["Addison Higham"]
|
9
|
+
s.email = "ahigham@instructure.com"
|
10
|
+
s.homepage = "http://github.com/addisonj/count_von_count"
|
11
|
+
s.summary = "Count lines of code and report it"
|
12
|
+
s.description = "Count lines of code with granularity and output it various formats"
|
13
|
+
s.required_rubygems_version = ">= 1.3.6"
|
14
|
+
s.files = `git ls-files -z`.split("\x0")
|
15
|
+
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
|
19
|
+
s.add_dependency 'thor'
|
20
|
+
s.add_dependency 'terminal-table'
|
21
|
+
|
22
|
+
s.add_development_dependency "bundler", "~> 1.6"
|
23
|
+
s.add_development_dependency "rake"
|
24
|
+
s.add_development_dependency "pry"
|
25
|
+
s.add_development_dependency "rs"
|
26
|
+
s.add_development_dependency "simplecov"
|
27
|
+
|
28
|
+
s.license = 'MIT'
|
29
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'count_von_count'
|
3
|
+
|
4
|
+
module CountVonCount
|
5
|
+
|
6
|
+
class CLI < Thor
|
7
|
+
|
8
|
+
desc "count PATH", "count the number of lines of code"
|
9
|
+
long_desc <<-DESC
|
10
|
+
By default, when you point to a project, it will count all the code in default set of directories:
|
11
|
+
|
12
|
+
- app/**/*.rb
|
13
|
+
|
14
|
+
- lib/**/*.rb
|
15
|
+
|
16
|
+
And tests in:
|
17
|
+
|
18
|
+
- spec/**/*_spec.rb
|
19
|
+
|
20
|
+
If you don't want to include these paths, you can pass --no_default and add a list of custom paths
|
21
|
+
using `-c` for code paths and `-t` for test paths. These paths are given relative to the project
|
22
|
+
directory.
|
23
|
+
|
24
|
+
If you want to output in a different format other than text, pass `-f {yaml,json}` to get what you want.
|
25
|
+
|
26
|
+
If you want to write the files out to a directory (instead of stdout), pass -o with a path and
|
27
|
+
it will end up in a file called results.txt (or whatever format you choose)
|
28
|
+
|
29
|
+
DESC
|
30
|
+
|
31
|
+
option :code, type: :array, aliases: :c, desc: "A list of relative code paths to include"
|
32
|
+
option :test, type: :array, aliases: :t, desc: "A list of relative test paths to include"
|
33
|
+
option :no_default, type: :boolean, aliases: :n, desc: "Don't include default paths", default: false
|
34
|
+
option :format, type: :string, aliases: :f, desc: "The format to output to, valid are yaml,json,txt", default: :txt
|
35
|
+
option :outout, type: :string, aliases: :o, desc: "A directory to write the results to"
|
36
|
+
|
37
|
+
def count(path=Dir.pwd)
|
38
|
+
CountVonCount.new(path, options[:code], options[:test], options[:no_default], options[:format].to_sym, options[:output]).run
|
39
|
+
end
|
40
|
+
|
41
|
+
default_task :count
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module CountVonCount
|
2
|
+
|
3
|
+
class Counter
|
4
|
+
attr_accessor :path, :code_paths, :test_paths, :formatter
|
5
|
+
|
6
|
+
def initialize(path, code_paths, test_paths, formatter)
|
7
|
+
@path = path
|
8
|
+
@formatter = formatter
|
9
|
+
@code_paths = expand_globs(code_paths)
|
10
|
+
raise "No files found in globs" if @code_paths.empty?
|
11
|
+
@test_paths = expand_globs(test_paths)
|
12
|
+
end
|
13
|
+
|
14
|
+
def expand_globs(globs)
|
15
|
+
Dir.chdir(@path) do
|
16
|
+
globs.flat_map do |g|
|
17
|
+
Pathname.glob(g).reject{|f| f.directory? }.map(&:realpath)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def run
|
23
|
+
results = {}
|
24
|
+
results[:code] = process_files(code_paths)
|
25
|
+
results[:tests] = process_files(test_paths) unless test_paths.empty?
|
26
|
+
formatter.write_output(results)
|
27
|
+
end
|
28
|
+
|
29
|
+
def process_files(files)
|
30
|
+
files_by_dir = files.group_by(&:dirname)
|
31
|
+
all_stats = []
|
32
|
+
by_dir = {}
|
33
|
+
by_file = {}
|
34
|
+
files_by_dir.each do |dir, dir_files|
|
35
|
+
stats_for_dir = []
|
36
|
+
dir_files.each do |file|
|
37
|
+
stat = Stat.new
|
38
|
+
stat.process(file)
|
39
|
+
unless stat.empty?
|
40
|
+
by_file[rel_path(file)] = stat.to_h
|
41
|
+
stats_for_dir.push(stat)
|
42
|
+
all_stats.push(stat)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
dir_sum = Stat.sum(stats_for_dir)
|
46
|
+
by_dir[rel_path(dir)] = dir_sum.to_h unless dir_sum.empty?
|
47
|
+
end
|
48
|
+
total = Stat.sum(all_stats).to_h
|
49
|
+
{total: total, by_dir: sort_by_loc(by_dir), by_file: sort_by_loc(by_file)}
|
50
|
+
end
|
51
|
+
|
52
|
+
def sort_by_loc(hash)
|
53
|
+
hash.sort_by { |_k, stat| stat[:loc] }.reverse.to_h
|
54
|
+
end
|
55
|
+
|
56
|
+
def rel_path(p)
|
57
|
+
Pathname.new(p).relative_path_from(@path).to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "yaml"
|
2
|
+
require "json"
|
3
|
+
require "terminal-table"
|
4
|
+
module CountVonCount
|
5
|
+
module Formatters
|
6
|
+
class Base
|
7
|
+
attr_reader :path
|
8
|
+
attr_reader :output_dir
|
9
|
+
def initialize(path, output = nil)
|
10
|
+
@path = path
|
11
|
+
@output_dir = output
|
12
|
+
end
|
13
|
+
|
14
|
+
def write_output(countObj)
|
15
|
+
formatted = serialize(countObj)
|
16
|
+
if output_dir
|
17
|
+
write_file(formatted)
|
18
|
+
else
|
19
|
+
write_stdout(formatted)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def write_file(formatted)
|
25
|
+
output_file = path.join(output_dir).join("results.#{extension}")
|
26
|
+
output_file.open("w") do |f|
|
27
|
+
f << formatted
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def write_stdout(formatted)
|
32
|
+
puts formatted
|
33
|
+
end
|
34
|
+
|
35
|
+
def extension
|
36
|
+
raise 'Must extend this method'
|
37
|
+
end
|
38
|
+
def serialize(countObj)
|
39
|
+
raise 'Must extend this method'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
class Text < Base
|
43
|
+
def extension
|
44
|
+
"txt"
|
45
|
+
end
|
46
|
+
def serialize(countObj)
|
47
|
+
output = build_table("Code", countObj[:code]).to_s
|
48
|
+
output += "\n\n"
|
49
|
+
output += build_table("Tests", countObj[:tests]).to_s
|
50
|
+
output
|
51
|
+
end
|
52
|
+
def build_table(name, countObj)
|
53
|
+
head = [""] + countObj[:total].keys.map(&:to_s)
|
54
|
+
rows = []
|
55
|
+
rows << ["total"] + countObj[:total].values
|
56
|
+
rows << :separator
|
57
|
+
rows << [{value: "By Dir", colspan: 7, align: :center}]
|
58
|
+
rows << :separator
|
59
|
+
rows.push *countObj[:by_dir].map{ |d, v| [d] + v.values }
|
60
|
+
rows << :separator
|
61
|
+
rows << [{value: "By File", colspan: 7, align: :center}]
|
62
|
+
rows << :separator
|
63
|
+
rows.push *countObj[:by_file].map{ |f, v| [f] + v.values }
|
64
|
+
Terminal::Table.new title: name, headings: head, rows: rows
|
65
|
+
end
|
66
|
+
end
|
67
|
+
class Json < Base
|
68
|
+
def extension
|
69
|
+
"json"
|
70
|
+
end
|
71
|
+
def serialize(countObj)
|
72
|
+
countObj.to_json
|
73
|
+
end
|
74
|
+
end
|
75
|
+
class Yaml < Base
|
76
|
+
def extension
|
77
|
+
"yaml"
|
78
|
+
end
|
79
|
+
def serialize(countObj)
|
80
|
+
countObj.to_yaml
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module CountVonCount
|
2
|
+
class Stat
|
3
|
+
PATTERNS = {
|
4
|
+
rb: {
|
5
|
+
line_comment: /^\s*#/,
|
6
|
+
begin_block_comment: /^=begin/,
|
7
|
+
end_block_comment: /^=end/,
|
8
|
+
class: /^\s*class\s+[_A-Z]/,
|
9
|
+
module: /^\s*module\s+[_A-Z]/,
|
10
|
+
method: /^\s*def\s+[_a-z]/,
|
11
|
+
},
|
12
|
+
js: {
|
13
|
+
line_comment: %r{^\s*//},
|
14
|
+
begin_block_comment: %r{^\s*/\*},
|
15
|
+
end_block_comment: %r{\*/},
|
16
|
+
method: /function(\s+[_a-zA-Z][\da-zA-Z]*)?\s*\(/,
|
17
|
+
},
|
18
|
+
coffee: {
|
19
|
+
line_comment: /^\s*#/,
|
20
|
+
begin_block_comment: /^\s*###/,
|
21
|
+
end_block_comment: /^\s*###/,
|
22
|
+
class: /^\s*class\s+[_A-Z]/,
|
23
|
+
method: /[-=]>/,
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
def self.get_pattern(type)
|
28
|
+
return PATTERNS[type]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.sum(stats)
|
32
|
+
stats.reduce(Stat.new) do |prev, val|
|
33
|
+
prev + val
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
VALS = %i(all loc methods modules classes comments)
|
38
|
+
attr_accessor *VALS
|
39
|
+
def initialize(all = 0, loc = 0, methods = 0, modules = 0, classes = 0, comments = 0)
|
40
|
+
@all = all
|
41
|
+
@loc = loc
|
42
|
+
@methods = methods
|
43
|
+
@modules = modules
|
44
|
+
@classes = classes
|
45
|
+
@comments = comments
|
46
|
+
end
|
47
|
+
|
48
|
+
def + (other)
|
49
|
+
r = self.class.new
|
50
|
+
VALS.each do |v|
|
51
|
+
r.send("#{v.to_s}=", (self.send(v) + other.send(v)))
|
52
|
+
end
|
53
|
+
r
|
54
|
+
end
|
55
|
+
|
56
|
+
def == (other)
|
57
|
+
VALS.each do |v|
|
58
|
+
return false if self.send(v) != other.send(v)
|
59
|
+
end
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def process(file)
|
64
|
+
File.open(file) do |io|
|
65
|
+
ft = file_type(file)
|
66
|
+
patterns = PATTERNS[ft] || {}
|
67
|
+
process_io(io, patterns)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def process_io(io, patterns)
|
72
|
+
comment_started = false
|
73
|
+
|
74
|
+
while line = io.gets
|
75
|
+
@all += 1
|
76
|
+
|
77
|
+
if comment_started
|
78
|
+
@comments += 1
|
79
|
+
if patterns[:end_block_comment] && line =~ patterns[:end_block_comment]
|
80
|
+
comment_started = false
|
81
|
+
end
|
82
|
+
next
|
83
|
+
else
|
84
|
+
if patterns[:begin_block_comment] && line =~ patterns[:begin_block_comment]
|
85
|
+
@comments += 1
|
86
|
+
comment_started = true
|
87
|
+
next
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
@classes += 1 if patterns[:class] && line =~ patterns[:class]
|
92
|
+
@methods += 1 if patterns[:method] && line =~ patterns[:method]
|
93
|
+
@modules += 1 if patterns[:module] && line =~ patterns[:module]
|
94
|
+
if (patterns[:line_comment] && line =~ patterns[:line_comment])
|
95
|
+
@comments += 1
|
96
|
+
elsif line !~ /^\s*$/
|
97
|
+
@loc += 1
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
def to_h
|
104
|
+
{all: all, loc: loc, methods: methods, modules: modules, classes: classes, comments: comments}
|
105
|
+
end
|
106
|
+
|
107
|
+
def file_type(file_path)
|
108
|
+
File.extname(file_path).sub(/\A\./, '').downcase.to_sym
|
109
|
+
end
|
110
|
+
|
111
|
+
def empty?
|
112
|
+
loc == 0
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require_relative "count_von_count/counter"
|
3
|
+
require_relative "count_von_count/stat"
|
4
|
+
require_relative "count_von_count/formatter"
|
5
|
+
module CountVonCount
|
6
|
+
def self.new(path, code_paths=nil, test_paths=nil, no_default=false, format=:txt, output = nil)
|
7
|
+
code_paths = code_paths || []
|
8
|
+
test_paths = test_paths || []
|
9
|
+
path = Pathname.new(path).realpath
|
10
|
+
unless no_default
|
11
|
+
code_paths = default_code_paths + code_paths
|
12
|
+
test_paths = default_test_paths + test_paths
|
13
|
+
end
|
14
|
+
raise "No code paths given" if code_paths.empty?
|
15
|
+
|
16
|
+
formatter = formatters[format].new(path, output)
|
17
|
+
CountVonCount::Counter.new(path, code_paths, test_paths, formatter)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.default_code_paths
|
21
|
+
return [
|
22
|
+
"app/**/*.rb",
|
23
|
+
"lib/**/*.rb"
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.default_test_paths
|
28
|
+
return [
|
29
|
+
"spec/**/*_spec.rb"
|
30
|
+
]
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.formatters
|
34
|
+
{
|
35
|
+
txt: CountVonCount::Formatters::Text,
|
36
|
+
json: CountVonCount::Formatters::Json,
|
37
|
+
yaml: CountVonCount::Formatters::Yaml
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
def fp(p)
|
4
|
+
Pathname.new(fixture_path).join(p)
|
5
|
+
end
|
6
|
+
describe CountVonCount::Counter do
|
7
|
+
let(:formatter) do
|
8
|
+
MockFormatter.new
|
9
|
+
end
|
10
|
+
let(:code_glob) do
|
11
|
+
["app/**/*.rb"]
|
12
|
+
end
|
13
|
+
let(:counter) do
|
14
|
+
return CountVonCount::Counter.new(fixture_path, code_glob, [], formatter)
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:counter_test) do
|
18
|
+
return CountVonCount::Counter.new(fixture_path, code_glob, code_glob, formatter)
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "#expand_globs" do
|
22
|
+
it "should expand the list of files to include the ones we expect" do
|
23
|
+
expect(counter.expand_globs(code_glob)).to eq [fp("app/controllers/test_controller.rb"), fp("app/models/foo.rb"), fp("app/models/test.rb")]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#run" do
|
28
|
+
it "should try to output a hash in the format we expect" do
|
29
|
+
allow(formatter).to receive(:write_output) do |output|
|
30
|
+
%i(total by_dir by_file).each do |k|
|
31
|
+
expect(output[:code]).to have_key(k)
|
32
|
+
end
|
33
|
+
%w(app/models app/controllers).each do |d|
|
34
|
+
expect(output[:code][:by_dir]).to have_key(d)
|
35
|
+
end
|
36
|
+
%w(app/models/test.rb app/models/test.rb app/controllers/test_controller.rb).each do |d|
|
37
|
+
expect(output[:code][:by_file]).to have_key(d)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
counter.run
|
41
|
+
end
|
42
|
+
|
43
|
+
it "shouldn't have a test section if no tests" do
|
44
|
+
allow(formatter).to receive(:write_output) do |output|
|
45
|
+
expect(output[:test]).to be_nil
|
46
|
+
end
|
47
|
+
counter.run
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should have a test section if there are tests" do
|
51
|
+
allow(formatter).to receive(:write_output) do |output|
|
52
|
+
expect(output[:tests]).to be_truthy
|
53
|
+
end
|
54
|
+
counter_test.run
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module FooModule
|
2
|
+
class FooClass
|
3
|
+
def one
|
4
|
+
x = 4 + 2
|
5
|
+
y = 6 + 8
|
6
|
+
end
|
7
|
+
def two
|
8
|
+
end
|
9
|
+
# one comment
|
10
|
+
# another comment
|
11
|
+
# def a_comment
|
12
|
+
|
13
|
+
STUFF = 'foo'
|
14
|
+
|
15
|
+
=begin
|
16
|
+
4
|
17
|
+
lines here
|
18
|
+
=end
|
19
|
+
|
20
|
+
class SubClass
|
21
|
+
def stuff
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
SimpleCov.start
|
4
|
+
|
5
|
+
def fixture_path
|
6
|
+
Pathname.new(__FILE__).dirname.join("./fixture").realpath
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'rspec'
|
11
|
+
require 'count_von_count'
|
12
|
+
|
13
|
+
class MockFormatter < CountVonCount::Formatters::Base
|
14
|
+
def initialize
|
15
|
+
end
|
16
|
+
def write_output(obj)
|
17
|
+
end
|
18
|
+
end
|
data/spec/stat_spec.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
Stat = CountVonCount::Stat
|
4
|
+
|
5
|
+
def stat_num(n)
|
6
|
+
Stat.new(*Array.new(6, n))
|
7
|
+
end
|
8
|
+
|
9
|
+
CONTENTS = <<-CON
|
10
|
+
module Thing
|
11
|
+
class Foo
|
12
|
+
# comment
|
13
|
+
def stuff
|
14
|
+
end
|
15
|
+
def other
|
16
|
+
4 + 4
|
17
|
+
end
|
18
|
+
=begin
|
19
|
+
one
|
20
|
+
two
|
21
|
+
=end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
CON
|
26
|
+
|
27
|
+
describe Stat do
|
28
|
+
let(:stat) do
|
29
|
+
return Stat.new
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#initialize" do
|
33
|
+
it "should initiliaze to empty values" do
|
34
|
+
%i(all loc methods modules classes comments).each do |val|
|
35
|
+
expect(stat.send(val)).to eq(0)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#+" do
|
41
|
+
it "should add together two stats to create a new stat" do
|
42
|
+
expect(stat_num(1) + stat_num(2)).to eq(stat_num(3))
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "::sum" do
|
47
|
+
it "should sum an array of stats" do
|
48
|
+
stats = (1..4).map{ |n| stat_num(n) }
|
49
|
+
sum = (1..4).reduce(:+)
|
50
|
+
expect(Stat.sum(stats)).to eq(stat_num(sum))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#parse_by_io" do
|
55
|
+
it "should parse a file and updates its numbers" do
|
56
|
+
vals = {
|
57
|
+
all: 15,
|
58
|
+
loc: 9,
|
59
|
+
methods: 2,
|
60
|
+
modules: 1,
|
61
|
+
classes: 1,
|
62
|
+
comments: 5
|
63
|
+
}
|
64
|
+
|
65
|
+
stat.process_io(StringIO.new(CONTENTS), Stat.get_pattern(:rb))
|
66
|
+
vals.each do |k, v|
|
67
|
+
expect(stat.send(k)).to eq(v), "expect #{k} to equal #{v} got #{stat.send(k)}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
metadata
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: count_von_count
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Addison Higham
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-18 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: terminal-table
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.6'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: pry
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rs
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: simplecov
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: Count lines of code with granularity and output it various formats
|
112
|
+
email: ahigham@instructure.com
|
113
|
+
executables:
|
114
|
+
- count_von_count
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".gitignore"
|
119
|
+
- Gemfile
|
120
|
+
- Gemfile.lock
|
121
|
+
- README.md
|
122
|
+
- Rakefile
|
123
|
+
- bin/count_von_count
|
124
|
+
- count_von_count.gemspec
|
125
|
+
- lib/count_von_count.rb
|
126
|
+
- lib/count_von_count/cli.rb
|
127
|
+
- lib/count_von_count/counter.rb
|
128
|
+
- lib/count_von_count/formatter.rb
|
129
|
+
- lib/count_von_count/stat.rb
|
130
|
+
- lib/count_von_count/version.rb
|
131
|
+
- spec/counter_spec.rb
|
132
|
+
- spec/fixture/app/controllers/test_controller.rb
|
133
|
+
- spec/fixture/app/models/foo.rb
|
134
|
+
- spec/fixture/app/models/test.rb
|
135
|
+
- spec/fixture/js/test.js
|
136
|
+
- spec/fixture/test.rb
|
137
|
+
- spec/spec_helper.rb
|
138
|
+
- spec/stat_spec.rb
|
139
|
+
homepage: http://github.com/addisonj/count_von_count
|
140
|
+
licenses:
|
141
|
+
- MIT
|
142
|
+
metadata: {}
|
143
|
+
post_install_message:
|
144
|
+
rdoc_options: []
|
145
|
+
require_paths:
|
146
|
+
- lib
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: 1.3.6
|
157
|
+
requirements: []
|
158
|
+
rubyforge_project:
|
159
|
+
rubygems_version: 2.2.2
|
160
|
+
signing_key:
|
161
|
+
specification_version: 4
|
162
|
+
summary: Count lines of code and report it
|
163
|
+
test_files: []
|
164
|
+
has_rdoc:
|