60
92
self.check_file_contents('a', 'something in a\n')
63
94
# TODO: test fancy_rename using a MemoryTransport
96
def test_01_rand_chars_empty(self):
97
result = osutils.rand_chars(0)
98
self.assertEqual(result, '')
100
def test_02_rand_chars_100(self):
101
result = osutils.rand_chars(100)
102
self.assertEqual(len(result), 100)
103
self.assertEqual(type(result), str)
104
self.assertContainsRe(result, r'^[a-z0-9]{100}$')
106
def test_is_inside(self):
107
is_inside = osutils.is_inside
108
self.assertTrue(is_inside('src', 'src/foo.c'))
109
self.assertFalse(is_inside('src', 'srccontrol'))
110
self.assertTrue(is_inside('src', 'src/a/a/a/foo.c'))
111
self.assertTrue(is_inside('foo.c', 'foo.c'))
112
self.assertFalse(is_inside('foo.c', ''))
113
self.assertTrue(is_inside('', 'foo.c'))
115
def test_is_inside_any(self):
116
SRC_FOO_C = pathjoin('src', 'foo.c')
117
for dirs, fn in [(['src', 'doc'], SRC_FOO_C),
118
(['src'], SRC_FOO_C),
121
self.assert_(is_inside_any(dirs, fn))
122
for dirs, fn in [(['src'], 'srccontrol'),
123
(['src'], 'srccontrol/foo')]:
124
self.assertFalse(is_inside_any(dirs, fn))
126
def test_is_inside_or_parent_of_any(self):
127
for dirs, fn in [(['src', 'doc'], 'src/foo.c'),
128
(['src'], 'src/foo.c'),
129
(['src/bar.c'], 'src'),
130
(['src/bar.c', 'bla/foo.c'], 'src'),
133
self.assert_(is_inside_or_parent_of_any(dirs, fn))
135
for dirs, fn in [(['src'], 'srccontrol'),
136
(['srccontrol/foo.c'], 'src'),
137
(['src'], 'srccontrol/foo')]:
138
self.assertFalse(is_inside_or_parent_of_any(dirs, fn))
140
def test_rmtree(self):
141
# Check to remove tree with read-only files/dirs
143
f = file('dir/file', 'w')
146
# would like to also try making the directory readonly, but at the
147
# moment python shutil.rmtree doesn't handle that properly - it would
148
# need to chmod the directory before removing things inside it - deferred
149
# for now -- mbp 20060505
150
# osutils.make_readonly('dir')
151
osutils.make_readonly('dir/file')
153
osutils.rmtree('dir')
155
self.failIfExists('dir/file')
156
self.failIfExists('dir')
158
def test_file_kind(self):
159
self.build_tree(['file', 'dir/'])
160
self.assertEquals('file', osutils.file_kind('file'))
161
self.assertEquals('directory', osutils.file_kind('dir/'))
162
if osutils.has_symlinks():
163
os.symlink('symlink', 'symlink')
164
self.assertEquals('symlink', osutils.file_kind('symlink'))
166
# TODO: jam 20060529 Test a block device
168
os.lstat('/dev/null')
170
if e.errno not in (errno.ENOENT,):
173
self.assertEquals('chardev', osutils.file_kind('/dev/null'))
175
mkfifo = getattr(os, 'mkfifo', None)
179
self.assertEquals('fifo', osutils.file_kind('fifo'))
183
AF_UNIX = getattr(socket, 'AF_UNIX', None)
185
s = socket.socket(AF_UNIX)
188
self.assertEquals('socket', osutils.file_kind('socket'))
192
def test_kind_marker(self):
193
self.assertEqual(osutils.kind_marker('file'), '')
194
self.assertEqual(osutils.kind_marker('directory'), '/')
195
self.assertEqual(osutils.kind_marker('symlink'), '@')
196
self.assertEqual(osutils.kind_marker('tree-reference'), '+')
198
def test_get_umask(self):
199
if sys.platform == 'win32':
200
# umask always returns '0', no way to set it
201
self.assertEqual(0, osutils.get_umask())
204
orig_umask = osutils.get_umask()
207
self.assertEqual(0222, osutils.get_umask())
209
self.assertEqual(0022, osutils.get_umask())
211
self.assertEqual(0002, osutils.get_umask())
213
self.assertEqual(0027, osutils.get_umask())
217
def assertFormatedDelta(self, expected, seconds):
218
"""Assert osutils.format_delta formats as expected"""
219
actual = osutils.format_delta(seconds)
220
self.assertEqual(expected, actual)
222
def test_format_delta(self):
223
self.assertFormatedDelta('0 seconds ago', 0)
224
self.assertFormatedDelta('1 second ago', 1)
225
self.assertFormatedDelta('10 seconds ago', 10)
226
self.assertFormatedDelta('59 seconds ago', 59)
227
self.assertFormatedDelta('89 seconds ago', 89)
228
self.assertFormatedDelta('1 minute, 30 seconds ago', 90)
229
self.assertFormatedDelta('3 minutes, 0 seconds ago', 180)
230
self.assertFormatedDelta('3 minutes, 1 second ago', 181)
231
self.assertFormatedDelta('10 minutes, 15 seconds ago', 615)
232
self.assertFormatedDelta('30 minutes, 59 seconds ago', 1859)
233
self.assertFormatedDelta('31 minutes, 0 seconds ago', 1860)
234
self.assertFormatedDelta('60 minutes, 0 seconds ago', 3600)
235
self.assertFormatedDelta('89 minutes, 59 seconds ago', 5399)
236
self.assertFormatedDelta('1 hour, 30 minutes ago', 5400)
237
self.assertFormatedDelta('2 hours, 30 minutes ago', 9017)
238
self.assertFormatedDelta('10 hours, 0 minutes ago', 36000)
239
self.assertFormatedDelta('24 hours, 0 minutes ago', 86400)
240
self.assertFormatedDelta('35 hours, 59 minutes ago', 129599)
241
self.assertFormatedDelta('36 hours, 0 minutes ago', 129600)
242
self.assertFormatedDelta('36 hours, 0 minutes ago', 129601)
243
self.assertFormatedDelta('36 hours, 1 minute ago', 129660)
244
self.assertFormatedDelta('36 hours, 1 minute ago', 129661)
245
self.assertFormatedDelta('84 hours, 10 minutes ago', 303002)
247
# We handle when time steps the wrong direction because computers
248
# don't have synchronized clocks.
249
self.assertFormatedDelta('84 hours, 10 minutes in the future', -303002)
250
self.assertFormatedDelta('1 second in the future', -1)
251
self.assertFormatedDelta('2 seconds in the future', -2)
253
def test_dereference_path(self):
254
self.requireFeature(SymlinkFeature)
255
cwd = osutils.realpath('.')
257
bar_path = osutils.pathjoin(cwd, 'bar')
258
# Using './' to avoid bug #1213894 (first path component not
259
# dereferenced) in Python 2.4.1 and earlier
260
self.assertEqual(bar_path, osutils.realpath('./bar'))
261
os.symlink('bar', 'foo')
262
self.assertEqual(bar_path, osutils.realpath('./foo'))
264
# Does not dereference terminal symlinks
265
foo_path = osutils.pathjoin(cwd, 'foo')
266
self.assertEqual(foo_path, osutils.dereference_path('./foo'))
268
# Dereferences parent symlinks
270
baz_path = osutils.pathjoin(bar_path, 'baz')
271
self.assertEqual(baz_path, osutils.dereference_path('./foo/baz'))
273
# Dereferences parent symlinks that are the first path element
274
self.assertEqual(baz_path, osutils.dereference_path('foo/baz'))
276
# Dereferences parent symlinks in absolute paths
277
foo_baz_path = osutils.pathjoin(foo_path, 'baz')
278
self.assertEqual(baz_path, osutils.dereference_path(foo_baz_path))
280
def test_changing_access(self):
281
f = file('file', 'w')
285
# Make a file readonly
286
osutils.make_readonly('file')
287
mode = os.lstat('file').st_mode
288
self.assertEqual(mode, mode & 0777555)
290
# Make a file writable
291
osutils.make_writable('file')
292
mode = os.lstat('file').st_mode
293
self.assertEqual(mode, mode | 0200)
295
if osutils.has_symlinks():
296
# should not error when handed a symlink
297
os.symlink('nonexistent', 'dangling')
298
osutils.make_readonly('dangling')
299
osutils.make_writable('dangling')
301
def test_kind_marker(self):
302
self.assertEqual("", osutils.kind_marker("file"))
303
self.assertEqual("/", osutils.kind_marker(osutils._directory_kind))
304
self.assertEqual("@", osutils.kind_marker("symlink"))
305
self.assertRaises(errors.BzrError, osutils.kind_marker, "unknown")
66
308
class TestSafeUnicode(TestCase):
78
320
self.assertEqual(u'foo\xae', osutils.safe_unicode('foo\xc2\xae'))
80
322
def test_bad_utf8_string(self):
81
self.assertRaises(BzrBadParameter, osutils.safe_unicode, '\xbb\xbb')
323
self.assertRaises(BzrBadParameterNotUnicode,
324
osutils.safe_unicode,
328
class TestSafeUtf8(TestCase):
330
def test_from_ascii_string(self):
332
self.assertEqual('foobar', osutils.safe_utf8(f))
334
def test_from_unicode_string_ascii_contents(self):
335
self.assertEqual('bargam', osutils.safe_utf8(u'bargam'))
337
def test_from_unicode_string_unicode_contents(self):
338
self.assertEqual('bargam\xc2\xae', osutils.safe_utf8(u'bargam\xae'))
340
def test_from_utf8_string(self):
341
self.assertEqual('foo\xc2\xae', osutils.safe_utf8('foo\xc2\xae'))
343
def test_bad_utf8_string(self):
344
self.assertRaises(BzrBadParameterNotUnicode,
345
osutils.safe_utf8, '\xbb\xbb')
348
class TestSafeRevisionId(TestCase):
350
def test_from_ascii_string(self):
351
# this shouldn't give a warning because it's getting an ascii string
352
self.assertEqual('foobar', osutils.safe_revision_id('foobar'))
354
def test_from_unicode_string_ascii_contents(self):
355
self.assertEqual('bargam',
356
osutils.safe_revision_id(u'bargam', warn=False))
358
def test_from_unicode_deprecated(self):
359
self.assertEqual('bargam',
360
self.callDeprecated([osutils._revision_id_warning],
361
osutils.safe_revision_id, u'bargam'))
363
def test_from_unicode_string_unicode_contents(self):
364
self.assertEqual('bargam\xc2\xae',
365
osutils.safe_revision_id(u'bargam\xae', warn=False))
367
def test_from_utf8_string(self):
368
self.assertEqual('foo\xc2\xae',
369
osutils.safe_revision_id('foo\xc2\xae'))
372
"""Currently, None is a valid revision_id"""
373
self.assertEqual(None, osutils.safe_revision_id(None))
376
class TestSafeFileId(TestCase):
378
def test_from_ascii_string(self):
379
self.assertEqual('foobar', osutils.safe_file_id('foobar'))
381
def test_from_unicode_string_ascii_contents(self):
382
self.assertEqual('bargam', osutils.safe_file_id(u'bargam', warn=False))
384
def test_from_unicode_deprecated(self):
385
self.assertEqual('bargam',
386
self.callDeprecated([osutils._file_id_warning],
387
osutils.safe_file_id, u'bargam'))
389
def test_from_unicode_string_unicode_contents(self):
390
self.assertEqual('bargam\xc2\xae',
391
osutils.safe_file_id(u'bargam\xae', warn=False))
393
def test_from_utf8_string(self):
394
self.assertEqual('foo\xc2\xae',
395
osutils.safe_file_id('foo\xc2\xae'))
398
"""Currently, None is a valid revision_id"""
399
self.assertEqual(None, osutils.safe_file_id(None))
402
class TestWin32Funcs(TestCase):
403
"""Test that the _win32 versions of os utilities return appropriate paths."""
405
def test_abspath(self):
406
self.assertEqual('C:/foo', osutils._win32_abspath('C:\\foo'))
407
self.assertEqual('C:/foo', osutils._win32_abspath('C:/foo'))
408
self.assertEqual('//HOST/path', osutils._win32_abspath(r'\\HOST\path'))
409
self.assertEqual('//HOST/path', osutils._win32_abspath('//HOST/path'))
411
def test_realpath(self):
412
self.assertEqual('C:/foo', osutils._win32_realpath('C:\\foo'))
413
self.assertEqual('C:/foo', osutils._win32_realpath('C:/foo'))
415
def test_pathjoin(self):
416
self.assertEqual('path/to/foo', osutils._win32_pathjoin('path', 'to', 'foo'))
417
self.assertEqual('C:/foo', osutils._win32_pathjoin('path\\to', 'C:\\foo'))
418
self.assertEqual('C:/foo', osutils._win32_pathjoin('path/to', 'C:/foo'))
419
self.assertEqual('path/to/foo', osutils._win32_pathjoin('path/to/', 'foo'))
420
self.assertEqual('/foo', osutils._win32_pathjoin('C:/path/to/', '/foo'))
421
self.assertEqual('/foo', osutils._win32_pathjoin('C:\\path\\to\\', '\\foo'))
423
def test_normpath(self):
424
self.assertEqual('path/to/foo', osutils._win32_normpath(r'path\\from\..\to\.\foo'))
425
self.assertEqual('path/to/foo', osutils._win32_normpath('path//from/../to/./foo'))
427
def test_getcwd(self):
428
cwd = osutils._win32_getcwd()
429
os_cwd = os.getcwdu()
430
self.assertEqual(os_cwd[1:].replace('\\', '/'), cwd[1:])
431
# win32 is inconsistent whether it returns lower or upper case
432
# and even if it was consistent the user might type the other
433
# so we force it to uppercase
434
# running python.exe under cmd.exe return capital C:\\
435
# running win32 python inside a cygwin shell returns lowercase
436
self.assertEqual(os_cwd[0].upper(), cwd[0])
438
def test_fixdrive(self):
439
self.assertEqual('H:/foo', osutils._win32_fixdrive('h:/foo'))
440
self.assertEqual('H:/foo', osutils._win32_fixdrive('H:/foo'))
441
self.assertEqual('C:\\foo', osutils._win32_fixdrive('c:\\foo'))
443
def test_win98_abspath(self):
445
self.assertEqual('C:/foo', osutils._win98_abspath('C:\\foo'))
446
self.assertEqual('C:/foo', osutils._win98_abspath('C:/foo'))
448
self.assertEqual('//HOST/path', osutils._win98_abspath(r'\\HOST\path'))
449
self.assertEqual('//HOST/path', osutils._win98_abspath('//HOST/path'))
451
cwd = osutils.getcwd().rstrip('/')
452
drive = osutils._nt_splitdrive(cwd)[0]
453
self.assertEqual(cwd+'/path', osutils._win98_abspath('path'))
454
self.assertEqual(drive+'/path', osutils._win98_abspath('/path'))
457
self.assertEqual(cwd+'/'+u, osutils._win98_abspath(u))
460
class TestWin32FuncsDirs(TestCaseInTempDir):
461
"""Test win32 functions that create files."""
463
def test_getcwd(self):
464
if win32utils.winver == 'Windows 98':
465
raise TestSkipped('Windows 98 cannot handle unicode filenames')
466
# Make sure getcwd can handle unicode filenames
470
raise TestSkipped("Unable to create Unicode filename")
473
# TODO: jam 20060427 This will probably fail on Mac OSX because
474
# it will change the normalization of B\xe5gfors
475
# Consider using a different unicode character, or make
476
# osutils.getcwd() renormalize the path.
477
self.assertEndsWith(osutils._win32_getcwd(), u'mu-\xb5')
479
def test_minimum_path_selection(self):
480
self.assertEqual(set(),
481
osutils.minimum_path_selection([]))
482
self.assertEqual(set(['a', 'b']),
483
osutils.minimum_path_selection(['a', 'b']))
484
self.assertEqual(set(['a/', 'b']),
485
osutils.minimum_path_selection(['a/', 'b']))
486
self.assertEqual(set(['a/', 'b']),
487
osutils.minimum_path_selection(['a/c', 'a/', 'b']))
489
def test_mkdtemp(self):
490
tmpdir = osutils._win32_mkdtemp(dir='.')
491
self.assertFalse('\\' in tmpdir)
493
def test_rename(self):
501
osutils._win32_rename('b', 'a')
502
self.failUnlessExists('a')
503
self.failIfExists('b')
504
self.assertFileEqual('baz\n', 'a')
506
def test_rename_missing_file(self):
512
osutils._win32_rename('b', 'a')
513
except (IOError, OSError), e:
514
self.assertEqual(errno.ENOENT, e.errno)
515
self.assertFileEqual('foo\n', 'a')
517
def test_rename_missing_dir(self):
520
osutils._win32_rename('b', 'a')
521
except (IOError, OSError), e:
522
self.assertEqual(errno.ENOENT, e.errno)
524
def test_rename_current_dir(self):
527
# You can't rename the working directory
528
# doing rename non-existant . usually
529
# just raises ENOENT, since non-existant
532
osutils._win32_rename('b', '.')
533
except (IOError, OSError), e:
534
self.assertEqual(errno.ENOENT, e.errno)
536
def test_splitpath(self):
537
def check(expected, path):
538
self.assertEqual(expected, osutils.splitpath(path))
541
check(['a', 'b'], 'a/b')
542
check(['a', 'b'], 'a/./b')
543
check(['a', '.b'], 'a/.b')
544
check(['a', '.b'], 'a\\.b')
546
self.assertRaises(errors.BzrError, osutils.splitpath, 'a/../b')
549
class TestMacFuncsDirs(TestCaseInTempDir):
550
"""Test mac special functions that require directories."""
552
def test_getcwd(self):
553
# On Mac, this will actually create Ba\u030agfors
554
# but chdir will still work, because it accepts both paths
556
os.mkdir(u'B\xe5gfors')
558
raise TestSkipped("Unable to create Unicode filename")
560
os.chdir(u'B\xe5gfors')
561
self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
563
def test_getcwd_nonnorm(self):
564
# Test that _mac_getcwd() will normalize this path
566
os.mkdir(u'Ba\u030agfors')
568
raise TestSkipped("Unable to create Unicode filename")
570
os.chdir(u'Ba\u030agfors')
571
self.assertEndsWith(osutils._mac_getcwd(), u'B\xe5gfors')
574
class TestSplitLines(TestCase):
576
def test_split_unicode(self):
577
self.assertEqual([u'foo\n', u'bar\xae'],
578
osutils.split_lines(u'foo\nbar\xae'))
579
self.assertEqual([u'foo\n', u'bar\xae\n'],
580
osutils.split_lines(u'foo\nbar\xae\n'))
582
def test_split_with_carriage_returns(self):
583
self.assertEqual(['foo\rbar\n'],
584
osutils.split_lines('foo\rbar\n'))
587
class TestWalkDirs(TestCaseInTempDir):
589
def test_walkdirs(self):
598
self.build_tree(tree)
599
expected_dirblocks = [
601
[('0file', '0file', 'file'),
602
('1dir', '1dir', 'directory'),
603
('2file', '2file', 'file'),
607
[('1dir/0file', '0file', 'file'),
608
('1dir/1dir', '1dir', 'directory'),
611
(('1dir/1dir', './1dir/1dir'),
618
for dirdetail, dirblock in osutils.walkdirs('.'):
619
if len(dirblock) and dirblock[0][1] == '.bzr':
620
# this tests the filtering of selected paths
623
result.append((dirdetail, dirblock))
625
self.assertTrue(found_bzrdir)
626
self.assertEqual(expected_dirblocks,
627
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
628
# you can search a subdir only, with a supplied prefix.
630
for dirblock in osutils.walkdirs('./1dir', '1dir'):
631
result.append(dirblock)
632
self.assertEqual(expected_dirblocks[1:],
633
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
635
def test__walkdirs_utf8(self):
644
self.build_tree(tree)
645
expected_dirblocks = [
647
[('0file', '0file', 'file'),
648
('1dir', '1dir', 'directory'),
649
('2file', '2file', 'file'),
653
[('1dir/0file', '0file', 'file'),
654
('1dir/1dir', '1dir', 'directory'),
657
(('1dir/1dir', './1dir/1dir'),
664
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
665
if len(dirblock) and dirblock[0][1] == '.bzr':
666
# this tests the filtering of selected paths
669
result.append((dirdetail, dirblock))
671
self.assertTrue(found_bzrdir)
672
self.assertEqual(expected_dirblocks,
673
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
674
# you can search a subdir only, with a supplied prefix.
676
for dirblock in osutils.walkdirs('./1dir', '1dir'):
677
result.append(dirblock)
678
self.assertEqual(expected_dirblocks[1:],
679
[(dirinfo, [line[0:3] for line in block]) for dirinfo, block in result])
681
def _filter_out_stat(self, result):
682
"""Filter out the stat value from the walkdirs result"""
683
for dirdetail, dirblock in result:
685
for info in dirblock:
686
# Ignore info[3] which is the stat
687
new_dirblock.append((info[0], info[1], info[2], info[4]))
688
dirblock[:] = new_dirblock
690
def test_unicode_walkdirs(self):
691
"""Walkdirs should always return unicode paths."""
692
name0 = u'0file-\xb6'
693
name1 = u'1dir-\u062c\u0648'
694
name2 = u'2file-\u0633'
699
name1 + '/' + name1 + '/',
703
self.build_tree(tree)
705
raise TestSkipped('Could not represent Unicode chars'
706
' in current encoding.')
707
expected_dirblocks = [
709
[(name0, name0, 'file', './' + name0),
710
(name1, name1, 'directory', './' + name1),
711
(name2, name2, 'file', './' + name2),
714
((name1, './' + name1),
715
[(name1 + '/' + name0, name0, 'file', './' + name1
717
(name1 + '/' + name1, name1, 'directory', './' + name1
721
((name1 + '/' + name1, './' + name1 + '/' + name1),
726
result = list(osutils.walkdirs('.'))
727
self._filter_out_stat(result)
728
self.assertEqual(expected_dirblocks, result)
729
result = list(osutils.walkdirs(u'./'+name1, name1))
730
self._filter_out_stat(result)
731
self.assertEqual(expected_dirblocks[1:], result)
733
def test_unicode__walkdirs_utf8(self):
734
"""Walkdirs_utf8 should always return utf8 paths.
736
The abspath portion might be in unicode or utf-8
738
name0 = u'0file-\xb6'
739
name1 = u'1dir-\u062c\u0648'
740
name2 = u'2file-\u0633'
745
name1 + '/' + name1 + '/',
749
self.build_tree(tree)
751
raise TestSkipped('Could not represent Unicode chars'
752
' in current encoding.')
753
name0 = name0.encode('utf8')
754
name1 = name1.encode('utf8')
755
name2 = name2.encode('utf8')
757
expected_dirblocks = [
759
[(name0, name0, 'file', './' + name0),
760
(name1, name1, 'directory', './' + name1),
761
(name2, name2, 'file', './' + name2),
764
((name1, './' + name1),
765
[(name1 + '/' + name0, name0, 'file', './' + name1
767
(name1 + '/' + name1, name1, 'directory', './' + name1
771
((name1 + '/' + name1, './' + name1 + '/' + name1),
777
# For ease in testing, if walkdirs_utf8 returns Unicode, assert that
778
# all abspaths are Unicode, and encode them back into utf8.
779
for dirdetail, dirblock in osutils._walkdirs_utf8('.'):
780
self.assertIsInstance(dirdetail[0], str)
781
if isinstance(dirdetail[1], unicode):
782
dirdetail = (dirdetail[0], dirdetail[1].encode('utf8'))
783
dirblock = [list(info) for info in dirblock]
784
for info in dirblock:
785
self.assertIsInstance(info[4], unicode)
786
info[4] = info[4].encode('utf8')
788
for info in dirblock:
789
self.assertIsInstance(info[0], str)
790
self.assertIsInstance(info[1], str)
791
self.assertIsInstance(info[4], str)
792
# Remove the stat information
793
new_dirblock.append((info[0], info[1], info[2], info[4]))
794
result.append((dirdetail, new_dirblock))
795
self.assertEqual(expected_dirblocks, result)
797
def test_unicode__walkdirs_unicode_to_utf8(self):
798
"""walkdirs_unicode_to_utf8 should be a safe fallback everywhere
800
The abspath portion should be in unicode
802
name0u = u'0file-\xb6'
803
name1u = u'1dir-\u062c\u0648'
804
name2u = u'2file-\u0633'
808
name1u + '/' + name0u,
809
name1u + '/' + name1u + '/',
813
self.build_tree(tree)
815
raise TestSkipped('Could not represent Unicode chars'
816
' in current encoding.')
817
name0 = name0u.encode('utf8')
818
name1 = name1u.encode('utf8')
819
name2 = name2u.encode('utf8')
821
# All of the abspaths should be in unicode, all of the relative paths
823
expected_dirblocks = [
825
[(name0, name0, 'file', './' + name0u),
826
(name1, name1, 'directory', './' + name1u),
827
(name2, name2, 'file', './' + name2u),
830
((name1, './' + name1u),
831
[(name1 + '/' + name0, name0, 'file', './' + name1u
833
(name1 + '/' + name1, name1, 'directory', './' + name1u
837
((name1 + '/' + name1, './' + name1u + '/' + name1u),
842
result = list(osutils._walkdirs_unicode_to_utf8('.'))
843
self._filter_out_stat(result)
844
self.assertEqual(expected_dirblocks, result)
846
def assertPathCompare(self, path_less, path_greater):
847
"""check that path_less and path_greater compare correctly."""
848
self.assertEqual(0, osutils.compare_paths_prefix_order(
849
path_less, path_less))
850
self.assertEqual(0, osutils.compare_paths_prefix_order(
851
path_greater, path_greater))
852
self.assertEqual(-1, osutils.compare_paths_prefix_order(
853
path_less, path_greater))
854
self.assertEqual(1, osutils.compare_paths_prefix_order(
855
path_greater, path_less))
857
def test_compare_paths_prefix_order(self):
858
# root before all else
859
self.assertPathCompare("/", "/a")
861
self.assertPathCompare("/a", "/b")
862
self.assertPathCompare("/b", "/z")
863
# high dirs before lower.
864
self.assertPathCompare("/z", "/a/a")
865
# except if the deeper dir should be output first
866
self.assertPathCompare("/a/b/c", "/d/g")
867
# lexical betwen dirs of the same height
868
self.assertPathCompare("/a/z", "/z/z")
869
self.assertPathCompare("/a/c/z", "/a/d/e")
871
# this should also be consistent for no leading / paths
872
# root before all else
873
self.assertPathCompare("", "a")
875
self.assertPathCompare("a", "b")
876
self.assertPathCompare("b", "z")
877
# high dirs before lower.
878
self.assertPathCompare("z", "a/a")
879
# except if the deeper dir should be output first
880
self.assertPathCompare("a/b/c", "d/g")
881
# lexical betwen dirs of the same height
882
self.assertPathCompare("a/z", "z/z")
883
self.assertPathCompare("a/c/z", "a/d/e")
885
def test_path_prefix_sorting(self):
886
"""Doing a sort on path prefix should match our sample data."""
917
sorted(original_paths, key=osutils.path_prefix_key))
918
# using the comparison routine shoudl work too:
921
sorted(original_paths, cmp=osutils.compare_paths_prefix_order))
924
class TestCopyTree(TestCaseInTempDir):
926
def test_copy_basic_tree(self):
927
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
928
osutils.copy_tree('source', 'target')
929
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
930
self.assertEqual(['c'], os.listdir('target/b'))
932
def test_copy_tree_target_exists(self):
933
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c',
935
osutils.copy_tree('source', 'target')
936
self.assertEqual(['a', 'b'], sorted(os.listdir('target')))
937
self.assertEqual(['c'], os.listdir('target/b'))
939
def test_copy_tree_symlinks(self):
940
self.requireFeature(SymlinkFeature)
941
self.build_tree(['source/'])
942
os.symlink('a/generic/path', 'source/lnk')
943
osutils.copy_tree('source', 'target')
944
self.assertEqual(['lnk'], os.listdir('target'))
945
self.assertEqual('a/generic/path', os.readlink('target/lnk'))
947
def test_copy_tree_handlers(self):
950
def file_handler(from_path, to_path):
951
processed_files.append(('f', from_path, to_path))
952
def dir_handler(from_path, to_path):
953
processed_files.append(('d', from_path, to_path))
954
def link_handler(from_path, to_path):
955
processed_links.append((from_path, to_path))
956
handlers = {'file':file_handler,
957
'directory':dir_handler,
958
'symlink':link_handler,
961
self.build_tree(['source/', 'source/a', 'source/b/', 'source/b/c'])
962
if osutils.has_symlinks():
963
os.symlink('a/generic/path', 'source/lnk')
964
osutils.copy_tree('source', 'target', handlers=handlers)
966
self.assertEqual([('d', 'source', 'target'),
967
('f', 'source/a', 'target/a'),
968
('d', 'source/b', 'target/b'),
969
('f', 'source/b/c', 'target/b/c'),
971
self.failIfExists('target')
972
if osutils.has_symlinks():
973
self.assertEqual([('source/lnk', 'target/lnk')], processed_links)
976
#class TestTerminalEncoding has been moved to test_osutils_encodings.py
977
# [bialix] 2006/12/26
980
class TestSetUnsetEnv(TestCase):
981
"""Test updating the environment"""
984
super(TestSetUnsetEnv, self).setUp()
986
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'),
987
'Environment was not cleaned up properly.'
988
' Variable BZR_TEST_ENV_VAR should not exist.')
990
if 'BZR_TEST_ENV_VAR' in os.environ:
991
del os.environ['BZR_TEST_ENV_VAR']
993
self.addCleanup(cleanup)
996
"""Test that we can set an env variable"""
997
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
998
self.assertEqual(None, old)
999
self.assertEqual('foo', os.environ.get('BZR_TEST_ENV_VAR'))
1001
def test_double_set(self):
1002
"""Test that we get the old value out"""
1003
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1004
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'bar')
1005
self.assertEqual('foo', old)
1006
self.assertEqual('bar', os.environ.get('BZR_TEST_ENV_VAR'))
1008
def test_unicode(self):
1009
"""Environment can only contain plain strings
1011
So Unicode strings must be encoded.
1013
uni_val, env_val = probe_unicode_in_user_encoding()
1015
raise TestSkipped('Cannot find a unicode character that works in'
1016
' encoding %s' % (bzrlib.user_encoding,))
1018
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', uni_val)
1019
self.assertEqual(env_val, os.environ.get('BZR_TEST_ENV_VAR'))
1021
def test_unset(self):
1022
"""Test that passing None will remove the env var"""
1023
osutils.set_or_unset_env('BZR_TEST_ENV_VAR', 'foo')
1024
old = osutils.set_or_unset_env('BZR_TEST_ENV_VAR', None)
1025
self.assertEqual('foo', old)
1026
self.assertEqual(None, os.environ.get('BZR_TEST_ENV_VAR'))
1027
self.failIf('BZR_TEST_ENV_VAR' in os.environ)
1030
class TestLocalTimeOffset(TestCase):
1032
def test_local_time_offset(self):
1033
"""Test that local_time_offset() returns a sane value."""
1034
offset = osutils.local_time_offset()
1035
self.assertTrue(isinstance(offset, int))
1036
# Test that the offset is no more than a eighteen hours in
1038
# Time zone handling is system specific, so it is difficult to
1039
# do more specific tests, but a value outside of this range is
1041
eighteen_hours = 18 * 3600
1042
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1044
def test_local_time_offset_with_timestamp(self):
1045
"""Test that local_time_offset() works with a timestamp."""
1046
offset = osutils.local_time_offset(1000000000.1234567)
1047
self.assertTrue(isinstance(offset, int))
1048
eighteen_hours = 18 * 3600
1049
self.assertTrue(-eighteen_hours < offset < eighteen_hours)
1052
class TestShaFileByName(TestCaseInTempDir):
1054
def test_sha_empty(self):
1055
self.build_tree_contents([('foo', '')])
1056
expected_sha = osutils.sha_string('')
1057
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))
1059
def test_sha_mixed_endings(self):
1060
text = 'test\r\nwith\nall\rpossible line endings\r\n'
1061
self.build_tree_contents([('foo', text)])
1062
expected_sha = osutils.sha_string(text)
1063
self.assertEqual(expected_sha, osutils.sha_file_by_name('foo'))