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