git_statistics 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/CHANGELOG.md +1 -0
- data/lib/git_statistics.rb +22 -19
- data/lib/git_statistics/collector.rb +11 -4
- data/lib/git_statistics/commits.rb +64 -24
- data/lib/git_statistics/results.rb +4 -4
- data/lib/git_statistics/utilities.rb +13 -2
- data/lib/git_statistics/version.rb +1 -1
- data/spec/collector_spec.rb +101 -114
- data/spec/commits_spec.rb +222 -171
- data/spec/results_spec.rb +113 -89
- data/spec/spec_helper.rb +6 -0
- data/spec/utilities_spec.rb +97 -55
- metadata +2 -2
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
* [0.4.0 - September 25, 2012](https://github.com/kevinjalbert/git_statistics/compare/v0.3.0...v0.4.0)
|
3
4
|
* [0.3.0 - September 12, 2012](https://github.com/kevinjalbert/git_statistics/compare/v0.2.0...v0.3.0)
|
4
5
|
* [0.2.0 - September 6, 2012](https://github.com/kevinjalbert/git_statistics/compare/v0.1.2...v0.2.0)
|
5
6
|
* [0.1.2 - April 12, 2012](https://github.com/kevinjalbert/git_statistics/compare/v0.1.1...v0.1.2)
|
data/lib/git_statistics.rb
CHANGED
@@ -6,38 +6,40 @@ module GitStatistics
|
|
6
6
|
@opts = Trollop::options do
|
7
7
|
opt :email, "Use author's email instead of name", :default => false
|
8
8
|
opt :merges, "Factor in merges when calculating statistics", :default => false
|
9
|
-
opt :
|
10
|
-
opt :
|
11
|
-
opt :load, "Load commits.json instead of re-collecting data", :default => false
|
12
|
-
opt :update, "Update commits.json with new data (same as save and load together)", :default => false
|
9
|
+
opt :pretty, "Save the commits in git_repo/.git_statistics in pretty print (larger file size)", :default => false
|
10
|
+
opt :update, "Update saved commits with new data", :default => false
|
13
11
|
opt :sort, "Sort authors by {commits, additions, deletions, create, delete, rename, copy, merges}", :default => "commits"
|
14
12
|
opt :top, "Show the top N authors in results", :default => 0
|
15
13
|
opt :branch, "Use current branch for statistics (otherwise all branches)", :default => false
|
16
14
|
opt :verbose, "Verbose output (shows progress)", :default => false
|
15
|
+
opt :limit, "The maximum limit of commits to hold in memory at a time", :default => 100
|
17
16
|
end
|
18
17
|
end
|
19
18
|
|
20
19
|
def execute
|
21
|
-
|
22
|
-
|
23
|
-
# Collect commit data
|
24
|
-
if @opts[:load] || @opts[:update]
|
25
|
-
collector.commits.load("commits.json")
|
26
|
-
else
|
27
|
-
collector.collect(@opts[:branch])
|
28
|
-
end
|
29
|
-
|
30
|
-
# Collect incremental recent data
|
20
|
+
# Collect data (incremental or fresh) based on presence of old data
|
31
21
|
if @opts[:update]
|
32
|
-
|
33
|
-
collector.
|
22
|
+
# Ensure commit directory is present
|
23
|
+
collector = Collector.new(@opts[:verbose], @opts[:limit], false, @opts[:pretty])
|
24
|
+
commits_directory = collector.repo_path + ".git_statistics" + File::Separator
|
25
|
+
FileUtils.mkdir_p(commits_directory)
|
26
|
+
file_count = Utilities.get_number_of_files(commits_directory, /\d+\.json/) - 1
|
27
|
+
|
28
|
+
# Only use --since if there is data present
|
29
|
+
if file_count >= 0
|
30
|
+
time = Utilities.get_modified_time(commits_directory + "#{file_count}.json")
|
31
|
+
collector.collect(@opts[:branch], "--since=\"#{time}\"")
|
32
|
+
collected = true
|
33
|
+
end
|
34
34
|
end
|
35
35
|
|
36
|
-
#
|
37
|
-
if
|
38
|
-
collector.
|
36
|
+
# If no data was collected as there was no present data then start fresh
|
37
|
+
if !collected
|
38
|
+
collector = Collector.new(@opts[:verbose], @opts[:limit], true, @opts[:pretty])
|
39
|
+
collector.collect(@opts[:branch])
|
39
40
|
end
|
40
41
|
|
42
|
+
# Calculate statistics
|
41
43
|
collector.commits.calculate_statistics(@opts[:email], @opts[:merges])
|
42
44
|
|
43
45
|
# Print results
|
@@ -45,4 +47,5 @@ module GitStatistics
|
|
45
47
|
puts results.print_summary(@opts[:sort], @opts[:email], @opts[:top])
|
46
48
|
end
|
47
49
|
end
|
50
|
+
|
48
51
|
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
module GitStatistics
|
2
2
|
class Collector
|
3
3
|
|
4
|
-
attr_accessor :commits, :verbose
|
4
|
+
attr_accessor :repo, :repo_path, :commits_path, :commits, :verbose
|
5
5
|
|
6
|
-
def initialize(verbose)
|
7
|
-
@commits = Commits.new
|
6
|
+
def initialize(verbose, limit, fresh, pretty)
|
8
7
|
@verbose = verbose
|
9
8
|
@repo = Utilities.get_repository
|
10
9
|
|
@@ -12,6 +11,10 @@ module GitStatistics
|
|
12
11
|
if @repo == nil
|
13
12
|
raise ("No git Repository Found")
|
14
13
|
end
|
14
|
+
|
15
|
+
@repo_path = File.expand_path("..", @repo.path) + File::Separator
|
16
|
+
@commits_path = @repo_path + ".git_statistics" + File::Separator
|
17
|
+
@commits = Commits.new(@commits_path, fresh, limit, pretty)
|
15
18
|
end
|
16
19
|
|
17
20
|
def collect(branch, time_since="", time_until="")
|
@@ -42,6 +45,10 @@ module GitStatistics
|
|
42
45
|
|
43
46
|
extract_commit(buffer) if not buffer.empty?
|
44
47
|
buffer = []
|
48
|
+
|
49
|
+
# Save commits to file if size exceeds limit or forced
|
50
|
+
@commits.flush_commits
|
51
|
+
@repo = Utilities.get_repository
|
45
52
|
end
|
46
53
|
|
47
54
|
buffer << line
|
@@ -49,10 +56,10 @@ module GitStatistics
|
|
49
56
|
|
50
57
|
# Extract the last commit
|
51
58
|
extract_commit(buffer) if not buffer.empty?
|
59
|
+
@commits.flush_commits(true)
|
52
60
|
end
|
53
61
|
|
54
62
|
def fall_back_collect_commit(sha)
|
55
|
-
|
56
63
|
# Create pipe for the git log to acquire commits
|
57
64
|
pipe = open("|git --no-pager show #{sha} --date=iso --reverse"\
|
58
65
|
" --no-color --find-copies-harder --numstat --encoding=utf-8 "\
|
@@ -1,17 +1,43 @@
|
|
1
1
|
module GitStatistics
|
2
2
|
class Commits < Hash
|
3
3
|
|
4
|
-
attr_accessor :stats, :
|
4
|
+
attr_accessor :stats, :totals, :path, :fresh, :limit, :pretty
|
5
|
+
|
6
|
+
def initialize(path, fresh, limit, pretty)
|
7
|
+
super()
|
8
|
+
@path = path
|
9
|
+
@fresh = fresh
|
10
|
+
@limit = limit
|
11
|
+
@pretty = pretty
|
12
|
+
clean
|
13
|
+
end
|
14
|
+
|
15
|
+
def clean
|
16
|
+
# Ensure the path exists
|
17
|
+
FileUtils.mkdir_p(@path)
|
18
|
+
|
19
|
+
# Remove all files within path if saving
|
20
|
+
if @fresh
|
21
|
+
Dir.entries(@path).each do |file|
|
22
|
+
next if file == "." || file == ".."
|
23
|
+
File.delete(path + File::Separator + file)
|
24
|
+
end
|
25
|
+
end
|
5
26
|
|
6
|
-
|
7
|
-
|
8
|
-
@stats = Hash.new(0)
|
9
|
-
@author_list = []
|
10
|
-
@language_list = []
|
27
|
+
# Initilize/resets stats and totals
|
28
|
+
@stats = Hash.new
|
11
29
|
@totals = Hash.new(0)
|
12
30
|
@totals[:languages] = {}
|
13
31
|
end
|
14
32
|
|
33
|
+
def flush_commits(force=false)
|
34
|
+
if self.size >= limit || force
|
35
|
+
file_count = Utilities.get_number_of_files(path, /\d+\.json/)
|
36
|
+
save(path + File::Separator + file_count.to_s + ".json", @pretty)
|
37
|
+
self.clear
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
15
41
|
def author_top_n_type(type, top_n=0)
|
16
42
|
top_n = 0 if top_n < 0
|
17
43
|
return nil if @stats.size == 0
|
@@ -20,34 +46,42 @@ module GitStatistics
|
|
20
46
|
end
|
21
47
|
|
22
48
|
def calculate_statistics(email, merge)
|
23
|
-
|
24
|
-
# Check that there are statistics to calculate
|
25
|
-
if self.size == 0
|
26
|
-
puts "Cannot calculate statistics as there is no data"
|
27
|
-
return
|
28
|
-
end
|
29
|
-
|
30
49
|
# Identify authors and author type
|
31
50
|
if email
|
32
51
|
type = :author_email
|
33
52
|
else
|
34
53
|
type = :author
|
35
54
|
end
|
36
|
-
@author_list = Utilities.unique_data_in_hash(self, type)
|
37
55
|
|
38
|
-
#
|
39
|
-
|
40
|
-
|
41
|
-
|
56
|
+
# For all the commit files created
|
57
|
+
Dir.entries(path).each do |file|
|
58
|
+
# Load commit file and extract the commits
|
59
|
+
if file =~ /\d+\.json/
|
60
|
+
load(path + File::Separator + file)
|
61
|
+
process_commits(type, merge)
|
62
|
+
self.clear
|
63
|
+
end
|
42
64
|
end
|
65
|
+
end
|
43
66
|
|
67
|
+
def process_commits(type, merge)
|
44
68
|
# Collect the stats from each commit
|
45
69
|
self.each do |key,value|
|
46
70
|
if !merge && value[:merge]
|
47
71
|
next
|
48
72
|
else
|
49
73
|
|
50
|
-
author
|
74
|
+
# Acquire author (make if not seen before)
|
75
|
+
author = @stats[value[type]]
|
76
|
+
|
77
|
+
if author == nil
|
78
|
+
@stats[value[type]] = Hash.new(0)
|
79
|
+
author = @stats[value[type]]
|
80
|
+
author[:languages] = {}
|
81
|
+
end
|
82
|
+
|
83
|
+
# If there are no changed files move to next commit
|
84
|
+
next if value[:files].size == 0
|
51
85
|
|
52
86
|
# Collect language stats
|
53
87
|
value[:files].each do |file|
|
@@ -57,11 +91,6 @@ module GitStatistics
|
|
57
91
|
|
58
92
|
# Add to repository's languages
|
59
93
|
add_language_stats(@totals, file)
|
60
|
-
|
61
|
-
# Add language to language list if not encountered before
|
62
|
-
if not @language_list.include?(file[:language])
|
63
|
-
@language_list << file[:language]
|
64
|
-
end
|
65
94
|
end
|
66
95
|
|
67
96
|
# Add commit stats to author
|
@@ -69,6 +98,10 @@ module GitStatistics
|
|
69
98
|
|
70
99
|
# Add commit stats to repository
|
71
100
|
add_commit_stats(@totals, value)
|
101
|
+
|
102
|
+
# Save new changes back to stats
|
103
|
+
@stats[value[type]] = author
|
104
|
+
author = nil
|
72
105
|
end
|
73
106
|
end
|
74
107
|
end
|
@@ -107,6 +140,13 @@ module GitStatistics
|
|
107
140
|
end
|
108
141
|
|
109
142
|
def save(file, pretty)
|
143
|
+
# Don't save if there is no information (i.e., using updates)
|
144
|
+
return if self.size == 0
|
145
|
+
|
146
|
+
# Ensure the path to the file exists
|
147
|
+
FileUtils.mkdir_p(File.dirname(file))
|
148
|
+
|
149
|
+
# Save file in a simple or pretty format
|
110
150
|
if pretty
|
111
151
|
File.open(file, 'w') {|file| file.write(JSON.pretty_generate(self))}
|
112
152
|
else
|
@@ -11,7 +11,7 @@ module GitStatistics
|
|
11
11
|
# Default to a 0 if given a negative number to display
|
12
12
|
top_n = 0 if top_n < 0
|
13
13
|
|
14
|
-
# Acquire data based on
|
14
|
+
# Acquire data based on sort type and top # to show
|
15
15
|
data = @commits.author_top_n_type(sort.to_sym, top_n)
|
16
16
|
if data == nil
|
17
17
|
raise "Parameter for --sort is not valid"
|
@@ -19,8 +19,8 @@ module GitStatistics
|
|
19
19
|
|
20
20
|
# Create config
|
21
21
|
config = {:data => data,
|
22
|
-
:author_length => Utilities.find_longest_length(data, 17),
|
23
|
-
:language_length => Utilities.find_longest_length(@commits.
|
22
|
+
:author_length => Utilities.find_longest_length(data.keys, 17),
|
23
|
+
:language_length => Utilities.find_longest_length(@commits.totals[:languages].keys, 8),
|
24
24
|
:sort => sort,
|
25
25
|
:email => email,
|
26
26
|
:top_n => top_n}
|
@@ -72,7 +72,7 @@ module GitStatistics
|
|
72
72
|
end
|
73
73
|
|
74
74
|
def print_header(config)
|
75
|
-
total_authors = @commits.
|
75
|
+
total_authors = @commits.stats.size
|
76
76
|
|
77
77
|
output = ""
|
78
78
|
# Print summary information of displayed results
|
@@ -97,12 +97,23 @@ module GitStatistics
|
|
97
97
|
|
98
98
|
def self.get_modified_time(file)
|
99
99
|
if OS.mac?
|
100
|
-
Time.at(`stat -f %m
|
100
|
+
Time.at(`stat -f %m #{file}`.to_i)
|
101
101
|
elsif OS.linux?
|
102
|
-
Time.at(`stat -c %Y
|
102
|
+
Time.at(`stat -c %Y #{file}`.to_i)
|
103
103
|
else
|
104
104
|
raise "Update on the Windows operating system is not supported"
|
105
105
|
end
|
106
106
|
end
|
107
|
+
|
108
|
+
def self.get_number_of_files(directory, pattern)
|
109
|
+
count = 0
|
110
|
+
files = Dir.entries(directory)
|
111
|
+
|
112
|
+
files.each do |file|
|
113
|
+
count += 1 if file =~ pattern
|
114
|
+
end
|
115
|
+
|
116
|
+
return count
|
117
|
+
end
|
107
118
|
end
|
108
119
|
end
|
data/spec/collector_spec.rb
CHANGED
@@ -2,36 +2,41 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
include GitStatistics
|
3
3
|
|
4
4
|
describe Collector do
|
5
|
-
|
6
|
-
|
5
|
+
let(:verbose) {false}
|
6
|
+
let(:limit) {100}
|
7
|
+
let(:fresh) {true}
|
8
|
+
let(:pretty) {false}
|
9
|
+
let(:collector) {Collector.new(verbose, limit, fresh, pretty)}
|
7
10
|
|
8
11
|
describe "#collect_branches" do
|
12
|
+
let(:branches) {collector.collect_branches(fixture(fixture_file))}
|
13
|
+
|
9
14
|
context "with many branches" do
|
10
|
-
|
15
|
+
let(:fixture_file) {"git_many_branches.txt"}
|
11
16
|
it {branches.size.should == 2}
|
12
17
|
it {branches[0].should == "issue_2"}
|
13
18
|
it {branches[1].should == "master"}
|
14
19
|
end
|
15
20
|
|
16
21
|
context "with zero branches" do
|
17
|
-
|
22
|
+
let(:fixture_file) {"git_zero_branches.txt"}
|
18
23
|
it {branches.size.should == 1}
|
19
24
|
it {branches[0].should == "master"}
|
20
25
|
end
|
21
26
|
end
|
22
27
|
|
23
28
|
describe "#extract_change_file" do
|
29
|
+
let(:file) {collector.extract_change_file(line)}
|
30
|
+
|
24
31
|
context "with a simple changed file" do
|
25
|
-
line
|
26
|
-
file = collector.extract_change_file(line)
|
32
|
+
let(:line) {"37 30 lib/file.rb"}
|
27
33
|
it {file[:additions].should == 37}
|
28
34
|
it {file[:deletions].should == 30}
|
29
35
|
it {file[:file].should == "lib/file.rb"}
|
30
36
|
end
|
31
37
|
|
32
38
|
context "with a simple rename/copy changed file" do
|
33
|
-
line
|
34
|
-
file = collector.extract_change_file(line)
|
39
|
+
let(:line) {"11 3 old_file.rb => lib/file.rb"}
|
35
40
|
it {file[:additions].should == 11}
|
36
41
|
it {file[:deletions].should == 3}
|
37
42
|
it {file[:file].should == "lib/file.rb"}
|
@@ -39,8 +44,7 @@ describe Collector do
|
|
39
44
|
end
|
40
45
|
|
41
46
|
context "with a complex rename/copy changed file" do
|
42
|
-
line
|
43
|
-
file = collector.extract_change_file(line)
|
47
|
+
let(:line) {"- - lib/{old_dir => new_dir}/file.rb"}
|
44
48
|
it {file[:additions].should == 0}
|
45
49
|
it {file[:deletions].should == 0}
|
46
50
|
it {file[:file].should == "lib/new_dir/file.rb"}
|
@@ -49,25 +53,26 @@ describe Collector do
|
|
49
53
|
end
|
50
54
|
|
51
55
|
describe "#extract_create_delete_file" do
|
56
|
+
let(:file) {collector.extract_create_delete_file(line)}
|
57
|
+
|
52
58
|
context "with a create changed file" do
|
53
|
-
line
|
54
|
-
file = collector.extract_create_delete_file(line)
|
59
|
+
let(:line) {"create mode 100644 lib/dir/file.rb"}
|
55
60
|
it {file[:status].should == "create"}
|
56
61
|
it {file[:file].should == "lib/dir/file.rb"}
|
57
62
|
end
|
58
63
|
|
59
64
|
context "with a delete changed file" do
|
60
|
-
line
|
61
|
-
file = collector.extract_create_delete_file(line)
|
65
|
+
let(:line) {"delete mode 100644 lib/file.rb"}
|
62
66
|
it {file[:status].should == "delete"}
|
63
67
|
it {file[:file].should == "lib/file.rb"}
|
64
68
|
end
|
65
69
|
end
|
66
70
|
|
67
71
|
describe "#extract_rename_copy_file" do
|
72
|
+
let(:file) {collector.extract_rename_copy_file(line)}
|
73
|
+
|
68
74
|
context "with a rename changed file" do
|
69
|
-
line
|
70
|
-
file = collector.extract_rename_copy_file(line)
|
75
|
+
let(:line) {"rename lib/{old_dir => new_dir}/file.rb (100%)"}
|
71
76
|
it {file[:status].should == "rename"}
|
72
77
|
it {file[:old_file].should == "lib/old_dir/file.rb"}
|
73
78
|
it {file[:new_file].should == "lib/new_dir/file.rb"}
|
@@ -75,8 +80,7 @@ describe Collector do
|
|
75
80
|
end
|
76
81
|
|
77
82
|
context "with a copy changed file" do
|
78
|
-
line
|
79
|
-
file = collector.extract_rename_copy_file(line)
|
83
|
+
let(:line) {"copy lib/dir/{old_file.rb => new_file.rb} (75%)"}
|
80
84
|
it {file[:status].should == "copy"}
|
81
85
|
it {file[:old_file].should == "lib/dir/old_file.rb"}
|
82
86
|
it {file[:new_file].should == "lib/dir/new_file.rb"}
|
@@ -85,56 +89,56 @@ describe Collector do
|
|
85
89
|
end
|
86
90
|
|
87
91
|
describe "#acquire_commit_data" do
|
92
|
+
let(:input) {fixture(fixture_file).read}
|
93
|
+
let(:data) {collector.acquire_commit_data(input)}
|
94
|
+
|
88
95
|
context "no parent, first commit" do
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
it {
|
93
|
-
it {
|
94
|
-
it {
|
95
|
-
it {commit_data[:data][:time].should == "2011-01-11 11:11:11 +0000"}
|
96
|
-
it {commit_data[:data][:merge].should be_false}
|
96
|
+
let(:fixture_file) {"commit_buffer_information_first.txt"}
|
97
|
+
it {data[:sha].should == "111111aa111a11111a11aa11aaaa11a111111a11"}
|
98
|
+
it {data[:data][:author].should == "Test Author"}
|
99
|
+
it {data[:data][:author_email].should == "author@test.com"}
|
100
|
+
it {data[:data][:time].should == "2011-01-11 11:11:11 +0000"}
|
101
|
+
it {data[:data][:merge].should be_false}
|
97
102
|
end
|
98
103
|
|
99
104
|
context "without merge, one parent" do
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
it {
|
104
|
-
it {
|
105
|
-
it {
|
106
|
-
it {commit_data[:data][:time].should == "2011-01-11 11:11:11 +0000"}
|
107
|
-
it {commit_data[:data][:merge].should be_false}
|
105
|
+
let(:fixture_file) {"commit_buffer_information.txt"}
|
106
|
+
it {data[:sha].should == "111111aa111a11111a11aa11aaaa11a111111a11"}
|
107
|
+
it {data[:data][:author].should == "Test Author"}
|
108
|
+
it {data[:data][:author_email].should == "author@test.com"}
|
109
|
+
it {data[:data][:time].should == "2011-01-11 11:11:11 +0000"}
|
110
|
+
it {data[:data][:merge].should be_false}
|
108
111
|
end
|
109
112
|
|
110
113
|
context "with merge, two parents" do
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
it {
|
115
|
-
it {
|
116
|
-
it {
|
117
|
-
it {commit_data[:data][:time].should == "2011-01-11 11:11:11 +0000"}
|
118
|
-
it {commit_data[:data][:merge].should be_true}
|
114
|
+
let(:fixture_file) {"commit_buffer_information_with_merge.txt"}
|
115
|
+
it {data[:sha].should == "111111aa111a11111a11aa11aaaa11a111111a11"}
|
116
|
+
it {data[:data][:author].should == "Test Author"}
|
117
|
+
it {data[:data][:author_email].should == "author@test.com"}
|
118
|
+
it {data[:data][:time].should == "2011-01-11 11:11:11 +0000"}
|
119
|
+
it {data[:data][:merge].should be_true}
|
119
120
|
end
|
120
121
|
end
|
121
122
|
|
122
123
|
describe "#identify_changed_files" do
|
124
|
+
let(:files) {collector.identify_changed_files(buffer)}
|
125
|
+
|
123
126
|
context "with no changes" do
|
124
|
-
buffer
|
125
|
-
files = collector.identify_changed_files(buffer)
|
127
|
+
let(:buffer) {[]}
|
126
128
|
it {files.size.should == 0}
|
127
129
|
it {files[0].should == nil}
|
128
130
|
end
|
129
131
|
|
130
132
|
context "with all types (create,delete,rename,copy) of files" do
|
131
133
|
# Create buffer which is an array of cleaned lines
|
132
|
-
buffer
|
133
|
-
|
134
|
-
|
135
|
-
|
134
|
+
let(:buffer) {
|
135
|
+
buffer = []
|
136
|
+
fixture("commit_buffer_changes.txt").readlines.each do |line|
|
137
|
+
buffer << Utilities.clean_string(line)
|
138
|
+
end
|
139
|
+
buffer
|
140
|
+
}
|
136
141
|
|
137
|
-
files = collector.identify_changed_files(buffer)
|
138
142
|
it {files.size.should == 5}
|
139
143
|
|
140
144
|
it {files[0][:additions].should == 45}
|
@@ -166,13 +170,18 @@ describe Collector do
|
|
166
170
|
end
|
167
171
|
|
168
172
|
describe "#extract_commit" do
|
169
|
-
|
170
|
-
|
173
|
+
# Create buffer which is an array of cleaned lines
|
174
|
+
let(:buffer) {
|
171
175
|
buffer = []
|
172
|
-
fixture(
|
176
|
+
fixture(fixture_file).readlines.each do |line|
|
173
177
|
buffer << Utilities.clean_string(line)
|
174
178
|
end
|
175
|
-
|
179
|
+
buffer
|
180
|
+
}
|
181
|
+
let(:data) {collector.extract_commit(buffer)}
|
182
|
+
|
183
|
+
context "with valid buffer" do
|
184
|
+
let(:fixture_file) {"commit_buffer_whole.txt"}
|
176
185
|
|
177
186
|
it {data[:author].should == "Kevin Jalbert"}
|
178
187
|
it {data[:author_email].should == "kevin.j.jalbert@gmail.com"}
|
@@ -215,85 +224,75 @@ describe Collector do
|
|
215
224
|
end
|
216
225
|
|
217
226
|
context "with buffer that has no file changes" do
|
218
|
-
|
219
|
-
buffer = []
|
220
|
-
fixture("commit_buffer_information.txt").readlines.each do |line|
|
221
|
-
buffer << Utilities.clean_string(line)
|
222
|
-
end
|
223
|
-
data = collector.extract_commit(buffer)
|
224
|
-
|
227
|
+
let(:fixture_file) {"commit_buffer_information.txt"}
|
225
228
|
it {data.should == nil}
|
226
229
|
end
|
227
230
|
|
228
231
|
context "with invalid buffer" do
|
229
|
-
|
230
|
-
buffer = "invalid input"
|
231
|
-
data = collector.extract_commit(buffer)
|
232
|
-
|
232
|
+
let(:buffer) {"invalid input"}
|
233
233
|
it {data.should == nil}
|
234
234
|
end
|
235
235
|
end
|
236
236
|
|
237
237
|
describe "#fall_back_collect_commit" do
|
238
|
+
let(:buffer) {collector.fall_back_collect_commit(sha)}
|
238
239
|
context "with valid sha" do
|
239
|
-
buffer = collector.fall_back_collect_commit("260bc61e2c42930d91f3503c5849b0a2351275cf")
|
240
|
-
|
241
240
|
# Create buffer which is an array of cleaned lines
|
242
|
-
expected
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
241
|
+
let(:expected) {
|
242
|
+
expected = []
|
243
|
+
fixture("commit_buffer_whole.txt").readlines.each do |line|
|
244
|
+
expected << Utilities.clean_string(line)
|
245
|
+
end
|
246
|
+
expected
|
247
|
+
}
|
248
|
+
let(:sha) {"260bc61e2c42930d91f3503c5849b0a2351275cf"}
|
249
|
+
|
250
|
+
it {buffer.should == expected}
|
248
251
|
end
|
249
252
|
|
250
253
|
context "with invalid sha" do
|
251
|
-
|
254
|
+
let(:sha) {"111111aa111a11111a11aa11aaaa11a111111a11"}
|
252
255
|
it {buffer.should == nil}
|
253
256
|
end
|
254
257
|
end
|
255
258
|
|
256
259
|
describe "#get_blob" do
|
257
|
-
sha
|
260
|
+
let(:sha) {"695b487432e8a1ede765b4e3efda088ab87a77f8"} # Commit within repository
|
261
|
+
let(:blob) {collector.get_blob(sha, file)}
|
258
262
|
|
259
263
|
context "with valid blob" do
|
260
|
-
file
|
261
|
-
blob = collector.get_blob(sha, file)
|
262
|
-
|
264
|
+
let(:file) {{:file => "Gemfile.lock"}}
|
263
265
|
it {blob.instance_of?(Grit::Blob).should be_true}
|
264
266
|
it {blob.name.should == file[:file].split(File::Separator).last}
|
265
267
|
end
|
266
268
|
|
267
269
|
context "with invalid blob" do
|
268
|
-
file
|
269
|
-
blob = collector.get_blob(sha, file)
|
270
|
-
|
270
|
+
let(:file) {{:file => "dir/nothing.rb"}}
|
271
271
|
it {blob.should == nil}
|
272
272
|
end
|
273
273
|
|
274
274
|
context "with deleted file" do
|
275
|
-
file
|
276
|
-
blob = collector.get_blob(sha, file)
|
277
|
-
|
275
|
+
let(:file) {{:file => "spec/collector_spec.rb"}}
|
278
276
|
it {blob.instance_of?(Grit::Blob).should be_true}
|
279
277
|
it {blob.name.should == file[:file].split(File::Separator).last}
|
280
278
|
end
|
281
279
|
end
|
282
280
|
|
283
281
|
describe "#process_blob" do
|
284
|
-
sha
|
285
|
-
|
286
|
-
|
287
|
-
file = {:file => "spec/collector_spec.rb",
|
288
|
-
:additions => 0,
|
289
|
-
:deletions => 6,
|
290
|
-
:status => "delete"}
|
291
|
-
|
292
|
-
blob = collector.get_blob(sha, file)
|
282
|
+
let(:sha) {"695b487432e8a1ede765b4e3efda088ab87a77f8"} # Commit within repository
|
283
|
+
let(:blob) {collector.get_blob(sha, file)}
|
284
|
+
let(:data) {
|
293
285
|
data = Hash.new(0)
|
294
286
|
data[:files] = []
|
295
|
-
|
296
|
-
|
287
|
+
collector.process_blob(data, blob, file)
|
288
|
+
}
|
289
|
+
let(:data_file) {data_file = data[:files].first}
|
290
|
+
|
291
|
+
context "with status (delete) blob" do
|
292
|
+
let(:file) {{:file => "spec/collector_spec.rb",
|
293
|
+
:additions => 0,
|
294
|
+
:deletions => 6,
|
295
|
+
:status => "delete"}}
|
297
296
|
|
298
297
|
it {data[:additions].should == file[:additions]}
|
299
298
|
it {data[:deletions].should == file[:deletions]}
|
@@ -310,16 +309,10 @@ describe Collector do
|
|
310
309
|
end
|
311
310
|
|
312
311
|
context "with invalid language blob" do
|
313
|
-
file
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
blob = collector.get_blob(sha, file)
|
319
|
-
data = Hash.new(0)
|
320
|
-
data[:files] = []
|
321
|
-
data = collector.process_blob(data, blob, file)
|
322
|
-
data_file = data[:files].first
|
312
|
+
let(:file) {{:file => "Gemfile.lock",
|
313
|
+
:additions => 33,
|
314
|
+
:deletions => 11,
|
315
|
+
:status => nil}}
|
323
316
|
|
324
317
|
it {data[:additions].should == file[:additions]}
|
325
318
|
it {data[:deletions].should == file[:deletions]}
|
@@ -336,16 +329,10 @@ describe Collector do
|
|
336
329
|
end
|
337
330
|
|
338
331
|
context "with valid language blob" do
|
339
|
-
file
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
blob = collector.get_blob(sha, file)
|
345
|
-
data = Hash.new(0)
|
346
|
-
data[:files] = []
|
347
|
-
data = collector.process_blob(data, blob, file)
|
348
|
-
data_file = data[:files].first
|
332
|
+
let(:file) {{:file => "README.md",
|
333
|
+
:additions => 7,
|
334
|
+
:deletions => 3,
|
335
|
+
:status => nil}}
|
349
336
|
|
350
337
|
it {data[:additions].should == file[:additions]}
|
351
338
|
it {data[:deletions].should == file[:deletions]}
|