177
179
self.assertFalse(t.has('last-revision'))
178
180
# TODO RBC 20060210 do a commit, check the inventory.basis is created
179
181
# correctly and last-revision file becomes present.
181
def test_uses_lockdir(self):
182
"""WorkingTreeFormat3 uses its own LockDir:
184
- lock is a directory
185
- when the WorkingTree is locked, LockDir can see that
187
t = self.get_transport()
189
dir = bzrdir.BzrDirMetaFormat1().initialize(url)
190
repo = dir.create_repository()
191
branch = dir.create_branch()
193
tree = workingtree.WorkingTreeFormat3().initialize(dir)
194
except errors.NotLocalUrl:
195
raise TestSkipped('Not a local URL')
196
self.assertIsDirectory('.bzr', t)
197
self.assertIsDirectory('.bzr/checkout', t)
198
self.assertIsDirectory('.bzr/checkout/lock', t)
199
our_lock = LockDir(t, '.bzr/checkout/lock')
200
self.assertEquals(our_lock.peek(), None)
202
self.assertTrue(our_lock.peek())
204
self.assertEquals(our_lock.peek(), None)
206
def test_missing_pending_merges(self):
207
control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
208
control.create_repository()
209
control.create_branch()
210
tree = workingtree.WorkingTreeFormat3().initialize(control)
211
tree._control_files._transport.delete("pending-merges")
212
self.assertEqual([], tree.pending_merges())
215
class TestFormat2WorkingTree(TestCaseWithTransport):
216
"""Tests that are specific to format 2 trees."""
218
def create_format2_tree(self, url):
219
return self.make_branch_and_tree(
220
url, format=bzrlib.bzrdir.BzrDirFormat6())
222
def test_conflicts(self):
223
# test backwards compatability
224
tree = self.create_format2_tree('.')
225
self.assertRaises(errors.UnsupportedOperation, tree.set_conflicts,
227
file('lala.BASE', 'wb').write('labase')
228
expected = conflicts.ContentsConflict('lala')
229
self.assertEqual(list(tree.conflicts()), [expected])
230
file('lala', 'wb').write('la')
231
tree.add('lala', 'lala-id')
232
expected = conflicts.ContentsConflict('lala', file_id='lala-id')
233
self.assertEqual(list(tree.conflicts()), [expected])
234
file('lala.THIS', 'wb').write('lathis')
235
file('lala.OTHER', 'wb').write('laother')
236
# When "text conflict"s happen, stem, THIS and OTHER are text
237
expected = conflicts.TextConflict('lala', file_id='lala-id')
238
self.assertEqual(list(tree.conflicts()), [expected])
239
os.unlink('lala.OTHER')
240
os.mkdir('lala.OTHER')
241
expected = conflicts.ContentsConflict('lala', file_id='lala-id')
242
self.assertEqual(list(tree.conflicts()), [expected])
245
class TestNonFormatSpecificCode(TestCaseWithTransport):
246
"""This class contains tests of workingtree that are not format specific."""
249
def test_gen_file_id(self):
250
gen_file_id = bzrlib.workingtree.gen_file_id
252
# We try to use the filename if possible
253
self.assertStartsWith(gen_file_id('bar'), 'bar-')
255
# but we squash capitalization, and remove non word characters
256
self.assertStartsWith(gen_file_id('Mwoo oof\t m'), 'mwoooofm-')
258
# We also remove leading '.' characters to prevent hidden file-ids
259
self.assertStartsWith(gen_file_id('..gam.py'), 'gam.py-')
260
self.assertStartsWith(gen_file_id('..Mwoo oof\t m'), 'mwoooofm-')
262
# we remove unicode characters, and still don't end up with a
264
self.assertStartsWith(gen_file_id(u'\xe5\xb5.txt'), 'txt-')
266
# Our current method of generating unique ids adds 33 characters
267
# plus an serial number (log10(N) characters)
268
# to the end of the filename. We now restrict the filename portion to
269
# be <= 20 characters, so the maximum length should now be approx < 60
271
# Test both case squashing and length restriction
272
fid = gen_file_id('A'*50 + '.txt')
273
self.assertStartsWith(fid, 'a'*20 + '-')
274
self.failUnless(len(fid) < 60)
276
# restricting length happens after the other actions, so
277
# we preserve as much as possible
278
fid = gen_file_id('\xe5\xb5..aBcd\tefGhijKLMnop\tqrstuvwxyz')
279
self.assertStartsWith(fid, 'abcdefghijklmnopqrst-')
280
self.failUnless(len(fid) < 60)
282
def test_next_id_suffix(self):
283
bzrlib.workingtree._gen_id_suffix = None
284
bzrlib.workingtree._next_id_suffix()
285
self.assertNotEqual(None, bzrlib.workingtree._gen_id_suffix)
286
bzrlib.workingtree._gen_id_suffix = "foo-"
287
bzrlib.workingtree._gen_id_serial = 1
288
self.assertEqual("foo-2", bzrlib.workingtree._next_id_suffix())
289
self.assertEqual("foo-3", bzrlib.workingtree._next_id_suffix())
290
self.assertEqual("foo-4", bzrlib.workingtree._next_id_suffix())
291
self.assertEqual("foo-5", bzrlib.workingtree._next_id_suffix())
292
self.assertEqual("foo-6", bzrlib.workingtree._next_id_suffix())
293
self.assertEqual("foo-7", bzrlib.workingtree._next_id_suffix())
294
self.assertEqual("foo-8", bzrlib.workingtree._next_id_suffix())
295
self.assertEqual("foo-9", bzrlib.workingtree._next_id_suffix())
296
self.assertEqual("foo-10", bzrlib.workingtree._next_id_suffix())
298
def test__translate_ignore_rule(self):
299
tree = self.make_branch_and_tree('.')
300
# translation should return the regex, the number of groups in it,
301
# and the original rule in a tuple.
302
# there are three sorts of ignore rules:
303
# root only - regex is the rule itself without the leading ./
306
tree._translate_ignore_rule("./rootdirrule"))
307
# full path - regex is the rule itself
309
"(path\\/to\\/file$)",
310
tree._translate_ignore_rule("path/to/file"))
311
# basename only rule - regex is a rule that ignores everything up
312
# to the last / in the filename
314
"((?:.*/)?(?!.*/)basenamerule$)",
315
tree._translate_ignore_rule("basenamerule"))
317
def test__combine_ignore_rules(self):
318
tree = self.make_branch_and_tree('.')
319
# the combined ignore regexs need the outer group indices
320
# placed in a dictionary with the rules that were combined.
321
# an empty set of rules
322
# this is returned as a list of combined regex,rule sets, because
323
# python has a limit of 100 combined regexes.
324
compiled_rules = tree._combine_ignore_rules([])
325
self.assertEqual([], compiled_rules)
326
# one of each type of rule.
327
compiled_rules = tree._combine_ignore_rules(
328
["rule1", "rule/two", "./three"])[0]
329
# what type *is* the compiled regex to do an isinstance of ?
330
self.assertEqual(3, compiled_rules[0].groups)
332
{0:"rule1",1:"rule/two",2:"./three"},
335
def test__combine_ignore_rules_grouping(self):
336
tree = self.make_branch_and_tree('.')
337
# when there are too many rules, the output is split into groups of 100
339
for index in range(198):
341
self.assertEqual(2, len(tree._combine_ignore_rules(rules)))
343
def test__get_ignore_rules_as_regex(self):
344
tree = self.make_branch_and_tree('.')
345
# Setup the default ignore list to be empty
346
ignores._set_user_ignores([])
348
# some plugins (shelf) modifies the DEFAULT_IGNORE list in memory
349
# which causes this test to fail so force the DEFAULT_IGNORE
351
orig_default = bzrlib.DEFAULT_IGNORE
352
# Also make sure the runtime ignore list is empty
353
orig_runtime = ignores._runtime_ignores
355
bzrlib.DEFAULT_IGNORE = []
356
ignores._runtime_ignores = set()
358
self.build_tree_contents([('.bzrignore', 'CVS\n.hg\n')])
359
reference_output = tree._combine_ignore_rules(
360
set(['CVS', '.hg']))[0]
361
regex_rules = tree._get_ignore_rules_as_regex()[0]
362
self.assertEqual(len(reference_output[1]), regex_rules[0].groups)
363
self.assertEqual(reference_output[1], regex_rules[1])
365
bzrlib.DEFAULT_IGNORE = orig_default
366
ignores._runtime_ignores = orig_runtime