@ -30,476 +30,515 @@
require 'spec_helper'
require 'spec_helper'
describe OpenProject :: Scm :: Adapters :: Git do
describe OpenProject :: Scm :: Adapters :: Git do
let ( :url ) { Rails . root . join ( '/tmp/does/not/exist.git' ) . to_s }
shared_examples " git adapter specs " do
let ( :config ) { { } }
let ( :protocol ) { " " }
let ( :encoding ) { nil }
let ( :url ) { protocol + Rails . root . join ( '/tmp/does/not/exist.git' ) . to_s }
let ( :adapter ) {
let ( :config ) { { } }
OpenProject :: Scm :: Adapters :: Git . new (
let ( :encoding ) { nil }
url ,
let ( :adapter ) {
nil ,
OpenProject :: Scm :: Adapters :: Git . new (
nil ,
url ,
nil ,
nil ,
encoding
nil ,
)
nil ,
}
encoding ,
" test-identifier "
before do
)
allow ( adapter . class ) . to receive ( :config ) . and_return ( config )
}
end
repos_dir = Dir . mktmpdir
describe 'client information' do
before do
it 'sets the Git client command' do
allow ( adapter . class ) . to receive ( :config ) . and_return ( config )
expect ( adapter . client_command ) . to eq ( 'git' )
end
context 'with client command from config' do
allow ( OpenProject :: Configuration )
let ( :config ) { { client_command : '/usr/local/bin/git' } }
. to receive ( :scm_local_checkout_path )
it 'overrides the Git client command from config' do
. and_return ( repos_dir )
expect ( adapter . client_command ) . to eq ( '/usr/local/bin/git' )
end
end
end
shared_examples 'correct client version' do | git_string , expected_version |
describe 'client information' do
it 'should set the correct client version' do
it 'sets the Git client command' do
expect ( adapter )
expect ( adapter . client_command ) . to eq ( 'git' )
. to receive ( :scm_version_from_command_line )
. and_return ( git_string )
expect ( adapter . client_version ) . to eq ( expected_version )
expect ( adapter . client_available ) . to be true
expect ( adapter . client_version_string ) . to eq ( expected_version . join ( '.' ) )
end
end
end
it_behaves_like 'correct client version' , " git version 1.7.3.4 \n " , [ 1 , 7 , 3 , 4 ]
it_behaves_like 'correct client version' , " 1.6.1 \n 1.7 \n 1.8 " , [ 1 , 6 , 1 ]
it_behaves_like 'correct client version' , " 1.6.2 \r \n 1.8.1 \r \n 1.9.1 " , [ 1 , 6 , 2 ]
end
describe 'invalid repository' do
context 'with client command from config' do
describe '.check_availability!' do
let ( :config ) { { client_command : '/usr/local/bin/git' } }
it 'should not be available' do
it 'overrides the Git client command from config' do
expect ( Dir . exists? ( url ) ) . to be false
expect ( adapter . client_command ) . to eq ( '/usr/local/bin/git' )
expect ( adapter ) . not_to be_available
end
expect { adapter . check_availability! }
. to raise_error ( OpenProject :: Scm :: Exceptions :: ScmUnavailable )
end
end
it 'should raise a meaningful error if shell output fails' do
shared_examples 'correct client version' do | git_string , expected_version |
expect ( adapter ) . to receive ( :branches )
it 'should set the correct client version' do
. and_raise OpenProject :: Scm :: Exceptions :: CommandFailed . new ( 'git' , '' )
expect ( adapter )
. to receive ( :scm_version_from_command_line )
. and_return ( git_string )
expect { adapter . check_availability! }
expect ( adapter . client_version ) . to eq ( expected_version )
. to raise_error ( OpenProject :: Scm :: Exceptions :: ScmUnavailable )
expect ( adapter . client_available ) . to be true
expect ( adapter . client_version_string ) . to eq ( expected_version . join ( '.' ) )
end
end
end
end
end
describe 'empty repository' do
it_behaves_like 'correct client version' , " git version 1.7.3.4 \n " , [ 1 , 7 , 3 , 4 ]
include_context 'with tmpdir'
it_behaves_like 'correct client version' , " 1.6.1 \n 1.7 \n 1.8 " , [ 1 , 6 , 1 ]
let ( :url ) { tmpdir }
it_behaves_like 'correct client version' , " 1.6.2 \r \n 1.8.1 \r \n 1.9.1 " , [ 1 , 6 , 2 ]
before do
adapter . initialize_bare_git
end
end
describe '.check_availability!' do
describe 'invalid repository' do
shared_examples 'check_availibility raises empty' do
describe '.check_availability!' do
it do
it 'should not be available' do
expect ( Dir . exists? ( url ) ) . to be false
expect ( adapter ) . not_to be_available
expect { adapter . check_availability! }
expect { adapter . check_availability! }
. to raise_error ( OpenProject :: Scm :: Exceptions :: ScmEmpty )
. to raise_error ( OpenProject :: Scm :: Exceptions :: ScmUnavailable )
end
end
end
it_behaves_like 'check_availibility raises empty'
it 'should raise a meaningful error if shell output fails' do
expect { adapter . check_availability! }
describe 'Git version compatibility' do
. to raise_error ( OpenProject :: Scm :: Exceptions :: ScmUnavailable )
before do
allow ( :: Open3 ) . to receive ( :capture2e ) . and_return ( output , nil )
end
context 'older Git version' do
let ( :output ) { " fatal: bad default revision 'HEAD' \n " }
it_behaves_like 'check_availibility raises empty'
end
context 'new Git version' do
let ( :output ) { " fatal: your current branch 'master' does not have any commits yet \n " }
it_behaves_like 'check_availibility raises empty'
end
end
end
end
end
end
end
describe 'local repository' do
describe 'empty repository' do
with_git_repository do | repo_dir |
include_context 'with tmpdir'
let ( :url ) { repo_ dir }
let ( :url ) { tmpdir }
it 'reads the git version' do
before do
expect ( adapter . client_version . length ) . to be > = 3
adapter . initialize_bare_git
end
end
it 'is a valid repository ' do
describe '.check_availability! ' do
expect ( Dir . exists? ( repo_dir ) ) . to be true
shared_examples 'check_availibility raises empty' do
it do
out , process = Open3 . capture2e ( 'git' , '--git-dir' , repo_dir , 'branch' )
expect { adapter . check_availability! }
expect ( process . exitstatus ) . to eq ( 0 )
. to raise_error ( OpenProject :: Scm :: Exceptions :: ScmEmpty )
expect ( out ) . to include ( 'master' )
end
end
end
it 'should be available' do
it_behaves_like 'check_availibility raises empty'
expect ( adapter ) . to be_available
expect { adapter . check_availability! } . to_not raise_error
end
it 'should read tags' do
describe 'Git version compatibility' do
expect ( adapter . tags ) . to match_array ( %w[ tag00.lightweight tag01.annotated ] )
before do
end
allow ( :: Open3 ) . to receive ( :capture2e ) . and_return ( output , nil )
end
describe '.branches ' do
context 'older Git version ' do
it 'should show the default branch' do
let ( :output ) { " fatal: bad default revision 'HEAD' \n " }
expect ( adapter . default_branch ) . to eq ( 'master' )
it_behaves_like 'check_availibility raises empty'
end
end
it 'should read branches' do
context 'new Git version' do
branches = %w[ latin-1-path-encoding master test-latin-1 test_branch ]
let ( :output ) { " fatal: your current branch 'master' does not have any commits yet \n " }
expect ( adapter . branches ) . to match_array ( branches )
it_behaves_like 'check_availibility raises empty'
end
end
end
end
end
end
describe '.info' do
describe 'local repository' do
it 'builds the info object' do
with_git_repository do | repo_dir |
info = adapter . info
let ( :url ) { " #{ protocol } #{ repo_dir } " }
expect ( info . root_url ) . to eq ( repo_dir )
expect ( info . lastrev . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
end
end
describe '.lastrev' do
before do
let ( :felix_hex ) { " Felix Sch \xC3 \xA4 fer " }
# make sure the repository is available before even bothering
# with the rest of the tests
expect ( adapter ) . to be_available
expect { adapter . check_availability! } . to_not raise_error
end
it 'references the last revision for empty path' do
it 'reads the git version' do
lastrev = adapter . lastrev ( '' , nil )
expect ( adapter . client_version . length ) . to be > = 3
expect ( lastrev . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
end
end
it 'references the last revision of the given path' do
it 'is a valid repository' do
lastrev = adapter . lastrev ( 'README' , nil )
expect ( Dir . exists? ( repo_dir ) ) . to be true
expect ( lastrev . identifier ) . to eq ( '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8' )
expect ( lastrev . author ) . to eq ( 'Adam Soltys <asoltys@gmail.com>' )
expect ( lastrev . time ) . to eq ( '2009-06-24 07:27:38 +0200' )
# Even though that commit has a message, lastrev doesn't parse that deliberately
out , process = Open3 . capture2e ( 'git' , '--git-dir' , repo_dir , 'branch' )
expect ( lastrev . message ) . to eq ( '' )
expect ( process . exitstatus ) . to eq ( 0 )
expect ( lastrev . branch ) . to be_nil
expect ( out ) . to include ( 'master' )
expect ( lastrev . paths ) . to be_nil
end
end
it 'references the last revision of the given path and identifier ' do
it 'should be using checkout ' do
lastrev = adapter . lastrev ( 'README' , '4f26664364207fa8b1af9f8722647ab2d4ac5d43' )
if protocol . blank?
expect ( lastrev . scmid ) . to eq ( '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8' )
expect ( adapter ) . not_to be_checkout
expect ( lastrev . identifier ) . to eq ( '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8' )
else
expect ( lastrev . author ) . to eq ( 'Adam Soltys <asoltys@gmail.com>' )
expect ( adapter ) . to be_checkout
expect ( lastrev . time ) . to eq ( '2009-06-24 05:27:38' )
end
end
end
it 'works with spaces in filename' do
it 'should be available' do
lastrev = adapter . lastrev ( 'filemane with spaces.txt' ,
expect ( adapter ) . to be_available
'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
expect { adapter . check_availability! } . to_not raise_error
expect ( lastrev . identifier ) . to eq ( 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
expect ( lastrev . scmid ) . to eq ( 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
expect ( lastrev . time ) . to eq ( '2010-09-18 19:59:46' )
end
end
it 'encodes strings correctly' do
it 'should read tags' do
lastrev = adapter . lastrev ( 'filemane with spaces.txt' ,
expect ( adapter . tags ) . to match_array ( %w[ tag00.lightweight tag01.annotated ] )
'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
expect ( lastrev . author ) . to eq ( 'Felix Schäfer <felix@fachschaften.org>' )
expect ( lastrev . author ) . to eq ( " #{ felix_hex } <felix@fachschaften.org> " )
end
end
end
describe '.revisions' do
describe '.branches' do
it 'should retrieve all revisions' do
it 'should show the default branch' do
rev = adapter . revisions ( '' , nil , nil , all : true )
expect ( adapter . default_branch ) . to eq ( 'master' )
expect ( rev . length ) . to eq ( 22 )
end
end
it 'should retrieve the latest revision ' do
it 'should read branches ' do
rev = adapter . revisions ( '' , nil , nil , all : true )
branches = %w[ latin-1-path-encoding master test-latin-1 test_branch ]
expect ( rev . latest . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
expect ( adapter . branches ) . to match_array ( branches )
expect ( rev . latest . format_identifier ) . to eq ( '71e5c1d3' )
end
end
end
it 'should retrieve a certain revisions' do
describe '.info' do
rev = adapter . revisions ( '' , '899a15d^' , '899a15d' )
it 'builds the info object' do
expect ( rev . length ) . to eq ( 1 )
info = adapter . info
expect ( rev [ 0 ] . identifier ) . to eq ( '899a15dba03a3b350b89c3f537e4bbe02a03cdc9' )
expect ( info . root_url ) . to eq ( " #{ protocol } #{ repo_dir } " )
expect ( rev [ 0 ] . author ) . to eq ( 'jsmith <jsmith@foo.bar>' )
expect ( info . lastrev . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
end
end
end
it 'should retrieve revisions in reverse' do
describe '.lastrev' do
rev = adapter . revisions ( '' , nil , nil , all : true , reverse : true )
let ( :felix_hex ) { " Felix Sch \xC3 \xA4 fer " }
expect ( rev . length ) . to eq ( 22 )
expect ( rev [ 0 ] . identifier ) . to eq ( '7234cb2750b63f47bff735edc50a1c0a433c2518' )
expect ( rev [ 20 ] . identifier ) . to eq ( '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127' )
end
it 'should retrieve revisions in a specific time frame' do
it 'references the last revision for empty path' do
since = Time . gm ( 2010 , 9 , 30 , 0 , 0 , 0 )
lastrev = adapter . lastrev ( '' , nil )
rev = adapter . revisions ( '' , nil , nil , all : true , since : since )
expect ( lastrev . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
expect ( rev . length ) . to eq ( 7 )
end
expect ( rev [ 0 ] . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
expect ( rev [ 1 ] . identifier ) . to eq ( '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127' )
expect ( rev [ 5 ] . identifier ) . to eq ( '9a6f3b947d16f11b537363a60904d1b1d3bfcd2f' )
expect ( rev [ 6 ] . identifier ) . to eq ( '67e7792ce20ccae2e4bb73eed09bb397819c8834' )
end
it 'should retrieve revisions in a specific time frame in reverse' do
it 'references the last revision of the given path' do
since = Time . gm ( 2010 , 9 , 30 , 0 , 0 , 0 )
lastrev = adapter . lastrev ( 'README' , nil )
rev = adapter . revisions ( '' , nil , nil , all : true , since : since , reverse : true )
expect ( lastrev . identifier ) . to eq ( '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8' )
expect ( rev . length ) . to eq ( 7 )
expect ( lastrev . author ) . to eq ( 'Adam Soltys <asoltys@gmail.com>' )
expect ( rev [ 0 ] . identifier ) . to eq ( '67e7792ce20ccae2e4bb73eed09bb397819c8834' )
expect ( lastrev . time ) . to eq ( '2009-06-24 07:27:38 +0200' )
expect ( rev [ 5 ] . identifier ) . to eq ( '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127' )
expect ( rev [ 6 ] . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
end
it 'should retrieve revisions by filename' do
# Even though that commit has a message, lastrev doesn't parse that deliberately
rev = adapter . revisions ( 'filemane with spaces.txt' , nil , nil , all : true )
expect ( lastrev . message ) . to eq ( '' )
expect ( rev . length ) . to eq ( 1 )
expect ( last rev. branch ) . to be_nil
expect ( rev [ 0 ] . identifier ) . to eq ( 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
expect ( lastrev . paths ) . to be_nil
end
end
it 'should retrieve revisions with arbitrary whitespace' do
it 'references the last revision of the given path and identifier' do
file = ' filename with a leading space.txt '
lastrev = adapter . lastrev ( 'README' , '4f26664364207fa8b1af9f8722647ab2d4ac5d43' )
rev = adapter . revisions ( file , nil , nil , all : true )
expect ( lastrev . scmid ) . to eq ( '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8' )
expect ( rev . length ) . to eq ( 1 )
expect ( lastrev . identifier ) . to eq ( '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8' )
expect ( rev [ 0 ] . paths [ 0 ] [ :path ] ) . to eq ( file )
expect ( lastrev . author ) . to eq ( 'Adam Soltys <asoltys@gmail.com>' )
end
expect ( lastrev . time ) . to eq ( '2009-06-24 05:27:38' )
end
it 'works with spaces in filename' do
lastrev = adapter . lastrev ( 'filemane with spaces.txt' ,
'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
expect ( lastrev . identifier ) . to eq ( 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
expect ( lastrev . scmid ) . to eq ( 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
expect ( lastrev . time ) . to eq ( '2010-09-18 19:59:46' )
end
it 'should show all paths of a revision' do
it 'encodes strings correctly ' do
rev = adapter . revisions ( '' , '899a15d^' , '899a15d' ) [ 0 ]
last rev = adapter . last rev( 'filemane with spaces.txt' ,
expect ( rev . paths . length ) . to eq ( 3 )
'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
expect ( rev . paths [ 0 ] ) . to eq ( action : 'M' , path : 'README' )
expect ( last rev. author ) . to eq ( 'Felix Schäfer <felix@fachschaften.org> ')
expect ( rev . paths [ 1 ] ) . to eq ( action : 'A' , path : 'images/edit.png' )
expect ( last rev. author ) . to eq ( " #{ felix_hex } <felix@fachschaften.org> " )
expect ( rev . paths [ 2 ] ) . to eq ( action : 'A' , path : 'sources/welcome_controller.rb' )
end
end
end
end
describe '.entries' do
describe '.revisions' do
shared_examples 'retrieve entries' do
it 'should retrieve all revisions' do
it 'should retrieve entries from an identifier' do
rev = adapter . revisions ( '' , nil , nil , all : true )
entries = adapter . entries ( '' , '83ca5fd' )
expect ( rev . length ) . to eq ( 22 )
expect ( entries . length ) . to eq ( 9 )
end
expect ( entries [ 0 ] . name ) . to eq ( 'images' )
it 'should retrieve the latest revision' do
expect ( entries [ 0 ] . kind ) . to eq ( 'dir' )
rev = adapter . revisions ( '' , nil , nil , all : true )
expect ( entries [ 0 ] . size ) . to be_nil
expect ( rev . latest . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
expect ( entries [ 0 ] ) . to be_dir
expect ( rev . latest . format_identifier ) . to eq ( '71e5c1d3' )
expect ( entries [ 0 ] ) . not_to be_file
end
expect ( entries [ 3 ] ) . to be_file
it 'should retrieve a certain revisions' do
expect ( entries [ 3 ] . size ) . to eq ( 56 )
rev = adapter . revisions ( '' , '899a15d^' , '899a15d' )
expect ( entries [ 3 ] . name ) . to eq ( ' filename with a leading space.txt ' )
expect ( rev . length ) . to eq ( 1 )
end
expect ( rev [ 0 ] . identifier ) . to eq ( '899a15dba03a3b350b89c3f537e4bbe02a03cdc9' )
expect ( rev [ 0 ] . author ) . to eq ( 'jsmith <jsmith@foo.bar>' )
it 'should have a related revision' do
end
entries = adapter . entries ( '' , '83ca5fd' )
rev = entries [ 0 ] . lastrev
it 'should retrieve revisions in reverse' do
expect ( rev . identifier ) . to eq ( 'deff712f05a90d96edbd70facc47d944be5897e3' )
rev = adapter . revisions ( '' , nil , nil , all : true , reverse : true )
expect ( rev . author ) . to eq ( 'Adam Soltys <asoltys@gmail.com>' )
expect ( rev . length ) . to eq ( 22 )
expect ( rev [ 0 ] . identifier ) . to eq ( '7234cb2750b63f47bff735edc50a1c0a433c2518' )
rev = entries [ 3 ] . lastrev
expect ( rev [ 20 ] . identifier ) . to eq ( '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127' )
expect ( rev . identifier ) . to eq ( '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c' )
end
expect ( rev . author ) . to eq ( 'Felix Schäfer <felix@fachschaften.org>' )
end
it 'should retrieve revisions in a specific time frame' do
since = Time . gm ( 2010 , 9 , 30 , 0 , 0 , 0 )
it 'can be retrieved by tag' do
rev = adapter . revisions ( '' , nil , nil , all : true , since : since )
entries = adapter . entries ( nil , 'tag01.annotated' )
expect ( rev . length ) . to eq ( 7 )
expect ( entries . length ) . to eq ( 3 )
expect ( rev [ 0 ] . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
expect ( rev [ 1 ] . identifier ) . to eq ( '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127' )
sources = entries [ 1 ]
expect ( rev [ 5 ] . identifier ) . to eq ( '9a6f3b947d16f11b537363a60904d1b1d3bfcd2f' )
expect ( sources . name ) . to eq ( 'sources' )
expect ( rev [ 6 ] . identifier ) . to eq ( '67e7792ce20ccae2e4bb73eed09bb397819c8834' )
expect ( sources . path ) . to eq ( 'sources' )
end
expect ( sources ) . to be_dir
it 'should retrieve revisions in a specific time frame in reverse' do
readme = entries [ 2 ]
since = Time . gm ( 2010 , 9 , 30 , 0 , 0 , 0 )
expect ( readme . name ) . to eq ( 'README' )
rev = adapter . revisions ( '' , nil , nil , all : true , since : since , reverse : true )
expect ( readme . path ) . to eq ( 'README' )
expect ( rev . length ) . to eq ( 7 )
expect ( readme ) . to be_file
expect ( rev [ 0 ] . identifier ) . to eq ( '67e7792ce20ccae2e4bb73eed09bb397819c8834' )
expect ( readme . size ) . to eq ( 27 )
expect ( rev [ 5 ] . identifier ) . to eq ( '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127' )
expect ( readme . lastrev . identifier ) . to eq ( '899a15dba03a3b350b89c3f537e4bbe02a03cdc9' )
expect ( rev [ 6 ] . identifier ) . to eq ( '71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
expect ( readme . lastrev . time ) . to eq ( Time . gm ( 2007 , 12 , 14 , 9 , 24 , 1 ) )
end
end
it 'should retrieve revisions by filename' do
it 'can be retrieved by branch' do
rev = adapter . revisions ( 'filemane with spaces.txt' , nil , nil , all : true )
entries = adapter . entries ( nil , 'test_branch' )
expect ( rev . length ) . to eq ( 1 )
expect ( entries . length ) . to eq ( 4 )
expect ( rev [ 0 ] . identifier ) . to eq ( 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b' )
sources = entries [ 1 ]
end
expect ( sources . name ) . to eq ( 'sources' )
expect ( sources . path ) . to eq ( 'sources' )
it 'should retrieve revisions with arbitrary whitespace' do
expect ( sources ) . to be_dir
file = ' filename with a leading space.txt '
rev = adapter . revisions ( file , nil , nil , all : true )
readme = entries [ 2 ]
expect ( rev . length ) . to eq ( 1 )
expect ( readme . name ) . to eq ( 'README' )
expect ( rev [ 0 ] . paths [ 0 ] [ :path ] ) . to eq ( file )
expect ( readme . path ) . to eq ( 'README' )
end
expect ( readme ) . to be_file
expect ( readme . size ) . to eq ( 159 )
it 'should show all paths of a revision' do
rev = adapter . revisions ( '' , '899a15d^' , '899a15d' ) [ 0 ]
expect ( readme . lastrev . identifier ) . to eq ( '713f4944648826f558cf548222f813dabe7cbb04' )
expect ( rev . paths . length ) . to eq ( 3 )
expect ( readme . lastrev . time ) . to eq ( Time . gm ( 2009 , 6 , 19 , 4 , 37 , 23 ) )
expect ( rev . paths [ 0 ] ) . to eq ( action : 'M' , path : 'README' )
expect ( rev . paths [ 1 ] ) . to eq ( action : 'A' , path : 'images/edit.png' )
expect ( rev . paths [ 2 ] ) . to eq ( action : 'A' , path : 'sources/welcome_controller.rb' )
end
end
end
end
describe 'encoding' do
describe '.entries' do
let ( :char1_hex ) { " \xc3 \x9c " . force_encoding ( 'UTF-8' ) }
shared_examples 'retrieve entries' do
it 'should retrieve entries from an identifier' do
entries = adapter . entries ( '' , '83ca5fd' )
expect ( entries . length ) . to eq ( 9 )
context 'with default encoding' do
expect ( entries [ 0 ] . name ) . to eq ( 'images' )
it_behaves_like 'retrieve entries'
expect ( entries [ 0 ] . kind ) . to eq ( 'dir' )
expect ( entries [ 0 ] . size ) . to be_nil
expect ( entries [ 0 ] ) . to be_dir
expect ( entries [ 0 ] ) . not_to be_file
it 'can retrieve directories containing entries encoded in latin-1' do
expect ( entries [ 3 ] ) . to be_file
entries = adapter . entries ( 'latin-1-dir' , '64f1f3e8' )
expect ( entries [ 3 ] . size ) . to eq ( 56 )
f1 = entries [ 1 ]
expect ( entries [ 3 ] . name ) . to eq ( ' filename with a leading space.txt ' )
end
expect ( f1 . name ) . to eq ( " test- \xDC -2.txt " )
it 'should have a related revision' do
expect ( f1 . path ) . to eq ( " latin-1-dir/test- \xDC -2.txt " )
entries = adapter . entries ( '' , '83ca5fd' )
expect ( f1 ) . to be_file
rev = entries [ 0 ] . lastrev
expect ( rev . identifier ) . to eq ( 'deff712f05a90d96edbd70facc47d944be5897e3' )
expect ( rev . author ) . to eq ( 'Adam Soltys <asoltys@gmail.com>' )
rev = entries [ 3 ] . lastrev
expect ( rev . identifier ) . to eq ( '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c' )
expect ( rev . author ) . to eq ( 'Felix Schäfer <felix@fachschaften.org>' )
end
end
it 'cannot retrieve files with latin-1 encoding in their path' do
it 'can be retrieved by tag' do
entries = adapter . entries ( 'latin-1-dir' , '64f1f3e8' )
entries = adapter . entries ( nil , 'tag01.annotated' )
latin1_path = entries [ 1 ] . path
expect ( entries . length ) . to eq ( 3 )
sources = entries [ 1 ]
expect ( sources . name ) . to eq ( 'sources' )
expect ( sources . path ) . to eq ( 'sources' )
expect ( sources ) . to be_dir
readme = entries [ 2 ]
expect ( readme . name ) . to eq ( 'README' )
expect ( readme . path ) . to eq ( 'README' )
expect ( readme ) . to be_file
expect ( readme . size ) . to eq ( 27 )
expect ( readme . lastrev . identifier ) . to eq ( '899a15dba03a3b350b89c3f537e4bbe02a03cdc9' )
expect ( readme . lastrev . time ) . to eq ( Time . gm ( 2007 , 12 , 14 , 9 , 24 , 1 ) )
end
expect { adapter . entries ( latin1_path , '1ca7f5ed' ) }
it 'can be retrieved by branch' do
. to raise_error ( OpenProject :: Scm :: Exceptions :: CommandFailed )
entries = adapter . entries ( nil , 'test_branch' )
expect ( entries . length ) . to eq ( 4 )
sources = entries [ 1 ]
expect ( sources . name ) . to eq ( 'sources' )
expect ( sources . path ) . to eq ( 'sources' )
expect ( sources ) . to be_dir
readme = entries [ 2 ]
expect ( readme . name ) . to eq ( 'README' )
expect ( readme . path ) . to eq ( 'README' )
expect ( readme ) . to be_file
expect ( readme . size ) . to eq ( 159 )
expect ( readme . lastrev . identifier ) . to eq ( '713f4944648826f558cf548222f813dabe7cbb04' )
expect ( readme . lastrev . time ) . to eq ( Time . gm ( 2009 , 6 , 19 , 4 , 37 , 23 ) )
end
end
end
end
context 'with latin-1 encoding' do
describe ' encoding' do
let ( :encoding ) { 'ISO-8859-1' }
let ( :char1_hex ) { " \xc3 \x9c " . force_encoding ( 'UTF-8' ) }
it_behaves_like 'retrieve entries'
context 'with default encoding' do
it_behaves_like 'retrieve entries'
it 'can be retrieved with latin-1 encoding' do
it 'can retrieve directories containing entries encoded in latin-1' do
entries = adapter . entries ( 'latin-1-dir' , '64f1f3e8' )
entries = adapter . entries ( 'latin-1-dir' , '64f1f3e8' )
expect ( entries . length ) . to eq ( 3 )
f1 = entries [ 1 ]
f1 = entries [ 1 ]
expect ( f1 . name ) . to eq ( " test- \xDC -2.txt " )
expect ( f1 . path ) . to eq ( " latin-1-dir/test- \xDC -2.txt " )
expect ( f1 ) . to be_file
end
it 'cannot retrieve files with latin-1 encoding in their path' do
entries = adapter . entries ( 'latin-1-dir' , '64f1f3e8' )
latin1_path = entries [ 1 ] . path
expect ( f1 . name ) . to eq ( " test- #{ char1_hex } -2.txt " )
expect { adapter . entries ( latin1_path , '1ca7f5ed' ) }
expect ( f1 . path ) . to eq ( " latin-1-dir/test- #{ char1_hex } -2.txt " )
. to raise_error ( OpenProject :: Scm :: Exceptions :: CommandFailed )
expect ( f1 ) . to be_file
end
end
end
it 'can be retrieved with latin-1 directories' do
context 'with latin-1 encoding' do
entries = adapter . entries ( " latin-1-dir/test- #{ char1_hex } -subdir " ,
let ( :encoding ) { 'ISO-8859-1' }
'1ca7f5ed' )
expect ( entries . length ) . to eq ( 3 )
it_behaves_like 'retrieve entries'
f1 = entries [ 1 ]
it 'can be retrieved with latin-1 encoding' do
entries = adapter . entries ( 'latin-1-dir' , '64f1f3e8' )
expect ( entries . length ) . to eq ( 3 )
f1 = entries [ 1 ]
expect ( f1 . name ) . to eq ( " test- #{ char1_hex } -2.txt " )
expect ( f1 . path ) . to eq ( " latin-1-dir/test- #{ char1_hex } -2.txt " )
expect ( f1 ) . to be_file
end
expect ( f1 ) . to be_file
it 'can be retrieved with latin-1 directories' do
expect ( f1 . name ) . to eq ( " test- #{ char1_hex } -2.txt " )
entries = adapter . entries ( " latin-1-dir/test- #{ char1_hex } -subdir " ,
expect ( f1 . path ) . to eq ( " latin-1-dir/test- #{ char1_hex } -subdir/test- #{ char1_hex } -2.txt " )
'1ca7f5ed' )
expect ( entries . length ) . to eq ( 3 )
f1 = entries [ 1 ]
expect ( f1 ) . to be_file
expect ( f1 . name ) . to eq ( " test- #{ char1_hex } -2.txt " )
expect ( f1 . path ) . to eq ( " latin-1-dir/test- #{ char1_hex } -subdir/test- #{ char1_hex } -2.txt " )
end
end
end
end
end
end
end
end
describe '.annotate' do
describe '.annotate' do
it 'should annotate a regular file' do
it 'should annotate a regular file' do
annotate = adapter . annotate ( 'sources/watchers_controller.rb' )
annotate = adapter . annotate ( 'sources/watchers_controller.rb' )
expect ( annotate ) . to be_kind_of ( OpenProject :: Scm :: Adapters :: Annotate )
expect ( annotate ) . to be_kind_of ( OpenProject :: Scm :: Adapters :: Annotate )
expect ( annotate . lines . length ) . to eq ( 41 )
expect ( annotate . lines . length ) . to eq ( 41 )
expect ( annotate . lines [ 4 ] . strip ) . to eq ( '# This program is free software; ' \
expect ( annotate . lines [ 4 ] . strip ) . to eq ( '# This program is free software; ' \
'you can redistribute it and/or' )
'you can redistribute it and/or' )
expect ( annotate . revisions [ 4 ] . identifier ) . to eq ( '7234cb2750b63f47bff735edc50a1c0a433c2518' )
expect ( annotate . revisions [ 4 ] . identifier ) . to eq ( '7234cb2750b63f47bff735edc50a1c0a433c2518' )
expect ( annotate . revisions [ 4 ] . author ) . to eq ( 'jsmith' )
expect ( annotate . revisions [ 4 ] . author ) . to eq ( 'jsmith' )
end
end
it 'should annotate moved file' do
it 'should annotate moved file' do
annotate = adapter . annotate ( 'renamed_test.txt' )
annotate = adapter . annotate ( 'renamed_test.txt' )
expect ( annotate . lines . length ) . to eq ( 2 )
expect ( annotate . lines . length ) . to eq ( 2 )
expect ( annotate . content ) . to eq ( " This is a test \n Let's pretend I'm adding a new feature! " )
expect ( annotate . content ) . to eq ( " This is a test \n Let's pretend I'm adding a new feature! " )
expect ( annotate . lines ) . to match_array ( [ 'This is a test' ,
expect ( annotate . lines ) . to match_array ( [ 'This is a test' ,
" Let's pretend I'm adding a new feature! " ] )
" Let's pretend I'm adding a new feature! " ] )
expect ( annotate . revisions . length ) . to eq ( 2 )
expect ( annotate . revisions . length ) . to eq ( 2 )
expect ( annotate . revisions [ 0 ] . identifier ) . to eq ( 'fba357b886984ee71185ad2065e65fc0417d9b92' )
expect ( annotate . revisions [ 0 ] . identifier ) . to eq ( 'fba357b886984ee71185ad2065e65fc0417d9b92' )
expect ( annotate . revisions [ 1 ] . identifier ) . to eq ( '7e61ac704deecde634b51e59daa8110435dcb3da' )
expect ( annotate . revisions [ 1 ] . identifier ) . to eq ( '7e61ac704deecde634b51e59daa8110435dcb3da' )
end
end
it 'should annotate with identifier' do
it 'should annotate with identifier' do
annotate = adapter . annotate ( 'README' , 'HEAD~10' )
annotate = adapter . annotate ( 'README' , 'HEAD~10' )
expect ( annotate . lines . length ) . to eq ( 1 )
expect ( annotate . lines . length ) . to eq ( 1 )
expect ( annotate . empty? ) . to be false
expect ( annotate . empty? ) . to be false
expect ( annotate . content ) . to eq ( " Mercurial test repository \r " )
expect ( annotate . content ) . to eq ( " Mercurial test repository \r " )
expect ( annotate . revisions . length ) . to eq ( 1 )
expect ( annotate . revisions . length ) . to eq ( 1 )
expect ( annotate . revisions [ 0 ] . identifier ) . to eq ( '899a15dba03a3b350b89c3f537e4bbe02a03cdc9' )
expect ( annotate . revisions [ 0 ] . identifier ) . to eq ( '899a15dba03a3b350b89c3f537e4bbe02a03cdc9' )
expect ( annotate . revisions [ 0 ] . author ) . to eq ( 'jsmith' )
expect ( annotate . revisions [ 0 ] . author ) . to eq ( 'jsmith' )
end
end
it 'should raise for an invalid path' do
it 'should raise for an invalid path' do
expect { adapter . annotate ( 'does_not_exist.txt' ) }
expect { adapter . annotate ( 'does_not_exist.txt' ) }
. to raise_error ( OpenProject :: Scm :: Exceptions :: CommandFailed )
. to raise_error ( OpenProject :: Scm :: Exceptions :: CommandFailed )
expect { adapter . annotate ( '/path/outside/repository' ) }
expect { adapter . annotate ( '/path/outside/repository' ) }
. to raise_error ( OpenProject :: Scm :: Exceptions :: CommandFailed )
. to raise_error ( OpenProject :: Scm :: Exceptions :: CommandFailed )
end
end
it 'should return nil for binary path' do
it 'should return nil for binary path' do
expect ( adapter . annotate ( 'images/edit.png' ) ) . to be_nil
expect ( adapter . annotate ( 'images/edit.png' ) ) . to be_nil
end
end
# We should rethink the output of annotated files for these formats.
# We should rethink the output of annotated files for these formats.
it 'also returns nil for UTF-16 encoded file' do
it 'also returns nil for UTF-16 encoded file' do
expect ( adapter . annotate ( 'utf16.txt' ) ) . to be_nil
expect ( adapter . annotate ( 'utf16.txt' ) ) . to be_nil
end
end
end
end
describe '.cat' do
describe '.cat' do
it 'outputs the given file' do
it 'outputs the given file' do
out = adapter . cat ( 'README' )
out = adapter . cat ( 'README' )
expect ( out ) . to include ( 'Git test repository' )
expect ( out ) . to include ( 'Git test repository' )
end
end
it 'raises an exception for an invalid file' do
it 'raises an exception for an invalid file' do
expect { adapter . cat ( 'doesnotexiss' ) }
expect { adapter . cat ( 'doesnotexiss' ) }
. to raise_error ( OpenProject :: Scm :: Exceptions :: CommandFailed )
. to raise_error ( OpenProject :: Scm :: Exceptions :: CommandFailed )
end
end
end
end
describe '.diff' do
describe '.diff' do
it 'provides a full diff of the last commit by default' do
it 'provides a full diff of the last commit by default' do
diff = adapter . diff ( '' , 'HEAD' )
diff = adapter . diff ( '' , 'HEAD' )
expect ( diff [ 0 ] ) . to eq ( 'commit 71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
expect ( diff [ 0 ] ) . to eq ( 'commit 71e5c1d3dca6304805b143b9d0e6695fb3895ea4' )
expect ( diff [ 1 ] ) . to eq ( " Author: Oliver G \xFC nther <mail@oliverguenther.de> " )
end
it 'provides a negative diff' do
bare = " Author: Oliver G \xFC nther <mail@oliverguenther.de> "
diff = adapter . diff ( '' , 'HEAD~2' , 'HEAD~1' )
cloned = " Author: Oliver Günther <mail@oliverguenther.de> "
expect ( diff . join ( " \n " ) ) . to include ( '-And this is a file' )
end
it 'provides the complete for the given range' do
# The strings returned by capture_out have escaped UTF-8 characters depending on
diff = adapter . diff ( '' , '61b685f' , '2f9c009' )
# wether we are working on a cloned or bare repository. I don't know why.
expect ( diff [ 1 ] ) . to eq ( 'index 6cbd30c..b94e68e 100644' )
# It doesn't make a difference further down the road, though. So just check both.
expect ( diff [ 10 ] ) . to eq ( 'index 4eca635..9a541fe 100644' )
expect ( diff [ 1 ] == bare || diff [ 1 ] == cloned ) . to eq true
end
end
it 'provides a negative diff' do
diff = adapter . diff ( '' , 'HEAD~2' , 'HEAD~1' )
expect ( diff . join ( " \n " ) ) . to include ( '-And this is a file' )
end
it 'provides the complete for the given range' do
diff = adapter . diff ( '' , '61b685f' , '2f9c009' )
expect ( diff [ 1 ] ) . to eq ( 'index 6cbd30c..b94e68e 100644' )
expect ( diff [ 10 ] ) . to eq ( 'index 4eca635..9a541fe 100644' )
end
it 'provides the selected diff for the given range' do
it 'provides the selected diff for the given range' do
diff = adapter . diff ( 'README' , '61b685f' , '2f9c009' )
diff = adapter . diff ( 'README' , '61b685f' , '2f9c009' )
expect ( diff ) . to eq ( << - DIFF . strip_heredoc . split ( " \n " ) )
expect ( diff ) . to eq ( << - DIFF . strip_heredoc . split ( " \n " ) )
diff - - git a / README b / README
diff - - git a / README b / README
index 6 cbd30c .. b94e68e 100644
index 6 cbd30c .. b94e68e 100644
- - - a / README
- - - a / README
+ + + b / README
+ + + b / README
@ @ - 1 + 1 , 4 @ @
@ @ - 1 + 1 , 4 @ @
Mercurial test repository
Mercurial test repository
+
+
+ Mercurial is a distributed version control system . Mercurial is dedicated to speed and efficiency with a sane user interface .
+ Mercurial is a distributed version control system . Mercurial is dedicated to speed and efficiency with a sane user interface .
+ It is written in Python .
+ It is written in Python .
DIFF
DIFF
end
end
end
end
end
end
end
end
end
context " with a local repository " do
it_behaves_like 'git adapter specs'
end
context " with a remote repository " do
it_behaves_like 'git adapter specs' do
let ( :protocol ) { " file:// " } # make it remote by using a protocol
end
end
end
end