34
40
from bzrlib.clone import copy_branch
35
41
from bzrlib.errors import BzrCommandError
36
42
from bzrlib.osutils import has_symlinks
37
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
38
from bzrlib.selftest.HTTPTestUtil import TestCaseWithWebserver
41
class ExternalBase(TestCaseInTempDir):
43
def runbzr(self, args, retcode=0, backtick=False):
44
if isinstance(args, basestring):
48
return self.run_bzr_captured(args, retcode=retcode)[0]
50
return self.run_bzr_captured(args, retcode=retcode)
43
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
44
from bzrlib.tests.blackbox import ExternalBase
53
46
class TestCommands(ExternalBase):
137
130
self.runbzr(['add', 'foo.c'])
138
131
self.runbzr(["commit", "-m", ""] , retcode=3)
133
def test_remove_deleted(self):
135
self.build_tree(['a'])
136
self.runbzr(['add', 'a'])
137
self.runbzr(['commit', '-m', 'added a'])
139
self.runbzr(['remove', 'a'])
140
141
def test_other_branch_commit(self):
141
142
# this branch is to ensure consistent behaviour, whether we're run
142
143
# inside a branch, or not.
157
158
self.runbzr('commit -m newstuff branch')
158
159
self.runbzr('commit -m newstuff branch', retcode=3)
161
161
def test_ignore_patterns(self):
162
162
from bzrlib.branch import Branch
164
b = Branch.initialize('.')
165
self.assertEquals(list(b.unknowns()), [])
163
Branch.initialize('.')
164
self.assertEquals(self.capture('unknowns'), '')
167
166
file('foo.tmp', 'wt').write('tmp files are ignored')
168
self.assertEquals(list(b.unknowns()), [])
169
167
self.assertEquals(self.capture('unknowns'), '')
171
169
file('foo.c', 'wt').write('int main() {}')
172
self.assertEquals(list(b.unknowns()), ['foo.c'])
173
170
self.assertEquals(self.capture('unknowns'), 'foo.c\n')
175
172
self.runbzr(['add', 'foo.c'])
178
175
# 'ignore' works when creating the .bzignore file
179
176
file('foo.blah', 'wt').write('blah')
180
self.assertEquals(list(b.unknowns()), ['foo.blah'])
177
self.assertEquals(self.capture('unknowns'), 'foo.blah\n')
181
178
self.runbzr('ignore *.blah')
182
self.assertEquals(list(b.unknowns()), [])
179
self.assertEquals(self.capture('unknowns'), '')
183
180
self.assertEquals(file('.bzrignore', 'rU').read(), '*.blah\n')
185
182
# 'ignore' works when then .bzrignore file already exists
186
183
file('garh', 'wt').write('garh')
187
self.assertEquals(list(b.unknowns()), ['garh'])
188
184
self.assertEquals(self.capture('unknowns'), 'garh\n')
189
185
self.runbzr('ignore garh')
190
self.assertEquals(list(b.unknowns()), [])
186
self.assertEquals(self.capture('unknowns'), '')
191
187
self.assertEquals(file('.bzrignore', 'rU').read(), '*.blah\ngarh\n')
193
189
def test_revert(self):
237
233
self.runbzr('revert')
236
def test_status(self):
238
self.build_tree(['hello.txt'])
239
result = self.runbzr("status")
240
self.assert_("unknown:\n hello.txt\n" in result, result)
241
self.runbzr("add hello.txt")
242
result = self.runbzr("status")
243
self.assert_("added:\n hello.txt\n" in result, result)
244
self.runbzr("commit -m added")
245
result = self.runbzr("status -r 0..1")
246
self.assert_("added:\n hello.txt\n" in result, result)
247
self.build_tree(['world.txt'])
248
result = self.runbzr("status -r 0")
249
self.assert_("added:\n hello.txt\n" \
250
"unknown:\n world.txt\n" in result, result)
241
252
def test_mv_modes(self):
242
253
"""Test two modes of operation for mv"""
287
298
self.assertEqual(file('../first.gz/hello', 'rt').read(), 'foo')
288
299
self.runbzr('export ../first.bz2 -r 1')
289
300
self.assertEqual(file('../first.bz2/hello', 'rt').read(), 'foo')
302
from tarfile import TarFile
290
303
self.runbzr('export ../first.tar -r 1')
291
304
self.assert_(os.path.isfile('../first.tar'))
292
from tarfile import TarFile
293
305
tf = TarFile('../first.tar')
294
306
self.assert_('first/hello' in tf.getnames(), tf.getnames())
295
307
self.assertEqual(tf.extractfile('first/hello').read(), 'foo')
310
323
tf = TarFile('../first2.tar')
311
324
self.assert_('pizza/hello' in tf.getnames(), tf.getnames())
326
from zipfile import ZipFile
327
self.runbzr('export ../first.zip -r 1')
328
self.failUnlessExists('../first.zip')
329
zf = ZipFile('../first.zip')
330
self.assert_('first/hello' in zf.namelist(), zf.namelist())
331
self.assertEqual(zf.read('first/hello'), 'foo')
333
self.runbzr('export ../first2.zip -r 1 --root pizza')
334
zf = ZipFile('../first2.zip')
335
self.assert_('pizza/hello' in zf.namelist(), zf.namelist())
337
self.runbzr('export ../first-zip --format=zip -r 1')
338
zf = ZipFile('../first-zip')
339
self.assert_('first-zip/hello' in zf.namelist(), zf.namelist())
313
341
def test_diff(self):
314
342
self.example_branch()
315
343
file('hello', 'wt').write('hello world!')
324
352
self.runbzr('diff')
326
354
def test_diff_branches(self):
327
self.build_tree(['branch1/', 'branch1/file', 'branch2/'])
355
self.build_tree(['branch1/', 'branch1/file', 'branch2/'], line_endings='binary')
328
356
branch = Branch.initialize('branch1')
330
branch.commit('add file')
357
branch.working_tree().add(['file'])
358
branch.working_tree().commit('add file')
331
359
copy_branch(branch, 'branch2')
332
print >> open('branch2/file', 'w'), 'new content'
360
print >> open('branch2/file', 'wb'), 'new content'
333
361
branch2 = Branch.open('branch2')
334
branch2.commit('update file')
362
branch2.working_tree().commit('update file')
335
363
# should open branch1 and diff against branch2,
336
364
output = self.run_bzr_captured(['diff', '-r', 'branch:branch2',
404
432
a = Branch.open('.')
405
433
b = Branch.open('../b')
406
434
a.storage.get_revision_xml(b.last_revision())
407
self.log('pending merges: %s', a.pending_merges())
408
self.assertEquals(a.pending_merges(), [b.last_revision()])
435
self.log('pending merges: %s', a.working_tree().pending_merges())
436
self.assertEquals(a.working_tree().pending_merges(),
409
438
self.runbzr('commit -m merged')
410
439
self.runbzr('merge ../b -r last:1')
411
self.assertEqual(Branch.open('.').pending_merges(), [])
440
self.assertEqual(Branch.open('.').working_tree().pending_merges(), [])
414
442
def test_merge_with_missing_file(self):
415
443
"""Merge handles missing file conflicts"""
501
529
self.runbzr('pull ../b')
502
530
self.runbzr('pull ../b')
532
def test_inventory(self):
534
def output_equals(value, *args):
535
out = self.runbzr(['inventory'] + list(args), backtick=True)
536
self.assertEquals(out, value)
539
open('a', 'wb').write('hello\n')
545
output_equals('a\n', '--kind', 'file')
546
output_equals('b\n', '--kind', 'directory')
504
548
def test_ls(self):
505
549
"""Test the abilities of 'bzr ls'"""
506
550
bzr = self.runbzr
609
653
self.runbzr('commit -m myfile')
610
654
self.run_bzr_captured('cat -r 1 myfile'.split(' '))
656
def test_pull_verbose(self):
657
"""Pull changes from one branch to another and watch the output."""
663
self.example_branch()
668
open('b', 'wb').write('else\n')
670
bzr(['commit', '-m', 'added b'])
673
out = bzr('pull --verbose ../b', backtick=True)
674
self.failIfEqual(out.find('Added Revisions:'), -1)
675
self.failIfEqual(out.find('message:\n added b'), -1)
676
self.failIfEqual(out.find('added b'), -1)
678
# Check that --overwrite --verbose prints out the removed entries
679
bzr('commit -m foo --unchanged')
681
bzr('commit -m baz --unchanged')
682
bzr('pull ../a', retcode=3)
683
out = bzr('pull --overwrite --verbose ../a', backtick=1)
685
remove_loc = out.find('Removed Revisions:')
686
self.failIfEqual(remove_loc, -1)
687
added_loc = out.find('Added Revisions:')
688
self.failIfEqual(added_loc, -1)
690
removed_message = out.find('message:\n baz')
691
self.failIfEqual(removed_message, -1)
692
self.failUnless(remove_loc < removed_message < added_loc)
694
added_message = out.find('message:\n foo')
695
self.failIfEqual(added_message, -1)
696
self.failUnless(added_loc < added_message)
613
698
def test_locations(self):
614
699
"""Using and remembering different locations"""
642
727
"""add command prints the names of added files."""
643
728
b = Branch.initialize('.')
644
729
self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
645
out = self.run_bzr_captured(['add'], retcode = 0)[0]
730
out = self.run_bzr_captured(['add'], retcode=0)[0]
646
731
# the ordering is not defined at the moment
647
732
results = sorted(out.rstrip('\n').split('\n'))
648
733
self.assertEquals(['added dir',
654
739
"""add -q does not print the names of added files."""
655
740
b = Branch.initialize('.')
656
741
self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
657
out = self.run_bzr_captured(['add', '-q'], retcode = 0)[0]
742
out = self.run_bzr_captured(['add', '-q'], retcode=0)[0]
658
743
# the ordering is not defined at the moment
659
744
results = sorted(out.rstrip('\n').split('\n'))
660
745
self.assertEquals([''], results)
747
def test_add_in_unversioned(self):
748
"""Try to add a file in an unversioned directory.
750
"bzr add" should add the parent(s) as necessary.
752
from bzrlib.branch import Branch
753
Branch.initialize('.')
754
self.build_tree(['inertiatic/', 'inertiatic/esp'])
755
self.assertEquals(self.capture('unknowns'), 'inertiatic\n')
756
self.run_bzr('add', 'inertiatic/esp')
757
self.assertEquals(self.capture('unknowns'), '')
759
# Multiple unversioned parents
760
self.build_tree(['veil/', 'veil/cerpin/', 'veil/cerpin/taxt'])
761
self.assertEquals(self.capture('unknowns'), 'veil\n')
762
self.run_bzr('add', 'veil/cerpin/taxt')
763
self.assertEquals(self.capture('unknowns'), '')
765
# Check whacky paths work
766
self.build_tree(['cicatriz/', 'cicatriz/esp'])
767
self.assertEquals(self.capture('unknowns'), 'cicatriz\n')
768
self.run_bzr('add', 'inertiatic/../cicatriz/esp')
769
self.assertEquals(self.capture('unknowns'), '')
771
def test_add_in_versioned(self):
772
"""Try to add a file in a versioned directory.
774
"bzr add" should do this happily.
776
from bzrlib.branch import Branch
777
Branch.initialize('.')
778
self.build_tree(['inertiatic/', 'inertiatic/esp'])
779
self.assertEquals(self.capture('unknowns'), 'inertiatic\n')
780
self.run_bzr('add', '--no-recurse', 'inertiatic')
781
self.assertEquals(self.capture('unknowns'), 'inertiatic'+os.sep+'esp\n')
782
self.run_bzr('add', 'inertiatic/esp')
783
self.assertEquals(self.capture('unknowns'), '')
785
def test_subdir_add(self):
786
"""Add in subdirectory should add only things from there down"""
787
from bzrlib.branch import Branch
789
eq = self.assertEqual
793
b = Branch.initialize('.')
795
self.build_tree(['src/', 'README'])
797
eq(sorted(t.unknowns()),
800
self.run_bzr('add', 'src')
802
self.build_tree(['src/foo.c'])
807
self.assertEquals(self.capture('unknowns'), 'README\n')
808
eq(len(t.read_working_inventory()), 3)
812
self.assertEquals(self.capture('unknowns'), '')
813
self.run_bzr('check')
662
815
def test_unknown_command(self):
663
816
"""Handling of unknown command."""
664
817
out, err = self.run_bzr_captured(['fluffy-badger'],
785
938
import bzrlib.gpg
786
939
oldstrategy = bzrlib.gpg.GPGStrategy
787
940
branch = Branch.initialize('.')
788
branch.commit("base", allow_pointless=True, rev_id='A')
789
branch.commit("base", allow_pointless=True, rev_id='B')
790
branch.commit("base", allow_pointless=True, rev_id='C')
941
branch.working_tree().commit("base", allow_pointless=True, rev_id='A')
942
branch.working_tree().commit("base", allow_pointless=True, rev_id='B')
943
branch.working_tree().commit("base", allow_pointless=True, rev_id='C')
792
945
# monkey patch gpg signing mechanism
793
946
from bzrlib.testament import Testament
849
1002
# nothing missing
850
1003
self.runbzr('missing ../missing/new-branch')
1005
def test_external_command(self):
1006
"""test that external commands can be run by setting the path"""
1007
cmd_name = 'test-command'
1008
output = 'Hello from test-command'
1009
if sys.platform == 'win32':
1015
oldpath = os.environ.get('BZRPATH', None)
1020
if os.environ.has_key('BZRPATH'):
1021
del os.environ['BZRPATH']
1023
f = file(cmd_name, 'wb')
1024
if sys.platform == 'win32':
1025
f.write('@echo off\n')
1027
f.write('#!/bin/sh\n')
1028
f.write('echo Hello from test-command')
1030
os.chmod(cmd_name, 0755)
1032
# It should not find the command in the local
1033
# directory by default, since it is not in my path
1034
bzr(cmd_name, retcode=3)
1036
# Now put it into my path
1037
os.environ['BZRPATH'] = '.'
1040
# The test suite does not capture stdout for external commands
1041
# this is because you have to have a real file object
1042
# to pass to Popen(stdout=FOO), and StringIO is not one of those.
1043
# (just replacing sys.stdout does not change a spawned objects stdout)
1044
#self.assertEquals(bzr(cmd_name), output)
1046
# Make sure empty path elements are ignored
1047
os.environ['BZRPATH'] = os.pathsep
1049
bzr(cmd_name, retcode=3)
1053
os.environ['BZRPATH'] = oldpath
853
1056
def listdir_sorted(dir):
854
1057
L = os.listdir(dir)
1144
1347
def test_log(self):
1145
1348
self.build_tree(['branch/', 'branch/file'])
1146
1349
branch = Branch.initialize('branch')
1147
branch.add(['file'])
1148
branch.commit('add file', rev_id='A')
1350
branch.working_tree().add(['file'])
1351
branch.working_tree().commit('add file', rev_id='A')
1149
1352
url = self.get_remote_url('branch/file')
1150
1353
output = self.capture('log %s' % url)
1151
1354
self.assertEqual(8, len(output.split('\n')))
1152
1355
copy = copy_branch(branch, 'branch2')
1153
branch.commit(message='empty commit')
1356
# FIXME: rbc 20051128 what is the remainder of this test testing?
1357
# - it does not seem to be http specific.
1358
branch.working_tree().commit(message='empty commit')
1154
1359
os.chdir('branch2')
1155
1360
self.run_bzr('merge', '../branch')
1156
copy.commit(message='merge')
1361
copy.working_tree().commit(message='merge')
1157
1362
output = self.capture('log')
1364
def test_check(self):
1365
self.build_tree(['branch/', 'branch/file'])
1366
branch = Branch.initialize('branch')
1367
branch.working_tree().add(['file'])
1368
branch.working_tree().commit('add file', rev_id='A')
1369
url = self.get_remote_url('branch/')
1370
self.run_bzr('check', url)