diff --git a/lib/git_stats/by_field_finder.rb b/lib/git_stats/by_field_finder.rb new file mode 100644 index 000000000..eadcb508d --- /dev/null +++ b/lib/git_stats/by_field_finder.rb @@ -0,0 +1,6 @@ +module ByFieldFinder + def method_missing(name, *args, &block) + field = name[/^by_(.*)$/, 1] + field ? find { |e| e.send(field) == args.first } : super + end +end \ No newline at end of file diff --git a/lib/git_stats/git_data/repo.rb b/lib/git_stats/git_data/repo.rb index b5b808052..dfaa12682 100644 --- a/lib/git_stats/git_data/repo.rb +++ b/lib/git_stats/git_data/repo.rb @@ -13,16 +13,15 @@ module GitStats end def authors - @authors ||= Command.new(self, 'git shortlog -se HEAD').run_and_parse.inject({}) do |hash, author| - hash[author[:email]] = Author.new(repo: self, name: author[:name], email: author[:email]) - hash - end + @authors ||= Command.new(self, 'git shortlog -se HEAD').run_and_parse.map do |author| + Author.new(repo: self, name: author[:name], email: author[:email]) + end.extend(ByFieldFinder) end def commits @commits ||= Command.new(self, 'git rev-list --pretty=format:"%h|%at|%ai|%aE" HEAD | grep -v commit').run.lines.map do |commit_line| hash, stamp, date, author_email = commit_line.split('|').map(&:strip) - author = authors[author_email] + author = authors.by_email(author_email) date = DateTime.parse(date) Commit.new(repo: self, hash: hash, stamp: stamp, date: date, author: author) diff --git a/spec/by_field_finder_spec.rb b/spec/by_field_finder_spec.rb new file mode 100644 index 000000000..5d1177abd --- /dev/null +++ b/spec/by_field_finder_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe ByFieldFinder do + let(:sut) { [double(field1: 'aa', field2: 'bb'), double(field1: 'cc', field2: 'bb'), double(field1: 'aa', field2: 'dd')].extend(ByFieldFinder) } + + [ + {field: :field1, search_value: 'aa', matching_index: 0}, + {field: :field1, search_value: 'cc', matching_index: 1}, + {field: :field2, search_value: 'bb', matching_index: 0}, + {field: :field2, search_value: 'dd', matching_index: 2}, + ].each do |test_params| + it 'should return first matching object' do + sut.send("by_#{test_params[:field]}", test_params[:search_value]).should == sut[test_params[:matching_index]] + end + end + + it 'should return nil if no object matches' do + sut.by_field1('xx').should == nil + end + + it 'should throw exception if elements doesnt respond to given field' do + expect { sut.by_non_existing_field }.to raise_error + end +end \ No newline at end of file diff --git a/spec/integration/repo_spec.rb b/spec/integration/repo_spec.rb new file mode 100644 index 000000000..395217242 --- /dev/null +++ b/spec/integration/repo_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe GitStats::GitData::Repo do + let(:repo) { build(:repo, path: 'spec/integration/test_repo', last_commit: '81e8be') } + let(:expected_authors) { [ + build(:author, repo: repo, name: "Tomasz Gieniusz", email: "tomasz.gieniusz@gmail.com"), + build(:author, repo: repo, name: "John Doe", email: "john.doe@gmail.com"), + ] } + + it 'should return all authors' do + repo.authors.should =~ expected_authors + end + +end \ No newline at end of file diff --git a/spec/repo_spec.rb b/spec/repo_spec.rb index 5e462d3c8..26aec9f93 100644 --- a/spec/repo_spec.rb +++ b/spec/repo_spec.rb @@ -2,10 +2,10 @@ require 'spec_helper' describe GitStats::GitData::Repo do let(:repo) { build(:repo) } - let(:expected_authors) { { - "john.doe@gmail.com" => build(:author, repo: repo, name: "John Doe", email: "john.doe@gmail.com"), - "joe.doe@gmail.com" => build(:author, repo: repo, name: "Joe Doe", email: "joe.doe@gmail.com") - } } + let(:expected_authors) { [ + build(:author, repo: repo, name: "John Doe", email: "john.doe@gmail.com"), + build(:author, repo: repo, name: "Joe Doe", email: "joe.doe@gmail.com") + ] } describe 'commit range' do it 'should return HEAD by default' do @@ -48,13 +48,13 @@ ce34874|1347482927|2012-09-12 22:48:47 +0200|joe.doe@gmail.com repo.commits.should == [ GitStats::GitData::Commit.new( repo: repo, hash: "5eab339", stamp: "1345835073", date: DateTime.parse("2012-08-24 21:04:33 +0200"), - author: repo.authors["john.doe@gmail.com"]), + author: repo.authors.by_email("john.doe@gmail.com")), GitStats::GitData::Commit.new( repo: repo, hash: "ce34874", stamp: "1347482927", date: DateTime.parse("2012-09-12 22:48:47 +0200"), - author: repo.authors["joe.doe@gmail.com"]), + author: repo.authors.by_email("joe.doe@gmail.com")), GitStats::GitData::Commit.new( repo: repo, hash: "e4412c3", stamp: "1348603824", date: DateTime.parse("2012-09-25 22:10:24 +0200"), - author: repo.authors["john.doe@gmail.com"]) + author: repo.authors.by_email("john.doe@gmail.com")) ] end end