git_stats 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/.gitmodules +3 -0
- data/.rspec +1 -0
- data/Gemfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +44 -0
- data/Rakefile +1 -0
- data/bin/git_stats +11 -0
- data/config/locales/en.yml +56 -0
- data/config/locales/pl.yml +56 -0
- data/config/locales/pl_default.yml +224 -0
- data/git_stats.gemspec +27 -0
- data/lib/git_stats.rb +15 -0
- data/lib/git_stats/base.rb +30 -0
- data/lib/git_stats/by_field_finder.rb +7 -0
- data/lib/git_stats/cli.rb +17 -0
- data/lib/git_stats/core_extensions/hash.rb +9 -0
- data/lib/git_stats/core_extensions/string.rb +6 -0
- data/lib/git_stats/core_extensions/symbol.rb +6 -0
- data/lib/git_stats/generator.rb +32 -0
- data/lib/git_stats/git_data/activity.rb +78 -0
- data/lib/git_stats/git_data/author.rb +67 -0
- data/lib/git_stats/git_data/blob.rb +38 -0
- data/lib/git_stats/git_data/command_parser.rb +33 -0
- data/lib/git_stats/git_data/command_runner.rb +10 -0
- data/lib/git_stats/git_data/commit.rb +63 -0
- data/lib/git_stats/git_data/repo.rb +137 -0
- data/lib/git_stats/git_data/short_stat.rb +33 -0
- data/lib/git_stats/hash_initializable.rb +7 -0
- data/lib/git_stats/i18n.rb +2 -0
- data/lib/git_stats/stats_view/charts/activity_charts.rb +70 -0
- data/lib/git_stats/stats_view/charts/authors_charts.rb +35 -0
- data/lib/git_stats/stats_view/charts/chart.rb +119 -0
- data/lib/git_stats/stats_view/charts/charts.rb +35 -0
- data/lib/git_stats/stats_view/charts/repo_charts.rb +53 -0
- data/lib/git_stats/stats_view/template.rb +20 -0
- data/lib/git_stats/stats_view/view.rb +72 -0
- data/lib/git_stats/stats_view/view_data.rb +31 -0
- data/lib/git_stats/version.rb +4 -0
- data/spec/by_field_finder_spec.rb +25 -0
- data/spec/factories.rb +25 -0
- data/spec/git_data/activity_spec.rb +38 -0
- data/spec/git_data/author_spec.rb +25 -0
- data/spec/git_data/blob_spec.rb +25 -0
- data/spec/git_data/cli_spec.rb +20 -0
- data/spec/git_data/command_observer_spec.rb +35 -0
- data/spec/git_data/commit_range_spec.rb +47 -0
- data/spec/git_data/commit_spec.rb +48 -0
- data/spec/git_data/generator_spec.rb +46 -0
- data/spec/git_data/repo_spec.rb +46 -0
- data/spec/git_data/short_stat_spec.rb +28 -0
- data/spec/hash_extension_spec.rb +26 -0
- data/spec/integration/activity_spec.rb +33 -0
- data/spec/integration/author_spec.rb +67 -0
- data/spec/integration/file_spec.rb +31 -0
- data/spec/integration/repo_spec.rb +68 -0
- data/spec/integration/shared.rb +37 -0
- data/spec/spec_helper.rb +13 -0
- data/templates/activity/_activity.haml +101 -0
- data/templates/activity/by_date.haml +1 -0
- data/templates/activity/day_of_week.haml +1 -0
- data/templates/activity/hour_of_day.haml +1 -0
- data/templates/activity/hour_of_week.haml +1 -0
- data/templates/activity/month_of_year.haml +1 -0
- data/templates/activity/year.haml +1 -0
- data/templates/activity/year_month.haml +1 -0
- data/templates/assets/bootstrap/css/bootstrap-responsive.css +1058 -0
- data/templates/assets/bootstrap/css/bootstrap-responsive.min.css +9 -0
- data/templates/assets/bootstrap/css/bootstrap.css +5774 -0
- data/templates/assets/bootstrap/css/bootstrap.min.css +9 -0
- data/templates/assets/bootstrap/img/glyphicons-halflings-white.png +0 -0
- data/templates/assets/bootstrap/img/glyphicons-halflings.png +0 -0
- data/templates/assets/bootstrap/js/bootstrap.js +2027 -0
- data/templates/assets/bootstrap/js/bootstrap.min.js +6 -0
- data/templates/assets/highstock.js +305 -0
- data/templates/assets/jquery.min.js +2 -0
- data/templates/authors/_authors.haml +66 -0
- data/templates/authors/best_authors.haml +1 -0
- data/templates/authors/changed_lines_by_author_by_date.haml +1 -0
- data/templates/authors/commits_sum_by_author_by_date.haml +1 -0
- data/templates/authors/deletions_by_author_by_date.haml +1 -0
- data/templates/authors/insertions_by_author_by_date.haml +1 -0
- data/templates/files/_files.haml +15 -0
- data/templates/files/by_date.haml +1 -0
- data/templates/files/by_extension.haml +1 -0
- data/templates/general.haml +28 -0
- data/templates/layout.haml +29 -0
- data/templates/lines/_lines.haml +15 -0
- data/templates/lines/by_date.haml +1 -0
- data/templates/lines/by_extension.haml +1 -0
- data/templates/static/index.html +5 -0
- metadata +268 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe GitStats::Generator do
|
5
|
+
let(:repo_path) { 'repo_path' }
|
6
|
+
let(:out_path) { 'out_path' }
|
7
|
+
let(:generator) { GitStats::Generator.new(repo_path, out_path) }
|
8
|
+
|
9
|
+
before { Dir.stub!(:exists? => true) }
|
10
|
+
|
11
|
+
it 'should raise exception if given repo path is not a git repository' do
|
12
|
+
Dir.should_receive(:exists?).with("#{repo_path}/.git").and_return(false)
|
13
|
+
expect { generator }.to raise_error(ArgumentError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should raise exception if given out directory doesn't exist" do
|
17
|
+
Dir.should_receive(:exists?).with(out_path).and_return(false)
|
18
|
+
expect { generator }.to raise_error(ArgumentError)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should pass command observer to repo' do
|
22
|
+
repo = double('repo')
|
23
|
+
GitStats::GitData::Repo.should_receive(:new).with(path: repo_path).and_return(repo)
|
24
|
+
|
25
|
+
generator = GitStats::Generator.new(repo_path, out_path)
|
26
|
+
|
27
|
+
observer = double('observer')
|
28
|
+
repo.should_receive(:add_command_observer).with(observer)
|
29
|
+
|
30
|
+
generator.add_command_observer observer
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should render all templates with view data for this repo' do
|
34
|
+
repo = double('repo')
|
35
|
+
GitStats::GitData::Repo.should_receive(:new).with(path: repo_path).and_return(repo)
|
36
|
+
|
37
|
+
view_data = double('view_data')
|
38
|
+
GitStats::StatsView::ViewData.should_receive(:new).with(repo).and_return(view_data)
|
39
|
+
|
40
|
+
view = double('view')
|
41
|
+
GitStats::StatsView::View.should_receive(:new).with(view_data, out_path).and_return(view)
|
42
|
+
view.should_receive(:render_all)
|
43
|
+
|
44
|
+
generator.render_all
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe GitStats::GitData::Repo do
|
5
|
+
let(:repo) { build(:repo) }
|
6
|
+
|
7
|
+
describe 'git output parsing' do
|
8
|
+
context 'invoking authors command' do
|
9
|
+
before do
|
10
|
+
repo.should_receive(:run).with('git shortlog -se HEAD').and_return(" 156 John Doe <john.doe@gmail.com>
|
11
|
+
53 Joe Doe <joe.doe@gmail.com>
|
12
|
+
")
|
13
|
+
end
|
14
|
+
it 'should parse git shortlog output to authors hash' do
|
15
|
+
repo.authors.should == [
|
16
|
+
build(:author, repo: repo, name: "John Doe", email: "john.doe@gmail.com"),
|
17
|
+
build(:author, repo: repo, name: "Joe Doe", email: "joe.doe@gmail.com")
|
18
|
+
]
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should parse git revlist output to date sorted commits array' do
|
22
|
+
repo.should_receive(:run).with("git rev-list --pretty=format:'%h|%at|%ai|%aE' HEAD | grep -v commit").and_return(
|
23
|
+
"e4412c3|1348603824|2012-09-25 22:10:24 +0200|john.doe@gmail.com
|
24
|
+
ce34874|1347482927|2012-09-12 22:48:47 +0200|joe.doe@gmail.com
|
25
|
+
5eab339|1345835073|2012-08-24 21:04:33 +0200|john.doe@gmail.com
|
26
|
+
")
|
27
|
+
|
28
|
+
repo.commits.should == [
|
29
|
+
GitStats::GitData::Commit.new(
|
30
|
+
repo: repo, sha: "5eab339", stamp: "1345835073", date: DateTime.parse("2012-08-24 21:04:33 +0200"),
|
31
|
+
author: repo.authors.by_email("john.doe@gmail.com")),
|
32
|
+
GitStats::GitData::Commit.new(
|
33
|
+
repo: repo, sha: "ce34874", stamp: "1347482927", date: DateTime.parse("2012-09-12 22:48:47 +0200"),
|
34
|
+
author: repo.authors.by_email("joe.doe@gmail.com")),
|
35
|
+
GitStats::GitData::Commit.new(
|
36
|
+
repo: repo, sha: "e4412c3", stamp: "1348603824", date: DateTime.parse("2012-09-25 22:10:24 +0200"),
|
37
|
+
author: repo.authors.by_email("john.doe@gmail.com"))
|
38
|
+
]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
it 'should parse git rev-parse command to project version' do
|
42
|
+
repo.should_receive(:run).with('git rev-parse --short HEAD').and_return('xyz')
|
43
|
+
repo.project_version.should == 'xyz'
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe GitStats::GitData::ShortStat do
|
5
|
+
let(:commit) { build(:commit, sha: 'abc') }
|
6
|
+
|
7
|
+
describe 'git output parsing' do
|
8
|
+
context 'parsing git show output' do
|
9
|
+
[
|
10
|
+
{content: '2 files changed, 17 insertions(+), 3 deletions(-)', expect: [2, 17, 3]},
|
11
|
+
{content: '1 file changed, 1 insertion(+), 1 deletion(-)', expect: [1, 1, 1]},
|
12
|
+
{content: '2 files changed, 3 deletions(-)', expect: [2, 0, 3]},
|
13
|
+
{content: '2 files changed, 5 insertions(+)', expect: [2, 5, 0]},
|
14
|
+
{content: '', expect: [0, 0, 0]},
|
15
|
+
].each do |test|
|
16
|
+
it "#{test[:content]} parsing" do
|
17
|
+
commit.repo.should_receive(:run).with("git show --shortstat --oneline abc").and_return("abc some commit\n#{test[:content]}")
|
18
|
+
|
19
|
+
|
20
|
+
commit.short_stat.should be_a(GitStats::GitData::ShortStat)
|
21
|
+
commit.short_stat.files_changed.should == test[:expect][0]
|
22
|
+
commit.short_stat.insertions.should == test[:expect][1]
|
23
|
+
commit.short_stat.deletions.should == test[:expect][2]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Hash do
|
5
|
+
context 'to_key_indexed_array' do
|
6
|
+
it 'should convert hash to array using keys as indexes' do
|
7
|
+
hash = {1 => 'x', 2 => 1, 5 => 'a'}
|
8
|
+
hash.to_key_indexed_array.should == [nil, 'x', 1, nil, nil, 'a']
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should throw exception if not all of the keys are numbers' do
|
12
|
+
hash = {1 => 'x', 'b' => 2}
|
13
|
+
expect { hash.to_key_indexed_array }.to raise_error(ArgumentError)
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'should take optional min_size and default parameters' do
|
17
|
+
let(:hash) { {1 => 'x', 2 => 1, 5 => 'a'} }
|
18
|
+
it 'should fill array with defaults up to min_size' do
|
19
|
+
hash.to_key_indexed_array(min_size: 8, default: 0).should == [0, 'x', 1, 0, 0, 'a', 0, 0]
|
20
|
+
end
|
21
|
+
it 'should use default value where key is not in hash' do
|
22
|
+
hash.to_key_indexed_array(min_size: 2, default: 0).should == [0, 'x', 1, 0, 0, 'a']
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'integration/shared'
|
3
|
+
|
4
|
+
describe GitStats::GitData::Activity do
|
5
|
+
include_context "shared"
|
6
|
+
|
7
|
+
let(:activity) { repo.activity }
|
8
|
+
|
9
|
+
it 'should count commits by hour' do
|
10
|
+
activity.by_hour.should == {10 => 4, 12 => 3, 13 => 1, 15 => 1, 17 => 1}
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should count commits by day of week' do
|
14
|
+
activity.by_wday.should == {0 => 3, 3 => 1, 5 => 5, 6 => 1}
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should count commits by day of week and hour' do
|
18
|
+
activity.by_wday_hour.should == {0 => {12 => 2, 13 => 1}, 3 => {15 => 1}, 5 => {10 => 4, 17 => 1}, 6 => {12 => 1}}
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should count commits by month' do
|
22
|
+
activity.by_month.should == {10 => 10}
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should count commits by year' do
|
26
|
+
activity.by_year.should == {2012 => 10}
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should count commits by year and month' do
|
30
|
+
activity.by_year_month.should == {2012 => {10 => 10}}
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'integration/shared'
|
3
|
+
|
4
|
+
describe GitStats::GitData::Activity do
|
5
|
+
include_context "shared"
|
6
|
+
|
7
|
+
let(:tg) { repo.authors.by_email('tomasz.gieniusz@gmail.com') }
|
8
|
+
let(:jd) { repo.authors.by_email('john.doe@gmail.com') }
|
9
|
+
|
10
|
+
it 'should filter commits to author' do
|
11
|
+
tg.commits.map(&:sha).should =~ %w(b3b4f81 d60b5ec ab47ef8 2c11f5e c87ecf9 b621a5d 4e7d0e9 872955c)
|
12
|
+
jd.commits.map(&:sha).should =~ %w(fd66657 81e8bef)
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'activity' do
|
16
|
+
it 'should count commits by hour' do
|
17
|
+
tg.activity.by_hour.should == {10 => 4, 12 => 2, 13 => 1, 17 => 1}
|
18
|
+
jd.activity.by_hour.should == {12 => 1, 15 => 1}
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should count commits by day of week' do
|
22
|
+
tg.activity.by_wday.should == {0 => 2, 5 => 5, 6 => 1}
|
23
|
+
jd.activity.by_wday.should == {0 => 1, 3 => 1}
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should count commits by day of week and hour' do
|
27
|
+
tg.activity.by_wday_hour.should == {0 => {12 => 1, 13 => 1}, 5 => {10 => 4, 17 => 1}, 6 => {12 => 1}}
|
28
|
+
jd.activity.by_wday_hour.should == {0 => {12 => 1}, 3 => {15 => 1}}
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should count commits by month' do
|
32
|
+
tg.activity.by_month.should == {10 => 8}
|
33
|
+
jd.activity.by_month.should == {10 => 2}
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should count commits by year' do
|
37
|
+
tg.activity.by_year.should == {2012 => 8}
|
38
|
+
jd.activity.by_year.should == {2012 => 2}
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should count commits by year and month' do
|
42
|
+
tg.activity.by_year_month.should == {2012 => {10 => 8}}
|
43
|
+
jd.activity.by_year_month.should == {2012 => {10 => 2}}
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'should count commits_sum_by_date' do
|
47
|
+
tg.commits_sum_by_date.map { |d, s| d }.should == tg_commit_dates
|
48
|
+
tg.commits_sum_by_date.map { |d, s| s }.should == [1, 2, 3, 4, 5, 6, 7, 8]
|
49
|
+
jd.commits_sum_by_date.map { |d, s| d }.should == jd_commit_dates
|
50
|
+
jd.commits_sum_by_date.map { |d, s| s }.should == [1, 2]
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should count insertions_by_date' do
|
54
|
+
tg.insertions_by_date.map { |d, s| d }.should == tg_commit_dates
|
55
|
+
tg.insertions_by_date.map { |d, s| s }.should == [4, 9, 14, 15, 20, 1020, 1021, 1021]
|
56
|
+
jd.insertions_by_date.map { |d, s| d }.should == jd_commit_dates
|
57
|
+
jd.insertions_by_date.map { |d, s| s }.should == [3, 103]
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should count deletions_by_date' do
|
61
|
+
tg.deletions_by_date.map { |d, s| d }.should == tg_commit_dates
|
62
|
+
tg.deletions_by_date.map { |d, s| s }.should == [0, 0, 4, 4, 9, 9, 10, 10]
|
63
|
+
jd.deletions_by_date.map { |d, s| d }.should == jd_commit_dates
|
64
|
+
jd.deletions_by_date.map { |d, s| s }.should == [0, 0]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'integration/shared'
|
3
|
+
|
4
|
+
describe GitStats::GitData::Repo do
|
5
|
+
include_context "shared"
|
6
|
+
|
7
|
+
it 'should gather all files in repo' do
|
8
|
+
repo.files.map(&:filename).should =~ %w(long_second.haml long.txt second.txt test2.rb test.rb test.txt)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should retrieve correct file content for old file' do
|
12
|
+
repo.commits.by_sha('c87ecf9').files.by_filename('test.txt').content.should == "bb
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
test
|
17
|
+
"
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should retrieve correct file content for the newest file' do
|
21
|
+
file = repo.files.by_filename('test.txt')
|
22
|
+
file.content.should == "bb
|
23
|
+
|
24
|
+
testtest
|
25
|
+
|
26
|
+
test
|
27
|
+
"
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'integration/shared'
|
3
|
+
|
4
|
+
describe GitStats::GitData::Repo do
|
5
|
+
include_context "shared"
|
6
|
+
|
7
|
+
it 'should gather all authors' do
|
8
|
+
repo.authors.should =~ expected_authors
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should calculate correct commits period' do
|
12
|
+
repo.commits_period.should == [DateTime.parse('2012-10-19 10:44:34 +0200'), DateTime.parse('2012-10-26 17:05:25 +0200')]
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should gather all commits sorted by date' do
|
16
|
+
repo.commits.map(&:sha).should =~ %w(b3b4f81 d60b5ec ab47ef8 2c11f5e c87ecf9 b621a5d fd66657 81e8bef 4e7d0e9 872955c)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should return project name from dir' do
|
20
|
+
repo.project_name.should == 'test_repo'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should return project version as last commit hash' do
|
24
|
+
repo.project_version.should == '872955c'
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should count files in repo' do
|
28
|
+
repo.files_count.should == 6
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should count files by date' do
|
32
|
+
repo.files_count_by_date.keys.should == commit_dates
|
33
|
+
repo.files_count_by_date.values.should == [1, 2, 2, 3, 3, 4, 5, 5, 6, 6]
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should count lines by date' do
|
37
|
+
repo.lines_count_by_date.keys.should == commit_dates
|
38
|
+
repo.files_count_by_date.values.should == [1, 2, 2, 3, 3, 4, 5, 5, 6, 6]
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should count all lines in repo' do
|
42
|
+
repo.lines_count.should == 1114
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should count files by extension in repo' do
|
46
|
+
repo.files_by_extension_count.should == {'.haml' => 1, '.txt' => 3, '.rb' => 2}
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should count lines by extension in repo' do
|
50
|
+
repo.lines_by_extension.should == {'.haml' => 100, '.txt' => 1008, '.rb' => 6}
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'should count commits_count_by_author' do
|
54
|
+
repo.commits_count_by_author.keys.should == expected_authors
|
55
|
+
repo.commits_count_by_author.values.should == [8, 2]
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should count lines_added_by_author' do
|
59
|
+
repo.insertions_by_author.keys.should == expected_authors
|
60
|
+
repo.insertions_by_author.values.should == [1021, 103]
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should count lines_deleted_by_author' do
|
64
|
+
repo.deletions_by_author.keys.should == expected_authors
|
65
|
+
repo.deletions_by_author.values.should == [10, 0]
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
shared_context "shared" do
|
5
|
+
let(:repo) { build(:test_repo, last_commit_sha: '872955c') }
|
6
|
+
let(:commit_dates) { [
|
7
|
+
DateTime.parse('2012-10-19 10:44:34 +0200'),
|
8
|
+
DateTime.parse('2012-10-19 10:46:10 +0200'),
|
9
|
+
DateTime.parse('2012-10-19 10:46:56 +0200'),
|
10
|
+
DateTime.parse('2012-10-19 10:47:35 +0200'),
|
11
|
+
DateTime.parse('2012-10-20 12:49:02 +0200'),
|
12
|
+
DateTime.parse('2012-10-21 12:49:02 +0200'),
|
13
|
+
DateTime.parse('2012-10-21 12:54:02 +0200'),
|
14
|
+
DateTime.parse('2012-10-21 13:20:00 +0200'),
|
15
|
+
DateTime.parse('2012-10-24 15:49:02 +0200'),
|
16
|
+
DateTime.parse('2012-10-26 17:05:25 +0200'),
|
17
|
+
] }
|
18
|
+
let(:tg_commit_dates) { [
|
19
|
+
DateTime.parse('2012-10-19 10:44:34 +0200'),
|
20
|
+
DateTime.parse('2012-10-19 10:46:10 +0200'),
|
21
|
+
DateTime.parse('2012-10-19 10:46:56 +0200'),
|
22
|
+
DateTime.parse('2012-10-19 10:47:35 +0200'),
|
23
|
+
DateTime.parse('2012-10-20 12:49:02 +0200'),
|
24
|
+
DateTime.parse('2012-10-21 12:49:02 +0200'),
|
25
|
+
DateTime.parse('2012-10-21 13:20:00 +0200'),
|
26
|
+
DateTime.parse('2012-10-26 17:05:25 +0200'),
|
27
|
+
] }
|
28
|
+
let(:jd_commit_dates) { [
|
29
|
+
DateTime.parse('2012-10-21 12:54:02 +0200'),
|
30
|
+
DateTime.parse('2012-10-24 15:49:02 +0200'),
|
31
|
+
] }
|
32
|
+
|
33
|
+
let(:expected_authors) { [
|
34
|
+
build(:author, repo: repo, name: "Tomasz Gieniusz", email: "tomasz.gieniusz@gmail.com"),
|
35
|
+
build(:author, repo: repo, name: "John Doe", email: "john.doe@gmail.com"),
|
36
|
+
] }
|
37
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
.tabbable.tabs-left
|
2
|
+
%ul.nav.nav-tabs
|
3
|
+
%li{class: page == :activity_by_date ? "active" : "" }
|
4
|
+
%a{href: "by_date.html"}= :activity_by_date.t
|
5
|
+
%li{class: page == :hour_of_day ? "active" : "" }
|
6
|
+
%a{href: "hour_of_day.html"}= :hour_of_day.t
|
7
|
+
%li{class: page == :day_of_week ? "active" : "" }
|
8
|
+
%a{href: "day_of_week.html"}= :day_of_week.t
|
9
|
+
%li{class: page == :hour_of_week ? "active" : "" }
|
10
|
+
%a{href: "hour_of_week.html"}= :hour_of_week.t
|
11
|
+
%li{class: page == :month_of_year ? "active" : "" }
|
12
|
+
%a{href: "month_of_year.html"}= :month_of_year.t
|
13
|
+
%li{class: page == :year ? "active" : "" }
|
14
|
+
%a{href: "year.html"}= :year.t
|
15
|
+
%li{class: page == :year_month ? "active" : "" }
|
16
|
+
%a{href: "year_month.html"}= :year_month.t
|
17
|
+
|
18
|
+
.tab-content
|
19
|
+
.tab-pane.active
|
20
|
+
.page-header.pagination-centered
|
21
|
+
%h1= page.t
|
22
|
+
%h3= "#{author.respond_to?(:name) ? author.name : ""} #{author.respond_to?(:email) ? "<#{author.email}>" : ""}"
|
23
|
+
- if page == :activity_by_date
|
24
|
+
= high_stock("charts.activity_by_date", charts.activity_by_date(author))
|
25
|
+
|
26
|
+
- elsif page == :hour_of_day
|
27
|
+
%table{:class => "table table-bordered table-condensed"}
|
28
|
+
%tr
|
29
|
+
%th= :hour.t
|
30
|
+
- (0..23).each do |h|
|
31
|
+
%th= h
|
32
|
+
%tr
|
33
|
+
%th= :commits.t
|
34
|
+
- author.activity.by_hour_array.each do |commits|
|
35
|
+
%td= commits
|
36
|
+
%tr
|
37
|
+
%th= :percentage.t
|
38
|
+
- author.activity.by_hour_array.each do |commits|
|
39
|
+
%td= (commits * 100.0 / author.activity.by_hour_array.sum).round(1)
|
40
|
+
= high_chart("charts.activity_by_hour", charts.activity_by_hour(author))
|
41
|
+
|
42
|
+
- elsif page == :day_of_week
|
43
|
+
%table{:class => "table table-bordered table-condensed"}
|
44
|
+
%tr
|
45
|
+
%th= :day.t
|
46
|
+
- I18n.t('date.abbr_day_names').each do |d|
|
47
|
+
%th= d
|
48
|
+
%tr
|
49
|
+
%th= :commits.t
|
50
|
+
- author.activity.by_wday_array.each do |commits|
|
51
|
+
%td= commits
|
52
|
+
%tr
|
53
|
+
%th= :percentage.t
|
54
|
+
- author.activity.by_wday_array.each do |commits|
|
55
|
+
%td= (commits * 100.0 / author.activity.by_wday_array.sum).round(1)
|
56
|
+
= high_chart("charts.activity_by_wday", charts.activity_by_wday(author))
|
57
|
+
|
58
|
+
- elsif page == :hour_of_week
|
59
|
+
%table{:class => "table table-bordered table-condensed"}
|
60
|
+
%tr
|
61
|
+
%th
|
62
|
+
- (0..23).each do |h|
|
63
|
+
%th= h
|
64
|
+
- max = author.activity.by_wday_hour.values.map {|h| h.values.empty? ? 0 : h.values.max }.max
|
65
|
+
- (0..6).each do |day|
|
66
|
+
%tr
|
67
|
+
%th= I18n.t('date.abbr_day_names')[day]
|
68
|
+
- (0..23).each do |hour|
|
69
|
+
- color = max ? "%02x" % (255 - author.activity.by_wday_hour[day][hour] * 100 / max) : "FF"
|
70
|
+
%td{style: "background-color: ##{color}#{color}#{color};"}= author.activity.by_wday_hour[day][hour]
|
71
|
+
|
72
|
+
- elsif page == :month_of_year
|
73
|
+
%table{:class => "table table-bordered table-condensed"}
|
74
|
+
%tr
|
75
|
+
%th= :month.t
|
76
|
+
- I18n.t('date.abbr_month_names')[1..-1].each do |m|
|
77
|
+
%th= m
|
78
|
+
%tr
|
79
|
+
%th= :commits.t
|
80
|
+
- author.activity.by_month_array.each do |commits|
|
81
|
+
%td= commits
|
82
|
+
%tr
|
83
|
+
%th= :percentage.t
|
84
|
+
- author.activity.by_month_array.each do |commits|
|
85
|
+
%td= (commits * 100.0 / author.activity.by_month_array.sum).round(1)
|
86
|
+
= high_chart("charts.activity_by_month", charts.activity_by_month(author))
|
87
|
+
|
88
|
+
- elsif page == :year
|
89
|
+
= high_chart("charts.activity_by_year", charts.activity_by_year(author))
|
90
|
+
|
91
|
+
- elsif page == :year_month
|
92
|
+
%table{:class => "table table-bordered table-condensed"}
|
93
|
+
%tr
|
94
|
+
%th
|
95
|
+
- I18n.t('date.abbr_month_names')[1..-1].each do |h|
|
96
|
+
%th= h
|
97
|
+
- author.activity.by_year_month.each do |year, months|
|
98
|
+
%tr
|
99
|
+
%th= year
|
100
|
+
- (1..12).each do |month|
|
101
|
+
%td= months[month]
|