1
# Copyright (C) 2005, 2006 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
"""Black-box tests for bzr diff.
25
from bzrlib import workingtree
26
from bzrlib.branch import Branch
27
from bzrlib.tests import TestSkipped
28
from bzrlib.tests.blackbox import ExternalBase
31
def subst_dates(string):
32
"""Replace date strings with constant values."""
33
return re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2} [-\+]\d{4}',
34
'YYYY-MM-DD HH:MM:SS +ZZZZ', string)
37
class TestDiff(ExternalBase):
39
def make_example_branch(self):
40
# FIXME: copied from test_too_much -- share elsewhere?
41
tree = self.make_branch_and_tree('.')
42
open('hello', 'wb').write('foo\n')
45
open('goodbye', 'wb').write('baz\n')
50
self.make_example_branch()
51
file('hello', 'wt').write('hello world!')
52
self.runbzr('commit -m fixing hello')
53
output = self.runbzr('diff -r 2..3', backtick=1, retcode=1)
54
self.assert_('\n+hello world!' in output)
55
output = self.runbzr('diff -r last:3..last:1', backtick=1, retcode=1)
56
self.assert_('\n+baz' in output)
57
file('moo', 'wb').write('moo')
58
self.runbzr('add moo')
62
def test_diff_prefix(self):
63
"""diff --prefix appends to filenames in output"""
64
self.make_example_branch()
65
file('hello', 'wb').write('hello world!\n')
66
out, err = self.runbzr('diff --prefix old/:new/', retcode=1)
67
self.assertEquals(err, '')
68
self.assertEqualDiff(subst_dates(out), '''\
69
=== modified file 'hello'
70
--- old/hello\tYYYY-MM-DD HH:MM:SS +ZZZZ
71
+++ new/hello\tYYYY-MM-DD HH:MM:SS +ZZZZ
78
def test_diff_p1(self):
79
"""diff -p1 produces lkml-style diffs"""
80
self.make_example_branch()
81
file('hello', 'wb').write('hello world!\n')
82
out, err = self.runbzr('diff -p1', retcode=1)
83
self.assertEquals(err, '')
84
self.assertEqualDiff(subst_dates(out), '''\
85
=== modified file 'hello'
86
--- old/hello\tYYYY-MM-DD HH:MM:SS +ZZZZ
87
+++ new/hello\tYYYY-MM-DD HH:MM:SS +ZZZZ
94
def test_diff_p0(self):
95
"""diff -p0 produces diffs with no prefix"""
96
self.make_example_branch()
97
file('hello', 'wb').write('hello world!\n')
98
out, err = self.runbzr('diff -p0', retcode=1)
99
self.assertEquals(err, '')
100
self.assertEqualDiff(subst_dates(out), '''\
101
=== modified file 'hello'
102
--- hello\tYYYY-MM-DD HH:MM:SS +ZZZZ
103
+++ hello\tYYYY-MM-DD HH:MM:SS +ZZZZ
110
def test_diff_nonexistent(self):
111
# Get an error from a file that does not exist at all
113
self.make_example_branch()
114
out, err = self.runbzr('diff does-not-exist', retcode=3)
115
self.assertContainsRe(err, 'not versioned.*does-not-exist')
117
def test_diff_unversioned(self):
118
# Get an error when diffing a non-versioned file.
120
self.make_example_branch()
121
self.build_tree(['unversioned-file'])
122
out, err = self.runbzr('diff unversioned-file', retcode=3)
123
self.assertContainsRe(err, 'not versioned.*unversioned-file')
125
# TODO: What should diff say for a file deleted in working tree?
127
def example_branches(self):
128
self.build_tree(['branch1/', 'branch1/file'], line_endings='binary')
129
self.capture('init branch1')
130
self.capture('add branch1/file')
131
self.run_bzr_captured(['commit', '-m', 'add file', 'branch1'])
132
self.capture('branch branch1 branch2')
133
print >> open('branch2/file', 'wb'), 'new content'
134
self.run_bzr_captured(['commit', '-m', 'update file', 'branch2'])
136
def test_diff_branches(self):
137
self.example_branches()
138
# should open branch1 and diff against branch2,
139
out, err = self.run_bzr_captured(['diff', '-r', 'branch:branch2',
142
self.assertEquals('', err)
143
self.assertEquals("=== modified file 'file'\n"
144
"--- file\tYYYY-MM-DD HH:MM:SS +ZZZZ\n"
145
"+++ file\tYYYY-MM-DD HH:MM:SS +ZZZZ\n"
148
"+contents of branch1/file\n"
149
"\n", subst_dates(out))
150
out, err = self.run_bzr_captured(['diff', 'branch2', 'branch1'],
152
self.assertEquals('', err)
153
self.assertEqualDiff("=== modified file 'file'\n"
154
"--- file\tYYYY-MM-DD HH:MM:SS +ZZZZ\n"
155
"+++ file\tYYYY-MM-DD HH:MM:SS +ZZZZ\n"
158
"+contents of branch1/file\n"
159
"\n", subst_dates(out))
161
def test_diff_revno_branches(self):
162
self.example_branches()
163
print >> open('branch2/file', 'wb'), 'even newer content'
164
self.run_bzr_captured(['commit', '-m',
165
'update file once more', 'branch2'])
167
out, err = self.run_bzr_captured(['diff', '-r',
168
'revno:1:branch2..revno:1:branch1'],
170
self.assertEquals('', err)
171
self.assertEquals('', out)
172
out, err = self.run_bzr_captured(['diff', '-r',
173
'revno:2:branch2..revno:1:branch1'],
175
self.assertEquals('', err)
176
self.assertEqualDiff("=== modified file 'file'\n"
177
"--- file\tYYYY-MM-DD HH:MM:SS +ZZZZ\n"
178
"+++ file\tYYYY-MM-DD HH:MM:SS +ZZZZ\n"
181
"+contents of branch1/file\n"
182
"\n", subst_dates(out))
184
def example_branch2(self):
185
self.build_tree(['branch1/', 'branch1/file1'], line_endings='binary')
186
self.capture('init branch1')
187
self.capture('add branch1/file1')
188
print >> open('branch1/file1', 'wb'), 'original line'
189
self.run_bzr_captured(['commit', '-m', 'first commit', 'branch1'])
191
print >> open('branch1/file1', 'wb'), 'repo line'
192
self.run_bzr_captured(['commit', '-m', 'second commit', 'branch1'])
194
def test_diff_to_working_tree(self):
195
self.example_branch2()
197
print >> open('branch1/file1', 'wb'), 'new line'
198
output = self.run_bzr_captured(['diff', '-r', '1..', 'branch1'],
200
self.assertTrue('\n-original line\n+new line\n' in output[0])
202
def test_diff_across_rename(self):
203
"""The working tree path should always be considered for diffing"""
204
self.make_example_branch()
205
self.run_bzr('diff', '-r', '0..1', 'hello', retcode=1)
206
wt = workingtree.WorkingTree.open_containing('.')[0]
207
wt.rename_one('hello', 'hello1')
208
self.run_bzr('diff', 'hello1', retcode=1)
209
self.run_bzr('diff', '-r', '0..1', 'hello1', retcode=1)
212
class TestCheckoutDiff(TestDiff):
214
def make_example_branch(self):
215
super(TestCheckoutDiff, self).make_example_branch()
216
self.runbzr('checkout . checkout')
219
def example_branch2(self):
220
super(TestCheckoutDiff, self).example_branch2()
221
os.mkdir('checkouts')
222
self.runbzr('checkout branch1 checkouts/branch1')
223
os.chdir('checkouts')
225
def example_branches(self):
226
super(TestCheckoutDiff, self).example_branches()
227
os.mkdir('checkouts')
228
self.runbzr('checkout branch1 checkouts/branch1')
229
self.runbzr('checkout branch2 checkouts/branch2')
230
os.chdir('checkouts')
233
class TestDiffLabels(TestDiff):
235
def test_diff_label_removed(self):
236
super(TestDiffLabels, self).make_example_branch()
237
self.runbzr('remove hello')
238
diff = self.run_bzr_captured(['diff'], retcode=1)
239
self.assertTrue("=== removed file 'hello'" in diff[0])
241
def test_diff_label_added(self):
242
super(TestDiffLabels, self).make_example_branch()
243
file('barbar', 'wt').write('barbar')
244
self.runbzr('add barbar')
245
diff = self.run_bzr_captured(['diff'], retcode=1)
246
self.assertTrue("=== added file 'barbar'" in diff[0])
248
def test_diff_label_modified(self):
249
super(TestDiffLabels, self).make_example_branch()
250
file('hello', 'wt').write('barbar')
251
diff = self.run_bzr_captured(['diff'], retcode=1)
252
self.assertTrue("=== modified file 'hello'" in diff[0])
254
def test_diff_label_renamed(self):
255
super(TestDiffLabels, self).make_example_branch()
256
self.runbzr('rename hello gruezi')
257
diff = self.run_bzr_captured(['diff'], retcode=1)
258
self.assertTrue("=== renamed file 'hello' => 'gruezi'" in diff[0])
261
class TestExternalDiff(TestDiff):
263
def test_external_diff(self):
264
"""Test that we can spawn an external diff process"""
265
# We have to use run_bzr_subprocess, because we need to
266
# test writing directly to stdout, (there was a bug in
267
# subprocess.py that we had to workaround).
268
# However, if 'diff' may not be available
269
self.make_example_branch()
270
orig_progress = os.environ.get('BZR_PROGRESS_BAR')
272
os.environ['BZR_PROGRESS_BAR'] = 'none'
273
out, err = self.run_bzr_subprocess('diff', '-r', '1',
274
'--diff-options', '-ub',
275
universal_newlines=True,
278
if orig_progress is None:
279
del os.environ['BZR_PROGRESS_BAR']
281
os.environ['BZR_PROGRESS_BAR'] = orig_progress
283
if 'Diff is not installed on this machine' in err:
284
raise TestSkipped("No external 'diff' is available")
285
self.assertEqual('', err)
286
# We have to skip the stuff in the middle, because it depends
288
self.assertStartsWith(out, "=== added file 'goodbye'\n"
289
"--- goodbye\t1970-01-01 00:00:00 +0000\n"
291
self.assertEndsWith(out, "\n@@ -0,0 +1 @@\n"