test/repository_test.rb in gitdocs-0.5.0.pre3 vs test/repository_test.rb in gitdocs-0.5.0.pre5
- old
+ new
@@ -6,11 +6,11 @@
let(:author1) { 'Art T. Fish <afish@example.com>' }
let(:author2) { 'A U Thor <author@example.com>' }
before do
FileUtils.rm_rf('tmp/unit')
- FileUtils.mkdir_p(local_repo_path)
+ mkdir
repo = Rugged::Repository.init_at(local_repo_path)
repo.config['user.email'] = 'afish@example.com'
repo.config['user.name'] = 'Art T. Fish'
end
@@ -19,11 +19,10 @@
# tests when necessary.
let(:path_or_share) { local_repo_path }
let(:remote_repo) { Rugged::Repository.init_at('tmp/unit/remote', :bare) }
let(:local_repo) { Rugged::Repository.new(local_repo_path) }
-
describe 'initialize' do
subject { repository }
describe 'with a missing path' do
let(:path_or_share) { 'tmp/unit/missing_path' }
@@ -116,11 +115,10 @@
write_and_commit('file2', 'beef', 'commit', author1)
end
it { subject.must_equal [] }
end
-
describe 'term found' do
let(:term) { 'foo' }
before do
write_and_commit('file1', 'foo', 'commit', author1)
write_and_commit('file2', 'beef', 'commit', author1)
@@ -203,23 +201,59 @@
describe 'when there is no remote' do
it { subject.must_equal :no_remote }
end
- describe 'when there is an error' do
- before do
- Rugged::Remote.add(
- Rugged::Repository.new(local_repo_path),
- 'origin',
- 'file:///bad/remote'
- )
+ describe 'with a valid remote with no initial commits' do
+ before { create_local_repo_with_remote }
+
+ describe 'when there is an error fetching' do
+ before do
+ Grit::Repo.any_instance.stubs(:remote_fetch)
+ .raises(Grit::Git::CommandFailed.new('', 1, 'fetch error output'))
+ end
+ it { subject.must_equal 'fetch error output' }
end
- it { subject.must_equal "Fetching origin\n" }
+
+ describe 'when there are no local commits' do
+ it { subject.must_equal :ok }
+ end
+
+ describe 'when there is a local commit' do
+ before { write_and_commit('file1', 'beef', 'conflict commit', author1) }
+ it { subject.must_equal :ok }
+ it { subject ; commit_count(local_repo).must_equal 1 }
+ end
+
+ describe 'then new remote commits are fetched' do
+ before do
+ bare_commit(
+ remote_repo,
+ 'file2', 'deadbeef',
+ 'second commit',
+ 'author@example.com', 'A U Thor'
+ )
+ end
+
+ describe 'when there is an error merging' do
+ before do
+ Grit::Git.any_instance.stubs(:merge)
+ .raises(Grit::Git::CommandFailed.new('', 1, 'merge error output'))
+ end
+ it { subject.must_equal 'merge error output' }
+ end
+
+ describe ' and merged' do
+ it { subject.must_equal :ok }
+ it { subject ; local_file_exist?('file2').must_equal true }
+ it { subject ; commit_count(local_repo).must_equal 1 }
+ end
+ end
end
- describe 'with a valid remote' do
- before { create_local_repo_with_remote }
+ describe 'with a valid remote with commits' do
+ before { create_local_repo_with_remote_with_commit }
describe 'when there is nothing to pull' do
it { subject.must_equal :ok }
end
@@ -234,27 +268,33 @@
write_and_commit('file1', 'beef', 'conflict commit', author1)
end
it { subject.must_equal ['file1'] }
it { subject ; commit_count(local_repo).must_equal 2 }
- it { subject ; local_repo_files.count.must_equal 3 }
- it { subject ; local_repo_files.must_include 'file1 (f6ea049 original)' }
- it { subject ; local_repo_files.must_include 'file1 (18ed963)' }
- it { subject ; local_repo_files.must_include 'file1 (7bfce5c)' }
+ it { subject ; local_file_count.must_equal 3 }
+ it { subject ; local_file_content('file1 (f6ea049 original)').must_equal 'foobar' }
+ it { subject ; local_file_content('file1 (18ed963)').must_equal 'beef' }
+ it { subject ; local_file_content('file1 (7bfce5c)').must_equal 'dead' }
end
- describe 'when new commits are pulled and merged' do
+ describe 'when there is a non-conflicted local commit' do
+ before { write_and_commit('file1', 'beef', 'conflict commit', author1) }
+ it { subject.must_equal :ok }
+ it { subject ; commit_count(local_repo).must_equal 2 }
+ end
+
+ describe 'when new remote commits are pulled and merged' do
before do
bare_commit(
remote_repo,
'file2', 'deadbeef',
'second commit',
'author@example.com', 'A U Thor'
)
end
it { subject.must_equal :ok }
- it { subject ; File.exists?(File.join(local_repo_path, 'file2')).must_equal true }
+ it { subject ; local_file_exist?('file2').must_equal true }
it { subject ; commit_count(local_repo).must_equal 2 }
end
end
end
@@ -276,11 +316,11 @@
describe 'when no remote' do
let(:last_oid) { nil }
it { subject.must_equal :no_remote }
end
- describe 'remote exists' do
+ describe 'remote exists with no commits' do
before { create_local_repo_with_remote }
describe 'last sync is nil' do
let(:last_oid) { nil }
@@ -290,28 +330,158 @@
Grit::Git.any_instance.stubs(:push).raises(
Grit::Git::CommandFailed.new('', 1, '')
)
end
it { subject.must_equal :nothing }
+ it { subject ; commit_count(local_repo).must_equal 0 }
end
describe 'and there is a conflicted file to push' do
before do
bare_commit(remote_repo, 'file1', 'dead', 'commit', 'A U Thor', 'author@example.com')
write('file1', 'beef')
end
+ it { subject ; commit_count(local_repo).must_equal 1 }
+ it { subject ; commit_count(remote_repo).must_equal 1 }
+ it { subject.must_equal :nothing }
+ end
+
+ describe 'and there are empty directories to push' do
+ before do
+ mkdir('directory')
+ mkdir('.hidden_empty')
+ end
+ it { subject.must_equal :ok }
+ it { subject ; commit_count(local_repo).must_equal 1 }
+ it { subject ; commit_count(remote_repo).must_equal 1 }
+ it { subject ; head_commit(remote_repo).message.must_equal "message\n" }
+ it { subject ; head_tree_files(remote_repo).count.must_equal 2 }
+ it { subject ; head_tree_files(remote_repo).must_include 'directory' }
+ it { subject ; head_tree_files(remote_repo).must_include '.hidden_empty' }
+ it { subject ; Dir.glob("#{local_repo_path}/**/.gitignore", File::FNM_DOTMATCH).count.must_equal 2 }
+ end
+
+ describe 'and there is a directory with a hidden file' do
+ before do
+ mkdir('directory')
+ write('directory/.hidden', '')
+ end
+ it { subject.must_equal :ok }
+ it { subject ; local_file_exist?('directory', '.gitignore').must_equal false }
+ it { subject ; commit_count(local_repo).must_equal 1 }
+ it { subject ; commit_count(remote_repo).must_equal 1 }
+ it { subject ; head_commit(remote_repo).message.must_equal "message\n" }
+ it { subject ; head_tree_files(remote_repo).count.must_equal 1 }
+ it { subject ; head_tree_files(remote_repo).must_include 'directory' }
+ end
+
+ describe 'and there is a new file to push' do
+ before { write('file2', 'foobar') }
+ it { subject.must_equal :ok }
+ it { subject ; commit_count(local_repo).must_equal 1 }
+ it { subject ; commit_count(remote_repo).must_equal 1 }
+ it { subject ; head_commit(remote_repo).message.must_equal "message\n" }
+ it { subject ; head_tree_files(remote_repo).count.must_equal 1 }
+ it { subject ; head_tree_files(remote_repo).must_include 'file2' }
+ end
+ end
+
+ describe 'last sync is not nil' do
+ let(:last_oid) { 'oid' }
+
+ describe 'and this is an error on the push' do
+ before do
+ write('file2', 'foobar')
+
+ # Simulate an error occurring during the push
+ Grit::Git.any_instance.stubs(:push).raises(
+ Grit::Git::CommandFailed.new('', 1, 'error message')
+ )
+ end
+ it { subject.must_equal 'error message' }
+ end
+
+ describe 'and this is nothing to push' do
+ it { subject.must_equal :nothing }
+ it { subject ; commit_count(local_repo).must_equal 0 }
+ end
+
+ describe 'and there is a conflicted commit to push' do
+ before do
+ bare_commit(remote_repo, 'file1', 'dead', 'commit', 'A U Thor', 'author@example.com')
+ write('file1', 'beef')
+ end
+ it { subject ; commit_count(local_repo).must_equal 1 }
+ it { subject ; commit_count(remote_repo).must_equal 1 }
+ it { subject.must_equal :conflict }
+ end
+
+ describe 'and there is a commit to push' do
+ before { write('file2', 'foobar') }
+ it { subject.must_equal :ok }
+ it { subject ; commit_count(local_repo).must_equal 1 }
+ it { subject ; commit_count(remote_repo).must_equal 1 }
+ it { subject ; head_commit(remote_repo).message.must_equal "message\n" }
+ it { subject ; head_tree_files(remote_repo).count.must_equal 1 }
+ it { subject ; head_tree_files(remote_repo).must_include 'file2' }
+ end
+ end
+ end
+
+ describe 'remote exists' do
+ before { create_local_repo_with_remote_with_commit }
+
+ describe 'last sync is nil' do
+ let(:last_oid) { nil }
+
+ describe 'and there is an error on push' do
+ # Simulate an error occurring during the push
+ before do
+ Grit::Git.any_instance.stubs(:push).raises(
+ Grit::Git::CommandFailed.new('', 1, '')
+ )
+ end
+ it { subject.must_equal :nothing }
+ it { subject ; commit_count(local_repo).must_equal 1 }
+ end
+
+ describe 'and there is a conflicted file to push' do
+ before do
+ bare_commit(remote_repo, 'file1', 'dead', 'commit', 'A U Thor', 'author@example.com')
+ write('file1', 'beef')
+ end
it { subject ; commit_count(local_repo).must_equal 2 }
it { subject ; commit_count(remote_repo).must_equal 2 }
it { subject.must_equal :nothing }
end
- describe 'and there is an empty directory to push' do
- before { FileUtils.mkdir_p(File.join(local_repo_path, 'directory')) }
+ describe 'and there are empty directories to push' do
+ before do
+ mkdir('directory')
+ mkdir('.hidden_empty')
+ end
it { subject.must_equal :ok }
it { subject ; commit_count(local_repo).must_equal 2 }
it { subject ; commit_count(remote_repo).must_equal 2 }
it { subject ; head_commit(remote_repo).message.must_equal "message\n" }
+ it { subject ; head_tree_files(remote_repo).count.must_equal 3 }
+ it { subject ; head_tree_files(remote_repo).must_include 'file1' }
+ it { subject ; head_tree_files(remote_repo).must_include 'directory' }
+ it { subject ; head_tree_files(remote_repo).must_include '.hidden_empty' }
+ it { subject ; Dir.glob("#{local_repo_path}/**/.gitignore", File::FNM_DOTMATCH).count.must_equal 2 }
+ end
+
+ describe 'and there is a directory with a hidden file' do
+ before do
+ mkdir('directory')
+ write('directory/.hidden', '')
+ end
+ it { subject.must_equal :ok }
+ it { subject ; local_file_exist?('directory', '.gitignore').must_equal false }
+ it { subject ; commit_count(local_repo).must_equal 2 }
+ it { subject ; commit_count(remote_repo).must_equal 2 }
+ it { subject ; head_commit(remote_repo).message.must_equal "message\n" }
it { subject ; head_tree_files(remote_repo).count.must_equal 2 }
it { subject ; head_tree_files(remote_repo).must_include 'file1' }
it { subject ; head_tree_files(remote_repo).must_include 'directory' }
end
@@ -352,10 +522,11 @@
it { subject.must_equal 'error message' }
end
describe 'and this is nothing to push' do
it { subject.must_equal :nothing }
+ it { subject ; commit_count(local_repo).must_equal 1 }
end
describe 'and there is a conflicted commit to push' do
before do
bare_commit(remote_repo, 'file1', 'dead', 'commit', 'A U Thor', 'author@example.com')
@@ -503,24 +674,30 @@
write_and_commit('directory/file2', 'beef', 'commit3', author2)
end
describe 'file does not include the revision' do
let(:ref) { @commit0 }
- it { subject ; File.read(file_name).must_equal 'beef' }
+ it { subject ; local_file_content('directory', 'file2').must_equal 'beef' }
end
describe 'file does include the revision' do
let(:ref) { @commit2 }
- it { subject ; File.read(file_name).must_equal "bar\n" }
+ it { subject ; local_file_content('directory', 'file2').must_equal "bar\n" }
end
end
##############################################################################
private
-
def create_local_repo_with_remote
+ FileUtils.rm_rf(local_repo_path)
+ repo = Rugged::Repository.clone_at(remote_repo.path, local_repo_path)
+ repo.config['user.email'] = 'afish@example.com'
+ repo.config['user.name'] = 'Art T. Fish'
+ end
+
+ def create_local_repo_with_remote_with_commit
bare_commit(
remote_repo,
'file1', 'foobar',
'initial commit',
'author@example.com', 'A U Thor'
@@ -529,17 +706,21 @@
repo = Rugged::Repository.clone_at(remote_repo.path, local_repo_path)
repo.config['user.email'] = 'afish@example.com'
repo.config['user.name'] = 'Art T. Fish'
end
+ def mkdir(*path)
+ FileUtils.mkdir_p(File.join(local_repo_path, *path))
+ end
+
def write(filename, content)
- FileUtils.mkdir_p(File.join(local_repo_path, File.dirname(filename)))
+ mkdir(File.dirname(filename))
File.write(File.join(local_repo_path, filename), content)
end
def write_and_commit(filename, content, commit_msg, author)
- FileUtils.mkdir_p(File.join(local_repo_path, File.dirname(filename)))
+ mkdir(File.dirname(filename))
File.write(File.join(local_repo_path, filename), content)
`cd #{local_repo_path} ; git add #{filename}; git commit -m '#{commit_msg}' --author='#{author}'`
`cd #{local_repo_path} ; git rev-parse HEAD`.strip
end
@@ -563,23 +744,40 @@
def commit_count(repo)
walker = Rugged::Walker.new(repo)
walker.push(repo.head.target)
walker.count
+ rescue Rugged::ReferenceError
+ # The repo does not have a head => no commits.
+ 0
end
def head_commit(repo)
walker = Rugged::Walker.new(repo)
walker.push(repo.head.target)
walker.first
+ rescue Rugged::ReferenceError
+ # The repo does not have a head => no commits => no head commit.
+ nil
end
def head_tree_files(repo)
head_commit(repo).tree.map { |x| x[:name] }
end
- def local_repo_files
- Dir.chdir(local_repo_path) do
+ # NOTE: This method is ignoring hidden files.
+ def local_file_count
+ files = Dir.chdir(local_repo_path) do
Dir.glob('*')
end
+ files.count
+ end
+
+ def local_file_exist?(*path_elements)
+ File.exist?(File.join(local_repo_path, *path_elements))
+ end
+
+ def local_file_content(*path_elements)
+ local_file_exist?(*path_elements).must_equal true
+ File.read(File.join(local_repo_path, *path_elements))
end
end