git_fame 1.7.2 → 2.0.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/.rspec +5 -3
- data/.travis.yml +6 -1
- data/README.md +60 -70
- data/Rakefile +13 -0
- data/bin/git-fame +34 -19
- data/git_fame.gemspec +11 -10
- data/lib/git_fame.rb +1 -6
- data/lib/git_fame/author.rb +14 -0
- data/lib/git_fame/base.rb +302 -125
- data/lib/git_fame/blame_parser.rb +83 -0
- data/lib/git_fame/commit_range.rb +27 -0
- data/lib/git_fame/errors.rb +3 -1
- data/lib/git_fame/silent_progressbar.rb +10 -3
- data/lib/git_fame/version.rb +1 -1
- data/spec/bin_spec.rb +69 -6
- data/spec/git_fame_spec.rb +318 -28
- data/spec/spec_helper.rb +28 -6
- metadata +55 -39
@@ -0,0 +1,83 @@
|
|
1
|
+
# Extracted from the dolt gem. Currently not maintained.
|
2
|
+
# Source: https://docs.omniref.com/ruby/gems/libdolt/0.33.14/symbols/Dolt::Git::Blame::PorcelainParser
|
3
|
+
module GitFame
|
4
|
+
class BlameParser
|
5
|
+
def initialize(output)
|
6
|
+
@output = output
|
7
|
+
@commits = {}
|
8
|
+
end
|
9
|
+
def parse
|
10
|
+
lines = @output.split("\n")
|
11
|
+
chunks = []
|
12
|
+
while lines.length > 0
|
13
|
+
chunk = extract_header(lines)
|
14
|
+
affected_lines = extract_lines(lines, chunk[:num_lines])
|
15
|
+
if chunks.last && chunk[:oid] == chunks.last[:oid]
|
16
|
+
chunks.last[:lines].concat(affected_lines)
|
17
|
+
else
|
18
|
+
chunk[:lines] = affected_lines
|
19
|
+
chunks << chunk
|
20
|
+
end
|
21
|
+
end
|
22
|
+
chunks
|
23
|
+
rescue Exception => error
|
24
|
+
raise Error, "Failed parsing Procelain: #{error.message}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def is_header?(line)
|
28
|
+
line =~ /^[0-9a-f]{40} \d+ \d+ \d+$/
|
29
|
+
end
|
30
|
+
|
31
|
+
def extract_header(lines)
|
32
|
+
header = lines.shift
|
33
|
+
pieces = header.scan(/^([0-9a-f]{40}) (\d+) (\d+) (\d+)$/).first
|
34
|
+
header = { :oid => pieces.first, :num_lines => pieces[3].to_i }
|
35
|
+
if lines.first =~ /^author/
|
36
|
+
header[:author] = extract_hash(lines, :author)
|
37
|
+
header[:committer] = extract_hash(lines, :committer)
|
38
|
+
header[:summary] = extract(lines, "summary")
|
39
|
+
header[:boundary] = extract(lines, "boundary")
|
40
|
+
throwaway = lines.shift until throwaway =~ /^filename/
|
41
|
+
@commits[header[:oid]] = header
|
42
|
+
else
|
43
|
+
header[:author] = @commits[header[:oid]][:author]
|
44
|
+
header[:committer] = @commits[header[:oid]][:committer]
|
45
|
+
header[:summary] = @commits[header[:oid]][:summary]
|
46
|
+
end
|
47
|
+
header
|
48
|
+
end
|
49
|
+
|
50
|
+
def extract_lines(lines, num)
|
51
|
+
extracted = []
|
52
|
+
num.times do
|
53
|
+
if extracted.length > 0
|
54
|
+
line = lines.shift # Header for next line
|
55
|
+
end
|
56
|
+
content = lines.shift # Actual content
|
57
|
+
next unless content
|
58
|
+
extracted.push(content[1..content.length]) # 8 spaces padding
|
59
|
+
end
|
60
|
+
extracted
|
61
|
+
end
|
62
|
+
|
63
|
+
def extract_hash(lines, type)
|
64
|
+
{
|
65
|
+
:name => extract(lines, "#{type}"),
|
66
|
+
:mail => extract(lines, "#{type}-mail").gsub(/[<>]/, ""),
|
67
|
+
:time => (Time.at(extract(lines, "#{type}-time").to_i).utc +
|
68
|
+
Time.zone_offset(extract(lines, "#{type}-tz")))
|
69
|
+
}
|
70
|
+
end
|
71
|
+
def extract(lines, thing)
|
72
|
+
if thing == "boundary"
|
73
|
+
if (line = lines.shift) == thing
|
74
|
+
return true
|
75
|
+
else
|
76
|
+
return ! lines.unshift(line)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
lines.shift.split("#{thing} ")[1]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
class CommitRange < Struct.new(:data, :current_branch)
|
2
|
+
SHORT_LENGTH = 7
|
3
|
+
|
4
|
+
def to_s(short = false)
|
5
|
+
@_to_s ||= range.map do |commit|
|
6
|
+
short ? shorten(commit) : commit
|
7
|
+
end.join("..")
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_range?
|
11
|
+
data.is_a?(Array)
|
12
|
+
end
|
13
|
+
|
14
|
+
def range
|
15
|
+
is_range? ? data : [data]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def branch?(commit)
|
21
|
+
current_branch == commit
|
22
|
+
end
|
23
|
+
|
24
|
+
def shorten(commit)
|
25
|
+
branch?(commit) ? commit : commit[0..SHORT_LENGTH]
|
26
|
+
end
|
27
|
+
end
|
data/lib/git_fame/errors.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
|
-
|
1
|
+
require "ruby-progressbar"
|
2
|
+
|
3
|
+
class SilentProgressbar < ProgressBar::Base
|
2
4
|
#
|
3
5
|
# @name String Name for progressbar
|
4
6
|
# @steps Fixnum Total number of steps
|
5
7
|
# @active Should progressbar be visible?
|
6
8
|
#
|
7
9
|
def initialize(name, steps, active = false)
|
8
|
-
|
9
|
-
super(
|
10
|
+
output = active ? $stdout : File.new("/dev/null", "w")
|
11
|
+
super({
|
12
|
+
title: name,
|
13
|
+
total: steps,
|
14
|
+
output: output,
|
15
|
+
smoothing: 0.6
|
16
|
+
})
|
10
17
|
end
|
11
18
|
end
|
data/lib/git_fame/version.rb
CHANGED
data/spec/bin_spec.rb
CHANGED
@@ -19,19 +19,21 @@ describe "bin/git-fame" do
|
|
19
19
|
"--sort=name",
|
20
20
|
"--sort=commits",
|
21
21
|
"--sort=loc",
|
22
|
-
"--
|
23
|
-
"--progressbar=0",
|
24
|
-
"--progressbar=1",
|
22
|
+
"--hide-progressbar",
|
25
23
|
"--whitespace",
|
26
|
-
"--
|
24
|
+
"--by-type",
|
27
25
|
"--include=hello",
|
28
26
|
"--exclude=hello",
|
29
27
|
"--extension=rb,ln",
|
30
28
|
"--branch=master",
|
31
29
|
"--format=csv",
|
32
30
|
"--format=pretty",
|
31
|
+
"--before=2010-01-01",
|
32
|
+
"--after=1980-01-01",
|
33
33
|
"--version",
|
34
|
-
"--help"
|
34
|
+
"--help",
|
35
|
+
"--verbose",
|
36
|
+
"--everything"
|
35
37
|
].each do |option|
|
36
38
|
it "should support #{option}" do
|
37
39
|
run(option).should be_a_succees
|
@@ -41,4 +43,65 @@ describe "bin/git-fame" do
|
|
41
43
|
it "should sort by loc by default" do
|
42
44
|
run("--sort=loc", "--progressbar=0").first.should eq(run("--progressbar=0").first)
|
43
45
|
end
|
44
|
-
|
46
|
+
|
47
|
+
context "dates" do
|
48
|
+
it "should fail on invalid before date" do
|
49
|
+
res = run("--before='---'")
|
50
|
+
res.should_not be_a_succees
|
51
|
+
res.first.should eq("Error: '---' is not a valid date\n")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should fail on invalid after date" do
|
55
|
+
res = run("--after='---'")
|
56
|
+
res.should_not be_a_succees
|
57
|
+
res.should include_output("Error: '---' is not a valid date\n")
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should not print stack trace on invalid dates (--after)" do
|
61
|
+
res = run("--after='---'")
|
62
|
+
res.should_not be_a_succees
|
63
|
+
res.should_not include_output("GitFame::Error")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should not print stack trace on invalid dates (--before)" do
|
67
|
+
res = run("--before='---'")
|
68
|
+
res.should_not be_a_succees
|
69
|
+
res.should_not include_output("GitFame::Error")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should not print stack trace on out of span (--before)" do
|
73
|
+
res = run("--before='1910-01-01'")
|
74
|
+
res.should_not be_a_succees
|
75
|
+
res.should_not include_output("GitFame::Error")
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should not print stack trace on out of span (--after)" do
|
79
|
+
res = run("--after='2100-01-01'")
|
80
|
+
res.should_not be_a_succees
|
81
|
+
res.should_not include_output("GitFame::Error")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "sort" do
|
86
|
+
it "should fail on non existing option" do
|
87
|
+
run("--sort=-----").should_not be_a_succees
|
88
|
+
end
|
89
|
+
|
90
|
+
results = []
|
91
|
+
GitFame::SORT.each do |option|
|
92
|
+
it "should be able to sort by #{option}" do
|
93
|
+
out = run("--sort=#{option}")
|
94
|
+
out.should be_a_succees
|
95
|
+
# TODO: Not a impl. problem
|
96
|
+
# Just not enough data
|
97
|
+
unless option == "name"
|
98
|
+
results.push(out.first)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it "#{GitFame::SORT.join(", ")} should not output the same thing" do
|
104
|
+
results.uniq.sort.should eq(results.sort)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/spec/git_fame_spec.rb
CHANGED
@@ -1,33 +1,39 @@
|
|
1
1
|
describe GitFame::Base do
|
2
|
-
let(:subject) { GitFame::Base.new({repository: repository}) }
|
2
|
+
let(:subject) { GitFame::Base.new({ repository: repository }) }
|
3
|
+
|
3
4
|
describe "#authors" do
|
4
5
|
it "should have a list of authors" do
|
5
6
|
subject.should have(3).authors
|
6
7
|
end
|
7
8
|
|
8
9
|
describe "author" do
|
9
|
-
|
10
|
-
|
10
|
+
let(:author) do
|
11
|
+
subject.authors.find do |author|
|
12
|
+
author.name.include?("Magnus Holm")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
11
16
|
it "should have a bunch of commits" do
|
12
|
-
author.
|
17
|
+
author.raw(:commits).should eq(41)
|
13
18
|
end
|
14
19
|
|
15
20
|
it "should respond to name" do
|
16
|
-
author.name.should eq("
|
21
|
+
author.name.should eq("Magnus Holm")
|
17
22
|
end
|
18
23
|
|
19
24
|
it "should have a number of locs" do
|
20
|
-
author.
|
25
|
+
author.raw(:loc).should eq(579)
|
21
26
|
end
|
22
27
|
|
23
28
|
it "should have a number of files" do
|
24
|
-
author.
|
29
|
+
author.raw(:files).should eq(4)
|
25
30
|
end
|
26
31
|
|
27
32
|
it "should have a distribution" do
|
28
|
-
author.distribution.should eq("
|
33
|
+
author.distribution.should eq("53.9 / 58.6 / 25.0")
|
29
34
|
end
|
30
35
|
end
|
36
|
+
|
31
37
|
describe "format" do
|
32
38
|
let(:author) do
|
33
39
|
GitFame::Author.new({
|
@@ -55,7 +61,7 @@ describe GitFame::Base do
|
|
55
61
|
it "should respond to #loc, #commits and #files" do
|
56
62
|
subject.files.should eq(16)
|
57
63
|
subject.commits.should eq(70)
|
58
|
-
subject.loc.should eq(
|
64
|
+
subject.loc.should eq(1075)
|
59
65
|
end
|
60
66
|
end
|
61
67
|
|
@@ -74,6 +80,7 @@ describe GitFame::Base do
|
|
74
80
|
repository: repository,
|
75
81
|
sort: "commits"
|
76
82
|
}).authors
|
83
|
+
|
77
84
|
authors.map(&:name).
|
78
85
|
should eq(["Magnus Holm", "Linus Oleander", "7rans"])
|
79
86
|
end
|
@@ -86,29 +93,55 @@ describe GitFame::Base do
|
|
86
93
|
authors.map(&:name).
|
87
94
|
should eq(["7rans", "Linus Oleander", "Magnus Holm"])
|
88
95
|
end
|
96
|
+
|
97
|
+
it "should be able to sort #authors by loc" do
|
98
|
+
authors = GitFame::Base.new({
|
99
|
+
repository: repository,
|
100
|
+
sort: "loc"
|
101
|
+
}).authors
|
102
|
+
authors.map(&:name).
|
103
|
+
should eq(["Magnus Holm", "7rans", "Linus Oleander"])
|
104
|
+
end
|
89
105
|
end
|
90
106
|
|
91
|
-
describe "
|
107
|
+
describe "exclude" do
|
92
108
|
let(:subject) do
|
93
109
|
GitFame::Base.new({
|
94
110
|
repository: repository,
|
95
|
-
exclude: "lib"
|
96
|
-
bytype: true,
|
97
|
-
extensions: "rb,rdoc"
|
111
|
+
exclude: "lib/*"
|
98
112
|
})
|
99
113
|
end
|
100
114
|
|
101
115
|
it "should exclude the lib folder" do
|
102
|
-
subject.file_list.include
|
116
|
+
subject.file_list.map(&:path).should_not include("lib/gash.rb")
|
103
117
|
end
|
104
118
|
|
105
119
|
it "should exclude non rb or rdoc files" do
|
106
|
-
subject.file_list.include
|
120
|
+
subject.file_list.map(&:path).should include("HISTORY")
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should exclude non matching paths" do
|
124
|
+
subject.file_list.map(&:path).should include("spec/gash_spec.rb")
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "types" do
|
129
|
+
let(:subject) do
|
130
|
+
GitFame::Base.new({
|
131
|
+
repository: repository,
|
132
|
+
by_type: true,
|
133
|
+
extensions: "rb,rdoc"
|
134
|
+
})
|
135
|
+
end
|
136
|
+
|
137
|
+
let(:author) do
|
138
|
+
subject.authors.find do |author|
|
139
|
+
author.name == "7rans"
|
140
|
+
end
|
107
141
|
end
|
108
142
|
|
109
|
-
let(:author) { subject.authors.find { |author| author.name == "7rans" } }
|
110
143
|
it "should break out counts by file type" do
|
111
|
-
author.file_type_counts["rdoc"].should eq(
|
144
|
+
author.file_type_counts["rdoc"].should eq(1)
|
112
145
|
end
|
113
146
|
|
114
147
|
it "should output zero for file types the author hasn't touched" do
|
@@ -116,6 +149,43 @@ describe GitFame::Base do
|
|
116
149
|
end
|
117
150
|
end
|
118
151
|
|
152
|
+
describe "include" do
|
153
|
+
let(:subject) do
|
154
|
+
GitFame::Base.new({
|
155
|
+
repository: repository,
|
156
|
+
include: "lib/*,spec/*"
|
157
|
+
})
|
158
|
+
end
|
159
|
+
|
160
|
+
it "should exclude the lib folder" do
|
161
|
+
subject.file_list.map(&:path).should include("lib/gash.rb")
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should exclude non rb or rdoc files" do
|
165
|
+
subject.file_list.map(&:path).should_not include("HISTORY")
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should exclude non matching paths" do
|
169
|
+
subject.file_list.map(&:path).should include("spec/gash_spec.rb")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "glob" do
|
174
|
+
it "should exclude" do
|
175
|
+
GitFame::Base.new({
|
176
|
+
repository: repository,
|
177
|
+
exclude: "lib/*.rb"
|
178
|
+
}).file_list.map(&:path).should_not include("lib/gash.rb")
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should include" do
|
182
|
+
GitFame::Base.new({
|
183
|
+
repository: repository,
|
184
|
+
include: "lib/*.rb"
|
185
|
+
}).file_list.map(&:path).should include("lib/gash.rb")
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
119
189
|
describe "#pretty_print" do
|
120
190
|
it "should print" do
|
121
191
|
lambda {
|
@@ -132,22 +202,21 @@ describe GitFame::Base do
|
|
132
202
|
end
|
133
203
|
|
134
204
|
it "should be equal to" do
|
135
|
-
subject.to_csv.should eq(
|
136
|
-
|
137
|
-
|
138
|
-
|
205
|
+
subject.to_csv.should eq([
|
206
|
+
"name,loc,commits,files,distribution\n",
|
207
|
+
"Magnus Holm,579,41,4,53.9 / 58.6 / 25.0\n",
|
208
|
+
"7rans,360,6,10,33.5 / 8.6 / 62.5\n",
|
209
|
+
"Linus Oleander,136,23,7,12.7 / 32.9 / 43.8\n",
|
210
|
+
].join)
|
139
211
|
end
|
140
212
|
end
|
141
213
|
|
142
|
-
describe "branches" do
|
214
|
+
describe "branches", :this do
|
143
215
|
it "should handle existing branches" do
|
144
|
-
|
216
|
+
GitFame::Base.new({
|
145
217
|
repository: repository,
|
146
|
-
branch: "
|
218
|
+
branch: "master"
|
147
219
|
}).authors
|
148
|
-
|
149
|
-
authors.count.should eq(1)
|
150
|
-
authors.first.name.should eq("Magnus Holm")
|
151
220
|
end
|
152
221
|
|
153
222
|
it "should raise an error if branch doesn't exist" do
|
@@ -156,7 +225,7 @@ describe GitFame::Base do
|
|
156
225
|
repository: repository,
|
157
226
|
branch: "-----"
|
158
227
|
}).authors
|
159
|
-
}.to raise_error(GitFame::
|
228
|
+
}.to raise_error(GitFame::Error)
|
160
229
|
end
|
161
230
|
|
162
231
|
it "should not raise on empty branch (use fallback)" do
|
@@ -171,4 +240,225 @@ describe GitFame::Base do
|
|
171
240
|
}).authors.should_not be_empty
|
172
241
|
end
|
173
242
|
end
|
243
|
+
|
244
|
+
describe "after", :this do
|
245
|
+
it "should raise error if 'after' is to far in the future" do
|
246
|
+
lambda do
|
247
|
+
GitFame::Base.new({
|
248
|
+
repository: repository,
|
249
|
+
after: "2020-01-01"
|
250
|
+
}).commits
|
251
|
+
end.should raise_error(GitFame::Error)
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should handle same day as HEAD" do
|
255
|
+
GitFame::Base.new({
|
256
|
+
repository: repository,
|
257
|
+
after: "2012-05-23"
|
258
|
+
}).commits.should eq(1)
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should handle an out of scope 'after' date" do
|
262
|
+
GitFame::Base.new({
|
263
|
+
repository: repository,
|
264
|
+
after: "2000-01-01"
|
265
|
+
}).commits.should eq(70)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
describe "before", :this do
|
270
|
+
it "should raise error if 'before' is to far back in history" do
|
271
|
+
lambda do
|
272
|
+
GitFame::Base.new({
|
273
|
+
repository: repository,
|
274
|
+
before: "1972-01-01"
|
275
|
+
}).commits
|
276
|
+
end.should raise_error(GitFame::Error)
|
277
|
+
end
|
278
|
+
|
279
|
+
it "should handle same day as last commit" do
|
280
|
+
GitFame::Base.new({
|
281
|
+
repository: repository,
|
282
|
+
before: "2008-08-31"
|
283
|
+
}).commits.should eq(1)
|
284
|
+
end
|
285
|
+
|
286
|
+
it "should handle an out of scope 'before' date" do
|
287
|
+
GitFame::Base.new({
|
288
|
+
repository: repository,
|
289
|
+
before: "2050-01-01"
|
290
|
+
}).commits.should eq(70)
|
291
|
+
end
|
292
|
+
|
293
|
+
it "should handle same day as last commit" do
|
294
|
+
GitFame::Base.new({
|
295
|
+
repository: repository,
|
296
|
+
before: "2008-08-31"
|
297
|
+
}).commits.should eq(1)
|
298
|
+
end
|
299
|
+
|
300
|
+
it "should validate before date" do
|
301
|
+
lambda do
|
302
|
+
GitFame::Base.new({
|
303
|
+
repository: repository,
|
304
|
+
before: "----"
|
305
|
+
})
|
306
|
+
end.should raise_error(GitFame::Error)
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should validate before date" do
|
310
|
+
lambda do
|
311
|
+
GitFame::Base.new({
|
312
|
+
repository: repository,
|
313
|
+
after: "----"
|
314
|
+
})
|
315
|
+
end.should raise_error(GitFame::Error)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe "span", :this do
|
320
|
+
it "should handle spans as inclusive" do
|
321
|
+
GitFame::Base.new({
|
322
|
+
repository: repository,
|
323
|
+
after: "2008-09-01",
|
324
|
+
before: "2008-09-03"
|
325
|
+
}).commits.should eq(4)
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should should possible a wide date span (include all)" do
|
329
|
+
GitFame::Base.new({
|
330
|
+
repository: repository,
|
331
|
+
after: "2000-01-01",
|
332
|
+
before: "2020-01-01"
|
333
|
+
}).commits.should eq(70)
|
334
|
+
end
|
335
|
+
|
336
|
+
it "should handle a too early 'after'" do
|
337
|
+
GitFame::Base.new({
|
338
|
+
repository: repository,
|
339
|
+
after: "2000-01-01",
|
340
|
+
before: "2008-08-31"
|
341
|
+
}).commits.should eq(1)
|
342
|
+
end
|
343
|
+
|
344
|
+
it "should catch empty commit span" do
|
345
|
+
lambda do
|
346
|
+
GitFame::Base.new({
|
347
|
+
repository: repository,
|
348
|
+
after: "2010-04-10",
|
349
|
+
before: "2010-04-11"
|
350
|
+
}).commits
|
351
|
+
end.should raise_error(GitFame::Error)
|
352
|
+
end
|
353
|
+
|
354
|
+
it "should handle a too late 'before'" do
|
355
|
+
GitFame::Base.new({
|
356
|
+
repository: repository,
|
357
|
+
after: "2012-02-29",
|
358
|
+
before: "2030-01-01"
|
359
|
+
}).commits.should eq(4)
|
360
|
+
end
|
361
|
+
|
362
|
+
it "should handle the after date same date as init commit" do
|
363
|
+
GitFame::Base.new({
|
364
|
+
repository: repository,
|
365
|
+
after: "2008-08-31",
|
366
|
+
before: "2008-09-03"
|
367
|
+
}).commits.should eq(5)
|
368
|
+
end
|
369
|
+
|
370
|
+
it "should handle an existing before with an old after" do
|
371
|
+
GitFame::Base.new({
|
372
|
+
repository: repository,
|
373
|
+
after: "2000-08-31",
|
374
|
+
before: "2008-09-03"
|
375
|
+
}).commits.should eq(5)
|
376
|
+
end
|
377
|
+
|
378
|
+
it "should handle an existing after with an old before" do
|
379
|
+
GitFame::Base.new({
|
380
|
+
repository: repository,
|
381
|
+
after: "2012-05-23",
|
382
|
+
before: "2020-01-01"
|
383
|
+
}).commits.should eq(1)
|
384
|
+
end
|
385
|
+
|
386
|
+
it "should raise an error if after > before" do
|
387
|
+
lambda do
|
388
|
+
GitFame::Base.new({
|
389
|
+
repository: repository,
|
390
|
+
after: "2020-01-01",
|
391
|
+
before: "2000-01-01"
|
392
|
+
}).commits
|
393
|
+
end.should raise_error(GitFame::Error)
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should raise error if set too high" do
|
397
|
+
lambda do
|
398
|
+
GitFame::Base.new({
|
399
|
+
repository: repository,
|
400
|
+
after: "2030-01-01",
|
401
|
+
before: "2050-01-01"
|
402
|
+
}).commits
|
403
|
+
end.should raise_error(GitFame::Error)
|
404
|
+
end
|
405
|
+
|
406
|
+
it "should raise error if set too low" do
|
407
|
+
lambda do
|
408
|
+
GitFame::Base.new({
|
409
|
+
repository: repository,
|
410
|
+
after: "1990-01-01",
|
411
|
+
before: "2000-01-01"
|
412
|
+
}).commits
|
413
|
+
end.should raise_error(GitFame::Error)
|
414
|
+
end
|
415
|
+
|
416
|
+
it "should handle same day" do
|
417
|
+
GitFame::Base.new({
|
418
|
+
repository: repository,
|
419
|
+
after: "2012-02-29",
|
420
|
+
before: "2012-02-29"
|
421
|
+
}).commits.should eq(3)
|
422
|
+
end
|
423
|
+
|
424
|
+
it "should handle same day (HEAD)" do
|
425
|
+
GitFame::Base.new({
|
426
|
+
repository: repository,
|
427
|
+
after: "2012-05-23",
|
428
|
+
before: "2012-05-23"
|
429
|
+
}).commits.should eq(1)
|
430
|
+
end
|
431
|
+
|
432
|
+
it "should handle same day (last commit)" do
|
433
|
+
GitFame::Base.new({
|
434
|
+
repository: repository,
|
435
|
+
after: "2008-08-31",
|
436
|
+
before: "2008-08-31"
|
437
|
+
}).commits.should eq(1)
|
438
|
+
end
|
439
|
+
|
440
|
+
it "should handle a non existent 'after' date" do
|
441
|
+
GitFame::Base.new({
|
442
|
+
repository: repository,
|
443
|
+
after: "2008-09-02",
|
444
|
+
before: "2008-09-04"
|
445
|
+
}).commits.should eq(4)
|
446
|
+
end
|
447
|
+
|
448
|
+
it "should handle a non existent 'before' date" do
|
449
|
+
GitFame::Base.new({
|
450
|
+
repository: repository,
|
451
|
+
after: "2008-09-04",
|
452
|
+
before: "2008-09-05"
|
453
|
+
}).commits.should eq(3)
|
454
|
+
end
|
455
|
+
|
456
|
+
it "should handle both non existent 'before' and 'after'" do
|
457
|
+
GitFame::Base.new({
|
458
|
+
repository: repository,
|
459
|
+
after: "2008-09-02",
|
460
|
+
before: "2008-09-05"
|
461
|
+
}).commits.should eq(4)
|
462
|
+
end
|
463
|
+
end
|
174
464
|
end
|