metior 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.travis.yml +7 -0
- data/.yardopts +4 -0
- data/Changelog.md +22 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +44 -0
- data/LICENSE +25 -0
- data/README.md +117 -0
- data/Rakefile +48 -0
- data/lib/core_ext/object.rb +25 -0
- data/lib/metior.rb +50 -0
- data/lib/metior/actor.rb +85 -0
- data/lib/metior/commit.rb +118 -0
- data/lib/metior/errors.rb +19 -0
- data/lib/metior/git.rb +25 -0
- data/lib/metior/git/actor.rb +43 -0
- data/lib/metior/git/commit.rb +68 -0
- data/lib/metior/git/repository.rb +72 -0
- data/lib/metior/github.rb +27 -0
- data/lib/metior/github/actor.rb +43 -0
- data/lib/metior/github/commit.rb +55 -0
- data/lib/metior/github/repository.rb +99 -0
- data/lib/metior/repository.rb +273 -0
- data/lib/metior/vcs.rb +150 -0
- data/lib/metior/version.rb +11 -0
- data/metior.gemspec +26 -0
- data/test/fixtures/mojombo-grit-master-1b2fe77.txt +0 -0
- data/test/helper.rb +26 -0
- data/test/mock_vcs/actor.rb +28 -0
- data/test/mock_vcs/commit.rb +53 -0
- data/test/mock_vcs/repository.rb +72 -0
- data/test/test_class_loading.rb +61 -0
- data/test/test_git.rb +22 -0
- data/test/test_github.rb +43 -0
- data/test/test_metior.rb +34 -0
- data/test/test_repository.rb +150 -0
- data/test/test_vcs.rb +40 -0
- metadata +223 -0
data/metior.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/lib/metior/version')
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "metior"
|
7
|
+
s.version = Metior::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = [ 'Sebastian Staudt' ]
|
10
|
+
s.email = [ 'koraktor@gmail.com' ]
|
11
|
+
s.homepage = 'http://koraktor.de/metior'
|
12
|
+
s.summary = 'A source code history analyzer API'
|
13
|
+
s.description = 'Metior is a source code history analyzer that provides various statistics about a source code repository and its change over time.'
|
14
|
+
|
15
|
+
Bundler.definition.dependencies.each do |dep|
|
16
|
+
if dep.groups.include?(:development) || dep.groups.include?(:test)
|
17
|
+
s.add_development_dependency(dep.name, dep.requirement.to_s)
|
18
|
+
else
|
19
|
+
s.add_dependency(dep.name, dep.requirement.to_s)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
s.files = `git ls-files`.split("\n")
|
24
|
+
s.test_files = `git ls-files -- test/*`.split("\n")
|
25
|
+
s.require_paths = [ 'lib' ]
|
26
|
+
end
|
Binary file
|
data/test/helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
7
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
8
|
+
require 'metior'
|
9
|
+
include Metior
|
10
|
+
|
11
|
+
Bundler.require :test
|
12
|
+
|
13
|
+
# Extends TestCase functionality
|
14
|
+
class Test::Unit::TestCase
|
15
|
+
|
16
|
+
# Provides a negative assertion that's easier on the eyes
|
17
|
+
#
|
18
|
+
# The assertion fails, if the given value is +true+.
|
19
|
+
#
|
20
|
+
# @param [true, false] boolean The value that should be +false+
|
21
|
+
# @param [String] message The message that should be displayed
|
22
|
+
def assert_not(boolean, message = '')
|
23
|
+
assert !boolean, message
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'metior/actor'
|
7
|
+
|
8
|
+
module Metior
|
9
|
+
|
10
|
+
module MockVCS
|
11
|
+
|
12
|
+
class Actor < Metior::Actor
|
13
|
+
|
14
|
+
def self.id_for(actor)
|
15
|
+
actor.last
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(repo, actor)
|
19
|
+
super repo
|
20
|
+
|
21
|
+
@id = actor.last
|
22
|
+
@name = actor.first
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'mock_vcs/actor'
|
7
|
+
require 'metior/commit'
|
8
|
+
|
9
|
+
module Metior
|
10
|
+
|
11
|
+
module MockVCS
|
12
|
+
|
13
|
+
class Commit < Metior::Commit
|
14
|
+
|
15
|
+
def initialize(repo, range, commit)
|
16
|
+
super repo, range
|
17
|
+
|
18
|
+
@additions = commit[:impact].first.to_i
|
19
|
+
@authored_date = Time.at commit[:info][6].to_i
|
20
|
+
@committed_date = Time.at commit[:info][3].to_i
|
21
|
+
@deletions = commit[:impact].last.to_i
|
22
|
+
@id = commit[:ids].first
|
23
|
+
@message = commit[:info].first
|
24
|
+
|
25
|
+
authors = repo.authors range
|
26
|
+
@author = authors[Actor.id_for commit[:info][4..5]]
|
27
|
+
@author = Actor.new repo, commit[:info][4..5] if author.nil?
|
28
|
+
@author.add_commit self
|
29
|
+
|
30
|
+
committers = repo.committers range
|
31
|
+
@committer = committers[Actor.id_for commit[:info][1..2]]
|
32
|
+
@committer = Actor.new repo, commit[:info][1..2] if @committer.nil?
|
33
|
+
@committer.add_commit self
|
34
|
+
|
35
|
+
@added_files = []
|
36
|
+
@modified_files = []
|
37
|
+
@deleted_files = []
|
38
|
+
commit[:files].each do |file|
|
39
|
+
if file.first == 'A'
|
40
|
+
@added_files << file.last
|
41
|
+
elsif file.first == 'A'
|
42
|
+
@deleted_files << file.last
|
43
|
+
else
|
44
|
+
@modified_files << file.last
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'metior/repository'
|
7
|
+
require 'mock_vcs/commit'
|
8
|
+
|
9
|
+
module Metior
|
10
|
+
|
11
|
+
module MockVCS
|
12
|
+
|
13
|
+
NAME = :mock
|
14
|
+
|
15
|
+
include VCS
|
16
|
+
|
17
|
+
class Repository < Metior::Repository
|
18
|
+
|
19
|
+
DEFAULT_BRANCH = 'master'
|
20
|
+
|
21
|
+
include Metior::MockVCS
|
22
|
+
|
23
|
+
def initialize(path)
|
24
|
+
super path
|
25
|
+
|
26
|
+
@file = File.open(File.expand_path(path), 'r')
|
27
|
+
@file.set_encoding 'utf-8' if @file.respond_to? :set_encoding
|
28
|
+
end
|
29
|
+
|
30
|
+
def load_commits(range)
|
31
|
+
commits = []
|
32
|
+
|
33
|
+
commit = {}
|
34
|
+
@file.lines.each do |line|
|
35
|
+
line.strip!
|
36
|
+
|
37
|
+
next if line.empty?
|
38
|
+
|
39
|
+
if line.match /^[AMD]\0/
|
40
|
+
commit[:files] = [] unless commit.key? :files
|
41
|
+
commit[:files] << line.split("\0")
|
42
|
+
elsif line.match /\d+\0\d+$/
|
43
|
+
commit[:impact] = line.split("\0")
|
44
|
+
|
45
|
+
if commits.empty?
|
46
|
+
if range.first != '' && !commit[:ids].include?(range.last)
|
47
|
+
commit = {}
|
48
|
+
next
|
49
|
+
end
|
50
|
+
elsif commit[:ids].include? range.first
|
51
|
+
break
|
52
|
+
end
|
53
|
+
|
54
|
+
commits << commit
|
55
|
+
commit = {}
|
56
|
+
else
|
57
|
+
line = line.split("\0")
|
58
|
+
ids = [line[0]]
|
59
|
+
ids += line[1][2..-2].split(', ') unless line[1].empty?
|
60
|
+
commit[:ids] = ids
|
61
|
+
commit[:info] = line[2..-1]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
commits
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
class TestClassLoading < Test::Unit::TestCase
|
9
|
+
|
10
|
+
context 'Metior' do
|
11
|
+
|
12
|
+
should 'load basic modules and dependencies first' do
|
13
|
+
assert Object.const_defined? :Metior
|
14
|
+
assert Metior.const_defined? :Git
|
15
|
+
assert Metior.const_defined? :GitHub
|
16
|
+
assert Metior.const_defined? :VCS
|
17
|
+
assert Metior.const_defined? :VERSION
|
18
|
+
|
19
|
+
assert !Metior.const_defined?(:Actor)
|
20
|
+
assert !Metior.const_defined?(:Commit)
|
21
|
+
assert !Metior.const_defined?(:Repository)
|
22
|
+
assert !Metior::Git.const_defined?(:Actor)
|
23
|
+
assert !Metior::Git.const_defined?(:Commit)
|
24
|
+
assert !Metior::Git.const_defined?(:Repository)
|
25
|
+
assert !Metior::GitHub.const_defined?(:Actor)
|
26
|
+
assert !Metior::GitHub.const_defined?(:Commit)
|
27
|
+
assert !Metior::GitHub.const_defined?(:Repository)
|
28
|
+
|
29
|
+
assert !Object.const_defined?(:Grit)
|
30
|
+
assert !Object.const_defined?(:Octokit)
|
31
|
+
end
|
32
|
+
|
33
|
+
should 'load requirements when using Git' do
|
34
|
+
Metior::Git::Repository
|
35
|
+
|
36
|
+
assert Metior.const_defined? :Actor
|
37
|
+
assert Metior.const_defined? :Commit
|
38
|
+
assert Metior.const_defined? :Repository
|
39
|
+
assert Metior::Git.const_defined? :Actor
|
40
|
+
assert Metior::Git.const_defined? :Commit
|
41
|
+
assert Metior::Git.const_defined? :Repository
|
42
|
+
|
43
|
+
assert Object.const_defined? :Grit
|
44
|
+
end
|
45
|
+
|
46
|
+
should 'load requirements when using GitHub' do
|
47
|
+
Metior::GitHub::Repository
|
48
|
+
|
49
|
+
assert Metior.const_defined? :Actor
|
50
|
+
assert Metior.const_defined? :Commit
|
51
|
+
assert Metior.const_defined? :Repository
|
52
|
+
assert Metior::GitHub.const_defined? :Actor
|
53
|
+
assert Metior::GitHub.const_defined? :Commit
|
54
|
+
assert Metior::GitHub.const_defined? :Repository
|
55
|
+
|
56
|
+
assert Object.const_defined? :Octokit
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
data/test/test_git.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
class TestGit < Test::Unit::TestCase
|
9
|
+
|
10
|
+
context 'The Git implementation' do
|
11
|
+
|
12
|
+
should 'support file stats' do
|
13
|
+
assert Metior::Git.supports? :file_stats
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'support line stats' do
|
17
|
+
assert Metior::Git.supports? :line_stats
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/test/test_github.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
class TestGitHub < Test::Unit::TestCase
|
9
|
+
|
10
|
+
context 'The GitHub implementation' do
|
11
|
+
|
12
|
+
should 'not support file stats' do
|
13
|
+
assert_not Metior::GitHub.supports? :file_stats
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'not support line stats' do
|
17
|
+
assert_not Metior::GitHub.supports? :line_stats
|
18
|
+
end
|
19
|
+
|
20
|
+
should 'not be able to get file stats of a repository' do
|
21
|
+
repo = Metior::GitHub::Repository.new 'koraktor', 'rubikon'
|
22
|
+
assert_raises UnsupportedError do
|
23
|
+
repo.file_stats
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'not be able to get the most significant authors of a repository' do
|
28
|
+
repo = Metior::GitHub::Repository.new 'koraktor', 'rubikon'
|
29
|
+
assert_raises UnsupportedError do
|
30
|
+
repo.significant_authors
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
should 'not be able to get the most significant commits of a repository' do
|
35
|
+
repo = Metior::GitHub::Repository.new 'koraktor', 'rubikon'
|
36
|
+
assert_raises UnsupportedError do
|
37
|
+
repo.significant_commits
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/test/test_metior.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
class TestMetior < Test::Unit::TestCase
|
9
|
+
|
10
|
+
context 'Metior' do
|
11
|
+
|
12
|
+
should 'should provide several VCS implementations' do
|
13
|
+
assert_equal({ :git => Git, :github => GitHub }, Metior.vcs_types)
|
14
|
+
assert_equal Git, Metior.vcs(:git)
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'raise an error if an implementation does not exist' do
|
18
|
+
begin
|
19
|
+
Metior.vcs :unknown
|
20
|
+
assert false
|
21
|
+
rescue
|
22
|
+
assert $!.is_a? RuntimeError
|
23
|
+
assert_equal 'No VCS registered for :unknown', $!.message
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'allow easy creation of a implementation specific repository' do
|
28
|
+
assert_kind_of Git::Repository, Metior.repository(:git, File.dirname(File.dirname(__FILE__)))
|
29
|
+
assert_kind_of GitHub::Repository, Metior.repository(:github, 'some', 'user')
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
# This code is free software; you can redistribute it and/or modify it under
|
2
|
+
# the terms of the new BSD License.
|
3
|
+
#
|
4
|
+
# Copyright (c) 2011, Sebastian Staudt
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
class TestRepository < Test::Unit::TestCase
|
9
|
+
|
10
|
+
context 'The base class for Metior VCS repositories' do
|
11
|
+
|
12
|
+
setup do
|
13
|
+
require 'metior/repository'
|
14
|
+
|
15
|
+
@repo = Metior::Repository.new('dummy')
|
16
|
+
end
|
17
|
+
|
18
|
+
should 'not implement the #load_commits method' do
|
19
|
+
assert_raise NotImplementedError do
|
20
|
+
@repo.send(:load_commits, nil)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'parse commit ranges correctly' do
|
25
|
+
assert_equal 'master'..'development', @repo.send(:parse_range, 'master'..'development')
|
26
|
+
assert_equal 'master'..'development', @repo.send(:parse_range, 'master..development')
|
27
|
+
assert_equal ''..'master', @repo.send(:parse_range, 'master')
|
28
|
+
end
|
29
|
+
|
30
|
+
should 'hit the cache when loading the same commit range' do
|
31
|
+
@repo.expects(:load_commits).once.returns([])
|
32
|
+
|
33
|
+
@repo.commits 'master'
|
34
|
+
@repo.commits 'master'
|
35
|
+
end
|
36
|
+
|
37
|
+
should 'miss the cache when loading a different commit range' do
|
38
|
+
@repo.expects(:load_commits).twice.returns([])
|
39
|
+
|
40
|
+
@repo.commits 'master'
|
41
|
+
@repo.commits 'HEAD'
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'A repository implementation' do
|
47
|
+
|
48
|
+
setup do
|
49
|
+
require 'mock_vcs/repository'
|
50
|
+
|
51
|
+
repo_file = "#{File.dirname(__FILE__)}/fixtures/mojombo-grit-master-1b2fe77.txt"
|
52
|
+
@repo = MockVCS::Repository.new repo_file
|
53
|
+
end
|
54
|
+
|
55
|
+
should 'be able to load all commits from the repository' do
|
56
|
+
commits = @repo.commits
|
57
|
+
assert_equal 415, commits.size
|
58
|
+
assert commits.all? { |commit| commit.is_a? Metior::Commit }
|
59
|
+
|
60
|
+
head = commits.first
|
61
|
+
assert_equal '4c592b4', head.id
|
62
|
+
end
|
63
|
+
|
64
|
+
should 'be able to load a range of commits from the repository' do
|
65
|
+
commits = @repo.commits 'ef2870b'..'4c592b4'
|
66
|
+
assert_equal 5, commits.size
|
67
|
+
assert commits.all? { |commit| commit.is_a? Metior::Commit }
|
68
|
+
assert_equal '4c592b4', commits.first.id
|
69
|
+
assert_equal 'f0cc7f7', commits.last.id
|
70
|
+
end
|
71
|
+
|
72
|
+
should 'know the authors of the repository' do
|
73
|
+
authors = @repo.authors
|
74
|
+
assert_equal 37, authors.size
|
75
|
+
assert authors.values.all? { |author| author.is_a? Metior::Actor }
|
76
|
+
|
77
|
+
assert_equal %w{
|
78
|
+
adam@therealadam.com aman@tmm1.net antonin@hildebrand.cz
|
79
|
+
bobbywilson0@gmail.com bryce@worldmedia.net cehoffman@gmail.com
|
80
|
+
chapados@sciencegeeks.org cho45@lowreal.net chris@ozmm.org
|
81
|
+
davetron5000@gmail.com david.kowis@rackspace.com dustin@spy.net
|
82
|
+
engel@engel.uk.to evil@che.lu gram.gibson@uky.edu
|
83
|
+
hiroshi3110@gmail.com igor@wiedler.ch johan@johansorensen.com
|
84
|
+
jos@catnook.com jpriddle@nevercraft.net kamal.fariz@gmail.com
|
85
|
+
koraktor@gmail.com mtraverso@acm.org ohnobinki@ohnopublishing.net
|
86
|
+
paul+git@mjr.org pjhyett@gmail.com rsanheim@gmail.com
|
87
|
+
rtomayko@gmail.com schacon@gmail.com scott@railsnewbie.com
|
88
|
+
technoweenie@gmail.com tim@dysinger.net tim@spork.in
|
89
|
+
tom@mojombo.com tom@taco.(none) voker57@gmail.com wayne@larsen.st
|
90
|
+
}, authors.keys.sort
|
91
|
+
end
|
92
|
+
|
93
|
+
should 'know the committers of the repository' do
|
94
|
+
committers = @repo.committers
|
95
|
+
assert_equal 29, committers.size
|
96
|
+
assert committers.values.all? { |committer| committer.is_a? Metior::Actor }
|
97
|
+
|
98
|
+
assert_equal %w{
|
99
|
+
adam@therealadam.com aman@tmm1.net antonin@hildebrand.cz
|
100
|
+
bobbywilson0@gmail.com bryce@worldmedia.net chris@ozmm.org
|
101
|
+
davetron5000@gmail.com david.kowis@rackspace.com dustin@spy.net
|
102
|
+
engel@engel.uk.to evil@che.lu hiroshi3110@gmail.com
|
103
|
+
johan@johansorensen.com jos@catnook.com kamal.fariz@gmail.com
|
104
|
+
koraktor@gmail.com mtraverso@acm.org ohnobinki@ohnopublishing.net
|
105
|
+
paul+git@mjr.org pjhyett@gmail.com rsanheim@gmail.com
|
106
|
+
rtomayko@gmail.com schacon@gmail.com technoweenie@gmail.com
|
107
|
+
tim@dysinger.net tim@spork.in tom@mojombo.com tom@taco.(none)
|
108
|
+
voker57@gmail.com
|
109
|
+
}, committers.keys.sort
|
110
|
+
end
|
111
|
+
|
112
|
+
should 'know the most significant authors of the repository' do
|
113
|
+
authors = @repo.significant_authors
|
114
|
+
assert_equal 3, authors.size
|
115
|
+
assert authors.all? { |author| author.is_a? Metior::Actor }
|
116
|
+
|
117
|
+
assert_equal [
|
118
|
+
"tom@mojombo.com", "schacon@gmail.com", "rtomayko@gmail.com"
|
119
|
+
], authors.collect { |author| author.id }
|
120
|
+
end
|
121
|
+
|
122
|
+
should 'know the most significant commits of the repository' do
|
123
|
+
commits = @repo.significant_commits('master', 8)
|
124
|
+
assert_equal 8, commits.size
|
125
|
+
assert commits.all? { |commit| commit.is_a? Metior::Commit }
|
126
|
+
|
127
|
+
assert_equal %w{
|
128
|
+
c0f0b4f 47ab25c f3a24ae 18ec70e 242253b c87612b 6bb41e4 4d9c7be
|
129
|
+
}, commits.collect { |commit| commit.id }
|
130
|
+
|
131
|
+
modifications = commits.first.modifications
|
132
|
+
commits[1..-1].each do |commit|
|
133
|
+
assert modifications >= commit.modifications
|
134
|
+
modifications = commit.modifications
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
should 'know the top authors of the repository' do
|
139
|
+
authors = @repo.top_authors
|
140
|
+
assert_equal 3, authors.size
|
141
|
+
assert authors.all? { |author| author.is_a? Metior::Actor }
|
142
|
+
|
143
|
+
assert_equal [
|
144
|
+
"tom@mojombo.com", "schacon@gmail.com", "technoweenie@gmail.com"
|
145
|
+
], authors.collect { |author| author.id }
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|