count_von_count 0.0.1
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 +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
|
+

|
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:
|